• Linux (x86) Exploit 开发系列教程之二(整数溢出)


    (1)漏洞代码

    //vuln.c
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void store_passwd_indb(char * passwd){
    }
    void validate_uname(char * uname){
    }
    void validate_passwd(char * passwd){
     char passwd_buf [11];
     unsigned char passwd_len = strlen(passwd); / * [1] * /
     if(passwd_len> = 4 && passwd_len <= 8){/ * [2] * /
      printf(“有效密码 n”); / * [3] * /
      fflush(stdout);
      strcpy(passwd_buf,passwd); / * [4] * /
     } else {
      printf(“Invalid Password  n”); / * [5] * /
      fflush(stdout);
     }
     store_passwd_indb(passwd_buf); / * [6] * /
    }
    int main(int argc,char * argv []){
     if(argc!= 3){
      printf(“Usage Error: n”);
      fflush(stdout);
      退出(-1);
     }
     validate_uname(argv [1]);
     validate_passwd(argv [2]);
     返回0;
    }
    

     (2)编译文件

    sudo sh -c "echo 0> / proc / sys / kernel / randomize_va_space"
     gcc -g -fno-stack-protector -z execstack -o vuln vuln.c
     sudo chown root vuln
     sudo chgrp root vuln
     sudo chmod + s vuln
    

     (3)原理:

    上述漏洞代码的[1]行显示了一个整数溢出错误。strlen()的返回类型是size_t(unsigned int),它存储在unsigned char数据类型中。因此,任何大于unsigned char的最大支持值(255)的值都会导致整数溢出。因此当密码长度为261时,261将被包裹并存储为“passwd_len”变量中的5!由于这个整数溢出,可以绕过行[2]执行的边界检查,从而导致基于堆栈的缓冲区溢出!

    (4)反汇编并绘制出漏洞代码的堆栈布局

    gdb-peda$ disassemble validate_passwd 
    Dump of assembler code for function validate_passwd:
       0x0804849e <+0>:	push   ebp
       0x0804849f <+1>:	mov    ebp,esp
       0x080484a1 <+3>:	push   edi
       0x080484a2 <+4>:	sub    esp,0x34
       0x080484a5 <+7>:	mov    eax,DWORD PTR [ebp+0x8]
       0x080484a8 <+10>:	mov    DWORD PTR [ebp-0x1c],0xffffffff
       0x080484af <+17>:	mov    edx,eax
       0x080484b1 <+19>:	mov    eax,0x0
       0x080484b6 <+24>:	mov    ecx,DWORD PTR [ebp-0x1c]
       0x080484b9 <+27>:	mov    edi,edx
       0x080484bb <+29>:	repnz scas al,BYTE PTR es:[edi]
       0x080484bd <+31>:	mov    eax,ecx
       0x080484bf <+33>:	not    eax
       0x080484c1 <+35>:	sub    eax,0x1
       0x080484c4 <+38>:	mov    BYTE PTR [ebp-0x9],al
       0x080484c7 <+41>:	cmp    BYTE PTR [ebp-0x9],0x3
       0x080484cb <+45>:	jbe    0x8048500 <validate_passwd+98>
       0x080484cd <+47>:	cmp    BYTE PTR [ebp-0x9],0x8
       0x080484d1 <+51>:	ja     0x8048500 <validate_passwd+98>
       0x080484d3 <+53>:	mov    DWORD PTR [esp],0x8048660
       0x080484da <+60>:	call   0x80483a0 <puts@plt>
       0x080484df <+65>:	mov    eax,ds:0x804a020
       0x080484e4 <+70>:	mov    DWORD PTR [esp],eax
       0x080484e7 <+73>:	call   0x8048380 <fflush@plt>
       0x080484ec <+78>:	mov    eax,DWORD PTR [ebp+0x8]
       0x080484ef <+81>:	mov    DWORD PTR [esp+0x4],eax
       0x080484f3 <+85>:	lea    eax,[ebp-0x14]
       0x080484f6 <+88>:	mov    DWORD PTR [esp],eax
       0x080484f9 <+91>:	call   0x8048390 <strcpy@plt>
       0x080484fe <+96>:	jmp    0x8048519 <validate_passwd+123>
       0x08048500 <+98>:	mov    DWORD PTR [esp],0x804866f
       0x08048507 <+105>:	call   0x80483a0 <puts@plt>
       0x0804850c <+110>:	mov    eax,ds:0x804a020
       0x08048511 <+115>:	mov    DWORD PTR [esp],eax
       0x08048514 <+118>:	call   0x8048380 <fflush@plt>
       0x08048519 <+123>:	lea    eax,[ebp-0x14]
       0x0804851c <+126>:	mov    DWORD PTR [esp],eax
       0x0804851f <+129>:	call   0x8048494 <store_passwd_indb>
       0x08048524 <+134>:	add    esp,0x34
       0x08048527 <+137>:	pop    edi
       0x08048528 <+138>:	pop    ebp
       0x08048529 <+139>:	ret    
    End of assembler dump.
    

     

    (5)当输入长度为261的密码,可以绕过边界检查,并允许我们覆盖堆栈中的返回地址。测试:

     EBP、EIP被覆盖为四个A

    (6)堆栈布局显示返回地址位于缓冲区'passwd_buf'的偏移(0x18)处。0x18计算如下:0xb+0x1+0x4+0x4+0x4,因此当用户输入“A” * 24 + “B” * 4 + “C” * 233,以A覆盖passwd_buf,passwd_len,对齐空间,edi和调用者的ebp,以“BBBB”覆盖返回地址,以"C"覆盖剩余空间.

    (6)找出shellcode的起始地址。ret_addr可以选择100个NOP里。

    攻击代码如下:

    运行,获取到root shell权限

    由于无法解释的神圣旨意,我们徒然地到处找你;你就是孤独,你就是神秘,比恒河或者日落还要遥远。。。。。。
  • 相关阅读:
    登陆中发现css页面不见了,变成了光秃秃的输入框问题
    servlet基础一
    解决问题:Error:(5, 59) java: 程序包javax.servlet.http不存在
    静态方法的引用
    登录功能之添加验证码(包含切换验证码)
    生成图片验证码(VerifyCode)
    idea编辑器中批量完成注释及批量取消注释
    jdbc连接测试
    利用IO流复制图片
    js 判空
  • 原文地址:https://www.cnblogs.com/momoli/p/10864836.html
Copyright © 2020-2023  润新知