# tl;dr
This short post presents a pure Go alternative to `rpc2socks` as a Sliver extension. There is absolutely no reason to use it over `rpc2socks`, but it presented itself as an interesting experiment to explore Sliver extensions in Go and SOCKS5 over SMB. It is available @https://github.com/zimnyaa/smbsocks/
This is all for fun only, I wouldn't recommend this over `rpc2socks`.
# usage
The solution consists of two components. The server (`rpcsrv.dll`) is meant to be executed at a server that you want to pivot through with `wmiexec`/`atexec`/WinRM/etc. This DLL with open a named pipe and start listening.
The client (`rpccli.dll`/`extension.json`) is a Sliver extension. Upon execution, it will try to connect using the current logon token to a remote named pipe. If successful, it will spin up a SSH connection and a local SOCKS proxy. After that, the operator can portforward to that local proxy on the implant side and obtain a way to tunnel connections through the victim. Here's the diagram:
```
operator -(portfwd)> implant -(smbsocks)> target -> segmented network
```
In practice, it looks like this:
![[Pasted image 20231227204621.png]]
![[Screenshot 2023-12-27 at 20.28.43.png]]
![[Screenshot 2023-12-27 at 20.28.49.png]]
And on the target side (with a DLL hijack):
![[Pasted image 20231227204734.png]]
# socks approach
SOCKS5 is spun up with an SSH connection over SMB (very similar to [[grpcssh]]). In short, this is how it works:
```js
spin up net.Conn over SMB ->
spin up ssh.Conn over net.Conn ->
forward Dial function from SSH to the socks server
```
# sliver extension
To create a Golang extension for Sliver, some C bootstrapping was required:
```c
typedef int (*goCallback)(const char*, int);
typedef struct _goArgs {
char* argsBuffer;
int bufferSize;
} goArgs;
void callGo(LPVOID param) {
dialpipe(param);
}
__declspec(dllexport) int __stdcall entrypoint(char *argsBuffer, int bufferSize, goCallback callback) {
goArgs args;
args.argsBuffer = argsBuffer;
args.bufferSize = bufferSize;
CreateThread(NULL, NULL, callGo, argsBuffer, NULL, NULL);
callback("socks thread created.", 22);
return 0;
}
```
Other than that, two Golang runtimes seem to be doing fine together.