type
status
date
slug
summary
tags
category
icon
password
昨天打了一下鹏城的比赛,里面的pwn题有一道比较有趣,需要自己写一下shellcode,这题,一开始我这里本地都能打通但远程打不通,后面给学长看了,学长帮我改了一下之后就打通了,这里记录下我写的脚本的问题所在,与后面学长的修改。
 
先讲一下有关于shellcode的编写。在程序中我们使用的pwntools默认的是32为程序,因此我们在写64位时要注意在要在最开始加上
 
然后在编写时要注意用以下格式,
在我们自己编写的shellcode里面要注意如果我们要修改某一个寄存器上的数值时要注意最好使用栈来传递,不要用mov直接传。比如我要修改rdx上的值为0xff
那就先将0xff压栈,然后在出栈到rdx中。
 
这道题基础思路就在我们申请的堆的指针被放在栈上,然后我们可以申请50个堆块,第50个堆块的指针刚好在main函数的返回地址那,然后程序将我们申请的堆块的地址的权限改为可读可写可执行(raw),于是我们就可以在申请序号为49(就是第50个)的堆块里写入shellcode。
 
但这个程序有问题在与,我们申请的这个chunk的大小只有0x20,能给我们写的长度更是只有0x10的长度,并且程序在最后有一个沙箱的存在,
与是我们就是考虑通过向49的chunk里写shellcode,在执行这个shellcode的,向raw的段写入orw的shellcode并让程序执行orw。
 
现在我们就来看看在执行我们的shellcode时程序中的寄存器都是什么,看看能不能找到供我们使用的
notion image
现在就是我们程序中的情况,可以看到此时的rax的值为0,那我们要执行read系统调用函数的系统调用号已经设置好了。
我们知道read函数还有设置rsi,rdi,rdx这3个寄存器。其中rsi为写入数据的地址,rdi为输入参数默认为0,rdx为要输入的数据长度。
此时在程序中可以看到rsi执行的为0x637b33d35010 ,这里是程序中所有heap的起始地址的+7位置,这里也有raw权限,并且空间足够我们写数据。
rdi此时为7,我们要修改为0,这里我们可以使用xor rdi,rdi 这个命令直接将rdi中的值归零。
RDX我们要修改为我们读入数据的长度,这里现在为0x637b33d35fe0 理论上了说是不用修改的,我们反正读入数据没这么多,但我一开始就是没修改这个寄存器,就导致我本地能打通,但远程打不通,然后在学长的电脑上也打不通本地。后来就感觉这个还是要想修改为比较小的数值。
与是对某一个寄存器传具体的参数要用栈来传递,就要先把0xff压入栈中,然后在把这个数出栈到rdx中。
然后就可以调用syscal进行系统调用
notion image
此时就可以执行向rsi-0x637b33d35010里读入0xff的数据,然后我们在使用jmp指令跳转到rsi里去执行我们写入的orw指令。
 
exp
 
这道题整体不难,但比较考验动调,其中的栈溢出和控制程序执行read,再跳转执行orw从而把flag直接输出来。
要注意的就是要修改一个寄存器的具体内容要先把那个内容压栈push,然后再将其pop到要修改的寄存器中。
house of系列泄露libc的一种奇妙办法
Loading...