格式化字符串漏洞实验

格式化字符串漏洞是由像 printf(user_input) 这样的代码引起的,其中 user_input 是用户输入的数据,具有 Set-UID root 权限的这类程序在运行的时候,printf 语句将会变得非常危险。

  • 实验一:

找出 secret[1]的值

输入命令:

ls
vi test.c
gcc -z execstack -fno-stack-protector -o djw test.c

其中test.c的代码为

include <stdlib.h>
include <stdio.h> define SECRET1 0x44
define SECRET2 0x55 int main(int argc, char *argv[])
{
char user_input[100];
int *secret;
long int_input;
int a, b, c, d; /* other variables, not used here.*/ /* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int)); /* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2; printf("The variable secret's address is 0x%8x (on stack)\n", &secret);
printf("The variable secret's value is 0x%8x (on heap)\n", secret);
printf("secret[0]'s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]'s address is 0x%8x (on heap)\n", &secret[1]); printf("Please enter a decimal integer\n");
scanf("%d", &int_input); /* getting an input from user */
printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */ /* Vulnerable place */
printf(user_input);
printf("\n"); /* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]);
return 0;
}

编译后进行执行,如图

首先定位 int_input 的位置,这样就确认了%s 在格式字符串中的位置(由于与文档上000000000000000C不一致,所以要进一步确定位置)

用%08x进行显示,如图

输入 secret[1]的地址,记得做进制转换,同时在格式字符串中加入%s,如图



U 的 ascii 码就是 55。

修改 secret[1]的值

如果只要求修改,不要求改什么,可以利用%n进行修改,修改如下:

修改 secret[1]为期望值

要改成自己期望的值,可以进行填充:



%n可以进行计数,0x3e8 = 1000。

  • 实验二:

include <sys/types.h>
include <sys/stat.h>
include <fcntl.h>
int main()
{
char buf[1000];
int fp, size;
unsigned int *address;
/* Putting any number you like at the beginning of the format string */
address = (unsigned int *) buf;
*address = 0x113222580;
/* Getting the rest of the format string */
scanf("%s", buf+4);
size = strlen(buf+4) + 4;
printf("The string length is %d\n", size);
/* Writing buf to "mystring" */
fp = open("mystring", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fp != -1) {
write(fp, buf, size);
close(fp);
} else {
printf("Open failed!\n");
}
}

现在让我们把第一个实验中的 scanf 语句去掉,并去掉与 int_input 变量相关的所有语句,同时设置关闭地址随机化选项。操作如下:



在这里,刚开始碰到了问题,权限不够。后来用sudo进行提权,要输入密码,根据以往设计者的情况,密码为dees,进行提权后指令即可执行成功。

修改 secret[0]的值

修改 test.c 后编译 test.c 与 write_string.c 然后通过 write_string 程序将内容输入进 mystring 文件中,文件内容包括代码中加入的头四个字节和你之后输入的内容。实验过程如下:



在这里试验了好多次,由于刚开始没有找准位置,以为./test不需要,./write_string之后直接按之前的位置安放%n进行输入就好。导致The original secrets和The news secret内容一致,甚至出现segmentation fault的情况。后来总结了一下,重新对test进行测试,找准了位置,再进行上面命令的输入,就得到了准确的结果。

0x31=49=5*8+5个逗号+开头4个字节。

最新文章

  1. C# 取整函数
  2. C#基础——系统登录功能的实现
  3. nginx和apache的比较
  4. 记录git多人协作开发常用的流程,供新手参考
  5. 是什么时候开始学习gulp了
  6. javascript限制上传文件大小
  7. Babelfish 分类: 哈希 2015-08-04 09:25 2人阅读 评论(0) 收藏
  8. cocos2d-x 3.0正式版 环境搭建 (解决载入失败,未能载入XXX包)
  9. 佛主保佑,永无bug
  10. 点击按钮改变标签内容(采用lambda函数方式)
  11. Swagger+Spring MVC框架学习分享
  12. jQuery复习:第四章
  13. javascript中=,==,与===的区别;以及特殊值NaN的讲解
  14. CDQ分治嵌套模板:多维偏序问题
  15. tornado 采用 epoll 代理构建高并发网络模型
  16. 如何利用MongoDB实现高性能,高可用的双活应用架构?
  17. Validator验证框架
  18. Web API Request Content多次读取
  19. UVA548 tree的思路
  20. docker学习(1)--基础概念

热门文章

  1. js的异步执行
  2. 用kryonet时kryo报buffer underflow错误
  3. Storm入门3-集群搭建
  4. WPF内置命令
  5. asp.net天网代码
  6. github项目配置
  7. Linux环境部署(JDK/Tomcat/MySQL/证书)
  8. yyyy-MM-dd与YYYY-MM-dd
  9. arm-linux-androideabi-addr2line
  10. VIM小技巧