之前给学弟学妹做培训用的文档(

Inhaltsverzeichnis

  1. What’s Pwn?
  2. 环境准备
  3. 缓冲区溢出
    1. 栈基础知识
  • shellcode
  • 程序保护机制
    1. checksec
    2. Canary(栈保护)
    3. Fortify
    4. NX(DEP)
    5. PIE(ASLR)
  • 其他漏洞
  • ELF病毒
  • What’s Pwn?

    引用维基百科的解释:

    在骇客 行话里,尤其在另外一种电脑技术方面,包括电脑( 伺服器或个人电脑 )、网站、闸道装置、或是应用程式,”pwn”在这一方面的意思是攻破(”to compromise”,危及、损害)或是控制(”to control”)。 在这一方面的意义上,它与骇客入侵与破解是相同意思的。 例如某一个外部团体已经取得未经公家许可的系统管理员控制权限,并利用这个权限骇入并入侵(”owned” 或是”pwned”)这个系统。

    在CTF中pwn大多是给你个二进制文件让你去利用它getshell。

    环境准备

    这部分不会讲,下面给链接自己去安装工具吧,安装遇到的错误基本都有解决方法,复制错误信息然后谷歌(:з」∠)
    pwntools
    pwntools常用模块
    gdb-peda
    gdb常用命令

    缓冲区溢出

    通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。

    来看一个栗子,pwnable.kr的第三题:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme); // smash me!
    if(key == 0xcafebabe){
    system("/bin/sh");
    }
    else{
    printf("Nah..\n");
    }
    }
    int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
    }

    很明显,要我们利用overflowme[32]去覆盖key的值getshell。

    (下面是现场演示时间,有兴趣的同学可以自己先做一下)

    栈基础知识

    在一次函数调用中,堆栈中将被依次压入:参数,返回地址,EBP。如果函数有局部变量,接下来,就在堆栈中开辟相应的空间以构造变量。函数执行结束,这些局部变量的内容将被丢失。但是不被清除。在函数返回的时候,弹出EBP,恢复堆栈到函数调用的地址,弹出返回地址到EIP以继续执行程序。

    __fastcall函数调用约定:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    push 参数3    
    push 参数2
    push 参数1 #参数由右向左入栈

    call 函数地址

    push ebp #保存当前栈底指针
    mov ebp,esp #设置新栈底
    sub esp, xxx #设置新栈顶,esp减去所需空间大小

    我们要做的其实就是控制EIP,EIP指令就是指向下一个要执行的命令,而RET指令就相当于POP EIP。当我们控制了EIP为我们想要的地址时,程序正常执行到RET就会自己跳转到我们的EIP了。

    栗子题目,Jarvis OJ pwn的Tell Me Something。

    shellcode

    shellcode是一组可注入的指令,可以在被攻击的程序中运行帮助我们获取控制权。
    最常用的shellcode是execve()的shellcode,在现有的进程空间里执行其他的进程。

    1
    \x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80

    具体的shellcode编写过程可以看我的这一篇文章

    通常利用shellcode的方法是利用缓冲区溢出将返回地址覆盖成shellcode的地址,常用的覆盖方法有下面两种:

    • ret_nop_shellcode型。将大量的返回地址ret填满缓冲区,接着是大量的nop,然后是shellcode。ret跳到nop区就会一直往下执行到shellcode中。

    • nop_shellcode_ret型。适用于大缓冲区,将返回地址覆盖为nop的大致位置,跳到nop中,然后继续执行到我们的shellcode中。但是这种方法的定位不是很准确,成功率并不大。

    栗子,利用栈溢出来在栈上执行我们的shellcode:pwnable.tw的第一题start。

    程序保护机制

    checksec

    用来检测程序的保护机制,用例:

    或者是gdb用插件peda:

    Canary(栈保护)

    也常称为‘金丝雀’,是一种缓解缓冲区溢出攻击的手段。启用栈保护之后就会在程序函数执行时往栈里插入cookie,当函数返回时会检查cookie信息是否正确,当我们利用溢出覆盖函数返回地址时如果将cookie信息也覆盖掉了就会导致栈保护检查失败停止程序运行。

    Fortify

    用于检查是否存在缓冲区溢出错误,但只是很轻微的检查,一般不会开启。

    NX(DEP)

    用于防止shellcode的执行。基本原理就是将数据所在的内存页标记为不可执行,当程序溢出并试图在数据页面上执行shellcode时,CPU就会抛出异常,不执行shellcode。

    PIE(ASLR)

    即内存地址随机化机制,将mmap的基址,栈和vdso页面随机化,有时也会开启堆地址随机化。增加攻击者在利用漏洞时找到正确地址的难度。

    其他漏洞

    linux下存在的漏洞当然远远不止上面提到的那些,比如还有格式化字符串漏洞、堆溢出、整型溢出等等,但考虑到时间以及同学们的接受能力问题,这里不会讲,当然考试也不会考(大概)。有能力的同学还是自己去学习吧:p

    ELF病毒

    既然前两个学长都讲了病毒…如果有时间的话,就来演示下Linux下的elf病毒吧。
    详细介绍是没时间的,只能演示下linux下的病毒是怎样的2333如果实在是感兴趣可以看我之前写的elf病毒分析 ,从elf文件格式到病毒原理都有介绍。
    演示病毒是elfmaster写的Skeksi病毒,没有公布源码,但给了消毒程序源码。(另外推荐对linux二进制感兴趣的同学看这个作者写的《linux二进制分析》)作者主页->http://www.bitlackeys.org