热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GDB动态调试攻防世界SimpleCheck100

文章目录题目IDA静态分析gdb动态调试gdb基本使用gdbpeda插件函数校验绕过总结题目攻防世界Reverse高手区题目链接simple-check-100,如

文章目录

  • 题目
  • IDA静态分析
  • gdb动态调试
    • gdb 基本使用
    • gdb peda插件
    • 函数校验绕过
  • 总结


题目

攻防世界 Reverse 高手区题目链接 simple-check-100,如下:
在这里插入图片描述解压缩得到三个文件:
在这里插入图片描述三个文件依次是一个 32 位 elf,一个 64 位 elf 和一个 32 位 exe。

ELF 文件 (Executable Linkable Format) 是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。Linux 下的目标文件和可执行文件都按照该格式进行存储,它是 Linux 的主要可执行文件格式。


IDA静态分析

1、查壳发现未加壳:
在这里插入图片描述
2、这 3 个文件拖进 IDA 后的反汇编结果是大体一致的,以 64 位 elf 文件为例进行分析,定位到 main 函数:
在这里插入图片描述3、按 F5 查看反汇编结果的的 C 语言伪代码:
在这里插入图片描述完整代码如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{void *v3; // rspconst char **v5; // [rsp+0h] [rbp-60h] BYREFint v6; // [rsp+Ch] [rbp-54h]char v7[28]; // [rsp+1Ch] [rbp-44h] BYREF__int64 v8; // [rsp+38h] [rbp-28h]const char ***v9; // [rsp+40h] [rbp-20h]unsigned __int64 v10; // [rsp+48h] [rbp-18h]v6 = argc;v5 = argv;v10 = __readfsqword(0x28u);v7[0] = 84;v7[1] = -56;v7[2] = 126;v7[3] = -29;v7[4] = 100;v7[5] = -57;v7[6] = 22;v7[7] = -102;v7[8] = -51;v7[9] = 17;v7[10] = 101;v7[11] = 50;v7[12] = 45;v7[13] = -29;v7[14] = -45;v7[15] = 67;v7[16] = -110;v7[17] = -87;v7[18] = -99;v7[19] = -46;v7[20] = -26;v7[21] = 109;v7[22] = 44;v7[23] = -45;v7[24] = -74;v7[25] = -67;v7[26] = -2;v7[27] = 106;v8 = 19LL;v3 = alloca(32LL);v9 = &v5;printf("Key: ");__isoc99_scanf("%s", v9);if ( (unsigned int)check_key(v9) )interesting_function(v7);elseputs("Wrong");return 0;
}

可以看到,程序的核心是让输入一个字符串,然后使用 check_key 函数进行判断,如果返回非 0(为真),则执行 interesting_fuction 函数。

4、双击跟进查看 interesting_fuction 函数伪代码:
在这里插入图片描述该函数对输入的 v7(未知)进行加密处理,最后 putchar 输出。

5、check_key 函数是一个计算校验和与正确的校验和对比的一个函数:
在这里插入图片描述
解题思路

只要让程序绕过 check_key 函数的检查,强行执行 interesting_function 函数,就能获得目标 Flag。故可以对程序进行动态调试,将 check_key 的返回结果改为 1,就能调用 interesting_function 函数并得到正确的 key。

gdb动态调试

GDB (GNU Debugger)是一个由 GNU 开源组织发布的、UNIX/LINUX 操作系统下的、基于命令行的、功能强大的程序调试工具。像所有的调试器一样,GDB 可以让你调试一个程序,包括让程序在你希望的地方停下,此时你可以查看变量、寄存器、内存及堆栈,更进一步你可以修改变量及内存值。对于一名 Linux 下工作的 C/C++ 程序员或逆向工作者,gdb 是必不可少的工具。

基础使用教程:linux下gdb调试方法与技巧整理、CTF 竞赛入门指南(CTF All In One)。


gdb 基本使用

gdb 的常用命令如下:
在这里插入图片描述
本人在自己的 VPS 服务器(Centos8)上安装 gdb,步骤如下:

#安装C++编译器
yum install gcc gcc-c++
#下载源码包
wget http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
#编译安装
tar -zxvf gdb-10.2.tar.gz
cd gdb-10.2
./configure --with-python=/usr/bin/python --enable-targets=all
make
sudo make install
#查看是否安装成功
gdb -v

