正己 发表于 2020-12-1 21:37

攻防世界mobile之easy-so

# **前言:**
每周一题,做做笔记,这个也不难,就是一个简单的算法。
软件链接:[飞机票](https://adworld.xctf.org.cn/media/task/attachments/456c1dab04b24036ba1d6e32a08dc882.apk)
***
# **过程:**
运行app,根据提示的字符串,打开jadx,搜索字符串,然后发现上方有个方法对这个条件进行判断,按住Ctrl跳过去,于是就看到了熟悉的native。

上IDA,搜索刚才的方法名check,只有一个结果,双击跳过去,F5转伪代码,大概看一下,就是`TestDec`输出的字符串和`f72c5a36569418a20907b55be5bf95ad`进行对比,如果相等则返回1,也就是验证通过。

双击`TestDec`,康康里面的运行逻辑。

代码如下:
```
v1 = (char *)a1;    //把a1的强转换成了char指针
if ( strlen(a1) >= 2 )//判断a1的长度是否大于等于2,如果是,则进行下面的逻辑
{
    v2 = 0;//初始化v2的值为0
    do   //第一个循环体
    {
      v3 = (int)&v1;   
      v4 = v1;   //取v1的地址
      v1 = v1; //逐个将v1的第v2个字符与第v2+16个字符交换位置
      ++v2; //v2自增
      *(_BYTE *)(v3 + 16) = v4;
    }
    while ( v2 < strlen(v1) >> 1 );   //结束循环的条件
}
result = (unsigned __int8)*v1; //条件不满足再把a1强转成unsigned__int18
if ( *v1 )
{
    *v1 = v1;
    v1 = result;
    result = strlen(v1);
    if ( result >= 3 )
    {
      v6 = 0;//初始化v6的值为0
      do   //第二个循环体
      {
      v7 = (int)&v1;
      v8 = v1; //取v1的地址
      *(_BYTE *)(v7 + 2) = v1;//逐个将v1的第v6+3个字符与第v7+2个字符交换位置
      *(_BYTE *)(v7 + 3) = v8;
      result = strlen(v1);
      v9 = v6 + 4;
      v6 += 2;
      }
      while ( v9 < result );
    }
}
return result;
```
其实关键的就是那两个循环体,第一个循环体将字符串从中间砍断,头拼接到尾,第二个循环体将字符串两两交换。接着打开我们的IDLE,编写一个简单的脚本来还原字符串,代码如下
```
data = list('f72c5a36569418a20907b55be5bf95ad') //把字符串传入,并转为列表
for i in range(len(data)//2)://第一个循环体
    a = data
    data = data
    data = a
for i in range(0,len(data),2)://第二个循环体
        a2 = data
        data=data
        data=a2
key=''.join(data) //拼接字符串
print("flag{"+key+"}")//把题目中的flag{}和最终字符串拼接并输出
```
***
# **最后:**
看一下IDLE的输出结果`flag{90705bb55efb59da7fc2a5636549812a}`,再到app测试一下,flag正确!

HNHuangJingYU 发表于 2021-9-18 15:34

本帖最后由 HNHuangJingYU 于 2021-9-22 11:49 编辑

代码加密其实就是两个循环进行位置互换
因为只是位置互换所以我们只要按着顺序去倒回来就行

    @Test
    public void demo2() {
      String str = "f72c5a36569418a20907b55be5bf95ad";
      char[] data = str.toCharArray();

      //伪代码中的第二次循环
      int index2 = 0;
      int result;
      int v9;
      do {
            char v8 = data;
            data = data;
            data = v8;
            result = data.length;
            v9 = index2 + 4;
            index2 += 2;
      }
      while (v9 < result);


      //循环后进行的简单的互换
      result = data;
      data = data;
      data = (char) result;
      result = data.length;


      //伪代码中第一次循环
      int index = 0;
      do
      {
            char v4 = data;
            data = data;
            data = v4;
            ++index;
      }
      while ( index < data.length >> 1 );

      System.out.println(data);
      //输出结果 -> 90705bb55efb59da7fc2a5636549812a
    }


正己 发表于 2020-12-1 21:38

溜了溜了

yiwai2012 发表于 2020-12-1 22:29

这是成神之路的第一个笔记 学习了

qihang5518 发表于 2020-12-1 22:32

谢谢分享代码教程,小白也可以跟着学习

芽衣 发表于 2020-12-1 23:28

来了来了

{:301_1003:}

K.G暗雪 发表于 2020-12-1 23:44

开始学习ctf!

CYD 发表于 2020-12-2 01:45

大佬牛逼

okgjkk 发表于 2020-12-2 08:07

非常满意学习了

bdcen007 发表于 2020-12-2 08:41

不好意思,走错了,我还以为是个游戏呢{:1_911:}

whofly 发表于 2020-12-2 09:13

攻防世界的人才啊
页: [1] 2 3 4
查看完整版本: 攻防世界mobile之easy-so