IE控件使用F12开发者工具
2020-08-25 12:35:00 Author: bbs.pediy.com(查看原文) 阅读量:368 收藏

雪    币: 25

活跃值: 活跃值 (157)

能力值:

( LV2,RANK:10 )

在线值:

入门级 So静态分析 CTF 之 easy-so write up

18小时前 337

入门级 So静态分析 CTF 之 easy-so write up

拿到 flag 值

APK 用 jadx 反编译后如图:

图片描述

查看判断函数 cyberpeace.CheckString 代码位置

图片描述

该题重点不在 Java 层, 只是调用了 so 计算下结果,然后再So中进行比对,成功核对 flag 则返回 1, 所以我们只需要研究 so 层即可

图片描述
这里用的是静态注册 Java_com_testjava_jack_pingan2_cyberpeace_CheckString

图片描述
从末尾往上找发现, 最终进行了 字符串比较, 下面是IDA反编译出来的伪代码(amr64)

bool __fastcall Java_com_testjava_jack_pingan2_cyberpeace_CheckString(__int64 a1)
{
  __int64 v1; // x0
  __int64 v2; // x20
  __int64 v3; // x0
  int v4; // w21
  unsigned __int64 v5; // x22
  __int64 v6; // x0
  _BYTE *v7; // x19
  unsigned __int64 v8; // x2
  unsigned __int64 v9; // x20
  _BYTE *v10; // x8
  char v11; // w9
  char v12; // w10
  char v13; // w9
  __int64 v14; // x20
  _BYTE *v15; // x8
  char v16; // w10
  unsigned __int64 v17; // x0
  unsigned __int64 v18; // x8

  v1 = (*(*a1 + 1352LL))();
  v2 = v1;
  v3 = strlen(v1);
  v4 = v3;
  v5 = ((v3 << 32) + 0x100000000LL) >> 32;
  v6 = malloc(v5);
  v7 = v6;
  if ( v5 > v4 )
    v8 = v5 - v4;
  else
    v8 = 0LL;
  memset(v6 + v4, 0LL, v8);
  memcpy(v7, v2, v4);
  if ( strlen(v7) >= 2 )
  {
    v9 = 0LL;
    do
    {
      v10 = &v7[v9];
      v11 = v7[v9 + 16];
      v12 = v7[v9++];
      *v10 = v11;
      v10[16] = v12;
    }
    while ( strlen(v7) >> 1 > v9 );
  }
  if ( *v7 )
  {
    v13 = v7[1];
    v7[1] = *v7;
    *v7 = v13;
    if ( strlen(v7) >= 3 )
    {
      v14 = 0LL;
      do
      {
        v15 = &v7[v14];
        v16 = v7[v14 + 2];
        v15[2] = v7[v14 + 3];
        v15[3] = v16;
        v17 = strlen(v7);
        v18 = v14 + 4;
        v14 += 2LL;
      }
      while ( v17 > v18 );
    }
  }
  return strcmp(v7, "f72c5a36569418a20907b55be5bf95ad") == 0;
}

因为最终是用 v7 来做字符串比较,所以我们分析 v7 是怎么来的即可,从下往上看

if ( *v7 ) // v7如果存在进入体内
  {
    v13 = v7[1];
    v7[1] = *v7;
    *v7 = v13;
    if ( strlen(v7) >= 3 )
    {
      v14 = 0LL;
      do
      {
        v15 = &v7[v14];
        v16 = v7[v14 + 2];
        v15[2] = v7[v14 + 3];
        v15[3] = v16;
        v17 = strlen(v7);
        v18 = v14 + 4;
        v14 += 2LL;
      }
      while ( v17 > v18 );
    }
  }

这块是一个位符 两两交换的操作 比如 123456 交换后就是 214365, 我们把 f72c5a36569418a20907b55be5bf95ad 两两交换回去得到 7fc2a5636549812a90705bb55efb59da

再往上看

  memset(v6 + v4, 0LL, v8);
  memcpy(v7, v2, v4);
  if ( strlen(v7) >= 2 )
  {
    v9 = 0LL;
    do
    {
      v10 = &v7[v9];
      v11 = v7[v9 + 16];
      v12 = v7[v9++];
      *v10 = v11;
      v10[16] = v12;
    }
    while ( strlen(v7) >> 1 > v9 );
  }

这是一个腰斩交换, 相当于 123456 换成了 456123
我们把上一步得到的 7fc2a5636549812a90705bb55efb59da 还回去得到结果flag
90705bb55efb59da7fc2a5636549812a

这是ctf上一个入门 so 题目, 很适合新手上手,感谢出题人。

[公告]SDC2020 看雪安全者开发者峰会10月23日将在上海举行!欢迎参加!


文章来源: https://bbs.pediy.com/thread-261626.htm
如有侵权请联系:admin#unsafe.sh