休闲

python漏洞扫描

时间:2010-12-5 17:23:32  作者:百科   来源:百科  查看:  评论:0
内容摘要:用Python写漏洞扫描器,最容易踩的坑不是代码写不出来,而是写出来之后扫谁。去年有个朋友让我帮他看看公司内网的一台测试服务器,他怀疑上面跑着个旧版本的Jenkins。我随手写了个脚本,用socket

用Python写漏洞扫描器,漏洞最容易踩的扫描坑不是代码写不出来,而是漏洞写出来之后扫谁。去年有个朋友让我帮他看看公司内网的扫描一台测试服务器,他怀疑上面跑着个旧版本的漏洞Jenkins。我随手写了个脚本,扫描用socket连了8080端口,漏洞发了个HTTP GET请求,扫描看响应头里的漏洞X-Jenkins字段。三秒钟出结果——2.289.1,扫描确实是漏洞个带CVE的版本。这事让我意识到,扫描Python做漏洞扫描的漏洞门槛低到离谱,但法律和道德的扫描边界比代码本身重要得多。

先聊端口扫描。漏洞nmap当然强,但Python的socket模块足够应付大多数场景。我习惯用connect_ex()而不是connect(),前者返回错误码而不是抛异常,批量扫的时候省去try-except的麻烦。写个循环,目标IP列表从文件读,端口列表从命令行参数传,超时设0.5秒。一千个端口扫一个C段,大概两分钟。有人喜欢用多线程,ThreadPoolExecutor扔进去,速度能快十倍,但别开太大——我试过500个线程,路由器直接把我IP封了半小时。

端口开了只是第一步。接下来是服务识别。banner抓取是最土但最有效的方法。连上端口,等几秒,看服务返回什么。SSH会告诉你OpenSSH版本,HTTP会返回Server头,MySQL会报协议版本。有个细节:很多服务不会主动发banner,得先发个探针。比如HTTP要发GET / HTTP/1.0\r\n\r\n,Redis发PING\r\n。我写过一个字典,针对不同端口发不同探针,命中率比瞎等强多了。

识别出服务版本之后,才是真正的漏洞匹配。别想着自己写CVE数据库,用现成的。Python有个库叫cve-search,能查NVD的数据,但API限速烦人。更实际的做法是维护一个本地JSON,只存你关心的那些漏洞。比如看到Apache 2.4.49,直接查CVE-2021-41773路径穿越;看到Log4j 2.14.1,JNDI注入跑不掉。匹配逻辑简单得很——版本号字符串比较,或者正则提取主版本号。我见过有人用机器学习做版本匹配,纯属脱裤子放屁。

写扫描器最危险的部分是漏洞验证。你写个PoC去测目标有没有某个漏洞,测试流量本身就可能触发入侵检测。去年我帮一个客户测他们内部的GitLab,写了个脚本检测CVE-2021-22205,结果刚发第一个请求,WAF就把我IP拉黑了。后来学乖了,所有验证请求都加随机延迟,User-Agent轮换,遇到403就停。更稳妥的办法是只做被动检测——看版本号,不实际利用。虽然误报率高,但至少不会把自己送进去。

代码组织上,我倾向于一个类搞定。Scanner类初始化时接收目标列表和端口范围,run()方法里串起扫描、识别、匹配三个步骤。结果输出用JSON,方便后续处理。别用print,用logging,级别设INFO,出错了写文件。有个坑:Python的socket.gethostbyname()在遇到不存在的域名时会阻塞很久,设个全局超时,或者用dnspython库自己控制。

最后说个真实案例。某次我扫一个客户的公网IP段,发现一台服务器开着6379端口,Redis未授权访问。我没写任何利用代码,只是连上去发了INFO命令,返回了服务器信息。截图发给客户,他们十分钟内就关了端口。这比写什么exp都管用。Python漏洞扫描的价值不在技术多高深,在于快速验证一个假设。你怀疑某个服务有问题,写二十行代码确认一下,比翻三天文档实在。但记住,扫之前拿到书面授权,扫的时候控制并发,扫完删掉所有数据。这行当里,进去的人多半不是技术不行,是手太痒。

最近更新
热门排行
copyright © 2026 powered by 力不从心网   sitemap