注意防坑】编译 gdb 时必须加上--with-python参数指定本地的 Python 路径,否则后续使用 gdb 插件时将各种报错(为此我浪费了整整一天……最终参照 博文 找到了该解决的办法)。

如下已成功安装 gdb 工具:
在这里插入图片描述
GDB基础用法演示

下面给出一个具有 test.c 的程序:

#include
int getSum(int n) {int sum&#61;0,i;for (i&#61;1;i<&#61;n;i&#43;&#43;)sum&#43;&#61;i;return sum;
}
int main(){int res&#61;getSum(100);printf("1&#43;2&#43;...&#43;100&#61;%d\n",res);
}

1、使用 gcc 编译 C 语言程序&#xff1a;
在这里插入图片描述
【注意】如果要调试程序&#xff0c;则在进行 gcc 编译的时候要加上 -g 参数&#xff08;表示 debug 模式&#xff09;&#xff0c;即gcc -g test.c -o test (如果是 C&#43;&#43; 程序的话则是g&#43;&#43; -g test.cpp -o test&#xff09;。如果没有 -g 参数&#xff0c;你将看不见程序的函数名、变量名&#xff0c;所代替的全是运行时的内存地址。

2、执行命令 gdb test&#xff0c;开始使用 GDB 对生成的 test 可执行程序进行调试&#xff08;GDB 会显示自己的提示符 gbd&#xff0c;提示并等待你输入调试命令&#xff09;&#xff1a;
在这里插入图片描述3、输入l命令&#xff08;相当于 list&#xff09;&#xff0c;gdb 将从第一行开始列出源码&#xff08;默认前 10 行&#xff09;&#xff1a;
在这里插入图片描述
直接回车表示&#xff0c;重复上一次命令&#xff08;继续输出第 10-20 行的源码&#xff09;&#xff1a;
在这里插入图片描述
4、执行命令break 9break getSum&#xff0c;表示在第 9 行处、getSum 函数处设置断点&#xff0c;同时执行命令info break可查看设置的断点信息&#xff1a;
在这里插入图片描述
5、执行命令run(简写 r) &#xff0c;开始从头运行程序&#xff0c;直到程序结束或者遇到断点并等待下一个命令&#xff1a;
在这里插入图片描述
6、执行命令 continue&#xff08;简写 c&#xff09;&#xff0c;表示从暂停处继续运行程序&#xff1a;
在这里插入图片描述
7、执行 step 命令&#xff0c;表示向前执行一步&#xff08;可进入被调用函数中&#xff09;&#xff0c;进一步可利用 print i&#xff08;变量名&#xff09;来查看变量的值&#xff1a;
在这里插入图片描述
8、执行命令 backtrace&#xff08;简写 bt&#xff09;&#xff0c;可查询当前函数调用栈&#xff0c;执行命令 finish&#xff0c;可退出当前函数并返回到上层函数中&#xff08;本例为 main 主函数&#xff09;&#xff1a;
在这里插入图片描述
9、执行命令set res &#61; 6666&#xff0c;可改变程序中指定变量的值&#xff1a;
在这里插入图片描述
10、info reg 命令可查看寄存器使用情况&#xff0c;info stack命令可查看堆栈使用情况&#xff1a;
在这里插入图片描述
最后执行命令 quit&#xff08;简写 q&#xff09;&#xff0c;即可退出 gdb&#xff1a;
在这里插入图片描述
而未被篡改变量值的程序正常的运行输出应当如下&#xff1a;
在这里插入图片描述

gdb peda插件

从上面的演示实例中也可以看出&#xff0c;gdb 非常强大&#xff0c;但是在调试过程中对于需要查看的辅助信息&#xff08;如寄存器信息&#xff09;都要手动输入命令&#xff0c;未免有点麻烦&#xff0c;所以就出现了插件&#xff0c;把某一些经常要查看的信息每一步都自动帮你显示出来&#xff0c;方便调试。一般来说有常用的 3 个 GDB 插件&#xff1a;peda、gef、gdbinit。
&#xff0c;完整介绍可参见&#xff1a;GDB的三个插件&#xff08;gef gdbinit peda&#xff09;。Github 上已经有人把这 3 个插件的项目合成了一个&#xff0c;使得插件的安装使用很方便&#xff1a;

