背景
RTO I 的课程结束了,Cobalt Strike 算是会用了。然后继上一篇文章之后,我还没有机会用 Cobalt Strike Beacon 做一下 Windows Defender Bypass。之后会写。
另外,我也想问一下我自己,Cobalt Strike 里面最基本的 payload - beacon,你了解清楚了吗?
所以今天,我就花点时间给自己解惑,同时也提出更多问题往后深入。
接下来先对 Beacon 做下逆向,看一下 HTTP Beacon 大致上都做了什么。
Beacon
创建一个基于 HTTP Listener 的 64位 beacon。

看一下文件格式,64位 PE 文件。

看到 PE 头。
xxd beacon.exe | less -S

这一段 bOb 很有意思,可以用作 Signature Detection 吗?

strings 一下看到了使用了哪些方法。

使用了哪些 dll。

在 IDA 里具体看一下。
创建命名管道
拖到 IDA。

从进度条长度来看,HTTP beacon 的复杂度并不高(也有可能是我什么都不懂,错的离谱)。

逆向的能力不是很强,所以先随便看看。
我的思路是能不能找到相关 API,如 VirtualAlloc,CreateThread 之类的字符串,或者是参数的字符串也行。所以我就一个一个点开看了一下。
运气比较好的是,在第四个 entry 就找到了。
如图,StartupInfo 是 CreateProcessA API 的参数。
CreateProcessA 方法原型。
BOOL CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
找到了 StartupInfo,就意味着找到了 CreateProcess 。

接着往下看,不一会儿看到了 GetProcAddress API。

调用之后检查 eax 返回值,如果是 0 表示成功,跳到 loc_4012A1。
接着一个一个翻看左边的方法名列表。
在 sub_401795 找到了 CreateThread 方法。看到了默认的 pipe name。
拼接完成之后,应该是 \\.\pipe\MSSE-XX-server。

其中 xx 是一个数字跟 ecx 中的数值 (0x26AA -> 9898)做除法运算(实际是取模),最后取了 EDX 中的余数作为 xx 的值。


这里创建了一个线程并执行。看一下到底启动了一个什么样的线程。跟进 sub_401685,那里是执行代码的起始地址。

再跟进 sub_4015D0。

所以,上面的 CreateThread 方法,是创建一个命名管道,用来写入和读取数据,命令执行的结果应该就是通过管道来获取的。第一步完成,HTTP Beacon 首先创建了一个命名管道,管道名称就是上面看到的
\\.\pipe\MSSE-XX-server
继续跟进代码,看下一步做了什么操作。
连接命名管道
创建完了命名管道(如果创建成功),紧接着就是执行 ConnectNamedPipe 连接该命名管道。

这里开始网管道里面写数据。

写数据有了,读取在哪里呢?
继续往下找,可以看到这里调用了 CreateFileA API。

这里 dwCreateionDisposition 设置为 0x3。
查看官方文档,这个设置是会打开一个已经存在的文件或者设备。

猜想这里是用 CreateFileA 打开了已经创建好的管道。
然后通过 ReadFile API 读取数据。

唯一可以说明这里打开的文件就是之前创建的管道的指标,就是这个 Buffer (lpFileName) 参数。

双击点进去,可以看到他指向了 sub_4015D0。

而 sub_4015D0 正是创建命名管道的方法。

进一步可以判定,这个 Buffer 就是管道名,ReadFile 就是读取了该管道的数据。
Beacon HTTP 请求?
接下来,我想找到诸如 IP 地址,端口,从而找到 HTTP 请求的代码。
结果通过 IP 地址找不到。

返回去看 strings 命令的输出,确实没有看到跟 HTTP 或者 Socket 连接相关的方法或者是 DLL。


而如果看一下 msfvenom 生成的 payload。
msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=127.0.0.1 LPORT=443 -f exe -o msf.exe
strings msf.exe
可以很清楚看到诸如 WSADuplicateSocketA,WinHTTPConnect 等方法,也看到了 WS2_32.dll。

有点疑惑。
拖到 windows 机器上用 WinDBG 看一下。

看来 strings 不能列出运行期间会加载的 dll。
在 WindDBG 里面看到了 winhttp.dll,WS2_32.dll。

选择 WS2_32.dll 在 recv API 上打个断点试一下。
bp ws2_32!recv

发送一条命令看一下能不能触发断点。

断点触发了。其实每隔5秒就会触发断点,因为 beacon 会 checkin,就算没有命令可以执行,C2 Server 也会发送相应的 response。

sleep 没有输出。再执行一个 whoami 看一下怎么发送命令结果的。

再次触发断点。单步执行。
今天告一段落,找时间继续。还要验证一下上面所说的读取数据的 CreateFileA 方法。
总结
这篇文章对 Beacon 做了一些比较简单的分析。开个头先,之后还会不断深入。
KEEP CALM AND HACK AWAY!
参考链接
- https://www.ired.team/miscellaneous-reversing-forensics/windows-kernel-internals/windows-x64-calling-convention-stack-frame
- https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
- https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa
- https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread
- https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpconnect
- https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaduplicatesocketa
- https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect
- https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastringtoaddressw
- https://decoded.avast.io/threatintel/decoding-cobalt-strike-understanding-payloads/
- https://docs.oracle.com/cd/E19455-01/806-3773/6jct9o0am/index.html#:~:text=div%20executes%20unsigned%20division.,AH%2C%20Dx%2C%20or%20EDX.


![[编程语言][C++][Qt]单独添加UI文件](https://img-blog.csdnimg.cn/acac9d73e7674108b28e571db11d049f.png#pic_center)








![BUUCTF Misc [ACTF新生赛2020]NTFS数据流 john-in-the-middle [ACTF新生赛2020]swp 喵喵喵](https://img-blog.csdnimg.cn/32c992ed9863441a9ec57fbfef35d1f0.png)





