前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >无文件执行:一切皆是shellcode (上)

无文件执行:一切皆是shellcode (上)

作者头像
七夜安全博客
发布2020-03-12 15:51:00
3.9K0
发布2020-03-12 15:51:00
举报
文章被收录于专栏:七夜安全博客

前言

良好的习惯是人生产生复利的有力助手。

有意思的项目

最近几篇文章都是关于无文件执行或者是逃逸execve检测的内容,今天接着延续着这个思路往下讲。在讲逃逸execve检测的时候,我提到直接执行shellcode是非常好的方式,但是shellcode的提取相对困难,就算是使用MSF工具生成的shellcode,功能也相对单一。如何能让shellcode的提取变得简单,成为我接下来思考的内容。

有一个大胆的想法:

ELF文件能否直接转化为shellcode

毕竟开发ELF的门槛还是挺低的

于是我就搜了一下elf2shellcode,没找到什么有用的项目,在寻找的过程中,找到了windows上的pe_to_shellcode项目:

https://github.com/hasherezade/pe_to_shellcode

这个项目很有意思,通过加壳的方式将exe文件转为了shellcode,接下会简单讲一下使用以及原理,打算分成几篇来讲,讲细致一些。

使用说明

这个项目有趣的地方是 将exe转化为shellcode,转化后的文件依然是完整的PE文件,不仅可以单独运行,也可以通过shellcode的方式运行。在项目的release页面,根据自身的系统下载runshc 和pe2shc文件:

使用pe2shc.exe转换您选择的PE:

代码语言:javascript
复制
pe2shc.exe <path to your PE> [output path]

使用runshc.exe运行输出文件,并检查转换是否正常:

代码语言:javascript
复制
runshc.exe <converted file>

演示

以windows中的calc.exe为例子,先转化calc,保存为calc_modify.exe ,命令如下:

代码语言:javascript
复制
D:\pe_to_shellcode>pe2shc.exe calc.exe calc_modify.exeReading module from: calc.exe[+] Saved as: calc_modify.exe

运行一下,奇迹就出现了,双击一下calc_modify.exe也是同样的效果:

代码语言:javascript
复制
D:\pe_to_shellcode>runshc64.exe calc_modify.exe[*] Reading module from: calc_modify.exe[*] Running the shellcode:

计算器弹起来:

是障眼法吗?

到这一步,虽然看到calc_modify.exe执行了,但是只要细想 这会不会是个障眼法 !!!

calc_modify.exe是真的像shellcode一样运行了吗?还是直接通过创建进程的方式来执行calc_modify.exe?

看一下runshc的源码就可以知道了。

代码语言:javascript
复制
#include <windows.h>#include <iostream>
#include "peconv.h"
int main(int argc, char *argv[]){    if (argc < 2) {        std::cout << "~ runshc ~\n"            << "Run shellcode: loads and deploys shellcode file.\n";#ifdef _WIN64        std::cout << "For 64-bit shellcodes.\n";#else        std::cout << "For 32-bit shellcodes.\n";#endif        std::cout << "Args: <shellcode_file>" << std::endl;        system("pause");        return 0;    }
    size_t exe_size = 0;    char* in_path = argv[1];
    std::cout << "[*] Reading module from: " << in_path << std::endl;    BYTE *my_exe = peconv::load_file(in_path, exe_size);    if (!my_exe) {        std::cout << "[-] Loading file failed" << std::endl;        return -1;    }    BYTE *test_buf = peconv::alloc_aligned(exe_size, PAGE_EXECUTE_READWRITE);    if (!test_buf) {        peconv::free_file(my_exe);        std::cout << "[-] Allocating buffer failed" << std::endl;        return -2;    }    //copy file content into executable buffer:    memcpy(test_buf, my_exe, exe_size);
    //free the original buffer:    peconv::free_file(my_exe);    my_exe = nullptr;
    std::cout << "[*] Running the shellcode:" << std::endl;    //run it:    int (*my_main)() = (int(*)()) ((ULONGLONG)test_buf);    int ret_val = my_main();
    peconv::free_aligned(test_buf, exe_size);    std::cout << "[+] The shellcode finished with a return value: " << std::hex << ret_val << std::endl;    return ret_val;}

在上述代码中,主要做了三件事:

  1. 读取exe文件到缓冲区
  2. 给exe文件分配可读可写可执行的内存,并将缓冲区中的内容复制到这段内存中
  3. 从内存中执行代码

基本上和shellcode的执行方式是一样的,看来真的是将PE文件转化为了shellcode。

原理

想知道原理,最直观的方式是比对calc.exe 与calc_modify.exe的二进制内容,看一下有哪些不同。

启动Beyond Compare工具采用16进制比对,会发现calc.exe后面附加了一段代码。

做过软件保护的同学,肯定可以看出这是一个类似壳的实现方式,至于这段壳是如何实现PE to shellcode功能的?

请看下次分解,涉及到汇编 ,大家心里有个准备哈。

总结

小想法

既然PE可以转化为shellcode,那么ELF应该也是可以通过这种方式转化为shellcode的,事实情况也是可以的,已经开始搞了。

那之后的网络+shellcode ,木马再也不落地。

推荐阅读:

linux无文件执行— fexecve 揭秘

沙盒syscall监控组件:strace and wtrace

无"命令"反弹shell-逃逸基于execve的命令监控(上)

APT组织武器:MuddyC3泄露代码分析

Python RASP 工程化:一次入侵的思考

教你学木马攻防 | 隧道木马 | 第一课

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 七夜安全博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 有意思的项目
    • 使用说明
      • 演示
        • 是障眼法吗?
          • 原理
          • 总结
            • 小想法
            相关产品与服务
            腾讯云代码分析
            腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,助力维护团队卓越代码文化。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档