# 从 Github 将汇聚了 gdb 的 3 个插件的项目拷贝到本地
git clone https://github.com/gatieme/GdbPlugins.git ~/GdbPlugin
# GdbPlugins 文件夹包含的 3 个插件对应启动命令&#xff1a;
echo "source ~/GdbPlugins/peda/peda.py" > ~/.gdbinit
echo "source ~/GdbPlugins/gef/gef.py" > ~/.gdbinit
echo "source ~/GdbPlugins/gdbinit/gdbinit" > ~/.gdbinit

成功克隆到本地后可以看到包含 3 个插件的文件夹&#xff1a;
在这里插入图片描述
下文将介绍其中的 peda 插件——peda 是 gdb 调试工具的插件&#xff0c;用于增强 gdb 的调试能力&#xff0c;同时增强 gdb 的显示&#xff1a;在调试过程中着色并显示反汇编代码&#xff0c;寄存器和内存信息&#xff08;单纯的 gdb 在内存信息、汇编信息的显示和查看上的不方便&#xff09;。

1、设置 gdb 以 peda 插件的执行形式启动&#xff0c;并调试上面编译好的 test 程序&#xff1a;
在这里插入图片描述
2、输入 start 命令开始调试程序&#xff0c;从下图中可以看到寄存器 (registers)&#xff0c;汇编代码 (code)&#xff0c;栈空间数据 (stack) 等信息&#xff1a;
在这里插入图片描述

在前面的文章 浅析缓冲区溢出漏洞的利用与Shellcode编写 中曾经介绍了函数调用过程中的内存堆栈变化&#xff0c;建议读者同步阅读博文 基于GDB-peda汇编调试理解函数调用栈 &#xff0c;作者利用 peda 插件来汇编调试一段程序&#xff0c;帮助深入理解函数调用栈。

函数校验绕过

返回到 CTF 题目中&#xff0c;在 Linux 中正常运行程序如下&#xff1a;
在这里插入图片描述
下面开始借助 gdb 对程序进行动态调试&#xff0c;将 check_key 函数的返回结果改为真即可正确的 key。

1、启动 gdb 调试程序&#xff0c;执行命令 break main 在 main 函数设置断点&#xff08;Breakpoint 1 at 0x4007c0&#xff09;&#xff0c;然后执行命令 run 开始运行程序&#xff1a;
在这里插入图片描述程序暂停在断点处&#xff1a;
在这里插入图片描述

2、上述程序暂停在 main 函数断点处&#xff0c;执行命令 next 开始一步步单步执行程序&#xff08;一直按回车键重复执行 next 命令即可&#xff09;&#xff0c;直到运行至 check_key 函数所在位置&#xff0c;随意输入 key 之后会有判断函数&#xff0c;所以注意看 check_key 所在位置&#xff1a;
在这里插入图片描述3、当判断函数执行完之后&#xff0c;再次跳到test eax, eax时候&#xff0c;可以用printi $eax查看寄存器的值&#xff0c;发现是 0&#xff1a;
在这里插入图片描述4、这样的话不会跳转藏有 flag 函数的位置&#xff0c;所以执行命令 set $eax&#61;1&#xff0c;手动篡改寄存器 eax 的值&#xff0c;最后执行命令 continue&#xff0c;运行程序直至程序终止&#xff0c;可获得 flag 值如下&#xff1a;
在这里插入图片描述提交 flag&#xff0c;over&#xff01;
在这里插入图片描述

总结

本文通过一道 CTF 题目&#xff0c;学习记录了 GDB 调试工具及其 peda 插件的使用&#xff0c;实现了对二进制程序的内存数值进行篡改并成功绕过程序的逻辑校验的目的&#xff0c;这有点类似于 Android 中使用 Frida 对 APP 的函数返回值进行 hook 拦截和篡改。


