pwn入门:详解gdb调试程序的常见命令

本文通过实例讲解了如何使用GDB调试器对存在溢出漏洞的程序进行调试,涉及pwn环境部署、gdb命令应用、溢出覆盖、大小端序影响及Python脚本编写,旨在帮助理解内存布局和程序执行过程。

目录

写在开头

一、pwn题目环境的部署

二、解题思路(不是重点) 

三、gdb的调试过程(重点) 

完整运行过程(run)  

调试程序(重点)

运行到程序的开始位置

设置断点

查看内存 

修改地址的值

单步运行/查看寄存器

四、python脚本的编写

总结与思考

写在开头

   近期又开始回头开始学pwn了,看了b站国资社畜大佬的视频,在大佬讲解的基础上做个总结,加入了我的一些思考。学pwn主要是要了解内存布局和程序的执行过程,感觉学习路线确实比较陡峭,今后我也会不定期更新这个系列。

      本文主要以对一个程序的调试过程为例,介绍gdb调试器的常见命令,并直观的展示所谓“溢出”覆盖的效果以及大小端序的问题。涉及的知识点包括:pwn题目环境的部署、gdb调试的常见命令、大小端序的影响、简单解pwn题目脚本的编写。特别说明,由于篇幅有限,本文不会过多介绍汇编指令以及程序运行时函数调用栈的变化过程。这些内容可能会在后面的博客中再做介绍,本文的重点是使用gdb对程序进行调试。本文需要的工具主要有gdb和pwntools,读者如果想跟着复现,只要有gdb和pwntools即可,安装过程详见:

pwn入门(1):kali配置相关环境(pwntools+gdb+peda)_gdb插件 peda-优快云博客

  备注:文末有我总结的gdb常见指令,有需要的读者可以直接看文末。 

一、pwn题目环境的部署

   这一部分属于调试过程的前置,想在本地部署一个pwn环境,用socat开启一个本地端口运行pwn题目(下文会细说)。当然读者如果仅仅了解gdb的话也可以不用考虑这么多,直接用p = process(./文件)即可。建议使用ubuntu或kali这样的系统部署环境、调试程序。

   首先我们要构建一个存在“溢出”漏洞的二进制文件。这里我们就用国资社畜大佬给出的question.c文件即可,其内容如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char sh[]="/bin/sh";

int init_func(){
    setvbuf(stdin,0,2,0);
    setvbuf(stdout,0,2,0);
    setvbuf(stderr,0,2,0);
    return 0;
}

int func(char *cmd){
        system(sh);
        return 0;
}

int main(){
    init_func();
    volatile int (*fp)();
    fp=0;
    int a;
    puts("input:");
    gets(&a);  //gets没有对输入字符的长度做限制,存在溢出
    if(fp){
        fp();
    }
    return 0;
}

   然后用gcc把这个文件编译一下,生成存在漏洞的二进制文件,注意编译的过程要关闭pie保护,命令如下:

gcc question.c -no-pie -o question1

此处简要说明一下PIE保护(不是本文重点)。

1.PIE保护是编译时默认开启的。如果想关闭pie保护,需要手动添加参数-no-pie

2.PIE (position-independent executable) 是一种生成地址无关可执行程序的技术。是一种保护机制,如果程序开启了PIE保护的话,那么在每次加载程序时都会改变加载的基地址。当然这种机制不利于我们本地调试程序,所以在这里就关闭了。

   接下来为了增强仪式感,我们可以在当前目录新建一个文件flag,拿到这个flag相当于解题成功。

 然后用socat开启8888端口部署这个题目question1,当然你也可以使用任何未被占用的其他端口:

socat tcp-l:8888,fork exec:./question1,reuseaddr

  然后另起一个终端(ctrl+shift+t),试一试能不能用nc连接这个题目,如下图连接成功:

 随便输入一段字符串看看效果,好像没啥问题:

二、解题思路(不是重点) 

   如果从解题的角度思考,我们只能拿到一个二进制文件,是看不到源代码的。当然可以放到ida中分析,也可以用反汇编工具查看伪源代码,然后再慢慢分析。不过由于本文的重点是用gdb调试程序,因此这里就直接从上面的源代码简要分析触发漏洞的位置:

1.溢出点:代码中存在危险函数gets()。gets函数用于获取用户的输入,且不会对输入的字符数量做限制,因此有可能会溢出覆盖其他内存。

2.后门函数:存在后门函数func,这个函数可以获取shell,我们要想办法让这个函数执行。

3.函数指针fp,原始的

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Boss_frank

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值