目标文件: ciscn_2019_ne_5。

来源 :https://buuoj.cn/challenges

保护情况:保护是没有保护的

主要伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // [esp+0h] [ebp-100h]
char src[4]; // [esp+4h] [ebp-FCh]
char v5; // [esp+8h] [ebp-F8h]
char s1[4]; // [esp+84h] [ebp-7Ch]
char v7; // [esp+88h] [ebp-78h]
int *v8; // [esp+F4h] [ebp-Ch] v8 = &argc;
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
fflush(stdout);
*(_DWORD *)s1 = 48;
memset(&v7, 0, 0x60u);
*(_DWORD *)src = 48;
memset(&v5, 0, 0x7Cu);
puts("Welcome to use LFS.");
printf("Please input admin password:");
__isoc99_scanf("%100s", s1); // 输入密码: administrator
if ( strcmp(s1, "administrator") )
{
puts("Password Error!");
exit(0);
}
puts("Welcome!");
while ( 1 )
{
puts("Input your operation:");
puts("1.Add a log.");
puts("2.Display all logs.");
puts("3.Print all logs.");
printf("0.Exit\n:");
__isoc99_scanf("%d", &v3);
switch ( v3 )
{
case 0:
exit(0); // 退出
return;
case 1:
AddLog((int)src); // 输入
break;
case 2:
Display(src); // 删除输入的
break;
case 3:
Print();
break;
case 4:
GetFlag(src); // 将输入的输出
break;
default:
continue;
}
}
}
int __cdecl AddLog(int a1)
{
printf("Please input new log info:");
return __isoc99_scanf("%128s", a1);
}
int __cdecl GetFlag(char *src)
{
char dest[4]; // [esp+0h] [ebp-48h]
char v3; // [esp+4h] [ebp-44h] *(_DWORD *)dest = 48;
memset(&v3, 0, 0x3Cu);
strcpy(dest, src);
return printf("The flag is your log:%s\n", dest);
}

GetFlag的栈结构示意

其它信息:

或者这个 "sh" 字符串也可以用其他方式找到:

调试目标 :构造GetFlag函数的栈溢出并借此开启一个shell。

先打上至少一个断点,不然待会干啥的白瞎

也可以直接对函数名下断点(如果程序没开PIE的话)

我将程序的执行断在了call进GetFlag前:

很明显,0xFFFFD3FC就是输入字符串的保存地,0x804891B是这个call的返回值。

用 "s"命令跟进这个call,直到抬栈完毕。( 想步过这个call的话用  "n"就好。)

先看看栈:

GetFlag函数中有个字符拷贝的行为,从GetFlag函数的栈顶开始写入0xFFFFD3FC之后的内容直到被 0 截断为止。

GetFlag函数的栈容量只有0x48个字节,再往后就是原 EBP 和返回值

思路:将GetFlag函数的返回值覆盖为system函数的地址 ,并在其后写入字符串 "sh"的地址 0x80482EA

接下来是利用 set 命令修改内存,但 set 命令一修改就是四个字节,有时候并不算太方便。

改原 EBP 到没什么讲究,只要四字节中没有为零的就好。

然后是覆盖返回值

这个不重要,占位子的,四字节中没有为零的就好

写入参数地址

至此,GetFlag的栈已经构造完成:

下面就是放飞自我的时候了( "go" 命令 :直接执行的下一个断点(但在这里是不可能的了)):

可以看到程序已经崩溃,并且如愿开启了shell。

记一次GDB调试的更多相关文章

  1. 用gdb调试python多线程代码-记一次死锁的发现

    | 版权:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.如有问题,可以邮件:wangxu198709@gmail.com 前言 相信很多人都有 ...

  2. Linux学习----gdb调试(指针的指针)

    昨天遇到一个很奇怪的问题,如下: 按照理论,最后*p的值应该是99,不知为什么是15了,所以今天记录用gdb调试的过程,并熟悉gdb的使用. (调试过程参考:http://www.cnblogs.co ...

  3. GDB调试实用命令

    个人感觉从windows平台转到linux平台一个不适应的地方就是调试器的使用.因为windows下调试器基本上都依赖快捷键和图像界面来完成操作,就算是windbg这种伪命令行的工具,命令也很简单比较 ...

  4. GDB调试命令小结

    1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...

  5. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  6. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  7. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  8. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  9. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

随机推荐

  1. 牛客网PAT练兵场-D进制的A+B

    题解:大多数做法是利用循环相除,取余.我是将将A+B传入f函数,利用递归实现D进制的输出 题目地址:https://www.nowcoder.com/questionTerminal/a2063993 ...

  2. 洛谷 P3951 NOIP 2017 小凯的疑惑

    洛谷 P3951 NOIP 2017 小凯的疑惑 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付 ...

  3. 学习seo赚钱一定要有超前的思路和眼光

    http://www.wocaoseo.com/thread-100-1-1.html        日子过的真是快,一天又一天,一年又一年,虽然过年的脚步将近,火车票的问题还是没有解决,昨天忙活了半 ...

  4. 起源seo为何要做seo培训

    http://www.wocaoseo.com/thread-91-1-1.html 焦大,在2010年末左右开始接触seo,2011年3月份正式开始做seo,到如今做seo已经3年了,实话说我没有其 ...

  5. 30年技术积累,技术流RTC如何成为视频直播领域的黑马?

    摘要:视频业务链的背后,本质是一张视频处理和分发网络.5G+云+AI时代下,实时音视频必然会步入到一个全新的发展期. 2020年这场肆虐全球的新冠疫情让很多企业重新审视自己对数字化的认识,正如 “大潮 ...

  6. Python自动化测试入门科技树

    Python基础: 入门语法和数据类型: 编码环境安装基本语法 常用数据类型 常用运算符 Llist.Tuple.Dict.if&for.while Python进阶: 函数: 语法 内置函数 ...

  7. 记录call、apply、bind的源码

    记录一下call.apply.bind的源码,然后从根本上明白其用法. 都知道call.apply与bind的用法,call(this,...arguments).apply(this,[argume ...

  8. Texstudio、Latex 大段注释,多行注释 快捷键

    Texstudio.Latex 大段注释,多行注释  快捷键 单行注释:在每行前加 %  即可 大段注释: \usepackage{verbatim} \begin{comment} ... \end ...

  9. 「面向 offer 学算法」笔面试大杀器 -- 单调栈

    目录 前言 单调栈 初入茅庐 小试牛刀 打怪升级 出师试炼 前言 单调栈是一种比较简单的数据结构.虽然简单,但在某些题目中能发挥很好的作用. 最近很多大厂的笔试.面试中都出现了单调栈的题目,而还有不少 ...

  10. [bash] 打印到屏幕相关语法

    程序: #!/bin/bash function showAlertMsg(){ echo -e "\e[1;31m"$"\e[0m" } function s ...