推荐阅读
  • 哈希表(Hash Table)是一种高效的查找算法,与传统的链表和树结构相比,其在查找过程中无需进行逐个元素的比较。本文将深入探讨哈希表的基本原理、应用场景以及优化策略,帮助读者全面理解其在实际开发中的优势和局限性。通过实例分析和代码示例,我们将展示如何有效利用哈希表提高数据处理效率,并解决常见的冲突问题。 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 在 Angular Google Maps 中实现图片嵌入信息窗口的功能,可以通过使用 `@agm/core` 库来实现。该库提供了丰富的 API 和组件,使得开发者可以轻松地在地图上的信息窗口中嵌入图片。本文将详细介绍如何配置和使用这些组件,以实现动态加载和显示图片的功能。此外,还将探讨一些常见的问题和解决方案,帮助开发者更好地集成这一功能。 ... [详细]
  • 本文详细介绍了在 SQL Server 2005 中优化和实现分页存储过程的方法。通过创建一个名为 `[dbo].[GetUsers]` 的存储过程,该过程接受两个参数:`@RowIndex`(当前指定的页数)和 `@RecordCount`(每页显示的记录数)。文章不仅提供了具体的代码示例,还深入探讨了性能优化技巧,包括索引使用和查询优化策略,以提高分页查询的效率和响应速度。 ... [详细]
  • 本文深入解析了Python在处理HTML过滤时的实现方法及其应用场景。通过具体实例,详细介绍了如何利用Python代码去除HTML字符串中的标签和其他无关信息,确保内容的纯净与安全。此外,文章还探讨了该技术在网页抓取、数据清洗等领域的实际应用,为开发者提供了宝贵的参考。 ... [详细]
  • 本文全面解析了 gRPC 的基础知识与高级应用,从 helloworld.proto 文件入手,详细阐述了如何定义服务接口。例如,`Greeter` 服务中的 `SayHello` 方法,该方法在客户端和服务器端的消息交互中起到了关键作用。通过实例代码,读者可以深入了解 gRPC 的工作原理及其在实际项目中的应用。 ... [详细]
  • FastDFS Nginx 扩展模块的源代码解析与技术剖析
    FastDFS Nginx 扩展模块的源代码解析与技术剖析 ... [详细]
  • 深入解析 Android TextView 中 getImeActionLabel() 方法的使用与代码示例 ... [详细]
  • 本文深入探讨了CGLIB BeanCopier在Bean对象复制中的应用及其优化技巧。相较于Spring的BeanUtils和Apache的BeanUtils,CGLIB BeanCopier在性能上具有显著优势。通过详细分析其内部机制和使用场景,本文提供了多种优化方法,帮助开发者在实际项目中更高效地利用这一工具。此外,文章还讨论了CGLIB BeanCopier在复杂对象结构和大规模数据处理中的表现,为读者提供了实用的参考和建议。 ... [详细]
  • 本文详细探讨了Zebra路由软件中的线程机制及其实际应用。通过对Zebra线程模型的深入分析,揭示了其在高效处理网络路由任务中的关键作用。文章还介绍了线程同步与通信机制,以及如何通过优化线程管理提升系统性能。此外,结合具体应用场景,展示了Zebra线程机制在复杂网络环境下的优势和灵活性。 ... [详细]
  • 本文深入探讨了 hCalendar 微格式在事件与时间、地点相关活动标记中的应用。作为微格式系列文章的第四篇,前文已分别介绍了 rel 属性用于定义链接关系、XFN 微格式增强链接的人际关系描述以及 hCard 微格式对个人和组织信息的描述。本次将重点解析 hCalendar 如何通过结构化数据标记,提高事件信息的可读性和互操作性。 ... [详细]
  • 本文详细介绍了 jQuery 的入门知识与实战应用,首先讲解了如何引入 jQuery 库及入口函数的使用方法,为初学者提供了清晰的操作指南。此外,还深入探讨了 jQuery 在实际项目中的多种应用场景,包括 DOM 操作、事件处理和 AJAX 请求等,帮助读者全面掌握 jQuery 的核心功能与技巧。 ... [详细]
  • CentOS 7环境下Jenkins的安装与前后端应用部署详解
    CentOS 7环境下Jenkins的安装与前后端应用部署详解 ... [详细]
  • jQuery插件验证与屏幕键盘功能的集成解决方案
    本文介绍了一种集成了验证功能和屏幕键盘的jQuery插件解决方案。该插件不仅提供了强大的表单验证功能,还引入了一个高度可定制的屏幕键盘,以增强用户体验。通过这一集成方案,开发者可以轻松实现复杂的表单验证逻辑,并为用户提供便捷的输入方式,特别适用于移动设备或特殊输入场景。 ... [详细]
  • 字节码开发笔记:深入解析与应用技巧 ... [详细]
author-avatar
陈怡伶翰纬
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有