攻防世界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-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
}
溜了溜了 这是成神之路的第一个笔记 学习了 谢谢分享代码教程,小白也可以跟着学习 来了来了
{:301_1003:} 开始学习ctf! 大佬牛逼 非常满意学习了 不好意思,走错了,我还以为是个游戏呢{:1_911:} 攻防世界的人才啊