├── README.md ├── go.mod ├── go.sum ├── img ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png └── main ├── func.go └── main.go /README.md: -------------------------------------------------------------------------------- 1 | # Ceyes 2 | 一款基于fofa根据域名或fofa语法收集C段分布数量的工具。 3 | 4 | ### 2023.6.28 更新 5 | 修复了fofa近期对api中的cloud_name的field进行限制导致工具无法正常执行的bug。目前已删除了cloud_name的标签查询,主要通过org标签来判断是否为云服务器。实际上org标签判断的广度其实高于cloud_name标签 6 | 7 | ### 2023.5.29 更新 8 | 1.修复了count计数去重存在问题的bug 9 | 10 | 2.添加-cloud参数,可识别该段是否为云服务器 11 | 12 | 云服务器的fofa指纹目前整理如下,主要识别方式通过org和cloud_name 2个字段进行判别,命中cloud_name基本上确定是云了,如果命中org字段可能是云也有可能是云厂商自家的资产。 13 | ``` 14 | 华为云 - Huawei Cloud Service data center [cloud_name="HuaWeiCloud"] 15 | 16 | 阿里云 - Hangzhou Alibaba Advertising Co.,Ltd. & Alibaba US Technology Co., Ltd. [cloud_name="aliyun"] 17 | 18 | 腾讯云 - Shenzhen Tencent Computer Systems Company Limited & Tencent Building, Kejizhongyi Avenue [cloud_name="tencent"] 19 | 20 | 百度云 - Beijing Baidu Netcom Science and Technology Co., Ltd. [cloud_name="baidu"] 21 | 22 | 亚马逊云 - AMAZON-02 & AMAZON-AES [cloud_name="Amazon"] 23 | 24 | google云 - GOOGLE-IT & GOOGLE [cloud_name="google"] 25 | 26 | azure云 - MICROSOFT-CORP-MSN-AS-BLOCK [cloud_name="azure"] 27 | 28 | Cloudflare - CLOUDFLARENET [cloud_name="Cloudflare"] 29 | ``` 30 | 31 | 效果如下 32 | 33 | ``` 34 | main.exe -f 1.txt -sc -cloud 35 | ``` 36 | 37 | ![5](img/5.png) 38 | 39 | 40 | ### 编译&运行 41 | ``` 42 | git clone https://github.com/SiJiDo/Ceyes.git 43 | cd Ceyes/main 44 | go build 45 | ``` 46 | 之后会在目标下产生一个main的可执行文件,第一次使用直接运行它,会在相同目录下生成一个config.yaml文件 47 | 内容如下 48 | ``` 49 | fofa_email: "" 50 | Fofa_api: "" 51 | ``` 52 | 填上自己的fofa邮箱和api即可,这里最好用高级会员,因为高级会员api一次可以查1W条数据,方便更加全面的统计c段分布。如果是普通会员的api查的数据很少,不一定全面。 53 | 54 | ### 使用方式 55 | 功能点如下 56 | ``` 57 | main.exe -h 58 | Usage of main.exe: 59 | -cloud 60 | check cloud 61 | -d string 62 | domain deafult use dork like (domain= xxx || host= xxx) 63 | -f string 64 | domain text 65 | -s string 66 | fofa search dork 67 | -sc 68 | sort result by count, deafult ip sort 69 | ``` 70 | #### 排序功能 71 | 72 | 通过-sc参数可以对结果进行排序,加上-sc参数会将结果按c段个数排序,不加-sc则按ip进行排序 73 | 74 | #### 用法1 根据fofa语句查询分布情况 75 | 76 | 这里得注意下,因为fofa语法中要用到双引号,所有正确写法如下 77 | ``` 78 | main.exe -s "title=\"北京大学\"" -sc 79 | ``` 80 | 81 | ![1](img/1.png) 82 | 83 | #### 用法2 根据主域名查询分布情况 84 | 85 | ``` 86 | main.exe -d "jd.com" -sc 87 | ``` 88 | 89 | ![2](img/2.png) 90 | 91 | #### 用法3 通过文件进行域名查询 92 | 93 | 这里文件内容通常是收集到主域名,比如下 94 | 95 | ``` 96 | //1.txt 97 | 98 | qq.com 99 | weixin.com 100 | tencent.com 101 | ``` 102 | 103 | Ceyes工具会对目标进行每个域名的ip分布进行信息收集,也会对最后的结果进行汇总 104 | 105 | ![image-20230529101524961](img/4.png) 106 | 107 | 当然我之前写到IEyes可以通过查备案快速收集域名,配合起来用也很不错 108 | 109 | ``` 110 | https://github.com/SiJiDo/IEyes 111 | ``` 112 | 113 | ![image-20230529101524961](img/3.png) 114 | 115 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module CEyes 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/PuerkitoBio/goquery v1.8.0 // indirect 7 | github.com/antchfx/htmlquery v1.2.5 // indirect 8 | github.com/antchfx/xmlquery v1.3.11 // indirect 9 | github.com/gobwas/glob v0.2.3 // indirect 10 | github.com/gocolly/colly v1.2.0 11 | github.com/kennygrant/sanitize v1.2.4 // indirect 12 | github.com/kirinlabs/HttpRequest v1.1.1 13 | github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect 14 | github.com/temoto/robotstxt v1.1.2 // indirect 15 | github.com/tidwall/gjson v1.14.4 16 | golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb 17 | google.golang.org/appengine v1.6.7 // indirect 18 | gopkg.in/yaml.v2 v2.4.0 19 | ) 20 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= 2 | github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= 3 | github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= 4 | github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= 5 | github.com/antchfx/htmlquery v1.2.5 h1:1lXnx46/1wtv1E/kzmH8vrfMuUKYgkdDBA9pIdMJnk4= 6 | github.com/antchfx/htmlquery v1.2.5/go.mod h1:2MCVBzYVafPBmKbrmwB9F5xdd+IEgRY61ci2oOsOQVw= 7 | github.com/antchfx/xmlquery v1.3.11 h1:8aRK7l3+dJjL8ZmwgVzG5AXysrP7Mss2424tfntKWKY= 8 | github.com/antchfx/xmlquery v1.3.11/go.mod h1:ywPcYkN0GvURUxXpUujaMVvuLSOYQBzoSfHKfAYezCE= 9 | github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8= 10 | github.com/antchfx/xpath v1.2.1/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= 11 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 12 | github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= 13 | github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= 14 | github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI= 15 | github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA= 16 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= 17 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 18 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 19 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 20 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 21 | github.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o= 22 | github.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak= 23 | github.com/kirinlabs/HttpRequest v1.1.1 h1:eBbFzpRd/Y7vQhRY30frHK3yAJiT1wDlB31Ryzyklc0= 24 | github.com/kirinlabs/HttpRequest v1.1.1/go.mod h1:XV38fA4rXZox83tlEV9KIQ7Cdsut319x6NGzVLuRlB8= 25 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 26 | github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI= 27 | github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= 28 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 29 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 30 | github.com/temoto/robotstxt v1.1.2 h1:W2pOjSJ6SWvldyEuiFXNxz3xZ8aiWX5LbfDiOFd7Fxg= 31 | github.com/temoto/robotstxt v1.1.2/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo= 32 | github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= 33 | github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= 34 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= 35 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= 36 | github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= 37 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 38 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 39 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 40 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 41 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 42 | golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 43 | golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= 44 | golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 45 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 46 | golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= 47 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 48 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 49 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 50 | golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 51 | golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 52 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 53 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 54 | golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= 55 | golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 56 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 57 | golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= 58 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 59 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 60 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 61 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 62 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 63 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 64 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 65 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 66 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 67 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 68 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 69 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 70 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 71 | golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 72 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 73 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 74 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 75 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 76 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= 77 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 78 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 79 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 80 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 81 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 82 | golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= 83 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 84 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= 85 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 86 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 87 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 88 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 89 | -------------------------------------------------------------------------------- /img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiJiDo/Ceyes/a63996197433e6098ddde78c8f6cb021234fb0a1/img/1.png -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiJiDo/Ceyes/a63996197433e6098ddde78c8f6cb021234fb0a1/img/2.png -------------------------------------------------------------------------------- /img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiJiDo/Ceyes/a63996197433e6098ddde78c8f6cb021234fb0a1/img/3.png -------------------------------------------------------------------------------- /img/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiJiDo/Ceyes/a63996197433e6098ddde78c8f6cb021234fb0a1/img/4.png -------------------------------------------------------------------------------- /img/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SiJiDo/Ceyes/a63996197433e6098ddde78c8f6cb021234fb0a1/img/5.png -------------------------------------------------------------------------------- /main/func.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | "net/url" 7 | "os" 8 | "sort" 9 | "strings" 10 | 11 | "github.com/kirinlabs/HttpRequest" 12 | "github.com/tidwall/gjson" 13 | ) 14 | 15 | func in(target string, str_array []string) bool { 16 | for _, element := range str_array { 17 | if target == element { 18 | return true 19 | } 20 | } 21 | return false 22 | } 23 | 24 | func check_cloud(cloud bool, info string) string { 25 | result := "" 26 | if cloud == false { 27 | return result 28 | } 29 | 30 | org_cloudlist := make(map[string]string) 31 | org_cloudlist["HuaWeiCloud"] = "Huawei Cloud Service data center" 32 | org_cloudlist["AliyunCloud"] = "Hangzhou Alibaba Advertising Co.,Ltd. & Alibaba US Technology Co., Ltd." 33 | org_cloudlist["TencentCloud"] = "Shenzhen Tencent Computer Systems Company Limited & Tencent Building, Kejizhongyi Avenue" 34 | org_cloudlist["BaiduCloud"] = "Beijing Baidu Netcom Science and Technology Co., Ltd." 35 | org_cloudlist["AmazonCloud"] = "AMAZON-02 & AMAZON-AES" 36 | org_cloudlist["GoogleCloud"] = "GOOGLE-IT & GOOGLE" 37 | org_cloudlist["AzureCloud"] = " MICROSOFT-CORP-MSN-AS-BLOCK" 38 | org_cloudlist["Cloudflare"] = "CLOUDFLARENET" 39 | 40 | tag := strings.Split(info, "+") 41 | org := tag[1] 42 | for k, v := range org_cloudlist { 43 | if strings.Contains(v, org) { 44 | result = k + "(maybe)" 45 | } 46 | } 47 | 48 | return result 49 | } 50 | 51 | func fofac(fofa_email string, fofa_api string, fofa_dock string, cloud bool) (map[string]int, map[string]string) { 52 | 53 | result := make(map[string]int) 54 | cloud_result := make(map[string]string) 55 | dorkbase64 := base64.StdEncoding.EncodeToString([]byte(fofa_dock)) 56 | 57 | url1 := "https://fofa.info/api/v1/search/all?fields=host,ip,port,as_organization&size=10000&email=" + url.QueryEscape(fofa_email) + "&key=" + url.QueryEscape(fofa_api) + "&qbase64=" + url.QueryEscape(dorkbase64) 58 | req := HttpRequest.NewRequest() 59 | req.SetCookies(map[string]string{ 60 | "auth_token": "123", 61 | }) 62 | 63 | resp, err := req.Get(url1) 64 | 65 | if err != nil { 66 | fmt.Println(err) 67 | os.Exit(1) 68 | } 69 | 70 | body, err := resp.Body() 71 | jsondata := gjson.Get(string(body), "results") 72 | 73 | datalist := jsondata.Array() 74 | var list []string 75 | for i := range datalist { 76 | data := datalist[i] 77 | ip := data.Array()[1].String() 78 | org := data.Array()[3].String() 79 | if in(ip, list) == false { 80 | list = append(list, ip+"+"+org) 81 | } 82 | } 83 | 84 | var ip_list []string 85 | 86 | for i := range list { 87 | if strings.Contains(list[i], ":") { 88 | continue 89 | } 90 | ip := strings.Split(list[i], "+")[0] 91 | if in(ip, ip_list) { 92 | continue 93 | } 94 | ip_list = append(ip_list, ip) 95 | ipc := strings.Split(list[i], ".")[0:3] 96 | a := ipc[0] + "." + ipc[1] + "." + ipc[2] + ".0/24" 97 | _, status := result[a] 98 | if status == true { 99 | result[a] = result[a] + 1 100 | if strings.Contains(cloud_result[a], "(maybe)") { 101 | cloud_result[a] = check_cloud(cloud, list[i]) 102 | } 103 | } else { 104 | result[a] = 1 105 | cloud_result[a] = check_cloud(cloud, list[i]) 106 | } 107 | } 108 | 109 | return result, cloud_result 110 | } 111 | 112 | func Contains(s1, s2 string) { 113 | panic("unimplemented") 114 | } 115 | 116 | type ip_count struct { 117 | Key string 118 | Val int 119 | } 120 | 121 | func sortbyip(result map[string]int) []ip_count { 122 | newresult := make([]ip_count, 0) 123 | for k, v := range result { 124 | newresult = append(newresult, ip_count{Key: k, Val: v}) 125 | } 126 | 127 | sort.Slice(newresult, func(i, j int) bool { 128 | return newresult[i].Val > newresult[j].Val 129 | }) 130 | return newresult 131 | } 132 | 133 | func sortbycount(result map[string]int) []ip_count { 134 | newresult := make([]ip_count, 0) 135 | for k, v := range result { 136 | newresult = append(newresult, ip_count{Key: k, Val: v}) 137 | } 138 | 139 | sort.Slice(newresult, func(i, j int) bool { 140 | return strings.Compare(newresult[i].Key, newresult[j].Key) < 0 141 | }) 142 | return newresult 143 | } 144 | -------------------------------------------------------------------------------- /main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "io/ioutil" 9 | "os" 10 | "strings" 11 | 12 | yaml "gopkg.in/yaml.v2" 13 | ) 14 | 15 | type Yaml struct { 16 | Fofa_email string `yaml:"fofa_email"` 17 | Fofa_api string `yaml:"Fofa_api"` 18 | } 19 | 20 | func checkError(err error) { 21 | if err != nil { 22 | panic(err) 23 | } 24 | } 25 | 26 | func GetFofaAuth() (string, string) { 27 | conf := new(Yaml) 28 | yamlFile, err := ioutil.ReadFile("config.yaml") 29 | 30 | err = yaml.Unmarshal(yamlFile, conf) 31 | 32 | checkError(err) 33 | fofa_email := conf.Fofa_email 34 | fofa_api := conf.Fofa_api 35 | return fofa_email, fofa_api 36 | } 37 | 38 | func setFofaAuthfile(src string) { 39 | stu := &Yaml{ 40 | Fofa_email: "", 41 | Fofa_api: "", 42 | } 43 | data, err := yaml.Marshal(stu) 44 | checkError(err) 45 | err = ioutil.WriteFile(src, data, 0777) 46 | checkError(err) 47 | } 48 | 49 | func main() { 50 | 51 | var filename string 52 | var fofaSearch string 53 | var sortCount bool 54 | var cloud bool 55 | var fofaDomain string 56 | var fofaDork []string 57 | fofa_email, fofa_api := GetFofaAuth() 58 | 59 | flag.StringVar(&fofaDomain, "d", "", "domain deafult use dork like (domain= xxx || host= xxx)") 60 | flag.StringVar(&filename, "f", "", "domain text") 61 | flag.StringVar(&fofaSearch, "s", "", "fofa search dork") 62 | flag.BoolVar(&sortCount, "sc", false, "sort result by count, deafult ip sort") 63 | flag.BoolVar(&cloud, "cloud", false, "check cloud") 64 | 65 | flag.Parse() 66 | 67 | f, err := os.Open("config.yaml") 68 | if err != nil && os.IsNotExist(err) { 69 | setFofaAuthfile("config.yaml") 70 | } 71 | f.Close() 72 | 73 | if filename == "" && fofaDomain == "" { 74 | fofaDork = append(fofaDork, fofaSearch) 75 | 76 | } else if fofaDomain != "" { 77 | tmp := "domain=\"" + fofaDomain + "\" || host=\"" + fofaDomain + "\"" 78 | fofaDork = append(fofaDork, tmp) 79 | } else { //read domain info to make fofa dork and search 80 | file, err := os.Open(filename) 81 | 82 | if err != nil { 83 | fmt.Println("file error:", err) 84 | } 85 | reader := bufio.NewReader(file) 86 | for { 87 | domain, err := reader.ReadString('\n') // end flag 88 | domain = strings.Replace(domain, " ", "", -1) 89 | domain = strings.Replace(domain, "\n", "", -1) 90 | domain = strings.Replace(domain, "\r", "", -1) 91 | if domain != "" { 92 | tmp := "domain=\"" + domain + "\" || host=\"" + domain + "\"" 93 | fofaDork = append(fofaDork, tmp) 94 | } 95 | if err == io.EOF { 96 | break 97 | } 98 | } 99 | } 100 | 101 | //strat search 102 | final_result := make(map[string]int) 103 | final_result_domain := make(map[string]string) 104 | final_cloud_result := make(map[string]string) 105 | for i := range fofaDork { 106 | fmt.Println("[+]now fofa dork is: [ " + fofaDork[i] + " ]") 107 | result, cloud_result := fofac(fofa_email, fofa_api, fofaDork[i], cloud) 108 | //sort result 109 | r := make([]ip_count, 0) 110 | if sortCount == false { 111 | r = sortbycount(result) 112 | } else { 113 | r = sortbyip(result) 114 | } 115 | for _, pair := range r { 116 | if len(pair.Key) == 15 { 117 | fmt.Printf("[+]ipc:%v count: %v %v \n", pair.Key, pair.Val, cloud_result[pair.Key]) 118 | } else if len(pair.Key) == 16 { 119 | fmt.Printf("[+]ipc:%v count: %v %v \n", pair.Key, pair.Val, cloud_result[pair.Key]) 120 | } else { 121 | fmt.Printf("[+]ipc:%v\t count: %v %v \n", pair.Key, pair.Val, cloud_result[pair.Key]) 122 | } 123 | } 124 | if filename == "" { 125 | break 126 | } else { 127 | for k, v := range result { 128 | _, status := final_result[k] 129 | if cloud_result[k] != "" { 130 | final_cloud_result[k] = "[" + cloud_result[k] + "]\t" 131 | if strings.Contains(final_cloud_result[k], "(maybe)") == false { 132 | final_cloud_result[k] = final_cloud_result[k] + "\t" 133 | } 134 | } else { 135 | final_cloud_result[k] = "\t\t\t" 136 | } 137 | if status == true { 138 | final_result[k] = final_result[k] + result[k] 139 | final_result_domain[k] = final_result_domain[k] + ", " + strings.Split(fofaDork[i], "host=")[1] 140 | } else { 141 | final_result[k] = v 142 | final_result_domain[k] = strings.Split(fofaDork[i], "host=")[1] 143 | 144 | } 145 | } 146 | } 147 | } 148 | 149 | if filename != "" { 150 | fmt.Println("====================all domains in file result=========================") 151 | 152 | r := make([]ip_count, 0) 153 | if sortCount == false { 154 | r = sortbycount(final_result) 155 | } else { 156 | r = sortbyip(final_result) 157 | } 158 | for _, pair := range r { 159 | domain := final_result_domain[pair.Key] 160 | if len(pair.Key) == 15 { 161 | fmt.Printf("[+]ipc:%v count: %v \t%v domain: %v\n", pair.Key, pair.Val, final_cloud_result[pair.Key], domain) 162 | } else if len(pair.Key) == 16 { 163 | fmt.Printf("[+]ipc:%v count: %v \t%v domain: %v\n", pair.Key, pair.Val, final_cloud_result[pair.Key], domain) 164 | } else { 165 | fmt.Printf("[+]ipc:%v\t count: %v \t%v domain: %v\n", pair.Key, pair.Val, final_cloud_result[pair.Key], domain) 166 | } 167 | } 168 | 169 | } 170 | } 171 | --------------------------------------------------------------------------------