目录
elrond32
tt3441810
re2-cpp-is-awesome
流浪者
SignIn
ease_Maze
ReverseMe-120
使用ida打开
需要使用参数1输入数据,然后放到sub_8048414函数中验证。
进入sub_8048414函数:
函数中对参数1的第一个字符使用参数2分支进行比较,后面有递归调用:
参数2的取值为 7 * (a2 + 1) % 11)
解密过程如下:
tal="ie ndags r "
a2=0
r="i"
while a2<10 :
a2 = 7 * (a2 + 1) % 11
r+=tal[a2]
print(r)
得到结果:isengard
启动程序输入参数得到flag:
拿到题目:
00400080 68 66 6C 00 00 48 BF 01 00 00 00 00 00 00 00 48
00400090 8D 34 24 48 BA 02 00 00 00 00 00 00 00 48 B8 01
004000A0 00 00 00 00 00 00 00 0F 05 68 61 67 00 00 48 BF
004000B0 01 00 00 00 00 00 00 00 48 8D 34 24 48 BA 02 00
004000C0 00 00 00 00 00 00 48 B8 01 00 00 00 00 00 00 00
004000D0 0F 05 68 7B 70 00 00 48 BF 01 00 00 00 00 00 00
004000E0 00 48 8D 34 24 48 BA 02 00 00 00 00 00 00 00 48
004000F0 B8 01 00 00 00 00 00 00 00 0F 05 68 6F 70 00 00
00400100 48 BF 01 00 00 00 00 00 00 00 48 8D 34 24 48 BA
00400110 02 00 00 00 00 00 00 00 48 B8 01 00 00 00 00 00
00400120 00 00 0F 05 68 70 6F 00 00 48 BF 01 00 00 00 00
00400130 00 00 00 48 8D 34 24 48 BA 02 00 00 00 00 00 00
00400140 00 48 B8 01 00 00 00 00 00 00 00 0F 05 68 70 72
00400150 00 00 48 BF 01 00 00 00 00 00 00 00 48 8D 34 24
00400160 48 BA 02 00 00 00 00 00 00 00 48 B8 01 00 00 00
00400170 00 00 00 00 0F 05 68 65 74 00 00 48 BF 01 00 00
00400180 00 00 00 00 00 48 8D 34 24 48 BA 02 00 00 00 00
00400190 00 00 00 48 B8 01 00 00 00 00 00 00 00 0F 05 68
004001A0 7D 0A 00 00 48 BF 01 00 00 00 00 00 00 00 48 8D
004001B0 34 24 48 BA 02 00 00 00 00 00 00 00 48 B8 01 00
004001C0 00 00 00 00 00 00 0F 05 48 31 FF 48 B8 3C 00 00
004001D0 00 00 00 00 00 0F 05
应该是dump出来的一段代码,拖放到ida中查看,转换为代码
找到一些push指令,把所有push的字节连接起来,注意最后一个:
‘}’前有个结束符, push是作为word处理的的 所以有可能需要把字节颠倒,并且颠倒后前四个字节为“flag”,得到:
flag{po***pret}
提交需要去掉flag。。。
放到ida中,关键代码:
v15 = 0;
for ( i = std::__cxx11::basic_string,std::allocator>::begin(&input); ; inc(&i) )
{
v14 = std::__cxx11::basic_string,std::allocator>::end(&input);
if ( !sub_400D3D((__int64)&i, (__int64)&v14) )
break;
v9 = *(unsigned __int8 *)ret_qword((__int64)&i);// 获取当前的第一个字节,也就是第i个字节
if ( (_BYTE)v9 != off_6020A0[dword_6020C0[v15]] )// 关键算法,v15是递增值=i, dword_6020C0是word,去获取off_6020A0中对应的值
print_err((__int64)&i, (__int64)&v14, v9);
++v15;
}
print_succ((__int64)&i, (__int64)&v14, v8);
off_6020A0 对应的字符串
dword_6020C0对应的数据,注意要用dword:
算法如下:
offstr="L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t"
index=[0x24,0x0,0x5,0x36,0x65,0x7,0x27,0x26,0x2D,0x1,0x3,0x0,0x0D,0x56,0x1,0x3,0x65,0x3,0x2D,0x16,0x2,0x15,0x3,0x65,0x0,0x29,0x44,0x44,0x1,0x44,0x2B]
flag=""
for i in range(0,50):
try:
flag += offstr[index[i]]
except:
print(flag)
break
同样放入ida,查看字符串
双击 恭喜 然后 ctrl x 查看调用
一直找到
Str1比较 字符串,上面有关键逻辑,Str1字符串是aAbcd...字符串的索引 p=*(a1+4i)
继续按X查找上层
注意v5是 int型数组
逆向代码:
tls="abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
dest = "KanXueCTF2019JustForhappy"
flag=""
for i in dest:
i=tls.index(i)
if i<10:
flag +=chr(i+48)
elif i < 36:
flag +=chr(i+87)
else:
flag += chr(i+29)
print(flag)
解压后ue打开看了下是ELF文件,拖到ida找到关键代码:
powm没见过不过上面有个65537 同时pow是指数运算,可以猜测是rsa公钥加密,对应的e、n、c已知,输入的数据处理后为m
先分解n得到p,q:
解出m:
输入数据转m的过程为:
字符串:
过程就是bytes转hex
所以m直接转可得:
import gmpy2
n=103461035900816914121390101299049044413950405173712170434161686539878160984549
c=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
p=282164587459512124844245113950593348271
q=366669102002966856876605669837014229419
e=65537
d=int(gmpy2.invert(e,(p-1)*(q-1)))
m=pow(c,d,n)
mhex = hex(m)[2:]
print(bytes.fromhex(mhex))
看题目必然是跟迷宫有关系,放大ida:
Step_0和Step_1生成迷宫,Step_2里面有循环输入,是需要走迷宫。所以0和1两步不用看,直接在Step_2里面下断点获取迷宫数据:
查看内容数据:x /48dw 0x7fffffffde50
分析Step_2代码:
判断条件是: 7 * v10 + v9 == 1
所以迷宫为7行、7列,V10为纵坐标,V9横坐标,对应的:
w - 上
a - 左
s - 下
d - 右
将迷宫处理一下:
1001111
1011001
1110111
0001100
1111000
1000111
111110
走1的路线:
ssddwdwdddssaasasaaassddddwdds
在这里提交了一下没成功,就在程序里面走完了,打印出了flag:
ida中查看字符串也可以看到flag的格式:
ida中查看算法:
可以计算出 上面sub_401000函数输出的数据,也就是"you_know_how_to_remove_junk_code"每个字节与0x25异或。
然后查看sub_401000函数可见
是一个4字节处理成3字节 结合上面的 byte_414E40可以得知base64解密算法。动态跟踪也能看出来。
最后代码:
import base64
encdata = "you_know_how_to_remove_junk_code"
xx=0x25252525252525252525252525252525
encdata2=""
for i in range(0,len(encdata)):
encdata2+= chr(ord(encdata[i])^0x25)
print(base64.b64encode(encdata2.encode()))