gdb 简单使用

先来看一下 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(cmd);
	return 0;
}

int main(){
    char a[8] = {};
    char b[8] = {};
    //char a[1] = {'b'};
	puts("input:");
	gets(a);  
	printf(a);
	if(b[0]=='a'){ 
		func(sh);
	}
    return 0;
}

编译执行 (这边先用 64 位处理编译了)

gcc x.c -o x
./x

程序的大致功能是输入一个字符串然后输出这个字符串。

反汇编一下

gdb ./x
start
disassemble main

image-20240118132106375

可以发现关键就在于 cmp 处。如果 al = 0x61 就会跳过 jne 执行后面的代码。

在 cmp 处打一个断点。

b *0x00005555555552d2

我们发现 eax 寄存器的值由上一步决定

于是在这 里也打一个断点

b *0x00005555555552ce

image-20240118132808110

从 0x00005555555552ce 出看一下 20 行汇编代码

x/20i 0x00005555555552ce

image-20240118133048915

eax = byte ptr [rbp -0x10] ,所以我们看一下 rbp -0x10 地址处有些什么内容

我们先执行到这一步,然后查看 rbp -0x10 地址处前 20个字节的数据。

x/20b $rbp-0x10

image-20240118133824369

可以看到第一个字节是 0x00 ,现在我们尝试把他第一个字节改为 0x61

查看值 rbp-0x10

p $rbp-0x10

image-20240118134642680

然后修改这处地址第一个字节

set *0x7fffffffe030 = 0x61

然后继续执行果然进入了函数里拿到 shell 了,本地验证了一下只要让 al = 0x61 就是能拿到 shell 的。

现在我们从头开始分析,怎么才能让 al 的值变为 0x61 呢?我们可以看到系统调用了 gets 函数读取输入赋给 [rbp -0x18]

image-20240118135853743

而 gets 函数很危险,碰到换行符才会停止输入

我们输入 aaa 再看看 0x7fffffffe028

image-20240118141407152

可以发现确实写进去了 有三个 616161,那如果我们写多点岂不是就能使之溢出覆盖 0x0x7fffffffe030 处的值了?

没错,这样就能拿到 shell 了。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值