文章来源|MS08067 红队培训班 第5期
本文作者:thresh(红队培训班5期学员)
0x01 钉钉机器人远控
钉钉,阿里巴巴出品,专为全球企业组织打造的智能移动办公平台,含PC版,IPad和手机版。远程视频会议,消息已读未读,DING消息任务管理,让沟通更高效;移动办公考勤,签到,审批,钉闪会,钉钉文档,钉钉教育解决方案,让工作学习更简单!
本次作业是使用钉钉机器人来实现远控服务器!
1、登录钉钉开放平台
可以先创建一个企业
选择应用开发,企业内部开发,添加一个机器人
记录生成的密钥
配置好开发管理,服务器出口IP添加VPS的地址,消息接收地址为一个可以接收数据的url,该url为后续在钉钉群中@机器人后,机器人处理接收和处理的接口地址
2、编写测试代码
代码包含:接收信息、发送信息、命令执行、接口认证,这里使用 flask 实现接收一个post请求,并将数据返回,接口调用详细参考钉钉开发管理平台。
# -*- coding: utf-8 -*-
import subprocess
import chardet
from flask import Flask, request
import hmac
import hashlib
import base64
import json
import requests
app = Flask(__name__)
# 消息数字签名计算核对
def check_sig(timestamp):
# 设置 secret,上面应用信息凭证的值
app_secret = 'xxx'
app_secret_enc = app_secret.encode('utf-8')
string_to_sign = '{}n{}'.format(timestamp, app_secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = base64.b64encode(hmac_code).decode('utf-8')
return sign
# 发送markdown消息
def send_md_msg(userid, title, message, webhook_url):
data = {
"msgtype": "markdown",
"markdown": {
"title": title,
"text": message
},
'''
"msgtype": "text",
"text": {
"content": message
},
'''
"at": {
"atUserIds": [
userid
],
}
}
# 利用requests发送post请求
req = requests.post(webhook_url, json=data)
# 命令执行
def exec_command(command):
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
data = p.stdout.read()
encoding = chardet.detect(data)['encoding']
out = "".join(data.decode(encoding))
return out
# 处理自动回复消息
def handle_info(req_data):
# 解析用户发送消息 通讯webhook_url
text_info = req_data['text']['content'].strip()
webhook_url = req_data['sessionWebhook']
senderid = req_data['senderId']
# print('***************text_info:', text_info)
# 处理系统命令
if 'command' in text_info:
cmd = str(text_info).split(':')[1]
title = '执行命令:'+cmd
text = exec_command(cmd)
send_md_msg(senderid, title, text, webhook_url)
def get_data():
# 第一步验证:是否是post请求
if request.method == "POST":
# print(request.headers)
# 签名验证 获取headers中的Timestamp和Sign
timestamp = request.headers.get('Timestamp')
sign = request.headers.get('Sign')
# 第二步验证:签名是否有效
if check_sig(timestamp) == sign:
# 获取、处理数据
req_data = json.loads(str(request.data, 'utf-8'))
# print(req_data)
handle_info(req_data)
print('验证通过')
print('验证不通过')
print('有get请求')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
3、在开发管理的服务器上启动服务
4、调试
在钉钉开放平台上选择调试
打开钉钉,会有一个TEST版本的群聊,可以在里面进行测试
可以看到,命令执行成功,服务器端请求成功
参考:
钉钉机器人设置:
https://open.dingtalk.com/document/robots/robot-overview
开发者管理:
<a href="https://open-dev.dingtalk.com/" l="" "="">https://open-dev.dingtalk.com/#/
钉钉开放平台
:https://open.dingtalk.com/document/robots/receive-message
钉钉自定义机器人:
Python 调用钉钉机器人
0x02 Windows api 函数使用
Windows API 函数搜索查找:https://docs.microsoft.com/zh-cn/search/
VirtualAlloc
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc
申请内存分配函数,内存申请成功返回已分配内存的基址,申请失败返回 NULL
C++语法
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
RtlMoveMenory
参考链接:
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlmovememory
将源内存块中的内容复制到目的内存块中,无返回值
C++语法
void RtlMoveMemory(
void* Destination, //指向移动目的地址的指针。
const void* Source, //指向要复制的内存地址的指针。
size_t Length //指定要复制的字节数。
);
// 返回值:
// 如果函数成功,则返回值为已分配页区域的基址。
// 如果函数失败,则返回值为 NULL。
CreateThread
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread
C++语法
HANDLE CreateThread(
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性
[in] SIZE_T dwStackSize, // 置初始栈的大小,以字节为单位
[in] LPTHREAD_START_ROUTINE lpStartAddress, // 指向线程函数的指针
[in, optional] __drv_aliasesMem LPVOID lpParameter, // 向线程函数传递的参数
[in] DWORD dwCreationFlags, // 线程创建属性
[out, optional] LPDWORD lpThreadId // 保存新线程的id
);
// 返回值:
// 如果函数成功,则返回值是新线程的句柄。
// 如果函数失败,则返回值为 NULL。
WaitForSingleObject
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
检测线程的状态
DWORD WaitForSingleObject(
[in] HANDLE hHandle, // #对象句柄。可以指定一系列的对象
[in] DWORD dwMilliseconds // #定时时间间隔
);
// 返回值:
// 如果函数成功,则返回值指示导致函数返回的事件。
VirtualProtect
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/api/memoryapi/nf-memoryapi-virtualprotect
更改调用进程的虚拟地址空间中已提交页区域的保护。
C++语法
BOOL VirtualProtect(
[in] LPVOID lpAddress, // 要更改其访问保护属性的页面区域的起始页的地址。
[in] SIZE_T dwSize, // 要更改其访问保护属性的区域的大小(以字节为单位)
[in] DWORD flNewProtect, // 内存保护选项。
[out] PDWORD lpflOldProtect // 指向一个变量的指针,该变量接收指定页区域中第一页的上一个访问保护值
);
// 函数成功,返回值为非零;函数执行失败,返回值为0
RtlCopyMemory
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/devnotes/rtlmovememory
将源内存块的内容复制到目标内存块,并支持重叠的源内存块和目标内存块
C++语法
VOID RtlMoveMemory(
_Out_ VOID UNALIGNED *Destination, // 指向要复制字节的目标内存块的指针
_In_ const VOID UNALIGNED *Source, // 指向要复制字节的源内存块的指针
_In_ SIZE_T Length // 从原复制到目标中的字节数
);
//无返回值
HeapCreate
参考链接:
https://docs.microsoft.com/zh-cn/windows/win32/api/heapapi/nf-heapapi-heapcreate
创建由调用进程使用的私有堆对象
C++语法
HANDLE HeapCreate(
[in] DWORD flOptions, // 堆的分配选项
[in] SIZE_T dwInitialSize, // 堆的初始大小
[in] SIZE_T dwMaximumSize // 堆的最大大小
);
//返回值:执行成功,返回值是新创建的堆的句柄;执行失败,返回值为NULL
HeapAlloc
从堆中去分配内存块,分配的内存不可移动
C++ 语法
DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
[in] HANDLE hHeap, // 将从中分配内存的堆的句柄。此句柄由 HeapCreate 或 GetProcessHeap 函数返回。
[in] DWORD dwFlags, // 堆分配选项。指定这些值中的任何一个都将覆盖使用 HeapCreate 创建堆时指定的相应值。
[in] SIZE_T dwBytes // 分配的字节数
);
//返回值:
//成功:返回值是指向已分配内存块的指针
//失败:未设置堆分配选项为 HEAP_GENERATE_EXCEPTIONS,则返回值为 NULL;否则返回特定的异常
CreateRemoteThread
创建在另一个进程的虚拟地址空间中运行的线程。
C++语法
HANDLE CreateRemoteThread(
[in] HANDLE hProcess, // 要在其中创建线程的进程的句柄
[in] LPSECURITY_ATTRIBUTES lpThreadAttributes, // 指向SECURITY_ATTRIBUTES结构的指针,该结构指定新线程的安全描述符并确定子进程是否可以继承返回的句柄。
[in] SIZE_T dwStackSize, // 堆栈的初始大小(以字节为单位)
[in] LPTHREAD_START_ROUTINE lpStartAddress, // 指向应用程序定义函数类型的指针LPTHREAD_START_ROUTINE由线程执行,并表示远程进程中线程的起始地址。
[in] LPVOID lpParameter, // 指向要传递给线程函数的变量的指针。
[in] DWORD dwCreationFlags, // 控制线程创建的标志
[out] LPDWORD lpThreadId // 指向接收线程标识符的变量的指针
);
//返回值:
//成功:返回值是新线程的句柄
//失败:返回值为 NULL
Python 实现shellcode 加载器
shellcode加载器中分别调用VirtualAlloc、RtlMoveMemory、CreateThread、WaitForSingleObject函数来实现
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
0
Python 实现屏幕截图
调用 win32 模块实现
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
1
0x03 注册表操作
注册表信息
win+r 输入 regedit 打开注册表编辑器
Windows 注册表有如下5个根键
注册表中值的类型
python 中使用的模块
win32api、win32con
常用函数
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
2
代码实现
1、通过 RegOpenKey 函数打开指定注册表中指定项,返回ERROR_SUCCESS。
2、根据需要调用RegQueryValue()、RegSetValue()、RegCreateKey()、RegDeleteKey()等函数对注册表进行增删查改操作。
Reg_Tools.py
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
3
代码基本能使用,在功能使用、兼容性和交互逻辑等方面还需改进。
举例使用:
python3 .Reg_Tools.py --regkey 'HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun' --type SelectValue
查找HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun下的启动信息
添加
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
4
再次查看
删除注册表
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress, // #要分配的内存区域的地址
[in] SIZE_T dwSize, // 申请分配内存的大小
[in] DWORD flAllocationType, // 申请分配内存的类型
[in] DWORD flProtect // 申请分配内存的保护
);
//返回值
//函数成功,则返回值为返回已分配的内存基址
//函数失败,则返回值为NULL
5
0x04 总结
钉钉机器人的服务端远控:打造了自定义的钉钉机器人,能够实现在钉钉群实现与机器人实现交互。
Windows API:查阅微软文档,熟悉了一些Windwos的API函数,这些函数可以在C++和Python中调用。同时,能够根据API函数分析shellcode加载器的原理。
注册表操作:在Python中调用 Windows 函数实现对注册表的增删查改。
本次作业能够将之前学习的知识和上课的内容融会贯通,收获了许多,同时,也还有需要改进的地方。
HVV行动-红队攻防 第6期
火热报名中
课程费用
已经报其他培训班的同学,可享优惠价2399元~
报名方式
1.可直接登录官网在线报名,报名地址:http://edu.ms08067.com/my/course/12
2.加客服微信报名
学习资源
上课时间
如果无法准时参加直播课程,在线培训的每节课程都会被录制成视频上传到官方网站(edu.ms08067.com),可随时随地在线观看。
上课方式
讲师介绍
讲师B:MS08067安全实验室核心成员,主要从事渗透测试、安全开发等方向研究。多次参加国家护网行动,拥有多年红队经验。
讲师C:MS08067安全实验室核心成员,前知名乙方研究员,擅长免杀。
全新课程目录6.0版
第1天课 | 信息收集总体概念 被动信息收集 信息收集的总体概念以及在整个红队流程中的位置; 被动信息收集的基本结构和基本逻辑; 被动信息收集的常见手段(网络空间搜索、被动信息收集工具、传统搜索); 被动信息收集后的信息处理; 被动信息收集工具的底层原理以及如何编写; |
第2天课 | 主动信息收集 信息收集完成之后的信息综合处理 主动信息收集的基本结构和基本逻辑; 主动信息收集的常见手段(仅限扫描的nmap和扫描带有poc的goby); 主动信息收集后的信息处理; 主动信息收集工具的底层原理以及如何编写; 如何将主动信息收集和被动信息收集的信息综合处理; 收集到的信息如何衔接到下一步的红队流程中; |
第3天课 | 社会工程学 社会工程学的含义以及实际应用; 社会工程学的知识体系; 社会工程学的学习方法; |
第4天课 | 社会工程学中的交互 社会工程学中的常见钓鱼方式以及应用; 社会工程学中如何根据收集到的信息利用目标的社会属性弱点进行交互; 社会工程学中的信任获得和信任利用方式; |
第5天课 | 实战中的快速审计 寻找源码中的多种途径; 快速查找源码中可利用的脆弱点; 使用工具发现脆弱点; |
第6天课 | POC的编写 POC编写应具备的哪些条件; Idea工具的安装; 本地IO进行内容读写; 网络请求进行发包模拟; POC实战; |
第7天课 | 红队之反溯源 工作机器;攻击资源; 匿名攻击; 识别反制; 反溯源案例; |
第8天课 | Windows内网提权 Potato家族提权;补丁提权;系统配置错误提权; 第三方服务提权;组策略提权;Bypassuac; 数据库提权;令牌窃取;密码收集提权; |
第9天课 | Liunx内网提权 系统内核提权;第三方服务提权; 数据库提权;密码收集提权; 键盘记录提权;Suid提权; Sudo提权;反弹shell提权; |
第10天课 | 内网穿透 内网穿透概述及正向代理和反向代理; 花生壳内网穿透;Frp内网穿透; Ngrok内网穿透;reGeorg+Proxifier; 向日葵代理及teamviewer; 最小化渗透概述;云函数;域前置; |
第11天课 | 外网打点技巧和Kerberos认证原理 入口权限获取;java中间件Nday; php集成环境;开源程序Nday; 边界网络设备利用;基础服务getshell; kerberos认证;kerberos认证流程; |
第12天课 | 域内信息收集及域信任 域内信息收集概述; 域内用户组收集;域信任关系收集; 用户目录收集;预控日志收集; Arp信息收集;Tcpdump;Sshkey收集; 铭感配置读取;网络拓扑架构分析判断; |
第13天课 | 域渗透工具实操实战 Setspn;Nslookup;AdFind; Psloggendon;360safebrowserdecrypt; SchtaskBackDoorWebshell;regeditBypassUAC; |
第14天课 | 票据伪造、域委派攻击、域控攻击 PTH认证过程解析;票据伪造攻击原理; Mimikatz实现票据伪造攻击; 域委派原理;域委派攻击方法; zerologin;nopac |
第15天课 | 域林渗透 域林渗透概述和父域子域及域信任关系分析;大型域渗透思路; 预控定位;Pth喷射;域信任攻击; 组策略漏洞;Web及系统漏洞;逃逸漏洞; |
第16天课 | Windows权限维持 Windows权限维持概述及隐藏技巧;关闭杀软; 注册表自启动;组策略脚本; 计划任务;服务自启动; 内存码;进程劫持;隐蔽隧道; |
第17天课 | Liunx权限维持 Liunx权限维持概述及隐藏技巧; 添加用户;SUIDshell; SSH公私钥;软连接; crontab计划任务;Strace后门;Openssh后门; 隐蔽隧道;关杀软; |
第18天课 | 痕迹清理 Windows操作系统的痕迹清理; Windows痕迹清理的基本思路和思考逻辑; Windows清理登录痕迹、操作痕迹及时间痕迹; Linux操作系统的痕迹清理; Linux痕迹清理的基本思路和思考逻辑; Linux清理登录痕迹、操作痕迹及时间痕迹; |
第19天课 | Meterpreter木马分析 反编译meterprter源码; 分析meterpreter源码; 源码级别免杀深入浅出; |
第20天课 | 免杀代码基础 编程语言基础; windowsapi基础; socket编程基础; shellcode加载器基础; |
第21天课 | shellcode基础 现代远控的基本结构; shellcode生成方式与可以使用的类型; shellcode源码内容; |
第22天课 | 代码上的免杀 杀毒软件基本原理; 杀毒软件基础复现; 针对杀毒软件特点免杀; 护网过程中如何手动和自动识别恶意代码; |
第23天课 | 人工层面的免杀 通信的加密; 通信内容的伪造; ip地址的保护; 护网过程中如何识别通信特征与内容; 反调试; |
第24天课 第25天课 | 实际红队案例分享、红队攻击思路 红队模拟面试; 实际红队案例分享; 红队攻击思路; 红队护网准备工具及蓝队分析反制方法及思路 红队准备工具; 邮件溯源工作; 水坑反制案例; |
如何提前预习
为更顺利的完成课程相关内容,请同学一定要提前预习相关知识点,已经报名的同学,请购买实验室出版的《内网安全攻防:渗透测试实战指南》一书或参加转发朋友圈赠送“内网知识星球”活动,学习相关的内容。
你距离红队大佬,只差一个决定
报名咨询联系小客服
扫描下方二维码加入星球学习
加入后邀请你进入内部微信群,内部微信群永久有效!
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...