• 天枢信息安全社团2015年招新



    CTF-PWN入门指导与学习路线

    PWN是一个黑客俚语,由"own"引申出来,含意是在对战中处在胜利的优势,或是竞争对手处在完全惨败的情形。在信息安全领域中,包括服务器或PC或是应用程序,PWN在这一方面的意思是攻破("to compromise")或是控制,取得未授权的访问进而入侵系统。

    PWN类题目属于二进制安全的重要分支,是对目标程序在逆向工程基础上进行漏洞挖掘和利用,入门难度相对比较大。大多数PWN题目关注x86和x64体系结构,所以入门时应该首先学习8086汇编语言。

    PWN类题目一般的形式是这样的:
    只提供和Linux或Windows下某程序的可执行文件给参赛选手,选手在本地逆向分析找到漏洞利用方法;服务器中同时在某一端口运行程序,在程序目录下放置flag.txt,里面写上flag信息;选手连接远程服务器,利用漏洞使运行的程序更改运行流程,拿到flag。

    推荐入门工具:OllyDBG、IDA。需要的资料已经以pdf形式提供(仍然建议大家使用正版书),下面以需要了解的知识点描述学习轨迹:
    入门---->
    基本的汇编语句与寄存器(PUSH、MOV、JMP、CALL等指令、EAX、ECX、EIP、ESP、EBP、ESI、EDI等寄存器、8086与80386)-->
    栈(局部变量在栈上的分布、栈保存的其他重要数据、小端序)-->
    函数调用发生了什么(返回地址的保存、栈帧、函数参数传递)-->
    数据与指令有什么不同(存储位置?数据能执行吗?)-->
    一些简单函数执行流程(C语言与汇编语言、观察printf(“Hello world”))-->
    漏洞利用方法(覆盖邻接变量、修改返回地址)-->
    一些常见的漏洞类型(缓冲区溢出(scanf,gets)、格式化字符串(printf)、堆溢出、整数溢出)->
    进阶---->
    Shellcode书写-->
    突破保护(GS、DEP、ASLR、JMP ESP,ret2libc,ROP)-->
    …----->
    招新的题目难度会很低,大家首先应学习、掌握入门部分的内容。

    考虑到大家的基础,下面以Windows下的一个有缓冲区溢出漏洞的简单程序example.exe为大家示例。
    漏洞在函数stack_over_flow()的gets()函数中,缓冲区只有16个字节,如果输入长度大于16,将覆盖很多重要数据包括stack_over_flow()函数的返回地址(需要学习栈相关内容)。远程服务器运行的例程的目录下有一个flag.txt文件,存放flag,而程序中已经写好了读取的代码readfile()但并没有被调用。我们通过缓冲区溢出覆盖到stack_over_flow()函数的返回地址,让其返回到readfile()就可以拿到flag。


    为了便于大家学习,首先给出程序的源码。但要知道,比赛题目并不给出源码。
    #include<stdio.h>
    #include<stdlib.h>
    int stack_over_flow()
    {
    char Password[16] = { 0, };
    gets(Password);
    return 0;
    }
    void readfile()
    {
    FILE* fp;
    char FileStr[20] = { 0, };
    printf("You've got the flag: ");
    if (fp = fopen("flag.txt", "r"))
    {
    fgets(FileStr, 48, fp);
    printf("%s ", FileStr);
    fclose(fp);
    }
    else
    printf("File error! ");
    exit(0);
    }
    int main()
    {
    printf("Welcome! ");
    printf("Please input your password(within 8 characters): ");
    stack_over_flow();
    printf("Good Bye! ");
    return 0;
    }

    可以使用IDA静态分析该程序,然后使用OllyDBG调试这一程序。IDA和OllyDBG工具的基本使用方法不再说明。运行程序,发现输出了两行提示然后要求用户输入。

    逆向分析,找到main函数的位置为00401160,观察还可以发现00401520为printf(),00401005就是stack_over_flow()函数。在反汇编窗口继续寻找可以找到readfile()函数的入口地址00401090。

    从00401005跳到00401030,stack_over_flow()就在这个位置。004011D0一定就是scanf()了。

    如下图所示,测试输入了8个‘A’(16进制表示为0x41),发现在栈如下所示。总共16个字节的空间,后面四个字节为之前保存的ebp,再下面四个字节处00401197就是本函数的返回地址。考虑输入20个‘A’,然后把返回地址覆盖为readfile()函数的入口地址00401090。这样当程序返回的时候就从栈中取出00401090作为EIP寄存器的内容,于是然后程序执行跳到了EIP处,读取文件显示flag。

    由于要输入的一些字符并不能从键盘中打印出来,我们可以借助Python输出重定向。

    输入的示例:python -c "print 'A'*20+'x90'+'x10'+'x40'+'x00'" | example.exe

    ⦁ 管道符号:‘|’,用来把Python输出重定向到example.exe的输入。
    ⦁ ‘A’:20个‘A’用来填充栈内空间。
    ⦁ 00401090:通过逆向工程的手段找到的readfile()函数的入口地址。因为是16进制所以有’x’;之所以采取这样的顺序是因为intel CPU的小端序(需要自行学习)。填的位置正好位于stack_over_flow()函数的返回地址处,相当于修改了这一地址。


    Written by default from TS2013.
    有问题可以联系我和其他学长帮助解决。我的邮箱:default@bupt.edu.cn
    学习安全知识技能需要热情,大家加油!

  • 相关阅读:
    关于TextField
    判断一个显示对象是否移除
    不争气的Discuz!NT 3.6和MVC3整合,主要实现同步登录和注册,登出。
    我的博客是英文的
    TFS不提供 Team Foundation 服务的解决办法。
    四 为提高entity framework 性能,要注意哪些事情.
    三 EF 和ado.net 的性能对比.
    一 关于大项目的经验总结
    在.net 中,ajax 如何调用本页数据源
    关于有序guid 的使用
  • 原文地址:https://www.cnblogs.com/csnd/p/12303912.html
Copyright © 2020-2023  润新知