├── libs ├── ssh │ ├── default.hf │ ├── hostname.hf │ ├── resolv.hf │ ├── wget.hf │ ├── ls.hf │ ├── version.hf │ ├── hosts.hf │ ├── arp.hf │ ├── df_h.hf │ ├── df.hf │ ├── inittab.hf │ ├── config.json │ ├── group.hf │ ├── ifconfig.hf │ ├── passwd.hf │ ├── cpuinfo.hf │ ├── ll_h.hf │ ├── ll.hf │ ├── ls_all.hf │ └── meminfo.hf └── telnet │ ├── default.hf │ ├── hostname.hf │ ├── resolv.hf │ ├── wget.hf │ ├── ls.hf │ ├── version.hf │ ├── arp.hf │ ├── hosts.hf │ ├── df_h.hf │ ├── df.hf │ ├── inittab.hf │ ├── config.json │ ├── group.hf │ ├── ifconfig.hf │ ├── passwd.hf │ ├── cpuinfo.hf │ ├── ll_h.hf │ ├── ll.hf │ ├── ls_all.hf │ └── meminfo.hf ├── db ├── ipip.ipdb └── sql │ └── hfish_db.sql ├── images ├── wx.jpg ├── data.png ├── fish.png ├── help.png ├── login.png ├── logo.png ├── mail.png ├── run.png ├── colony.png ├── setting.png └── dashboard.png ├── .gitattributes ├── static ├── favicon.ico ├── images │ ├── xy.png │ ├── hfish.png │ ├── logo.png │ └── avatar.jpg ├── data │ ├── img │ │ ├── bg01.png │ │ ├── bg02.png │ │ ├── bg03.png │ │ ├── bg04.png │ │ ├── header.png │ │ ├── panel.png │ │ └── thumb.jpg │ └── css │ │ ├── bootstrap │ │ └── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── app.css ├── fonts │ ├── ionicons.eot │ ├── ionicons.ttf │ ├── ionicons.woff │ ├── themify.eot │ ├── themify.ttf │ ├── themify.woff │ ├── typicons.eot │ ├── typicons.ttf │ ├── typicons.woff │ ├── FontAwesome.otf │ ├── Pe-icon-7-stroke.eot │ ├── Pe-icon-7-stroke.ttf │ ├── Pe-icon-7-stroke.woff │ ├── Simple-Line-Icons.eot │ ├── Simple-Line-Icons.ttf │ ├── Simple-Line-Icons.woff │ ├── Simple-Line-Icons.woff2 │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── Material-Design-Iconic-Font.eot │ ├── Material-Design-Iconic-Font.ttf │ ├── Material-Design-Iconic-Font.woff │ ├── Material-Design-Iconic-Font.woff2 │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ ├── weathericons-regular-webfont.eot │ ├── weathericons-regular-webfont.ttf │ ├── weathericons-regular-webfont.woff │ ├── glyphicons-halflings-regular.woff2 │ └── weathericons-regular-webfont.woff2 ├── css │ ├── tables.stack-mixin.css │ ├── tables.stack-mixin.css.map │ ├── tablesaw.stackonly.css.map │ └── tablesaw.stackonly.css ├── libs │ ├── wangeditor3 │ │ └── fonts │ │ │ └── w-e-icon.woff │ ├── bootstrap-sweetalert │ │ └── thumbs-up.jpg │ ├── switchery │ │ └── switchery.min.css │ ├── counterup │ │ └── jquery.counterup.min.js │ ├── waypoints │ │ └── lib │ │ │ ├── shortcuts │ │ │ ├── sticky.min.js │ │ │ ├── inview.min.js │ │ │ ├── infinite.min.js │ │ │ ├── sticky.js │ │ │ ├── infinite.js │ │ │ └── inview.js │ │ │ └── waypoints.debug.js │ └── page │ │ └── jquery.sPage.css └── js │ ├── jquery.app.js │ └── detect.js ├── core ├── protocol │ ├── tftp │ │ ├── libs │ │ │ ├── .travis.yml │ │ │ ├── CONTRIBUTORS │ │ │ ├── .gitignore │ │ │ ├── backoff.go │ │ │ ├── single_port_test.go │ │ │ ├── tftp_anticipate_test.go │ │ │ ├── LICENSE │ │ │ ├── netascii │ │ │ │ ├── netascii.go │ │ │ │ └── netascii_test.go │ │ │ ├── connection.go │ │ │ ├── single_port.go │ │ │ └── client.go │ │ └── tftp.go │ ├── ssh │ │ ├── gliderlabs │ │ │ ├── ssh_test.go │ │ │ ├── example_test.go │ │ │ ├── wrap.go │ │ │ ├── conn.go │ │ │ ├── context_test.go │ │ │ ├── util.go │ │ │ ├── doc.go │ │ │ ├── options.go │ │ │ ├── tcpip_test.go │ │ │ ├── agent.go │ │ │ ├── server_test.go │ │ │ └── options_test.go │ │ └── ssh.go │ ├── memcache │ │ ├── global.go │ │ └── LinkedHashMap │ │ │ ├── linked_hashmap.go │ │ │ └── linklist.go │ ├── ftp │ │ ├── graval │ │ │ ├── ftplogger.go │ │ │ ├── ftpfileinfo.go │ │ │ ├── listformatter.go │ │ │ └── ftpdriver.go │ │ └── ftp.go │ ├── httpx │ │ └── http.go │ ├── custom │ │ └── custom.go │ └── telnet │ │ └── telnet.go ├── pool │ └── pool.go ├── exec │ └── exec.go ├── dbUtil │ └── dbUtil.go ├── rpc │ ├── core │ │ ├── client_test.go │ │ ├── debug.go │ │ └── jsonrpc │ │ │ ├── client.go │ │ │ └── server.go │ └── client │ │ └── client.go └── alert │ └── alert.go ├── utils ├── md5 │ └── md5.go ├── is │ └── is.go ├── passwd │ └── passwd.go ├── log │ └── log.go ├── ping │ └── ping.go ├── page │ └── page.go ├── json │ ├── ssh.go │ └── telnet.go ├── cache │ └── cache.go ├── try │ └── try.go ├── cors │ └── cors.go ├── send │ └── gomail.go ├── color │ └── color.go ├── conf │ └── conf.go ├── ip │ └── ip.go └── file │ └── file.go ├── .gitignore ├── make.sh ├── docker-compose.yml ├── error └── error.go ├── main.go ├── web ├── deep │ ├── static │ │ ├── x.js │ │ ├── wordpress-logo.svg │ │ └── l10n.min.css │ └── html │ │ └── index.html └── wordPress │ ├── static │ ├── x.js │ ├── wordpress-logo.svg │ └── l10n.min.css │ └── html │ └── index.html ├── view ├── colony │ └── view.go ├── mail │ └── view.go ├── login │ └── view.go ├── url.go └── fish │ └── view.go ├── dockerfile ├── Entrypoint.sh └── Dockerfile ├── go.mod ├── README_CN.md └── README.md /libs/ssh/default.hf: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /libs/telnet/default.hf: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /libs/ssh/hostname.hf: -------------------------------------------------------------------------------- 1 | web_server -------------------------------------------------------------------------------- /libs/telnet/hostname.hf: -------------------------------------------------------------------------------- 1 | web_server -------------------------------------------------------------------------------- /libs/ssh/resolv.hf: -------------------------------------------------------------------------------- 1 | nameserver 8.8.8.8 2 | nameserver 8.8.4.4 3 | -------------------------------------------------------------------------------- /libs/telnet/resolv.hf: -------------------------------------------------------------------------------- 1 | nameserver 8.8.8.8 2 | nameserver 8.8.4.4 3 | -------------------------------------------------------------------------------- /db/ipip.ipdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/db/ipip.ipdb -------------------------------------------------------------------------------- /images/wx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/wx.jpg -------------------------------------------------------------------------------- /images/data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/data.png -------------------------------------------------------------------------------- /images/fish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/fish.png -------------------------------------------------------------------------------- /images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/help.png -------------------------------------------------------------------------------- /images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/login.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/logo.png -------------------------------------------------------------------------------- /images/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/mail.png -------------------------------------------------------------------------------- /images/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/run.png -------------------------------------------------------------------------------- /libs/ssh/wget.hf: -------------------------------------------------------------------------------- 1 | wget:未指定 URL 2 | 用法: wget [选项]... [URL]... 3 | 4 | 请尝试使用“wget --help”查看更多的选项。 -------------------------------------------------------------------------------- /libs/telnet/wget.hf: -------------------------------------------------------------------------------- 1 | wget:未指定 URL 2 | 用法: wget [选项]... [URL]... 3 | 4 | 请尝试使用“wget --help”查看更多的选项。 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=Go 2 | *.css linguist-language=Go 3 | *.html linguist-language=Go -------------------------------------------------------------------------------- /images/colony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/colony.png -------------------------------------------------------------------------------- /images/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/setting.png -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/images/dashboard.png -------------------------------------------------------------------------------- /static/images/xy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/images/xy.png -------------------------------------------------------------------------------- /static/images/hfish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/images/hfish.png -------------------------------------------------------------------------------- /static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/images/logo.png -------------------------------------------------------------------------------- /static/data/img/bg01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/bg01.png -------------------------------------------------------------------------------- /static/data/img/bg02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/bg02.png -------------------------------------------------------------------------------- /static/data/img/bg03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/bg03.png -------------------------------------------------------------------------------- /static/data/img/bg04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/bg04.png -------------------------------------------------------------------------------- /static/data/img/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/header.png -------------------------------------------------------------------------------- /static/data/img/panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/panel.png -------------------------------------------------------------------------------- /static/data/img/thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/img/thumb.jpg -------------------------------------------------------------------------------- /static/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/ionicons.eot -------------------------------------------------------------------------------- /static/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/ionicons.ttf -------------------------------------------------------------------------------- /static/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/ionicons.woff -------------------------------------------------------------------------------- /static/fonts/themify.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/themify.eot -------------------------------------------------------------------------------- /static/fonts/themify.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/themify.ttf -------------------------------------------------------------------------------- /static/fonts/themify.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/themify.woff -------------------------------------------------------------------------------- /static/fonts/typicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/typicons.eot -------------------------------------------------------------------------------- /static/fonts/typicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/typicons.ttf -------------------------------------------------------------------------------- /static/fonts/typicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/typicons.woff -------------------------------------------------------------------------------- /static/images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/images/avatar.jpg -------------------------------------------------------------------------------- /static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /libs/ssh/ls.hf: -------------------------------------------------------------------------------- 1 | bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var -------------------------------------------------------------------------------- /static/css/tables.stack-mixin.css: -------------------------------------------------------------------------------- 1 | /* Tablesaw Sass Mixins */ 2 | 3 | /*# sourceMappingURL=tables.stack-mixin.css.map */ 4 | -------------------------------------------------------------------------------- /libs/telnet/ls.hf: -------------------------------------------------------------------------------- 1 | bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var -------------------------------------------------------------------------------- /static/fonts/Pe-icon-7-stroke.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Pe-icon-7-stroke.eot -------------------------------------------------------------------------------- /static/fonts/Pe-icon-7-stroke.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Pe-icon-7-stroke.ttf -------------------------------------------------------------------------------- /static/fonts/Pe-icon-7-stroke.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Pe-icon-7-stroke.woff -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Simple-Line-Icons.woff2 -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /core/protocol/tftp/libs/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | os: 4 | - linux 5 | - osx 6 | 7 | before_install: 8 | - ulimit -n 4096 9 | -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /libs/ssh/version.hf: -------------------------------------------------------------------------------- 1 | Linux version 3.2.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-14) ) #1 SMP Debian 3.2.68-1+deb7u1 2 | -------------------------------------------------------------------------------- /static/libs/wangeditor3/fonts/w-e-icon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/libs/wangeditor3/fonts/w-e-icon.woff -------------------------------------------------------------------------------- /libs/telnet/version.hf: -------------------------------------------------------------------------------- 1 | Linux version 3.2.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.6.3 (Debian 4.6.3-14) ) #1 SMP Debian 3.2.68-1+deb7u1 2 | -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Material-Design-Iconic-Font.eot -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Material-Design-Iconic-Font.ttf -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Material-Design-Iconic-Font.woff -------------------------------------------------------------------------------- /static/fonts/Material-Design-Iconic-Font.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/Material-Design-Iconic-Font.woff2 -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/weathericons-regular-webfont.eot -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/weathericons-regular-webfont.ttf -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/weathericons-regular-webfont.woff -------------------------------------------------------------------------------- /static/libs/bootstrap-sweetalert/thumbs-up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/libs/bootstrap-sweetalert/thumbs-up.jpg -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /static/fonts/weathericons-regular-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/fonts/weathericons-regular-webfont.woff2 -------------------------------------------------------------------------------- /core/protocol/tftp/libs/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Dmitri Popov 2 | Mojo Talantikite 3 | Giovanni Bajo 4 | Andrew Danforth 5 | Victor Lowther 6 | minghuadev on github.com 7 | Owen Mooney 8 | -------------------------------------------------------------------------------- /libs/ssh/hosts.hf: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 2 | ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 -------------------------------------------------------------------------------- /libs/ssh/arp.hf: -------------------------------------------------------------------------------- 1 | Address HWtype HWaddress Flags Mask Iface 2 | gateway ether ee:ff:ff:ff:ff:ff C eth0 -------------------------------------------------------------------------------- /libs/telnet/arp.hf: -------------------------------------------------------------------------------- 1 | Address HWtype HWaddress Flags Mask Iface 2 | gateway ether ee:ff:ff:ff:ff:ff C eth0 -------------------------------------------------------------------------------- /libs/telnet/hosts.hf: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 2 | ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 -------------------------------------------------------------------------------- /static/data/css/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/css/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/data/css/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/css/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/data/css/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/css/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/data/css/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyberCraftsmanx/HFish-Honeypot/HEAD/static/data/css/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /static/css/tables.stack-mixin.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,0BAA0B", 4 | "sources": ["../plugins/tablesaw/src/tables.stack-mixin.scss"], 5 | "names": [], 6 | "file": "tables.stack-mixin.css" 7 | } -------------------------------------------------------------------------------- /utils/md5/md5.go: -------------------------------------------------------------------------------- 1 | package md5 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | ) 7 | 8 | func Md5(str string) string { 9 | h := md5.New() 10 | h.Write([]byte(str)) 11 | return hex.EncodeToString(h.Sum(nil)) 12 | } 13 | -------------------------------------------------------------------------------- /core/pool/pool.go: -------------------------------------------------------------------------------- 1 | package pool 2 | 3 | import ( 4 | "sync" 5 | "github.com/panjf2000/ants" 6 | ) 7 | 8 | func New(size int) (sync.WaitGroup, *ants.Pool) { 9 | wg := sync.WaitGroup{} 10 | pool, _ := ants.NewPool(size) 11 | return wg, pool 12 | } 13 | -------------------------------------------------------------------------------- /utils/is/is.go: -------------------------------------------------------------------------------- 1 | package is 2 | 3 | import ( 4 | "HFish/utils/conf" 5 | ) 6 | 7 | func Rpc() bool { 8 | rpcStatus := conf.Get("rpc", "status") 9 | 10 | if rpcStatus == "2" { 11 | return true 12 | } else { 13 | return false 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /utils/passwd/passwd.go: -------------------------------------------------------------------------------- 1 | package passwd 2 | 3 | import "regexp" 4 | 5 | // 密码脱敏 6 | func Desensitization(str string, x string) string { 7 | re, _ := regexp.Compile("(\\S{1})(\\S{1,20})(\\S{1})") 8 | return re.ReplaceAllString(str, "$1"+x+"$3") 9 | } 10 | -------------------------------------------------------------------------------- /utils/log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | "time" 7 | ) 8 | 9 | func Pr(typex string, ip string, text string, a ...interface{}) { 10 | fmt.Fprintln(gin.DefaultWriter, "["+typex+"] "+ip+" - ["+time.Now().Format("2006-01-02 15:04:05")+"] "+text+" ", a) 11 | } 12 | -------------------------------------------------------------------------------- /libs/ssh/df_h.hf: -------------------------------------------------------------------------------- 1 | 文件系统 容量 已用 可用 已用% 挂载点 2 | /dev/vda1 40G 14G 24G 37% / 3 | devtmpfs 487M 0 487M 0% /dev 4 | tmpfs 497M 0 497M 0% /dev/shm 5 | tmpfs 497M 556K 496M 1% /run 6 | tmpfs 497M 0 497M 0% /sys/fs/cgroup 7 | tmpfs 100M 0 100M 0% /run/user/0 -------------------------------------------------------------------------------- /libs/telnet/df_h.hf: -------------------------------------------------------------------------------- 1 | 文件系统 容量 已用 可用 已用% 挂载点 2 | /dev/vda1 40G 14G 24G 37% / 3 | devtmpfs 487M 0 487M 0% /dev 4 | tmpfs 497M 0 497M 0% /dev/shm 5 | tmpfs 497M 556K 496M 1% /run 6 | tmpfs 497M 0 497M 0% /sys/fs/cgroup 7 | tmpfs 100M 0 100M 0% /run/user/0 -------------------------------------------------------------------------------- /core/exec/exec.go: -------------------------------------------------------------------------------- 1 | package exec 2 | 3 | import ( 4 | "os/exec" 5 | "bytes" 6 | ) 7 | 8 | func Execute(shell string) (string, error) { 9 | cmd := exec.Command("/bin/bash", "-c", shell) 10 | var out bytes.Buffer 11 | 12 | cmd.Stdout = &out 13 | err := cmd.Run() 14 | if err != nil { 15 | return "", err 16 | } 17 | return out.String(), nil 18 | } 19 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/ssh_test.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestKeysEqual(t *testing.T) { 8 | defer func() { 9 | if r := recover(); r != nil { 10 | t.Errorf("The code did panic") 11 | } 12 | }() 13 | 14 | if KeysEqual(nil, nil) { 15 | t.Error("two nil keys should not return true") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | .idea 15 | vendor 16 | .DS_Store 17 | */.DS_Store 18 | */.idea/% 19 | */vendor/% 20 | db/*.db 21 | logs/*.log -------------------------------------------------------------------------------- /libs/ssh/df.hf: -------------------------------------------------------------------------------- 1 | 文件系统 1K-块 已用 可用 已用% 挂载点 2 | /dev/vda1 41151808 14343860 24694516 37% / 3 | devtmpfs 498608 0 498608 0% /dev 4 | tmpfs 508084 0 508084 0% /dev/shm 5 | tmpfs 508084 556 507528 1% /run 6 | tmpfs 508084 0 508084 0% /sys/fs/cgroup 7 | tmpfs 101620 0 101620 0% /run/user/0 -------------------------------------------------------------------------------- /libs/telnet/df.hf: -------------------------------------------------------------------------------- 1 | 文件系统 1K-块 已用 可用 已用% 挂载点 2 | /dev/vda1 41151808 14343860 24694516 37% / 3 | devtmpfs 498608 0 498608 0% /dev 4 | tmpfs 508084 0 508084 0% /dev/shm 5 | tmpfs 508084 556 507528 1% /run 6 | tmpfs 508084 0 508084 0% /sys/fs/cgroup 7 | tmpfs 101620 0 101620 0% /run/user/0 -------------------------------------------------------------------------------- /core/protocol/tftp/libs/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /make.sh: -------------------------------------------------------------------------------- 1 | ../xgo --targets=darwin/amd64 -ldflags='-w -s' . 2 | ../xgo --targets=darwin/386 -ldflags='-w -s' . 3 | ../xgo --targets=linux/arm64 -ldflags='-w -s' . 4 | ../xgo --targets=linux/amd64 -ldflags='-w -s' . 5 | ../xgo --targets=linux/386 -ldflags='-w -s' . 6 | ../xgo --targets=linux/arm-7 -ldflags='-w -s' . 7 | ../xgo --targets=windows/amd64 -ldflags='-w -s' . 8 | ../xgo --targets=windows/386 -ldflags='-w -s' . 9 | -------------------------------------------------------------------------------- /utils/ping/ping.go: -------------------------------------------------------------------------------- 1 | package ping 2 | 3 | import ( 4 | "net/http" 5 | "HFish/utils/try" 6 | "HFish/utils/conf" 7 | ) 8 | 9 | func Ping() { 10 | try.Try(func() { 11 | rpcStatus := conf.Get("rpc", "status") 12 | 13 | s := "Server" 14 | 15 | if rpcStatus == "2" { 16 | s = "Client" 17 | } 18 | 19 | resp, _ := http.Get("http://ping.hfish.io/test?s=" + s) 20 | defer resp.Body.Close() 21 | }).Catch(func() {}) 22 | } 23 | -------------------------------------------------------------------------------- /utils/page/page.go: -------------------------------------------------------------------------------- 1 | package page 2 | 3 | // 分页从1开始 4 | func Start(currentPage int, pageSize int) int { 5 | return (currentPage - 1) * pageSize 6 | } 7 | 8 | // 分页结束 9 | func End(currentPage int64, pageSize int64) int64 { 10 | return currentPage * pageSize 11 | } 12 | 13 | // 分页总页数 14 | func TotalPage(count int, pageSize int) int { 15 | result := count / pageSize 16 | yu := count % pageSize 17 | if yu > 0 { 18 | result = result + 1 19 | } 20 | return result 21 | } 22 | -------------------------------------------------------------------------------- /utils/json/ssh.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "github.com/bitly/go-simplejson" 5 | "HFish/utils/log" 6 | "io/ioutil" 7 | ) 8 | 9 | var sshJson []byte 10 | 11 | func init() { 12 | file, err := ioutil.ReadFile("./libs/ssh/config.json") 13 | 14 | if err != nil { 15 | log.Pr("HFish", "127.0.0.1", "读取文件失败", err) 16 | } 17 | 18 | sshJson = file 19 | } 20 | 21 | func GetSsh() (*simplejson.Json, error) { 22 | res, err := simplejson.NewJson(sshJson) 23 | return res, err 24 | } 25 | -------------------------------------------------------------------------------- /utils/json/telnet.go: -------------------------------------------------------------------------------- 1 | package json 2 | 3 | import ( 4 | "github.com/bitly/go-simplejson" 5 | "HFish/utils/log" 6 | "io/ioutil" 7 | ) 8 | 9 | var telnetJson []byte 10 | 11 | func init() { 12 | file, err := ioutil.ReadFile("./libs/telnet/config.json") 13 | 14 | if err != nil { 15 | log.Pr("HFish", "127.0.0.1", "读取文件失败", err) 16 | } 17 | 18 | telnetJson = file 19 | } 20 | 21 | func GetTelnet() (*simplejson.Json, error) { 22 | res, err := simplejson.NewJson(telnetJson) 23 | return res, err 24 | } 25 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | hfish: 4 | build: 5 | context: ./dockerfile 6 | dockerfile: ./Dockerfile 7 | restart: always 8 | ports: 9 | - "9001:9001" # Landing page 10 | 11 | - "21:21" 12 | - "22:22" 13 | - "23:23" 14 | - "69:69" 15 | - "3306:3306" 16 | - "5900:5900" 17 | - "6379:6379" 18 | - "7879:7879" 19 | - "8080:8080" 20 | - "8081:8081" 21 | - "8989:8989" 22 | - "9000:9000" 23 | - "9200:9200" 24 | - "11211:11211" 25 | -------------------------------------------------------------------------------- /libs/ssh/inittab.hf: -------------------------------------------------------------------------------- 1 | # inittab is no longer used when using systemd. 2 | # 3 | # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. 4 | # 5 | # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target 6 | # 7 | # systemd uses 'targets' instead of runlevels. By default, there are two main targets: 8 | # 9 | # multi-user.target: analogous to runlevel 3 10 | # graphical.target: analogous to runlevel 5 11 | # 12 | # To view current default target, run: 13 | # systemctl get-default 14 | # 15 | # To set a default target, run: 16 | # systemctl set-default TARGET.target 17 | # -------------------------------------------------------------------------------- /libs/telnet/inittab.hf: -------------------------------------------------------------------------------- 1 | # inittab is no longer used when using systemd. 2 | # 3 | # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. 4 | # 5 | # Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target 6 | # 7 | # systemd uses 'targets' instead of runlevels. By default, there are two main targets: 8 | # 9 | # multi-user.target: analogous to runlevel 3 10 | # graphical.target: analogous to runlevel 5 11 | # 12 | # To view current default target, run: 13 | # systemctl get-default 14 | # 15 | # To set a default target, run: 16 | # systemctl set-default TARGET.target 17 | # -------------------------------------------------------------------------------- /utils/cache/cache.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "github.com/patrickmn/go-cache" 5 | "time" 6 | ) 7 | 8 | var c *cache.Cache 9 | 10 | func init() { 11 | c = cache.New(5*time.Minute, 10*time.Minute) 12 | } 13 | 14 | func Get(key string) (interface{}, bool) { 15 | // 读取缓存 16 | vaule, is := c.Get(key) 17 | return vaule, is 18 | } 19 | 20 | func Set(key string, vaule interface{}) { 21 | // 写入缓存 默认过期时间 22 | c.Set(key, vaule, cache.DefaultExpiration) 23 | } 24 | 25 | func Setx(key string, vaule interface{}) { 26 | // 写入缓存 永不过期 27 | c.Set(key, vaule, cache.NoExpiration) 28 | } 29 | -------------------------------------------------------------------------------- /core/protocol/tftp/tftp.go: -------------------------------------------------------------------------------- 1 | package tftp 2 | 3 | import ( 4 | "HFish/core/protocol/tftp/libs" 5 | "fmt" 6 | "io" 7 | "os" 8 | "time" 9 | ) 10 | 11 | func readHandler(filename string, rf io.ReaderFrom) error { 12 | return nil 13 | } 14 | 15 | func writeHandler(filename string, wt io.WriterTo) error { 16 | return nil 17 | } 18 | 19 | func Start(address string) { 20 | s := libs.NewServer(readHandler, writeHandler) 21 | s.SetTimeout(5 * time.Second) 22 | err := s.ListenAndServe(address) 23 | if err != nil { 24 | fmt.Fprintf(os.Stdout, "server: %v\n", err) 25 | os.Exit(1) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /error/error.go: -------------------------------------------------------------------------------- 1 | package error 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | const ( 8 | ErrSuccessCode = 200 9 | ErrSuccessMsg = "success" 10 | 11 | ErrFailApiKeyCode = 1001 12 | ErrFailApiKeyMsg = "秘钥不正确" 13 | 14 | ErrFailLoginCode = 1002 15 | ErrFailLoginMsg = "账号密码不正确" 16 | 17 | ErrFailMailCode = 1003 18 | ErrFailMailMsg = "邮箱未启用" 19 | 20 | ErrFailConfigCode = 1004 21 | ErrFailConfigMsg = "请配置后在启用" 22 | 23 | ErrFailPlugCode = 1005 24 | ErrFailPlugMsg = "上报信息错误" 25 | ) 26 | 27 | func Check(e error, tips string) { 28 | if e != nil { 29 | fmt.Println(tips) 30 | //panic(e) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "HFish/utils/setting" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | //setting.Run() 11 | args := os.Args 12 | if args == nil || len(args) < 2 { 13 | setting.Help() 14 | } else { 15 | if args[1] == "help" || args[1] == "--help" { 16 | setting.Help() 17 | } else if args[1] == "init" || args[1] == "--init" { 18 | setting.Init() 19 | } else if args[1] == "version" || args[1] == "--version" { 20 | fmt.Println("v0.6.3") 21 | } else if args[1] == "run" || args[1] == "--run" { 22 | setting.Run() 23 | } else { 24 | setting.Help() 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/try/try.go: -------------------------------------------------------------------------------- 1 | package try 2 | 3 | import "reflect" 4 | 5 | func Try(f func()) *tryStruct { 6 | return &tryStruct{ 7 | catches: make(map[reflect.Type]ExeceptionHandler), 8 | hold: f, 9 | } 10 | } 11 | 12 | type ExeceptionHandler func(interface{}) 13 | 14 | type tryStruct struct { 15 | catches map[reflect.Type]ExeceptionHandler 16 | hold func() 17 | } 18 | 19 | func (t *tryStruct) Catch(f func()) { 20 | defer func() { 21 | if e := recover(); nil != e { 22 | if h, ok := t.catches[reflect.TypeOf(e)]; ok { 23 | h(e) 24 | } else { 25 | f() 26 | } 27 | } 28 | }() 29 | 30 | t.hold() 31 | } 32 | -------------------------------------------------------------------------------- /libs/telnet/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "command": { 3 | "default": "default", 4 | "ls": "ls", 5 | "ls -all": "ls_all", 6 | "arp": "arp", 7 | "cat /proc/cpuinfo": "cpuinfo", 8 | "cat /etc/group": "group", 9 | "cat /etc/hosts": "hosts", 10 | "hostname": "hostname", 11 | "cat /etc/inittab": "inittab", 12 | "cat /proc/meminfo": "meminfo", 13 | "cat /etc/passwd": "passwd", 14 | "cat /etc/resolv.conf": "resolv", 15 | "cat /proc/version": "version", 16 | "ifconfig": "ifconfig", 17 | "df -h": "df_h", 18 | "df": "df", 19 | "wget": "wget", 20 | "ll": "ll", 21 | "ll -h": "ll_h" 22 | } 23 | } -------------------------------------------------------------------------------- /core/protocol/tftp/libs/backoff.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | const ( 9 | defaultTimeout = 5 * time.Second 10 | defaultRetries = 5 11 | ) 12 | 13 | type backoffFunc func(int) time.Duration 14 | 15 | type backoff struct { 16 | attempt int 17 | handler backoffFunc 18 | } 19 | 20 | func (b *backoff) reset() { 21 | b.attempt = 0 22 | } 23 | 24 | func (b *backoff) count() int { 25 | return b.attempt 26 | } 27 | 28 | func (b *backoff) backoff() { 29 | if b.handler == nil { 30 | time.Sleep(time.Duration(rand.Int63n(int64(time.Second)))) 31 | } else { 32 | time.Sleep(b.handler(b.attempt)) 33 | } 34 | b.attempt++ 35 | } 36 | -------------------------------------------------------------------------------- /static/libs/switchery/switchery.min.css: -------------------------------------------------------------------------------- 1 | .switchery{background-color:#fff;border:1px solid #dfdfdf;border-radius:20px;cursor:pointer;display:inline-block;height:30px;position:relative;vertical-align:middle;width:50px;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;box-sizing:content-box;background-clip:content-box}.switchery>small{background:#fff;border-radius:100%;box-shadow:0 1px 3px rgba(0,0,0,0.4);height:30px;position:absolute;top:0;width:30px}.switchery-small{border-radius:20px;height:20px;width:33px}.switchery-small>small{height:20px;width:20px}.switchery-large{border-radius:40px;height:40px;width:66px}.switchery-large>small{height:40px;width:40px} -------------------------------------------------------------------------------- /libs/ssh/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "account": "root", 3 | "password": "root", 4 | "hostname": "[root@web_server ~]# ", 5 | "command": { 6 | "default": "default", 7 | "ls": "ls", 8 | "ls -all": "ls_all", 9 | "arp": "arp", 10 | "cat /proc/cpuinfo": "cpuinfo", 11 | "cat /etc/group": "group", 12 | "cat /etc/hosts": "hosts", 13 | "hostname": "hostname", 14 | "cat /etc/inittab": "inittab", 15 | "cat /proc/meminfo": "meminfo", 16 | "cat /etc/passwd": "passwd", 17 | "cat /etc/resolv.conf": "resolv", 18 | "cat /proc/version": "version", 19 | "ifconfig": "ifconfig", 20 | "df -h": "df_h", 21 | "df": "df", 22 | "wget": "wget", 23 | "ll": "ll", 24 | "ll -h": "ll_h" 25 | } 26 | } -------------------------------------------------------------------------------- /web/deep/static/x.js: -------------------------------------------------------------------------------- 1 | function report() { 2 | var login_field = $("#user_login").val(); 3 | var password = $("#user_pass").val(); 4 | 5 | $.ajax({ 6 | type: "POST", 7 | url: "/api/v1/post/deep_report", 8 | dataType: "json", 9 | data: { 10 | "name": "暗网钓鱼", 11 | "info": login_field + "&&" + password, 12 | "sec_key": "9cbf8a4dcb8e30682b927f352d6559a0" 13 | }, 14 | success: function (e) { 15 | if (e.code == "200") { 16 | alert("账号密码错误"); 17 | } else { 18 | console.log(e.msg) 19 | } 20 | }, 21 | error: function (e) { 22 | console.log("fail") 23 | } 24 | }); 25 | } -------------------------------------------------------------------------------- /web/wordPress/static/x.js: -------------------------------------------------------------------------------- 1 | function report() { 2 | var login_field = $("#user_login").val(); 3 | var password = $("#user_pass").val(); 4 | 5 | $.ajax({ 6 | type: "POST", 7 | url: "/api/v1/post/report", 8 | dataType: "json", 9 | data: { 10 | "name": "WordPress钓鱼", 11 | "info": login_field + "&&" + password, 12 | "sec_key": "9cbf8a4dcb8e30682b927f352d6559a0" 13 | }, 14 | success: function (e) { 15 | if (e.code == "200") { 16 | alert("账号密码错误"); 17 | } else { 18 | console.log(e.msg) 19 | } 20 | }, 21 | error: function (e) { 22 | console.log("fail") 23 | } 24 | }); 25 | } -------------------------------------------------------------------------------- /libs/ssh/group.hf: -------------------------------------------------------------------------------- 1 | root:x:0: 2 | daemon:x:1: 3 | bin:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mail:x:8: 10 | news:x:9: 11 | uucp:x:10: 12 | man:x:12: 13 | proxy:x:13: 14 | kmem:x:15: 15 | dialout:x:20: 16 | fax:x:21: 17 | voice:x:22: 18 | cdrom:x:24:richard 19 | floppy:x:25:richard 20 | tape:x:26: 21 | sudo:x:27: 22 | audio:x:29:richard 23 | dip:x:30:richard 24 | www-data:x:33: 25 | backup:x:34: 26 | operator:x:37: 27 | list:x:38: 28 | irc:x:39: 29 | src:x:40: 30 | gnats:x:41: 31 | shadow:x:42: 32 | utmp:x:43: 33 | video:x:44:richard 34 | sasl:x:45: 35 | plugdev:x:46:richard 36 | staff:x:50: 37 | games:x:60: 38 | users:x:100: 39 | nogroup:x:65534: 40 | libuuid:x:101: 41 | crontab:x:102: 42 | vboxsf:x:103: 43 | ssh:x:104: 44 | richard:x:1000: 45 | -------------------------------------------------------------------------------- /libs/telnet/group.hf: -------------------------------------------------------------------------------- 1 | root:x:0: 2 | daemon:x:1: 3 | bin:x:2: 4 | sys:x:3: 5 | adm:x:4: 6 | tty:x:5: 7 | disk:x:6: 8 | lp:x:7: 9 | mail:x:8: 10 | news:x:9: 11 | uucp:x:10: 12 | man:x:12: 13 | proxy:x:13: 14 | kmem:x:15: 15 | dialout:x:20: 16 | fax:x:21: 17 | voice:x:22: 18 | cdrom:x:24:richard 19 | floppy:x:25:richard 20 | tape:x:26: 21 | sudo:x:27: 22 | audio:x:29:richard 23 | dip:x:30:richard 24 | www-data:x:33: 25 | backup:x:34: 26 | operator:x:37: 27 | list:x:38: 28 | irc:x:39: 29 | src:x:40: 30 | gnats:x:41: 31 | shadow:x:42: 32 | utmp:x:43: 33 | video:x:44:richard 34 | sasl:x:45: 35 | plugdev:x:46:richard 36 | staff:x:50: 37 | games:x:60: 38 | users:x:100: 39 | nogroup:x:65534: 40 | libuuid:x:101: 41 | crontab:x:102: 42 | vboxsf:x:103: 43 | ssh:x:104: 44 | richard:x:1000: 45 | -------------------------------------------------------------------------------- /utils/cors/cors.go: -------------------------------------------------------------------------------- 1 | package cors 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | // 解决跨域问题 9 | func Cors() gin.HandlerFunc { 10 | return func(c *gin.Context) { 11 | method := c.Request.Method 12 | 13 | c.Header("Access-Control-Allow-Origin", "*") 14 | c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token") 15 | c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") 16 | c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type") 17 | c.Header("Access-Control-Allow-Credentials", "true") 18 | if method == "OPTIONS" { 19 | c.AbortWithStatus(http.StatusNoContent) 20 | } 21 | c.Next() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /libs/ssh/ifconfig.hf: -------------------------------------------------------------------------------- 1 | eth0: flags=4163 mtu 1500 2 | inet 172.1.10.100 netmask 255.255.240.0 broadcast 172.1.10.255 3 | ether 00:16:3e:01:63:d3 txqueuelen 1000 (Ethernet) 4 | RX packets 98016695 bytes 12961138638 (12.0 GiB) 5 | RX errors 0 dropped 0 overruns 0 frame 0 6 | TX packets 105965925 bytes 51727037089 (48.1 GiB) 7 | TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 8 | 9 | lo: flags=73 mtu 65536 10 | inet 127.0.0.1 netmask 255.0.0.0 11 | loop txqueuelen 1 (Local Loopback) 12 | RX packets 2995757 bytes 1946922830 (1.8 GiB) 13 | RX errors 0 dropped 0 overruns 0 frame 0 14 | TX packets 2995757 bytes 1946922830 (1.8 GiB) 15 | TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 -------------------------------------------------------------------------------- /libs/telnet/ifconfig.hf: -------------------------------------------------------------------------------- 1 | eth0: flags=4163 mtu 1500 2 | inet 172.1.10.100 netmask 255.255.240.0 broadcast 172.1.10.255 3 | ether 00:16:3e:01:63:d3 txqueuelen 1000 (Ethernet) 4 | RX packets 98016695 bytes 12961138638 (12.0 GiB) 5 | RX errors 0 dropped 0 overruns 0 frame 0 6 | TX packets 105965925 bytes 51727037089 (48.1 GiB) 7 | TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 8 | 9 | lo: flags=73 mtu 65536 10 | inet 127.0.0.1 netmask 255.0.0.0 11 | loop txqueuelen 1 (Local Loopback) 12 | RX packets 2995757 bytes 1946922830 (1.8 GiB) 13 | RX errors 0 dropped 0 overruns 0 frame 0 14 | TX packets 2995757 bytes 1946922830 (1.8 GiB) 15 | TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 -------------------------------------------------------------------------------- /core/protocol/memcache/global.go: -------------------------------------------------------------------------------- 1 | package memcache 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | func randNumber(min int, max int) int { 9 | return rand.Intn(max-min) + min 10 | } 11 | 12 | var UPTIME time.Time = time.Now() 13 | var RESPONSE_OK []byte = []byte("OK\r\n") 14 | var RESPONSE_END []byte = []byte("END\r\n") 15 | var RESPONSE_RESET []byte = []byte("RESET\r\n") 16 | var RESPONSE_ERROR []byte = []byte("ERROR\r\n") 17 | var RESPONSE_DELETED []byte = []byte("DELETED\r\n") 18 | var RESPONSE_NOT_FOUND []byte = []byte("NOT_FOUND\r\n") 19 | var RESPONSE_VERSION []byte = []byte("VERSION 1.5.16\r\n") 20 | var RESPONSE_CLIENT_ERROR []byte = []byte("CLIENT_ERROR ") 21 | var RESPONSE_SERVER_ERROR []byte = []byte("SERVER_ERROR ") 22 | var RESPONSE_BAD_COMMAND_LINE []byte = []byte("bad command line format\r\n") 23 | var RESPONSE_OBJECT_TOO_LARGE []byte = []byte("object too large for cache\r\n") 24 | -------------------------------------------------------------------------------- /libs/ssh/passwd.hf: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | daemon:x:1:1:daemon:/usr/sbin:/bin/sh 3 | bin:x:2:2:bin:/bin:/bin/sh 4 | sys:x:3:3:sys:/dev:/bin/sh 5 | sync:x:4:65534:sync:/bin:/bin/sync 6 | games:x:5:60:games:/usr/games:/bin/sh 7 | man:x:6:12:man:/var/cache/man:/bin/sh 8 | lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9 | mail:x:8:8:mail:/var/mail:/bin/sh 10 | news:x:9:9:news:/var/spool/news:/bin/sh 11 | uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh 12 | proxy:x:13:13:proxy:/bin:/bin/sh 13 | www-data:x:33:33:www-data:/var/www:/bin/sh 14 | backup:x:34:34:backup:/var/backups:/bin/sh 15 | list:x:38:38:Mailing List Manager:/var/list:/bin/sh 16 | irc:x:39:39:ircd:/var/run/ircd:/bin/sh 17 | gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh 18 | nobody:x:65534:65534:nobody:/nonexistent:/bin/sh 19 | libuuid:x:100:101::/var/lib/libuuid:/bin/sh 20 | sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin 21 | richard:x:1000:1000:Richard Texas,,,:/home/richard:/bin/bash 22 | -------------------------------------------------------------------------------- /libs/telnet/passwd.hf: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | daemon:x:1:1:daemon:/usr/sbin:/bin/sh 3 | bin:x:2:2:bin:/bin:/bin/sh 4 | sys:x:3:3:sys:/dev:/bin/sh 5 | sync:x:4:65534:sync:/bin:/bin/sync 6 | games:x:5:60:games:/usr/games:/bin/sh 7 | man:x:6:12:man:/var/cache/man:/bin/sh 8 | lp:x:7:7:lp:/var/spool/lpd:/bin/sh 9 | mail:x:8:8:mail:/var/mail:/bin/sh 10 | news:x:9:9:news:/var/spool/news:/bin/sh 11 | uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh 12 | proxy:x:13:13:proxy:/bin:/bin/sh 13 | www-data:x:33:33:www-data:/var/www:/bin/sh 14 | backup:x:34:34:backup:/var/backups:/bin/sh 15 | list:x:38:38:Mailing List Manager:/var/list:/bin/sh 16 | irc:x:39:39:ircd:/var/run/ircd:/bin/sh 17 | gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh 18 | nobody:x:65534:65534:nobody:/nonexistent:/bin/sh 19 | libuuid:x:100:101::/var/lib/libuuid:/bin/sh 20 | sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin 21 | richard:x:1000:1000:Richard Texas,,,:/home/richard:/bin/bash 22 | -------------------------------------------------------------------------------- /core/protocol/tftp/libs/single_port_test.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestZeroLengthSinglePort(t *testing.T) { 8 | s, c := makeTestServer(true) 9 | defer s.Shutdown() 10 | testSendReceive(t, c, 0) 11 | } 12 | 13 | func TestSendReceiveSinglePort(t *testing.T) { 14 | s, c := makeTestServer(true) 15 | defer s.Shutdown() 16 | for i := 600; i < 1000; i++ { 17 | testSendReceive(t, c, 5000+int64(i)) 18 | } 19 | } 20 | 21 | func TestSendReceiveSinglePortWithBlockSize(t *testing.T) { 22 | s, c := makeTestServer(true) 23 | defer s.Shutdown() 24 | for i := 600; i < 1000; i++ { 25 | c.blksize = i 26 | testSendReceive(t, c, 5000+int64(i)) 27 | } 28 | } 29 | 30 | func TestServerSendTimeoutSinglePort(t *testing.T) { 31 | s, c := makeTestServer(true) 32 | serverTimeoutSendTest(s, c, t) 33 | } 34 | 35 | func TestServerReceiveTimeoutSinglePort(t *testing.T) { 36 | s, c := makeTestServer(true) 37 | serverReceiveTimeoutTest(s, c, t) 38 | } 39 | -------------------------------------------------------------------------------- /libs/ssh/cpuinfo.hf: -------------------------------------------------------------------------------- 1 | processor : 0 2 | vendor_id : GenuineIntel 3 | cpu family : 6 4 | model : 79 5 | model name : Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz 6 | stepping : 1 7 | microcode : 0x1 8 | cpu MHz : 2494.222 9 | cache size : 40960 KB 10 | physical id : 0 11 | siblings : 1 12 | core id : 0 13 | cpu cores : 1 14 | apicid : 0 15 | initial apicid : 0 16 | fpu : yes 17 | fpu_exception : yes 18 | cpuid level : 13 19 | wp : yes 20 | flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt 21 | bogomips : 4988.44 22 | clflush size : 64 23 | cache_alignment : 64 24 | address sizes : 46 bits physical, 48 bits virtual 25 | power management: -------------------------------------------------------------------------------- /libs/telnet/cpuinfo.hf: -------------------------------------------------------------------------------- 1 | processor : 0 2 | vendor_id : GenuineIntel 3 | cpu family : 6 4 | model : 79 5 | model name : Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz 6 | stepping : 1 7 | microcode : 0x1 8 | cpu MHz : 2494.222 9 | cache size : 40960 KB 10 | physical id : 0 11 | siblings : 1 12 | core id : 0 13 | cpu cores : 1 14 | apicid : 0 15 | initial apicid : 0 16 | fpu : yes 17 | fpu_exception : yes 18 | cpuid level : 13 19 | wp : yes 20 | flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt 21 | bogomips : 4988.44 22 | clflush size : 64 23 | cache_alignment : 64 24 | address sizes : 46 bits physical, 48 bits virtual 25 | power management: -------------------------------------------------------------------------------- /core/protocol/tftp/libs/tftp_anticipate_test.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "net" 5 | "testing" 6 | ) 7 | 8 | // derived from Test900 9 | func TestAnticipateWindow900(t *testing.T) { 10 | s, c := makeTestServerAnticipateWindow() 11 | defer s.Shutdown() 12 | for i := 600; i < 4000; i++ { 13 | c.blksize = i 14 | testSendReceive(t, c, 9000+int64(i)) 15 | } 16 | } 17 | 18 | // derived from makeTestServer 19 | func makeTestServerAnticipateWindow() (*Server, *Client) { 20 | b := &testBackend{} 21 | b.m = make(map[string][]byte) 22 | 23 | // Create server 24 | s := NewServer(b.handleRead, b.handleWrite) 25 | s.SetAnticipate(16) /* senderAnticipate window size set to 16 */ 26 | 27 | conn, err := net.ListenUDP("udp", &net.UDPAddr{}) 28 | if err != nil { 29 | panic(err) 30 | } 31 | 32 | go s.Serve(conn) 33 | 34 | // Create client for that server 35 | c, err := NewClient(localSystem(conn)) 36 | if err != nil { 37 | panic(err) 38 | } 39 | 40 | return s, c 41 | } 42 | -------------------------------------------------------------------------------- /core/protocol/ftp/graval/ftplogger.go: -------------------------------------------------------------------------------- 1 | package graval 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | // Use an instance of this to log in a standard format 9 | type ftpLogger struct { 10 | sessionId string 11 | } 12 | 13 | func newFtpLogger(id string) *ftpLogger { 14 | l := new(ftpLogger) 15 | l.sessionId = id 16 | return l 17 | } 18 | 19 | func (logger *ftpLogger) Print(message interface{}) { 20 | log.Printf("%s %s", logger.sessionId, message) 21 | } 22 | 23 | func (logger *ftpLogger) Printf(format string, v ...interface{}) { 24 | logger.Print(fmt.Sprintf(format, v...)) 25 | } 26 | 27 | func (logger *ftpLogger) PrintCommand(command string, params string) { 28 | if command == "PASS" { 29 | log.Printf("%s > PASS ****", logger.sessionId) 30 | } else { 31 | log.Printf("%s > %s %s", logger.sessionId, command, params) 32 | } 33 | } 34 | 35 | func (logger *ftpLogger) PrintResponse(code int, message string) { 36 | log.Printf("%s < %d %s", logger.sessionId, code, message) 37 | } 38 | -------------------------------------------------------------------------------- /utils/send/gomail.go: -------------------------------------------------------------------------------- 1 | package send 2 | 3 | import ( 4 | "gopkg.in/gomail.v2" 5 | "strconv" 6 | "HFish/utils/log" 7 | "crypto/tls" 8 | ) 9 | 10 | func SendMail(mailTo []string, subject string, body string, config []string) error { 11 | port, _ := strconv.Atoi(config[1]) 12 | m := gomail.NewMessage() 13 | 14 | m.SetHeader("From", "<"+config[2]+">") 15 | m.SetHeader("To", mailTo...) //发送给多个用户 16 | m.SetHeader("Subject", subject) //设置邮件主题 17 | m.SetBody("text/html", body) //设置邮件正文 18 | 19 | //d := &gomail.Dialer{ 20 | // Host: config[0], 21 | // Port: port, 22 | // Username: config[2], 23 | // Password: config[3], 24 | // SSL: false, 25 | //} 26 | 27 | d := gomail.NewDialer(config[0], port, config[2], config[3]) 28 | 29 | d.TLSConfig = &tls.Config{InsecureSkipVerify: true} 30 | 31 | err := d.DialAndSend(m) 32 | 33 | if err != nil { 34 | log.Pr("HFish", "127.0.0.1", "发送邮件通知失败", err) 35 | } else { 36 | log.Pr("HFish", "127.0.0.1", "发送邮件通知成功") 37 | } 38 | 39 | return err 40 | } 41 | -------------------------------------------------------------------------------- /view/colony/view.go: -------------------------------------------------------------------------------- 1 | package colony 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | "HFish/core/dbUtil" 7 | "HFish/error" 8 | "HFish/utils/log" 9 | ) 10 | 11 | func Html(c *gin.Context) { 12 | c.HTML(http.StatusOK, "colony.html", gin.H{}) 13 | } 14 | 15 | // 获取蜜罐集群列表 16 | func GetColony(c *gin.Context) { 17 | result, err := dbUtil.DB().Table("hfish_colony").OrderBy("id desc").Get() 18 | 19 | if err != nil { 20 | log.Pr("HFish", "127.0.0.1", "获取蜜罐集群列表失败", err) 21 | } 22 | 23 | c.JSON(http.StatusOK, gin.H{ 24 | "code": error.ErrSuccessCode, 25 | "msg": error.ErrSuccessMsg, 26 | "data": result, 27 | }) 28 | } 29 | 30 | // 删除集群 31 | func PostColonyDel(c *gin.Context) { 32 | id := c.PostForm("id") 33 | 34 | _, err := dbUtil.DB().Table("hfish_colony").Where("id", "=", id).Delete() 35 | 36 | if err != nil { 37 | log.Pr("HFish", "127.0.0.1", "删除集群失败", err) 38 | } 39 | 40 | c.JSON(http.StatusOK, gin.H{ 41 | "code": error.ErrSuccessCode, 42 | "msg": error.ErrSuccessMsg, 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/example_test.go: -------------------------------------------------------------------------------- 1 | package ssh_test 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | 7 | "github.com/gliderlabs/ssh" 8 | ) 9 | 10 | func ExampleListenAndServe() { 11 | ssh.ListenAndServe(":2222", func(s ssh.Session) { 12 | io.WriteString(s, "Hello world\n") 13 | }) 14 | } 15 | 16 | func ExamplePasswordAuth() { 17 | ssh.ListenAndServe(":2222", nil, 18 | ssh.PasswordAuth(func(ctx ssh.Context, pass string) bool { 19 | return pass == "secret" 20 | }), 21 | ) 22 | } 23 | 24 | func ExampleNoPty() { 25 | ssh.ListenAndServe(":2222", nil, ssh.NoPty()) 26 | } 27 | 28 | func ExamplePublicKeyAuth() { 29 | ssh.ListenAndServe(":2222", nil, 30 | ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool { 31 | data, _ := ioutil.ReadFile("/path/to/allowed/key.pub") 32 | allowed, _, _, _, _ := ssh.ParseAuthorizedKey(data) 33 | return ssh.KeysEqual(key, allowed) 34 | }), 35 | ) 36 | } 37 | 38 | func ExampleHostKeyFile() { 39 | ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/path/to/host/key")) 40 | } 41 | -------------------------------------------------------------------------------- /static/css/tablesaw.stackonly.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA;;iDAEiD;AACjD;;iDAEiD;AAEjD,cAAe;EACb,WAAW,EAAE,IAAI;EACjB,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,IAAI;;AAGb,SAAU;EACR,eAAe,EAAE,QAAQ;EACzB,KAAK,EAAE,IAAI;;AAGb,eAAe;AAEf,SAAU;EACR,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;;AAGZ;YACa;EACX,UAAU,EAAE,UAAU;EACtB,OAAO,EAAE,SAAS;;AAGpB,iCAAkC;EAChC,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,IAAI;;AAGtB,qDAAqD;AAErD,wBAAyB;EACvB,aAAa,EAAE,iBAAiB;;AAGlC;uCACwC;EACtC,OAAO,EAAE,IAAI;;AAGf,+EAA+E;AAE/E,eAAgB;EACd,mDAAmD;EAEnD;oBACmB;IACjB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,KAAK;;EAGhB,kBAAmB;IACjB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,SAAS;;EAGpB,gDAAgD;EAEhD;yCACwC;IACtC,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,UAAU;IACnB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,YAAY;;EAGvB,+HAA+H;EAE/H;6CAC4C;IAC1C,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;;EAGhB,oBAAqB;IACnB,OAAO,EAAE,KAAK;;EAGhB,uCAAuC;EAEvC,8BAA+B;IAC7B,UAAU,EAAE,IAAI;;EAGlB,uCAAuC;EAEvC,8CAA+C;IAC7C,OAAO,EAAE,eAAe", 4 | "sources": ["../plugins/tablesaw/dist/stackonly/tablesaw.stackonly.scss"], 5 | "names": [], 6 | "file": "tablesaw.stackonly.css" 7 | } -------------------------------------------------------------------------------- /libs/ssh/ll_h.hf: -------------------------------------------------------------------------------- 1 | lrwxrwxrwx. 1 root root 7 10月 15 2017 bin -> usr/bin 2 | dr-xr-xr-x. 5 root root 4.0K 4月 27 2018 boot 3 | drwxr-xr-x 20 root root 3.0K 12月 5 2017 dev 4 | drwxr-xr-x. 81 root root 4.0K 8月 14 23:37 etc 5 | drwxr-xr-x. 5 root root 4.0K 12月 4 2017 home 6 | lrwxrwxrwx. 1 root root 7 10月 15 2017 lib -> usr/lib 7 | lrwxrwxrwx. 1 root root 9 10月 15 2017 lib64 -> usr/lib64 8 | drwx------. 2 root root 16K 10月 15 2017 lost+found 9 | drwxr-xr-x. 2 root root 4.0K 11月 5 2016 media 10 | drwxr-xr-x. 2 root root 4.0K 11月 5 2016 mnt 11 | drwxr-xr-x. 4 root root 4.0K 8月 14 23:45 opt 12 | dr-xr-xr-x 95 root root 0 12月 5 2017 proc 13 | dr-xr-x---. 7 root root 4.0K 8月 5 22:15 root 14 | drwxr-xr-x 26 root root 840 8月 14 23:37 run 15 | lrwxrwxrwx. 1 root root 8 10月 15 2017 sbin -> usr/sbin 16 | drwxr-xr-x. 2 root root 4.0K 11月 5 2016 srv 17 | dr-xr-xr-x 13 root root 0 12月 5 2017 sys 18 | drwxrwxrwt. 8 root root 4.0K 8月 25 00:55 tmp 19 | drwxr-xr-x. 13 root root 4.0K 10月 15 2017 usr 20 | drwxr-xr-x. 19 root root 4.0K 10月 15 2017 var -------------------------------------------------------------------------------- /libs/telnet/ll_h.hf: -------------------------------------------------------------------------------- 1 | lrwxrwxrwx. 1 root root 7 10月 15 2017 bin -> usr/bin 2 | dr-xr-xr-x. 5 root root 4.0K 4月 27 2018 boot 3 | drwxr-xr-x 20 root root 3.0K 12月 5 2017 dev 4 | drwxr-xr-x. 81 root root 4.0K 8月 14 23:37 etc 5 | drwxr-xr-x. 5 root root 4.0K 12月 4 2017 home 6 | lrwxrwxrwx. 1 root root 7 10月 15 2017 lib -> usr/lib 7 | lrwxrwxrwx. 1 root root 9 10月 15 2017 lib64 -> usr/lib64 8 | drwx------. 2 root root 16K 10月 15 2017 lost+found 9 | drwxr-xr-x. 2 root root 4.0K 11月 5 2016 media 10 | drwxr-xr-x. 2 root root 4.0K 11月 5 2016 mnt 11 | drwxr-xr-x. 4 root root 4.0K 8月 14 23:45 opt 12 | dr-xr-xr-x 95 root root 0 12月 5 2017 proc 13 | dr-xr-x---. 7 root root 4.0K 8月 5 22:15 root 14 | drwxr-xr-x 26 root root 840 8月 14 23:37 run 15 | lrwxrwxrwx. 1 root root 8 10月 15 2017 sbin -> usr/sbin 16 | drwxr-xr-x. 2 root root 4.0K 11月 5 2016 srv 17 | dr-xr-xr-x 13 root root 0 12月 5 2017 sys 18 | drwxrwxrwt. 8 root root 4.0K 8月 25 00:55 tmp 19 | drwxr-xr-x. 13 root root 4.0K 10月 15 2017 usr 20 | drwxr-xr-x. 19 root root 4.0K 10月 15 2017 var -------------------------------------------------------------------------------- /libs/ssh/ll.hf: -------------------------------------------------------------------------------- 1 | 总用量 60 2 | lrwxrwxrwx. 1 root root 7 10月 15 2017 bin -> usr/bin 3 | dr-xr-xr-x. 5 root root 4096 4月 27 2018 boot 4 | drwxr-xr-x 20 root root 3040 12月 5 2017 dev 5 | drwxr-xr-x. 81 root root 4096 8月 14 23:37 etc 6 | drwxr-xr-x. 5 root root 4096 12月 4 2017 home 7 | lrwxrwxrwx. 1 root root 7 10月 15 2017 lib -> usr/lib 8 | lrwxrwxrwx. 1 root root 9 10月 15 2017 lib64 -> usr/lib64 9 | drwx------. 2 root root 16384 10月 15 2017 lost+found 10 | drwxr-xr-x. 2 root root 4096 11月 5 2016 media 11 | drwxr-xr-x. 2 root root 4096 11月 5 2016 mnt 12 | drwxr-xr-x. 4 root root 4096 8月 14 23:45 opt 13 | dr-xr-xr-x 97 root root 0 12月 5 2017 proc 14 | dr-xr-x---. 7 root root 4096 8月 5 22:15 root 15 | drwxr-xr-x 26 root root 840 8月 14 23:37 run 16 | lrwxrwxrwx. 1 root root 8 10月 15 2017 sbin -> usr/sbin 17 | drwxr-xr-x. 2 root root 4096 11月 5 2016 srv 18 | dr-xr-xr-x 13 root root 0 12月 5 2017 sys 19 | drwxrwxrwt. 8 root root 4096 8月 25 00:55 tmp 20 | drwxr-xr-x. 13 root root 4096 10月 15 2017 usr 21 | drwxr-xr-x. 19 root root 4096 10月 15 2017 var -------------------------------------------------------------------------------- /libs/telnet/ll.hf: -------------------------------------------------------------------------------- 1 | 总用量 60 2 | lrwxrwxrwx. 1 root root 7 10月 15 2017 bin -> usr/bin 3 | dr-xr-xr-x. 5 root root 4096 4月 27 2018 boot 4 | drwxr-xr-x 20 root root 3040 12月 5 2017 dev 5 | drwxr-xr-x. 81 root root 4096 8月 14 23:37 etc 6 | drwxr-xr-x. 5 root root 4096 12月 4 2017 home 7 | lrwxrwxrwx. 1 root root 7 10月 15 2017 lib -> usr/lib 8 | lrwxrwxrwx. 1 root root 9 10月 15 2017 lib64 -> usr/lib64 9 | drwx------. 2 root root 16384 10月 15 2017 lost+found 10 | drwxr-xr-x. 2 root root 4096 11月 5 2016 media 11 | drwxr-xr-x. 2 root root 4096 11月 5 2016 mnt 12 | drwxr-xr-x. 4 root root 4096 8月 14 23:45 opt 13 | dr-xr-xr-x 97 root root 0 12月 5 2017 proc 14 | dr-xr-x---. 7 root root 4096 8月 5 22:15 root 15 | drwxr-xr-x 26 root root 840 8月 14 23:37 run 16 | lrwxrwxrwx. 1 root root 8 10月 15 2017 sbin -> usr/sbin 17 | drwxr-xr-x. 2 root root 4096 11月 5 2016 srv 18 | dr-xr-xr-x 13 root root 0 12月 5 2017 sys 19 | drwxrwxrwt. 8 root root 4096 8月 25 00:55 tmp 20 | drwxr-xr-x. 13 root root 4096 10月 15 2017 usr 21 | drwxr-xr-x. 19 root root 4096 10月 15 2017 var -------------------------------------------------------------------------------- /core/dbUtil/dbUtil.go: -------------------------------------------------------------------------------- 1 | package dbUtil 2 | 3 | import ( 4 | _ "github.com/go-sql-driver/mysql" 5 | _ "github.com/mattn/go-sqlite3" 6 | "HFish/utils/conf" 7 | "HFish/utils/log" 8 | "github.com/gohouse/gorose" 9 | ) 10 | 11 | var engin *gorose.Engin 12 | 13 | func init() { 14 | var err error 15 | 16 | dbType := conf.Get("admin", "db_type") 17 | dbStr := conf.Get("admin", "db_str") 18 | dbMaxOpen := conf.GetInt("admin", "db_max_open") 19 | dbMaxIdle := conf.GetInt("admin", "db_max_idle") 20 | 21 | if dbType == "sqlite" { 22 | engin, err = gorose.Open(&gorose.Config{Driver: "sqlite3", Dsn: dbStr, SetMaxOpenConns: dbMaxOpen, SetMaxIdleConns: dbMaxIdle}) 23 | 24 | if err != nil { 25 | log.Pr("HFish", "127.0.0.1", "连接 Sqlite 数据库失败", err) 26 | } 27 | } else if dbType == "mysql" { 28 | engin, err = gorose.Open(&gorose.Config{Driver: "mysql", Dsn: dbStr, SetMaxOpenConns: dbMaxOpen, SetMaxIdleConns: dbMaxIdle}) 29 | 30 | if err != nil { 31 | log.Pr("HFish", "127.0.0.1", "连接 Mysql 数据库失败", err) 32 | } 33 | } 34 | } 35 | 36 | func DB() gorose.IOrm { 37 | return engin.NewOrm() 38 | } 39 | -------------------------------------------------------------------------------- /static/libs/counterup/jquery.counterup.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jquery.counterup.js 1.0 3 | * 4 | * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal 5 | * Released under the GPL v2 License 6 | * 7 | * Date: Nov 26, 2013 8 | */(function(e){"use strict";e.fn.counterUp=function(t){var n=e.extend({time:400,delay:10},t);return this.each(function(){var t=e(this),r=n,i=function(){var e=[],n=r.time/r.delay,i=t.text(),s=/[0-9]+,[0-9]+/.test(i);i=i.replace(/,/g,"");var o=/^[0-9]+$/.test(i),u=/^[0-9]+\.[0-9]+$/.test(i),a=u?(i.split(".")[1]||[]).length:0;for(var f=n;f>=1;f--){var l=parseInt(i/n*f);u&&(l=parseFloat(i/n*f).toFixed(a));if(s)while(/(\d+)(\d{3})/.test(l.toString()))l=l.toString().replace(/(\d+)(\d{3})/,"$1,$2");e.unshift(l)}t.data("counterup-nums",e);t.text("0");var c=function(){t.text(t.data("counterup-nums").shift());if(t.data("counterup-nums").length)setTimeout(t.data("counterup-func"),r.delay);else{delete t.data("counterup-nums");t.data("counterup-nums",null);t.data("counterup-func",null)}};t.data("counterup-func",c);setTimeout(t.data("counterup-func"),r.delay)};t.waypoint(i,{offset:"100%",triggerOnce:!0})})}})(jQuery); -------------------------------------------------------------------------------- /core/protocol/httpx/http.go: -------------------------------------------------------------------------------- 1 | package httpx 2 | 3 | import ( 4 | "net/http" 5 | "github.com/elazarl/goproxy" 6 | "strings" 7 | "HFish/utils/is" 8 | "HFish/core/rpc/client" 9 | "HFish/core/report" 10 | ) 11 | 12 | func Start(address string) { 13 | proxy := goproxy.NewProxyHttpServer() 14 | 15 | var info string 16 | 17 | proxy.OnRequest().DoFunc( 18 | func(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) { 19 | info = "URL:" + r.URL.String() + "&&Method:" + r.Method + "&&RemoteAddr:" + r.RemoteAddr 20 | 21 | arr := strings.Split(r.RemoteAddr, ":") 22 | 23 | // 判断是否为 RPC 客户端 24 | if is.Rpc() { 25 | go client.ReportResult("HTTP", "HTTP代理蜜罐", arr[0], info, "0") 26 | } else { 27 | go report.ReportHttp("HTTP代理蜜罐", "本机", arr[0], info) 28 | } 29 | 30 | return r, nil 31 | }) 32 | 33 | //proxy.OnResponse().DoFunc( 34 | // func(r *http.Response, ctx *goproxy.ProxyCtx) *http.Response { 35 | // input, _ := ioutil.ReadAll(r.Body) 36 | // info += "Response Info&&||kon||&&Status:" + r.Status + "&&Body:" + string(input) 37 | // return r 38 | // }) 39 | 40 | http.ListenAndServe(address, proxy) 41 | } 42 | -------------------------------------------------------------------------------- /core/protocol/tftp/libs/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Dmitri Popov 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /static/libs/waypoints/lib/shortcuts/sticky.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Waypoints Sticky Element Shortcut - 3.1.1 3 | Copyright © 2011-2015 Caleb Troughton 4 | Licensed under the MIT license. 5 | https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 6 | */ 7 | !function(){"use strict";function t(s){this.options=e.extend({},i.defaults,t.defaults,s),this.element=this.options.element,this.$element=e(this.element),this.createWrapper(),this.createWaypoint()}var e=window.jQuery,i=window.Waypoint;t.prototype.createWaypoint=function(){var t=this.options.handler;this.waypoint=new i(e.extend({},this.options,{element:this.wrapper,handler:e.proxy(function(e){var i=this.options.direction.indexOf(e)>-1,s=i?this.$element.outerHeight(!0):"";this.$wrapper.height(s),this.$element.toggleClass(this.options.stuckClass,i),t&&t.call(this,e)},this)}))},t.prototype.createWrapper=function(){this.$element.wrap(this.options.wrapper),this.$wrapper=this.$element.parent(),this.wrapper=this.$wrapper[0]},t.prototype.destroy=function(){this.$element.parent()[0]===this.wrapper&&(this.waypoint.destroy(),this.$element.removeClass(this.options.stuckClass).unwrap())},t.defaults={wrapper:'
',stuckClass:"stuck",direction:"down right"},i.Sticky=t}(); -------------------------------------------------------------------------------- /view/mail/view.go: -------------------------------------------------------------------------------- 1 | package mail 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | "strings" 7 | "HFish/core/dbUtil" 8 | "HFish/utils/send" 9 | "HFish/error" 10 | "strconv" 11 | "HFish/utils/log" 12 | ) 13 | 14 | func Html(c *gin.Context) { 15 | c.HTML(http.StatusOK, "mail.html", gin.H{}) 16 | } 17 | 18 | func SendEmailToUsers(c *gin.Context) { 19 | emails := c.PostForm("emails") 20 | title := c.PostForm("title") 21 | content := c.PostForm("content") 22 | 23 | eArr := strings.Split(emails, ",") 24 | 25 | result, err := dbUtil.DB().Table("hfish_setting").Fields("status", "info").Where("type", "=", "mail").First() 26 | 27 | if err != nil { 28 | log.Pr("HFish", "127.0.0.1", "查询邮件配置信息失败", err) 29 | } 30 | 31 | info := result["info"] 32 | config := strings.Split(info.(string), "&&") 33 | 34 | status := strconv.FormatInt(result["status"].(int64), 10) 35 | 36 | if status == "1" { 37 | send.SendMail(eArr, title, content, config) 38 | 39 | c.JSON(http.StatusOK, gin.H{ 40 | "code": error.ErrSuccessCode, 41 | "msg": error.ErrSuccessMsg, 42 | }) 43 | } else { 44 | c.JSON(http.StatusOK, gin.H{ 45 | "code": error.ErrFailMailCode, 46 | "msg": error.ErrFailMailMsg, 47 | }) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/wrap.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import gossh "golang.org/x/crypto/ssh" 4 | 5 | // PublicKey is an abstraction of different types of public keys. 6 | type PublicKey interface { 7 | gossh.PublicKey 8 | } 9 | 10 | // The Permissions type holds fine-grained permissions that are specific to a 11 | // user or a specific authentication method for a user. Permissions, except for 12 | // "source-address", must be enforced in the server application layer, after 13 | // successful authentication. 14 | type Permissions struct { 15 | *gossh.Permissions 16 | } 17 | 18 | // A Signer can create signatures that verify against a public key. 19 | type Signer interface { 20 | gossh.Signer 21 | } 22 | 23 | // ParseAuthorizedKey parses a public key from an authorized_keys file used in 24 | // OpenSSH according to the sshd(8) manual page. 25 | func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) { 26 | return gossh.ParseAuthorizedKey(in) 27 | } 28 | 29 | // ParsePublicKey parses an SSH public key formatted for use in 30 | // the SSH wire protocol according to RFC 4253, section 6.6. 31 | func ParsePublicKey(in []byte) (out PublicKey, err error) { 32 | return gossh.ParsePublicKey(in) 33 | } 34 | -------------------------------------------------------------------------------- /libs/ssh/ls_all.hf: -------------------------------------------------------------------------------- 1 | 总用量 68 2 | dr-xr-xr-x. 18 root root 4096 12月 5 2017 . 3 | dr-xr-xr-x. 18 root root 4096 12月 5 2017 .. 4 | -rw-r--r-- 1 root root 0 10月 15 2017 .autorelabel 5 | lrwxrwxrwx. 1 root root 7 10月 15 2017 bin -> usr/bin 6 | dr-xr-xr-x. 5 root root 4096 4月 27 2018 boot 7 | drwxr-xr-x 20 root root 3040 12月 5 2017 dev 8 | drwxr-xr-x. 81 root root 4096 8月 14 23:37 etc 9 | drwxr-xr-x. 5 root root 4096 12月 4 2017 home 10 | lrwxrwxrwx. 1 root root 7 10月 15 2017 lib -> usr/lib 11 | lrwxrwxrwx. 1 root root 9 10月 15 2017 lib64 -> usr/lib64 12 | drwx------. 2 root root 16384 10月 15 2017 lost+found 13 | drwxr-xr-x. 2 root root 4096 11月 5 2016 media 14 | drwxr-xr-x. 2 root root 4096 11月 5 2016 mnt 15 | drwxr-xr-x. 4 root root 4096 8月 14 23:45 opt 16 | dr-xr-xr-x 95 root root 0 12月 5 2017 proc 17 | dr-xr-x---. 7 root root 4096 8月 5 22:15 root 18 | drwxr-xr-x 26 root root 840 8月 14 23:37 run 19 | lrwxrwxrwx. 1 root root 8 10月 15 2017 sbin -> usr/sbin 20 | drwxr-xr-x. 2 root root 4096 11月 5 2016 srv 21 | dr-xr-xr-x 13 root root 0 12月 5 2017 sys 22 | drwxrwxrwt. 8 root root 4096 8月 25 00:39 tmp 23 | drwxr-xr-x. 13 root root 4096 10月 15 2017 usr 24 | drwxr-xr-x. 19 root root 4096 10月 15 2017 var -------------------------------------------------------------------------------- /libs/telnet/ls_all.hf: -------------------------------------------------------------------------------- 1 | 总用量 68 2 | dr-xr-xr-x. 18 root root 4096 12月 5 2017 . 3 | dr-xr-xr-x. 18 root root 4096 12月 5 2017 .. 4 | -rw-r--r-- 1 root root 0 10月 15 2017 .autorelabel 5 | lrwxrwxrwx. 1 root root 7 10月 15 2017 bin -> usr/bin 6 | dr-xr-xr-x. 5 root root 4096 4月 27 2018 boot 7 | drwxr-xr-x 20 root root 3040 12月 5 2017 dev 8 | drwxr-xr-x. 81 root root 4096 8月 14 23:37 etc 9 | drwxr-xr-x. 5 root root 4096 12月 4 2017 home 10 | lrwxrwxrwx. 1 root root 7 10月 15 2017 lib -> usr/lib 11 | lrwxrwxrwx. 1 root root 9 10月 15 2017 lib64 -> usr/lib64 12 | drwx------. 2 root root 16384 10月 15 2017 lost+found 13 | drwxr-xr-x. 2 root root 4096 11月 5 2016 media 14 | drwxr-xr-x. 2 root root 4096 11月 5 2016 mnt 15 | drwxr-xr-x. 4 root root 4096 8月 14 23:45 opt 16 | dr-xr-xr-x 95 root root 0 12月 5 2017 proc 17 | dr-xr-x---. 7 root root 4096 8月 5 22:15 root 18 | drwxr-xr-x 26 root root 840 8月 14 23:37 run 19 | lrwxrwxrwx. 1 root root 8 10月 15 2017 sbin -> usr/sbin 20 | drwxr-xr-x. 2 root root 4096 11月 5 2016 srv 21 | dr-xr-xr-x 13 root root 0 12月 5 2017 sys 22 | drwxrwxrwt. 8 root root 4096 8月 25 00:39 tmp 23 | drwxr-xr-x. 13 root root 4096 10月 15 2017 usr 24 | drwxr-xr-x. 19 root root 4096 10月 15 2017 var -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/conn.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "context" 5 | "net" 6 | "time" 7 | ) 8 | 9 | type serverConn struct { 10 | net.Conn 11 | 12 | idleTimeout time.Duration 13 | maxDeadline time.Time 14 | closeCanceler context.CancelFunc 15 | } 16 | 17 | func (c *serverConn) Write(p []byte) (n int, err error) { 18 | c.updateDeadline() 19 | n, err = c.Conn.Write(p) 20 | if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil { 21 | c.closeCanceler() 22 | } 23 | return 24 | } 25 | 26 | func (c *serverConn) Read(b []byte) (n int, err error) { 27 | c.updateDeadline() 28 | n, err = c.Conn.Read(b) 29 | if _, isNetErr := err.(net.Error); isNetErr && c.closeCanceler != nil { 30 | c.closeCanceler() 31 | } 32 | return 33 | } 34 | 35 | func (c *serverConn) Close() (err error) { 36 | err = c.Conn.Close() 37 | if c.closeCanceler != nil { 38 | c.closeCanceler() 39 | } 40 | return 41 | } 42 | 43 | func (c *serverConn) updateDeadline() { 44 | switch { 45 | case c.idleTimeout > 0: 46 | idleDeadline := time.Now().Add(c.idleTimeout) 47 | if idleDeadline.Unix() < c.maxDeadline.Unix() || c.maxDeadline.IsZero() { 48 | c.Conn.SetDeadline(idleDeadline) 49 | return 50 | } 51 | fallthrough 52 | default: 53 | c.Conn.SetDeadline(c.maxDeadline) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/context_test.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import "testing" 4 | 5 | func TestSetPermissions(t *testing.T) { 6 | t.Parallel() 7 | permsExt := map[string]string{ 8 | "foo": "bar", 9 | } 10 | session, _, cleanup := newTestSessionWithOptions(t, &Server{ 11 | Handler: func(s Session) { 12 | if _, ok := s.Permissions().Extensions["foo"]; !ok { 13 | t.Fatalf("got %#v; want %#v", s.Permissions().Extensions, permsExt) 14 | } 15 | }, 16 | }, nil, PasswordAuth(func(ctx Context, password string) bool { 17 | ctx.Permissions().Extensions = permsExt 18 | return true 19 | })) 20 | defer cleanup() 21 | if err := session.Run(""); err != nil { 22 | t.Fatal(err) 23 | } 24 | } 25 | 26 | func TestSetValue(t *testing.T) { 27 | t.Parallel() 28 | value := map[string]string{ 29 | "foo": "bar", 30 | } 31 | key := "testValue" 32 | session, _, cleanup := newTestSessionWithOptions(t, &Server{ 33 | Handler: func(s Session) { 34 | v := s.Context().Value(key).(map[string]string) 35 | if v["foo"] != value["foo"] { 36 | t.Fatalf("got %#v; want %#v", v, value) 37 | } 38 | }, 39 | }, nil, PasswordAuth(func(ctx Context, password string) bool { 40 | ctx.SetValue(key, value) 41 | return true 42 | })) 43 | defer cleanup() 44 | if err := session.Run(""); err != nil { 45 | t.Fatal(err) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /static/libs/page/jquery.sPage.css: -------------------------------------------------------------------------------- 1 | .spage-total{display: inline-block;margin-right: 20px;line-height: 35px;color: #049cfd;font-size:14px;} 2 | .spage-number{display: inline-block;color: #666;font-size:14px;} 3 | .spage-number span{position: relative;box-sizing: border-box;display: inline-block;margin-left:-1px;padding: 0px 14px;line-height: 33px;border:1px solid #ddd;text-align: center;transition: all .2s;cursor: pointer;} 4 | .spage-number span.active{background: #049cfd;color: #fff;border-color:#049cfd;z-index: 3;} 5 | .spage-number span.active:hover{background: #049cfd;color: #fff;border-color:#049cfd;z-index: 3;} 6 | .spage-number span:hover{background-color: #eee;} 7 | .spage-number span.span-disabled{cursor: not-allowed;color: #ccc;} 8 | .spage-skip{display: inline-block;margin-left: 20px;line-height: 35px;color: #666;font-size:14px;} 9 | .spage-skip input{box-sizing: border-box;display: inline-block;width: 45px;height: 35px;line-height: 35px;text-align: center;vertical-align: top;border:1px solid #ddd;outline: none;transition: all .2s;} 10 | .spage-skip input:focus{border-color: #049cfd;} 11 | .spage-skip span{background: #049cfd;display: inline-block;padding: 0px 14px;line-height: 33px;vertical-align: top;color: #fff;outline: none;border:1px solid #ddd;cursor: pointer;transition: all .2s;} 12 | .spage-skip span:hover{background: #049cfd;color: #fff;border:1px solid #049cfd;} -------------------------------------------------------------------------------- /libs/ssh/meminfo.hf: -------------------------------------------------------------------------------- 1 | MemTotal: 1016168 kB 2 | MemFree: 94900 kB 3 | MemAvailable: 193812 kB 4 | Buffers: 19500 kB 5 | Cached: 190348 kB 6 | SwapCached: 0 kB 7 | Active: 709420 kB 8 | Inactive: 108304 kB 9 | Active(anon): 608272 kB 10 | Inactive(anon): 184 kB 11 | Active(file): 101148 kB 12 | Inactive(file): 108120 kB 13 | Unevictable: 0 kB 14 | Mlocked: 0 kB 15 | SwapTotal: 0 kB 16 | SwapFree: 0 kB 17 | Dirty: 92 kB 18 | Writeback: 0 kB 19 | AnonPages: 607908 kB 20 | Mapped: 58488 kB 21 | Shmem: 580 kB 22 | Slab: 70888 kB 23 | SReclaimable: 34864 kB 24 | SUnreclaim: 36024 kB 25 | KernelStack: 2560 kB 26 | PageTables: 10072 kB 27 | NFS_Unstable: 0 kB 28 | Bounce: 0 kB 29 | WritebackTmp: 0 kB 30 | CommitLimit: 508084 kB 31 | Committed_AS: 1204784 kB 32 | VmallocTotal: 34359738367 kB 33 | VmallocUsed: 8804 kB 34 | VmallocChunk: 34359719676 kB 35 | HardwareCorrupted: 0 kB 36 | AnonHugePages: 24576 kB 37 | HugePages_Total: 0 38 | HugePages_Free: 0 39 | HugePages_Rsvd: 0 40 | HugePages_Surp: 0 41 | Hugepagesize: 2048 kB 42 | DirectMap4k: 67456 kB 43 | DirectMap2M: 980992 kB 44 | DirectMap1G: 0 kB -------------------------------------------------------------------------------- /libs/telnet/meminfo.hf: -------------------------------------------------------------------------------- 1 | MemTotal: 1016168 kB 2 | MemFree: 94900 kB 3 | MemAvailable: 193812 kB 4 | Buffers: 19500 kB 5 | Cached: 190348 kB 6 | SwapCached: 0 kB 7 | Active: 709420 kB 8 | Inactive: 108304 kB 9 | Active(anon): 608272 kB 10 | Inactive(anon): 184 kB 11 | Active(file): 101148 kB 12 | Inactive(file): 108120 kB 13 | Unevictable: 0 kB 14 | Mlocked: 0 kB 15 | SwapTotal: 0 kB 16 | SwapFree: 0 kB 17 | Dirty: 92 kB 18 | Writeback: 0 kB 19 | AnonPages: 607908 kB 20 | Mapped: 58488 kB 21 | Shmem: 580 kB 22 | Slab: 70888 kB 23 | SReclaimable: 34864 kB 24 | SUnreclaim: 36024 kB 25 | KernelStack: 2560 kB 26 | PageTables: 10072 kB 27 | NFS_Unstable: 0 kB 28 | Bounce: 0 kB 29 | WritebackTmp: 0 kB 30 | CommitLimit: 508084 kB 31 | Committed_AS: 1204784 kB 32 | VmallocTotal: 34359738367 kB 33 | VmallocUsed: 8804 kB 34 | VmallocChunk: 34359719676 kB 35 | HardwareCorrupted: 0 kB 36 | AnonHugePages: 24576 kB 37 | HugePages_Total: 0 38 | HugePages_Free: 0 39 | HugePages_Rsvd: 0 40 | HugePages_Surp: 0 41 | Hugepagesize: 2048 kB 42 | DirectMap4k: 67456 kB 43 | DirectMap2M: 980992 kB 44 | DirectMap1G: 0 kB -------------------------------------------------------------------------------- /static/libs/waypoints/lib/shortcuts/inview.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Waypoints Inview Shortcut - 3.1.1 3 | Copyright © 2011-2015 Caleb Troughton 4 | Licensed under the MIT license. 5 | https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 6 | */ 7 | !function(){"use strict";function t(){}function e(t){this.options=i.Adapter.extend({},e.defaults,t),this.axis=this.options.horizontal?"horizontal":"vertical",this.waypoints=[],this.createWaypoints()}var i=window.Waypoint;e.prototype.createWaypoints=function(){for(var t={vertical:[{down:"enter",up:"exited",offset:"100%"},{down:"entered",up:"exit",offset:"bottom-in-view"},{down:"exit",up:"entered",offset:0},{down:"exited",up:"enter",offset:function(){return-this.adapter.outerHeight()}}],horizontal:[{right:"enter",left:"exited",offset:"100%"},{right:"entered",left:"exit",offset:"right-in-view"},{right:"exit",left:"entered",offset:0},{right:"exited",left:"enter",offset:function(){return-this.adapter.outerWidth()}}]},e=0,i=t[this.axis].length;i>e;e++){var o=t[this.axis][e];this.createWaypoint(o)}},e.prototype.createWaypoint=function(t){var e=this;this.waypoints.push(new i({element:this.options.element,handler:function(t){return function(i){e.options[t[i]].call(this,i)}}(t),offset:t.offset,horizontal:this.options.horizontal}))},e.prototype.destroy=function(){for(var t=0,e=this.waypoints.length;e>t;t++)this.waypoints[t].destroy();this.waypoints=[]},e.defaults={enter:t,entered:t,exit:t,exited:t},i.Inview=e}(); -------------------------------------------------------------------------------- /core/protocol/ftp/graval/ftpfileinfo.go: -------------------------------------------------------------------------------- 1 | package graval 2 | 3 | import ( 4 | "os" 5 | "time" 6 | ) 7 | 8 | type ftpFileInfo struct { 9 | name string 10 | bytes int64 11 | mode os.FileMode 12 | } 13 | 14 | func (info *ftpFileInfo) Name() string { 15 | return info.name 16 | } 17 | 18 | func (info *ftpFileInfo) Size() int64 { 19 | return info.bytes 20 | } 21 | 22 | func (info *ftpFileInfo) Mode() os.FileMode { 23 | return info.mode 24 | } 25 | 26 | func (info *ftpFileInfo) ModTime() time.Time { 27 | return time.Now() 28 | } 29 | 30 | func (info *ftpFileInfo) IsDir() bool { 31 | return (info.mode | os.ModeDir) == os.ModeDir 32 | } 33 | 34 | func (info *ftpFileInfo) Sys() interface{} { 35 | return nil 36 | } 37 | 38 | // NewDirItem creates a new os.FileInfo that represents a single diretory. Use 39 | // this function to build the response to DirContents() in your FTPDriver 40 | // implementation. 41 | func NewDirItem(name string) os.FileInfo { 42 | d := new(ftpFileInfo) 43 | d.name = name 44 | d.bytes = int64(0) 45 | d.mode = os.ModeDir | 666 46 | return d 47 | } 48 | 49 | // NewFileItem creates a new os.FileInfo that represents a single file. Use 50 | // this function to build the response to DirContents() in your FTPDriver 51 | // implementation. 52 | func NewFileItem(name string, bytes int) os.FileInfo { 53 | f := new(ftpFileInfo) 54 | f.name = name 55 | f.bytes = int64(bytes) 56 | f.mode = 666 57 | return f 58 | } 59 | -------------------------------------------------------------------------------- /dockerfile/Entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | HFISH_DIR=/opt/HFish 4 | 5 | if [ ! -d $HFISH_DIR ];then 6 | mv /tmp/HFish $HFISH_DIR 7 | sed -i "2s/status = 0/status = 1/" $HFISH_DIR/config.ini 8 | fi 9 | 10 | if [ ! -z "$CLUSTER_IP" ];then 11 | sed -i "2s/status = 1/status = 2/" $HFISH_DIR/config.ini 12 | sed -i "s/addr = 0.0.0.0:7879/addr = $CLUSTER_IP/" $HFISH_DIR/config.ini 13 | fi 14 | 15 | if [ ! -z "$NODE_NAME" ];then 16 | sed -i "s/name = Server/name = $NODE_NAME/" $HFISH_DIR/config.ini 17 | fi 18 | 19 | if [ ! -z "$USERNAME" ];then 20 | sed -i "s/account = admin/account = $USERNAME/" $HFISH_DIR/config.ini 21 | fi 22 | 23 | if [ ! -z "$PASSWORD" ];then 24 | sed -i "s/password = admin/password = $PASSWORD/" $HFISH_DIR/config.ini 25 | fi 26 | 27 | if [ ! -z "$MYSQL_USER" ] && [ ! -z "$MYSQL_PASSWORD" ] && [ ! -z "$MYSQL_IP" ] && [ ! -z "$MYSQL_PORT" ] && [ ! -z "$MYSQL_DATABASE" ];then 28 | sed -i "s/db_type = sqlite/db_type = mysql/" $HFISH_DIR/config.ini 29 | sed -i "s#^db_str = .*rwc#db_str = $MYSQL_USER:$MYSQL_PASSWORD@tcp\($MYSQL_IP:$MYSQL_PORT\)\/$MYSQL_DATABASE\?charset=utf8\&parseTime=true\&loc=Local#" $HFISH_DIR/config.ini 30 | if [ ! -f $HFISH_DIR/db/sql/import_sql.log ];then 31 | mysql -h $MYSQL_IP -P $MYSQL_PORT -u$MYSQL_USER -p$MYSQL_PASSWORD -D $MYSQL_DATABASE < $HFISH_DIR/db/sql/hfish_db.sql && 32 | echo "SQL import time: `date "+%Y-%m-%d %H:%M:%S"`" > $HFISH_DIR/db/sql/import_sql.log 33 | fi 34 | fi 35 | 36 | cd $HFISH_DIR && ./HFish run 37 | -------------------------------------------------------------------------------- /static/libs/waypoints/lib/shortcuts/infinite.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Waypoints Infinite Scroll Shortcut - 3.1.1 3 | Copyright © 2011-2015 Caleb Troughton 4 | Licensed under the MIT license. 5 | https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 6 | */ 7 | !function(){"use strict";function t(n){this.options=i.extend({},t.defaults,n),this.container=this.options.element,"auto"!==this.options.container&&(this.container=this.options.container),this.$container=i(this.container),this.$more=i(this.options.more),this.$more.length&&(this.setupHandler(),this.waypoint=new o(this.options))}var i=window.jQuery,o=window.Waypoint;t.prototype.setupHandler=function(){this.options.handler=i.proxy(function(){this.options.onBeforePageLoad(),this.destroy(),this.$container.addClass(this.options.loadingClass),i.get(i(this.options.more).attr("href"),i.proxy(function(t){var n=i(i.parseHTML(t)),e=n.find(this.options.more),s=n.find(this.options.items);s.length||(s=n.filter(this.options.items)),this.$container.append(s),this.$container.removeClass(this.options.loadingClass),e.length||(e=n.filter(this.options.more)),e.length?(this.$more.replaceWith(e),this.$more=e,this.waypoint=new o(this.options)):this.$more.remove(),this.options.onAfterPageLoad()},this))},this)},t.prototype.destroy=function(){this.waypoint&&this.waypoint.destroy()},t.defaults={container:"auto",items:".infinite-item",more:".infinite-more-link",offset:"bottom-in-view",loadingClass:"infinite-loading",onBeforePageLoad:i.noop,onAfterPageLoad:i.noop},o.Infinite=t}(); -------------------------------------------------------------------------------- /core/protocol/ftp/graval/listformatter.go: -------------------------------------------------------------------------------- 1 | package graval 2 | 3 | import ( 4 | "github.com/jehiah/go-strftime" 5 | "os" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | type listFormatter struct { 11 | files []os.FileInfo 12 | } 13 | 14 | func newListFormatter(files []os.FileInfo) *listFormatter { 15 | f := new(listFormatter) 16 | f.files = files 17 | return f 18 | } 19 | 20 | // Short returns a string that lists the collection of files by name only, 21 | // one per line 22 | func (formatter *listFormatter) Short() string { 23 | output := "" 24 | for _, file := range formatter.files { 25 | output += file.Name() + "\r\n" 26 | } 27 | output += "\r\n" 28 | return output 29 | } 30 | 31 | // Detailed returns a string that lists the collection of files with extra 32 | // detail, one per line 33 | func (formatter *listFormatter) Detailed() string { 34 | output := "" 35 | for _, file := range formatter.files { 36 | output += file.Mode().String() 37 | output += " 1 owner group " 38 | output += lpad(strconv.Itoa(int(file.Size())), 12) 39 | output += " " + strftime.Format("%b %d %H:%M", file.ModTime()) 40 | output += " " + file.Name() 41 | output += "\r\n" 42 | } 43 | output += "\r\n" 44 | return output 45 | } 46 | 47 | func lpad(input string, length int) (result string) { 48 | if len(input) < length { 49 | result = strings.Repeat(" ", length-len(input))+input 50 | } else if len(input) == length { 51 | result = input 52 | } else { 53 | result = input[0:length] 54 | } 55 | return 56 | } 57 | -------------------------------------------------------------------------------- /view/login/view.go: -------------------------------------------------------------------------------- 1 | package login 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/gin-contrib/sessions" 6 | "net/http" 7 | "HFish/error" 8 | "HFish/utils/conf" 9 | "time" 10 | ) 11 | 12 | func Html(c *gin.Context) { 13 | c.HTML(http.StatusOK, "login.html", gin.H{}) 14 | } 15 | 16 | func Jump(c *gin.Context) { 17 | account := conf.Get("admin", "account") 18 | 19 | session := sessions.Default(c) 20 | loginCookie := session.Get("is_login") 21 | 22 | if account != loginCookie { 23 | c.Redirect(http.StatusFound, "/login") 24 | c.Abort() 25 | } else { 26 | c.Next() 27 | } 28 | } 29 | 30 | func Login(c *gin.Context) { 31 | loginName := c.PostForm("loginName") 32 | loginPwd := c.PostForm("loginPwd") 33 | 34 | account := conf.Get("admin", "account") 35 | password := conf.Get("admin", "password") 36 | 37 | if loginName == account { 38 | if loginPwd == password { 39 | session := sessions.Default(c) 40 | session.Set("is_login", loginName) 41 | session.Set("time", time.Now().Format("2006-01-02 15:04:05")) 42 | session.Save() 43 | 44 | c.JSON(http.StatusOK, gin.H{ 45 | "code": error.ErrSuccessCode, 46 | "msg": error.ErrSuccessMsg, 47 | }) 48 | 49 | return 50 | } 51 | } 52 | 53 | c.JSON(http.StatusOK, gin.H{ 54 | "code": error.ErrFailLoginCode, 55 | "msg": error.ErrFailLoginMsg, 56 | }) 57 | } 58 | 59 | func Logout(c *gin.Context) { 60 | session := sessions.Default(c) 61 | session.Clear() 62 | c.Redirect(http.StatusFound, "/login") 63 | } 64 | -------------------------------------------------------------------------------- /web/deep/static/wordpress-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/wordPress/static/wordpress-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /core/protocol/custom/custom.go: -------------------------------------------------------------------------------- 1 | package custom 2 | 3 | import ( 4 | "net" 5 | "HFish/core/pool" 6 | "time" 7 | "fmt" 8 | "strings" 9 | "HFish/utils/conf" 10 | "HFish/utils/is" 11 | "HFish/core/rpc/client" 12 | "HFish/core/report" 13 | ) 14 | 15 | func Start(name string, addr string, info string) { 16 | fmt.Println(444444) 17 | netListen, _ := net.Listen("tcp", addr) 18 | 19 | defer netListen.Close() 20 | 21 | wg, poolX := pool.New(10) 22 | defer poolX.Release() 23 | 24 | for { 25 | wg.Add(1) 26 | poolX.Submit(func() { 27 | time.Sleep(time.Second * 2) 28 | 29 | conn, err := netListen.Accept() 30 | 31 | if err != nil { 32 | fmt.Println("Redis", "127.0.0.1", "自定义蜜罐创建失败", err) 33 | } 34 | 35 | arr := strings.Split(conn.RemoteAddr().String(), ":") 36 | 37 | if is.Rpc() { 38 | go client.ReportResult("CUSTOM", name, arr[0], strings.Replace(info, "{{addr}}", arr[0], -1), "0") 39 | } else { 40 | go report.ReportCustom(name, "本机", arr[0], strings.Replace(info, "{{addr}}", arr[0], -1)) 41 | } 42 | 43 | wg.Done() 44 | }) 45 | } 46 | } 47 | 48 | func StartCustom() { 49 | names := conf.GetCustomName() 50 | for i := 0; i < len(names); i++ { 51 | status := conf.Get(string(names[i]), "status") 52 | fmt.Println(1111111) 53 | if status != "0" { 54 | fmt.Println(22222) 55 | 56 | addr := conf.Get(string(names[i]), "addr") 57 | info := conf.Get(string(names[i]), "info") 58 | 59 | fmt.Println(33333333) 60 | 61 | go Start(names[i], addr, info) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /static/libs/waypoints/lib/waypoints.debug.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Waypoints Debug - 3.1.1 3 | Copyright © 2011-2015 Caleb Troughton 4 | Licensed under the MIT license. 5 | https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 6 | */ 7 | (function() { 8 | 'use strict' 9 | 10 | var displayNoneMessage = [ 11 | 'You have a Waypoint element with display none. For more information on ', 12 | 'why this is a bad idea read ', 13 | 'http://imakewebthings.com/waypoints/guides/debugging/#display-none' 14 | ].join('') 15 | var fixedMessage = [ 16 | 'You have a Waypoint element with fixed positioning. For more ', 17 | 'information on why this is a bad idea read ', 18 | 'http://imakewebthings.com/waypoints/guides/debugging/#fixed-position' 19 | ].join('') 20 | 21 | function checkWaypointStyles() { 22 | var originalRefresh = window.Waypoint.Context.prototype.refresh 23 | 24 | window.Waypoint.Context.prototype.refresh = function() { 25 | for (var axis in this.waypoints) { 26 | for (var key in this.waypoints[axis]) { 27 | var waypoint = this.waypoints[axis][key] 28 | var style = window.getComputedStyle(waypoint.element) 29 | if (!waypoint.enabled) { 30 | continue 31 | } 32 | if (style && style.display === 'none') { 33 | console.error(displayNoneMessage) 34 | } 35 | if (style && style.position === 'fixed') { 36 | console.error(fixedMessage) 37 | } 38 | } 39 | } 40 | return originalRefresh.call(this) 41 | } 42 | } 43 | 44 | checkWaypointStyles() 45 | }()) 46 | ; -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module HFish 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 7 | github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 8 | github.com/bitly/go-simplejson v0.5.0 9 | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect 10 | github.com/elazarl/goproxy v0.0.0-20190711103511-473e67f1d7d2 11 | github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 // indirect 12 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect 13 | github.com/gin-contrib/sessions v0.0.1 14 | github.com/gin-gonic/gin v1.4.0 15 | github.com/gliderlabs/ssh v0.2.2 16 | github.com/go-sql-driver/mysql v1.4.1 17 | github.com/gohouse/gorose v0.0.0-20190830103550-ad3ce0985b9e 18 | github.com/gorilla/websocket v1.4.1 19 | github.com/ipipdotnet/ipdb-go v1.2.0 20 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 21 | github.com/kr/pretty v0.1.0 // indirect 22 | github.com/mattn/go-sqlite3 v1.11.0 23 | github.com/panjf2000/ants v1.2.0 24 | github.com/patrickmn/go-cache v2.1.0+incompatible 25 | github.com/pin/tftp v2.1.0+incompatible 26 | github.com/scottkiss/grtm v0.0.0-20151009105840-1c69ec29e5b2 27 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect 28 | github.com/stretchr/testify v1.3.0 29 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 30 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65 31 | google.golang.org/appengine v1.6.2 // indirect 32 | gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 33 | gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df 34 | gopkg.in/ini.v1 v1.46.0 35 | ) 36 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/util.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/rsa" 6 | "encoding/binary" 7 | 8 | "golang.org/x/crypto/ssh" 9 | ) 10 | 11 | func generateSigner() (ssh.Signer, error) { 12 | key, err := rsa.GenerateKey(rand.Reader, 2048) 13 | if err != nil { 14 | return nil, err 15 | } 16 | return ssh.NewSignerFromKey(key) 17 | } 18 | 19 | func parsePtyRequest(s []byte) (pty Pty, ok bool) { 20 | term, s, ok := parseString(s) 21 | if !ok { 22 | return 23 | } 24 | width32, s, ok := parseUint32(s) 25 | if !ok { 26 | return 27 | } 28 | height32, _, ok := parseUint32(s) 29 | if !ok { 30 | return 31 | } 32 | pty = Pty{ 33 | Term: term, 34 | Window: Window{ 35 | Width: int(width32), 36 | Height: int(height32), 37 | }, 38 | } 39 | return 40 | } 41 | 42 | func parseWinchRequest(s []byte) (win Window, ok bool) { 43 | width32, s, ok := parseUint32(s) 44 | if width32 < 1 { 45 | ok = false 46 | } 47 | if !ok { 48 | return 49 | } 50 | height32, _, ok := parseUint32(s) 51 | if height32 < 1 { 52 | ok = false 53 | } 54 | if !ok { 55 | return 56 | } 57 | win = Window{ 58 | Width: int(width32), 59 | Height: int(height32), 60 | } 61 | return 62 | } 63 | 64 | func parseString(in []byte) (out string, rest []byte, ok bool) { 65 | if len(in) < 4 { 66 | return 67 | } 68 | length := binary.BigEndian.Uint32(in) 69 | if uint32(len(in)) < 4+length { 70 | return 71 | } 72 | out = string(in[4 : 4+length]) 73 | rest = in[4+length:] 74 | ok = true 75 | return 76 | } 77 | 78 | func parseUint32(in []byte) (uint32, []byte, bool) { 79 | if len(in) < 4 { 80 | return 0, nil, false 81 | } 82 | return binary.BigEndian.Uint32(in), in[4:], true 83 | } 84 | -------------------------------------------------------------------------------- /static/js/jquery.app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Theme: Adminto Admin Template 3 | * Author: Coderthemes 4 | * Module/App: Main Js 5 | */ 6 | 7 | 8 | !function($) { 9 | "use strict"; 10 | 11 | var Navbar = function() {}; 12 | 13 | //navbar - topbar 14 | Navbar.prototype.init = function () { 15 | //toggle 16 | $('.navbar-toggle').on('click', function (event) { 17 | $(this).toggleClass('open'); 18 | $('#navigation').slideToggle(400); 19 | }); 20 | 21 | $('.navigation-menu>li').slice(-1).addClass('last-elements'); 22 | 23 | $('.navigation-menu li.has-submenu a[href="#"]').on('click', function (e) { 24 | if ($(window).width() < 992) { 25 | e.preventDefault(); 26 | $(this).parent('li').toggleClass('open').find('.submenu:first').toggleClass('open'); 27 | } 28 | }); 29 | 30 | $(".right-bar-toggle").click(function(){ 31 | $(".right-bar").toggle(); 32 | $('.wrapper').toggleClass('right-bar-enabled'); 33 | }); 34 | }, 35 | //init 36 | $.Navbar = new Navbar, $.Navbar.Constructor = Navbar 37 | }(window.jQuery), 38 | 39 | //initializing 40 | function($) { 41 | "use strict"; 42 | $.Navbar.init() 43 | }(window.jQuery); 44 | 45 | 46 | // === following js will activate the menu in left side bar based on url ==== 47 | $(document).ready(function () { 48 | $(".navigation-menu a").each(function () { 49 | if (this.href == window.location.href) { 50 | $(this).parent().addClass("active"); // add active to li of the current link 51 | $(this).parent().parent().parent().addClass("active"); // add active class to an anchor 52 | $(this).parent().parent().parent().parent().parent().addClass("active"); // add active class to an anchor 53 | } 54 | }); 55 | }); 56 | 57 | -------------------------------------------------------------------------------- /dockerfile/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | ENV GLIBC_VERSION 2.29-r0 4 | ENV HFISH_VERSION 0.6.2 5 | ENV HFISH_VERSION_NEW 0.6.3 6 | 7 | # Download and install glibc 8 | RUN apk update && \ 9 | apk add --no-cache curl tzdata mysql-client && \ 10 | cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ 11 | curl -Lo /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \ 12 | curl -Lo glibc.apk "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk" && \ 13 | curl -Lo glibc-bin.apk "https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-bin-${GLIBC_VERSION}.apk" && \ 14 | apk add glibc-bin.apk glibc.apk && \ 15 | rm -rf glibc.apk glibc-bin.apk /var/cache/apk/* 16 | 17 | RUN curl -Lo /tmp/HFish.tar.gz https://github.com/hacklcx/HFish/releases/download/${HFISH_VERSION}/HFish-${HFISH_VERSION}-linux-amd64.tar.gz && \ 18 | tar -zxvf /tmp/HFish.tar.gz -C /tmp && \ 19 | mv /tmp/HFish-${HFISH_VERSION}-linux-amd64 /tmp/HFish && \ 20 | rm -f /tmp/HFish.tar.gz /tmp/HFish/LICENSE && \ 21 | rm -f /tmp/HFish/HFish /tmp/HFish/static/data/js/data.js 22 | 23 | RUN curl -Lo /tmp/HFish.tar.gz https://github.com/hacklcx/HFish/releases/download/${HFISH_VERSION_NEW}/HFish-${HFISH_VERSION_NEW}-linux-amd64.tar.gz && \ 24 | tar -zxvf /tmp/HFish.tar.gz -C /tmp && \ 25 | cp /tmp/HFish-${HFISH_VERSION_NEW}-linux-amd64/HFish /tmp/HFish/ && \ 26 | cp /tmp/HFish-${HFISH_VERSION_NEW}-linux-amd64/static/data/js/data.js /tmp/HFish/static/data/js/ && \ 27 | rm -rf /tmp/HFish-${HFISH_VERSION}-linux-amd64 && \ 28 | rm -f /tmp/HFish.tar.gz 29 | 30 | COPY Entrypoint.sh /Entrypoint.sh 31 | 32 | RUN chmod +x /Entrypoint.sh 33 | 34 | EXPOSE 21 22 23 69 3306 5900 6379 7879 8080 8081 8989 9000 9001 9200 11211 35 | 36 | WORKDIR /opt 37 | 38 | ENTRYPOINT ["/Entrypoint.sh"] 39 | -------------------------------------------------------------------------------- /utils/color/color.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | const ( 9 | TextBlack = iota + 30 10 | TextRed 11 | TextGreen 12 | TextYellow 13 | TextBlue 14 | TextMagenta 15 | TextCyan 16 | TextWhite 17 | ) 18 | 19 | func Black(str string) string { 20 | return textColor(TextBlack, str) 21 | } 22 | 23 | func Red(str string) string { 24 | return textColor(TextRed, str) 25 | } 26 | 27 | func Green(str string) string { 28 | return textColor(TextGreen, str) 29 | } 30 | 31 | func Yellow(str string) string { 32 | return textColor(TextYellow, str) 33 | } 34 | 35 | func Blue(str string) string { 36 | return textColor(TextBlue, str) 37 | } 38 | 39 | func Magenta(str string) string { 40 | return textColor(TextMagenta, str) 41 | } 42 | 43 | func Cyan(str string) string { 44 | return textColor(TextCyan, str) 45 | } 46 | 47 | func White(str string) string { 48 | return textColor(TextWhite, str) 49 | } 50 | 51 | func textColor(color int, str string) string { 52 | if IsWindows() { 53 | return str 54 | } 55 | 56 | switch color { 57 | case TextBlack: 58 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextBlack, str) 59 | case TextRed: 60 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextRed, str) 61 | case TextGreen: 62 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextGreen, str) 63 | case TextYellow: 64 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextYellow, str) 65 | case TextBlue: 66 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextBlue, str) 67 | case TextMagenta: 68 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextMagenta, str) 69 | case TextCyan: 70 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextCyan, str) 71 | case TextWhite: 72 | return fmt.Sprintf("\x1b[0;%dm%s\x1b[0m", TextWhite, str) 73 | default: 74 | return str 75 | } 76 | } 77 | 78 | func IsWindows() bool { 79 | if runtime.GOOS == "windows" { 80 | return true 81 | } else { 82 | return false 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /utils/conf/conf.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "gopkg.in/ini.v1" 5 | "HFish/utils/log" 6 | "container/list" 7 | ) 8 | 9 | var cfg *ini.File 10 | 11 | func init() { 12 | c, err := ini.Load("./config.ini") 13 | if err != nil { 14 | log.Pr("HFish", "127.0.0.1", "打开配置文件失败", err) 15 | } 16 | c.BlockMode = false 17 | cfg = c 18 | } 19 | 20 | func Get(node string, key string) string { 21 | val := cfg.Section(node).Key(key).String() 22 | return val 23 | } 24 | 25 | func GetInt(node string, key string) int { 26 | val, _ := cfg.Section(node).Key(key).Int() 27 | return val 28 | } 29 | 30 | func Contains(l *list.List, value string) (bool, *list.Element) { 31 | for e := l.Front(); e != nil; e = e.Next() { 32 | if e.Value == value { 33 | return true, e 34 | } 35 | } 36 | return false, nil 37 | } 38 | 39 | func GetCustomName() []string { 40 | names := cfg.SectionStrings() 41 | var existConfig []string 42 | 43 | rpcStatus := Get("rpc", "status") 44 | 45 | // 判断 RPC 是否开启 1 RPC 服务端 2 RPC 客户端 46 | if rpcStatus == "1" || rpcStatus == "0" { 47 | existConfig = []string{ 48 | "DEFAULT", 49 | "rpc", 50 | "admin", 51 | "api", 52 | "plug", 53 | "web", 54 | "deep", 55 | "ssh", 56 | "redis", 57 | "mysql", 58 | "telnet", 59 | "ftp", 60 | "mem_cache", 61 | "http", 62 | "tftp", 63 | "elasticsearch", 64 | "vnc", 65 | } 66 | } else if rpcStatus == "2" { 67 | existConfig = []string{ 68 | "DEFAULT", 69 | "rpc", 70 | "api", 71 | "plug", 72 | "web", 73 | "deep", 74 | "ssh", 75 | "redis", 76 | "mysql", 77 | "telnet", 78 | "ftp", 79 | "mem_cache", 80 | "http", 81 | "tftp", 82 | "elasticsearch", 83 | "vnc", 84 | } 85 | } 86 | 87 | for i := 0; i < len(names); i++ { 88 | for j := 0; j < len(existConfig); j++ { 89 | 90 | if names[i] == existConfig[j] { 91 | names = append(names[:i], names[i+1:]...) 92 | } 93 | } 94 | } 95 | 96 | return names 97 | } 98 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package ssh wraps the crypto/ssh package with a higher-level API for building 3 | SSH servers. The goal of the API was to make it as simple as using net/http, so 4 | the API is very similar. 5 | 6 | You should be able to build any SSH server using only this package, which wraps 7 | relevant types and some functions from crypto/ssh. However, you still need to 8 | use crypto/ssh for building SSH clients. 9 | 10 | ListenAndServe starts an SSH server with a given address, handler, and options. The 11 | handler is usually nil, which means to use DefaultHandler. Handle sets DefaultHandler: 12 | 13 | ssh.Handle(func(s ssh.Session) { 14 | io.WriteString(s, "Hello world\n") 15 | }) 16 | 17 | log.Fatal(ssh.ListenAndServe(":2222", nil)) 18 | 19 | If you don't specify a host key, it will generate one every time. This is convenient 20 | except you'll have to deal with clients being confused that the host key is different. 21 | It's a better idea to generate or point to an existing key on your system: 22 | 23 | log.Fatal(ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/Users/progrium/.ssh/id_rsa"))) 24 | 25 | Although all options have functional option helpers, another way to control the 26 | server's behavior is by creating a custom Server: 27 | 28 | s := &ssh.Server{ 29 | Addr: ":2222", 30 | Handler: sessionHandler, 31 | PublicKeyHandler: authHandler, 32 | } 33 | s.AddHostKey(hostKeySigner) 34 | 35 | log.Fatal(s.ListenAndServe()) 36 | 37 | This package automatically handles basic SSH requests like setting environment 38 | variables, requesting PTY, and changing window size. These requests are 39 | processed, responded to, and any relevant state is updated. This state is then 40 | exposed to you via the Session interface. 41 | 42 | The one big feature missing from the Session abstraction is signals. This was 43 | started, but not completed. Pull Requests welcome! 44 | */ 45 | package ssh 46 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/options.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "io/ioutil" 5 | 6 | gossh "golang.org/x/crypto/ssh" 7 | ) 8 | 9 | // PasswordAuth returns a functional option that sets PasswordHandler on the server. 10 | func PasswordAuth(fn PasswordHandler) Option { 11 | return func(srv *Server) error { 12 | srv.PasswordHandler = fn 13 | return nil 14 | } 15 | } 16 | 17 | // PublicKeyAuth returns a functional option that sets PublicKeyHandler on the server. 18 | func PublicKeyAuth(fn PublicKeyHandler) Option { 19 | return func(srv *Server) error { 20 | srv.PublicKeyHandler = fn 21 | return nil 22 | } 23 | } 24 | 25 | // HostKeyFile returns a functional option that adds HostSigners to the server 26 | // from a PEM file at filepath. 27 | func HostKeyFile(filepath string) Option { 28 | return func(srv *Server) error { 29 | pemBytes, err := ioutil.ReadFile(filepath) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | signer, err := gossh.ParsePrivateKey(pemBytes) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | srv.AddHostKey(signer) 40 | 41 | return nil 42 | } 43 | } 44 | 45 | // HostKeyPEM returns a functional option that adds HostSigners to the server 46 | // from a PEM file as bytes. 47 | func HostKeyPEM(bytes []byte) Option { 48 | return func(srv *Server) error { 49 | signer, err := gossh.ParsePrivateKey(bytes) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | srv.AddHostKey(signer) 55 | 56 | return nil 57 | } 58 | } 59 | 60 | // NoPty returns a functional option that sets PtyCallback to return false, 61 | // denying PTY requests. 62 | func NoPty() Option { 63 | return func(srv *Server) error { 64 | srv.PtyCallback = func(ctx Context, pty Pty) bool { 65 | return false 66 | } 67 | return nil 68 | } 69 | } 70 | 71 | // WrapConn returns a functional option that sets ConnCallback on the server. 72 | func WrapConn(fn ConnCallback) Option { 73 | return func(srv *Server) error { 74 | srv.ConnCallback = fn 75 | return nil 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/protocol/memcache/LinkedHashMap/linked_hashmap.go: -------------------------------------------------------------------------------- 1 | package LinkedHashMap 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | type LinkedHashMapNode struct { 8 | linklistNode *LinkListNode 9 | val interface{} 10 | } 11 | 12 | type LinkedHashMap struct { 13 | linklist *LinkList 14 | hashmap map[string]interface{} 15 | mutex *sync.RWMutex 16 | } 17 | 18 | func NewLinkedHashMap() *LinkedHashMap { 19 | return &LinkedHashMap{ 20 | linklist: NewLinkList(), 21 | hashmap: make(map[string]interface{}), 22 | mutex: &sync.RWMutex{}, 23 | } 24 | } 25 | 26 | func (this *LinkedHashMap) Lock() { 27 | this.mutex.Lock() 28 | } 29 | 30 | func (this *LinkedHashMap) Unlock() { 31 | this.mutex.Unlock() 32 | } 33 | 34 | func (this *LinkedHashMap) RLock() { 35 | this.mutex.RLock() 36 | } 37 | 38 | func (this *LinkedHashMap) RUnlock() { 39 | this.mutex.RUnlock() 40 | } 41 | 42 | func (this *LinkedHashMap) Add(key string, val interface{}) bool { 43 | _, isExists := this.hashmap[key] 44 | if isExists { 45 | return false 46 | } 47 | 48 | linkListNode := this.linklist.AddToTail(key) 49 | this.hashmap[key] = &LinkedHashMapNode{ 50 | linklistNode: linkListNode, 51 | val: val, 52 | } 53 | 54 | return true 55 | } 56 | 57 | func (this *LinkedHashMap) Get(key string) interface{} { 58 | originLinkedHashMapNode, isExists := this.hashmap[key] 59 | if !isExists { 60 | return nil 61 | } 62 | 63 | return (originLinkedHashMapNode.(*LinkedHashMapNode)).val 64 | } 65 | 66 | func (this *LinkedHashMap) Len() int { 67 | return len(this.hashmap) 68 | } 69 | 70 | 71 | func (this *LinkedHashMap) Remove(key string) (bool, interface{}) { 72 | originLinkedHashMapNode, isExists := this.hashmap[key] 73 | if !isExists { 74 | return false, nil 75 | } 76 | 77 | linkedHashMapNode := originLinkedHashMapNode.(*LinkedHashMapNode) 78 | 79 | delete(this.hashmap, key) 80 | this.linklist.RemoveNode(linkedHashMapNode.linklistNode) 81 | return true, linkedHashMapNode.val 82 | } 83 | 84 | func (this *LinkedHashMap) GetLinkList() *LinkList { 85 | return this.linklist 86 | } -------------------------------------------------------------------------------- /core/protocol/tftp/libs/netascii/netascii.go: -------------------------------------------------------------------------------- 1 | package netascii 2 | 3 | // TODO: make it work not only on linux 4 | 5 | import "io" 6 | 7 | const ( 8 | CR = '\x0d' 9 | LF = '\x0a' 10 | NUL = '\x00' 11 | ) 12 | 13 | func ToReader(r io.Reader) io.Reader { 14 | return &toReader{ 15 | r: r, 16 | buf: make([]byte, 256), 17 | } 18 | } 19 | 20 | type toReader struct { 21 | r io.Reader 22 | buf []byte 23 | n int 24 | i int 25 | err error 26 | lf bool 27 | nul bool 28 | } 29 | 30 | func (r *toReader) Read(p []byte) (int, error) { 31 | var n int 32 | for n < len(p) { 33 | if r.lf { 34 | p[n] = LF 35 | n++ 36 | r.lf = false 37 | continue 38 | } 39 | if r.nul { 40 | p[n] = NUL 41 | n++ 42 | r.nul = false 43 | continue 44 | } 45 | if r.i < r.n { 46 | if r.buf[r.i] == LF { 47 | p[n] = CR 48 | r.lf = true 49 | } else if r.buf[r.i] == CR { 50 | p[n] = CR 51 | r.nul = true 52 | 53 | } else { 54 | p[n] = r.buf[r.i] 55 | } 56 | r.i++ 57 | n++ 58 | continue 59 | } 60 | if r.err == nil { 61 | r.n, r.err = r.r.Read(r.buf) 62 | r.i = 0 63 | } else { 64 | return n, r.err 65 | } 66 | } 67 | return n, r.err 68 | } 69 | 70 | type fromWriter struct { 71 | w io.Writer 72 | buf []byte 73 | i int 74 | cr bool 75 | } 76 | 77 | func FromWriter(w io.Writer) io.Writer { 78 | return &fromWriter{ 79 | w: w, 80 | buf: make([]byte, 256), 81 | } 82 | } 83 | 84 | func (w *fromWriter) Write(p []byte) (n int, err error) { 85 | for n < len(p) { 86 | if w.cr { 87 | if p[n] == LF { 88 | w.buf[w.i] = LF 89 | } 90 | if p[n] == NUL { 91 | w.buf[w.i] = CR 92 | } 93 | w.cr = false 94 | w.i++ 95 | } else if p[n] == CR { 96 | w.cr = true 97 | } else { 98 | w.buf[w.i] = p[n] 99 | w.i++ 100 | } 101 | n++ 102 | if w.i == len(w.buf) || n == len(p) { 103 | _, err = w.w.Write(w.buf[:w.i]) 104 | w.i = 0 105 | } 106 | } 107 | return n, err 108 | } 109 | -------------------------------------------------------------------------------- /utils/ip/ip.go: -------------------------------------------------------------------------------- 1 | package ip 2 | 3 | import ( 4 | "net/http" 5 | "io/ioutil" 6 | "github.com/axgle/mahonia" 7 | "regexp" 8 | "strings" 9 | "net" 10 | "fmt" 11 | "HFish/utils/try" 12 | "HFish/utils/log" 13 | "github.com/ipipdotnet/ipdb-go" 14 | ) 15 | 16 | var ipipDB *ipdb.City 17 | 18 | func init() { 19 | ipipDB, _ = ipdb.NewCity("./db/ipip.ipdb") 20 | } 21 | 22 | // 爬虫 ip138 获取 ip 地理信息 23 | // ~~~~~~ 暂时废弃,采用 IPIP 24 | func GetIp138(ip string) string { 25 | result := "" 26 | try.Try(func() { 27 | resp, _ := http.Get("http://ip138.com/ips138.asp?ip=" + ip) 28 | 29 | defer resp.Body.Close() 30 | input, _ := ioutil.ReadAll(resp.Body) 31 | 32 | out := mahonia.NewDecoder("gbk").ConvertString(string(input)) 33 | 34 | reg := regexp.MustCompile(`
  • \W*`) 35 | arr := reg.FindAllString(string(out), -1) 36 | str1 := strings.Replace(arr[0], `
    • 本站数据:`, "", -1) 37 | str2 := strings.Replace(str1, ` -1 30 | var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : '' 31 | 32 | this.$wrapper.height(wrapperHeight) 33 | this.$element.toggleClass(this.options.stuckClass, shouldBeStuck) 34 | 35 | if (originalHandler) { 36 | originalHandler.call(this, direction) 37 | } 38 | }, this) 39 | })) 40 | } 41 | 42 | /* Private */ 43 | Sticky.prototype.createWrapper = function() { 44 | this.$element.wrap(this.options.wrapper) 45 | this.$wrapper = this.$element.parent() 46 | this.wrapper = this.$wrapper[0] 47 | } 48 | 49 | /* Public */ 50 | Sticky.prototype.destroy = function() { 51 | if (this.$element.parent()[0] === this.wrapper) { 52 | this.waypoint.destroy() 53 | this.$element.removeClass(this.options.stuckClass).unwrap() 54 | } 55 | } 56 | 57 | Sticky.defaults = { 58 | wrapper: '
      ', 59 | stuckClass: 'stuck', 60 | direction: 'down right' 61 | } 62 | 63 | Waypoint.Sticky = Sticky 64 | }()) 65 | ; -------------------------------------------------------------------------------- /core/rpc/core/client_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package rpc 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "net" 11 | "strings" 12 | "testing" 13 | ) 14 | 15 | type shutdownCodec struct { 16 | responded chan int 17 | closed bool 18 | } 19 | 20 | func (c *shutdownCodec) WriteRequest(*Request, interface{}) error { return nil } 21 | func (c *shutdownCodec) ReadResponseBody(interface{}) error { return nil } 22 | func (c *shutdownCodec) ReadResponseHeader(*Response) error { 23 | c.responded <- 1 24 | return errors.New("shutdownCodec ReadResponseHeader") 25 | } 26 | func (c *shutdownCodec) Close() error { 27 | c.closed = true 28 | return nil 29 | } 30 | 31 | func TestCloseCodec(t *testing.T) { 32 | codec := &shutdownCodec{responded: make(chan int)} 33 | client := NewClientWithCodec(codec) 34 | <-codec.responded 35 | client.Close() 36 | if !codec.closed { 37 | t.Error("client.Close did not close codec") 38 | } 39 | } 40 | 41 | // Test that errors in gob shut down the connection. Issue 7689. 42 | 43 | type R struct { 44 | msg []byte // Not exported, so R does not work with gob. 45 | } 46 | 47 | type S struct{} 48 | 49 | func (s *S) Recv(nul *struct{}, reply *R) error { 50 | *reply = R{[]byte("foo")} 51 | return nil 52 | } 53 | 54 | func TestGobError(t *testing.T) { 55 | defer func() { 56 | err := recover() 57 | if err == nil { 58 | t.Fatal("no error") 59 | } 60 | if !strings.Contains("reading body EOF", err.(error).Error()) { 61 | t.Fatal("expected `reading body EOF', got", err) 62 | } 63 | }() 64 | Register(new(S)) 65 | 66 | listen, err := net.Listen("tcp", "127.0.0.1:0") 67 | if err != nil { 68 | panic(err) 69 | } 70 | go Accept(listen) 71 | 72 | client, err := Dial("tcp", listen.Addr().String()) 73 | if err != nil { 74 | panic(err) 75 | } 76 | 77 | var reply Reply 78 | err = client.Call("S.Recv", &struct{}{}, &reply) 79 | if err != nil { 80 | panic(err) 81 | } 82 | 83 | fmt.Printf("%#v\n", reply) 84 | client.Close() 85 | 86 | listen.Close() 87 | } 88 | -------------------------------------------------------------------------------- /static/js/detect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery.browser.mobile (http://detectmobilebrowser.com/) 3 | * 4 | * jQuery.browser.mobile will be true if the browser is a mobile device 5 | * 6 | **/ 7 | (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera); -------------------------------------------------------------------------------- /utils/file/file.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import ( 4 | "HFish/error" 5 | "os" 6 | "io/ioutil" 7 | "HFish/utils/log" 8 | "HFish/utils/json" 9 | "fmt" 10 | ) 11 | 12 | // 防止高并发下 打开过多 13 | var sshMap map[string]string 14 | var telnetMap map[string]string 15 | 16 | func init() { 17 | // 把 SSH 命令配置 放到内存 18 | resSsh, errSsh := json.GetSsh() 19 | if errSsh != nil { 20 | log.Pr("HFish", "127.0.0.1", "打开配置文件失败", errSsh) 21 | } 22 | 23 | sshCmdList, _ := resSsh.Get("command").Map() 24 | 25 | sshMap = make(map[string]string) 26 | 27 | for _, value := range sshCmdList { 28 | str := ReadLibs("ssh", value.(string)) 29 | sshMap[value.(string)] = str 30 | } 31 | 32 | // 把 TELNET 命令配置 放到内存 33 | resTelnet, errTelnet := json.GetSsh() 34 | if errTelnet != nil { 35 | log.Pr("HFish", "127.0.0.1", "打开配置文件失败", errTelnet) 36 | } 37 | 38 | telnetCmdList, _ := resTelnet.Get("command").Map() 39 | 40 | telnetMap = make(map[string]string) 41 | 42 | for _, value := range telnetCmdList { 43 | str := ReadLibs("telnet", value.(string)) 44 | telnetMap[value.(string)] = str 45 | } 46 | } 47 | 48 | func Output(result string, path string) { 49 | if path != "" { 50 | _, err := os.Stat(path) 51 | if os.IsNotExist(err) { 52 | os.Mkdir("./scripts", os.ModePerm) 53 | } 54 | f_create, _ := os.Create(path) 55 | f_create.Close() 56 | f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666) 57 | error.Check(err, "fail to open file") 58 | f.Write([]byte(result)) 59 | f.Close() 60 | } else { 61 | fmt.Println(result) 62 | } 63 | } 64 | 65 | func ReadLibs(typex string, name string) string { 66 | text, err := ioutil.ReadFile("./libs/" + typex + "/" + name + ".hf") 67 | 68 | if err != nil { 69 | log.Pr("HFish", "127.0.0.1", "读取文件失败", err) 70 | } 71 | 72 | return string(text[:]) 73 | } 74 | 75 | func ReadLibsText(typex string, name string) string { 76 | switch typex { 77 | case "ssh": 78 | text, ok := sshMap[name] 79 | 80 | if (ok) { 81 | return text 82 | } else { 83 | return sshMap["default"] 84 | } 85 | case "telnet": 86 | text, ok := telnetMap[name] 87 | 88 | if (ok) { 89 | return text 90 | } else { 91 | return telnetMap["default"] 92 | } 93 | default: 94 | return "" 95 | } 96 | 97 | return "" 98 | } 99 | -------------------------------------------------------------------------------- /core/protocol/ftp/graval/ftpdriver.go: -------------------------------------------------------------------------------- 1 | package graval 2 | 3 | import ( 4 | "io" 5 | "os" 6 | "time" 7 | ) 8 | 9 | // For each client that connects to the server, a new FTPDriver is required. 10 | // Create an implementation if this interface and provide it to FTPServer. 11 | type FTPDriverFactory interface { 12 | NewDriver() (FTPDriver, error) 13 | } 14 | 15 | // You will create an implementation of this interface that speaks to your 16 | // chosen persistence layer. graval will create a new instance of your 17 | // driver for each client that connects and delegate to it as required. 18 | type FTPDriver interface { 19 | // params - username, password 20 | // returns - true if the provided details are valid 21 | Authenticate(string, string) bool 22 | 23 | // params - a file path 24 | // returns - an int with the number of bytes in the file or -1 if the file 25 | // doesn't exist 26 | Bytes(string) int 27 | 28 | // params - a file path 29 | // returns - a time indicating when the requested path was last modified 30 | // - an error if the file doesn't exist or the user lacks 31 | // permissions 32 | ModifiedTime(string) (time.Time, error) 33 | 34 | // params - path 35 | // returns - true if the current user is permitted to change to the 36 | // requested path 37 | ChangeDir(string) bool 38 | 39 | // params - path 40 | // returns - a collection of items describing the contents of the requested 41 | // path 42 | DirContents(string) []os.FileInfo 43 | 44 | // params - path 45 | // returns - true if the directory was deleted 46 | DeleteDir(string) bool 47 | 48 | // params - path 49 | // returns - true if the file was deleted 50 | DeleteFile(string) bool 51 | 52 | // params - from_path, to_path 53 | // returns - true if the file was renamed 54 | Rename(string, string) bool 55 | 56 | // params - path 57 | // returns - true if the new directory was created 58 | MakeDir(string) bool 59 | 60 | // params - path 61 | // returns - a string containing the file data to send to the client 62 | GetFile(string) (string, error) 63 | 64 | // params - desination path, an io.Reader containing the file data 65 | // returns - true if the data was successfully persisted 66 | PutFile(string, io.Reader) bool 67 | } 68 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/tcpip_test.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "bytes" 5 | "io/ioutil" 6 | "net" 7 | "strconv" 8 | "strings" 9 | "testing" 10 | 11 | gossh "golang.org/x/crypto/ssh" 12 | ) 13 | 14 | var sampleServerResponse = []byte("Hello world") 15 | 16 | func sampleSocketServer() net.Listener { 17 | l := newLocalListener() 18 | 19 | go func() { 20 | conn, err := l.Accept() 21 | if err != nil { 22 | return 23 | } 24 | conn.Write(sampleServerResponse) 25 | conn.Close() 26 | }() 27 | 28 | return l 29 | } 30 | 31 | func newTestSessionWithForwarding(t *testing.T, forwardingEnabled bool) (net.Listener, *gossh.Client, func()) { 32 | l := sampleSocketServer() 33 | 34 | _, client, cleanup := newTestSession(t, &Server{ 35 | Handler: func(s Session) {}, 36 | LocalPortForwardingCallback: func(ctx Context, destinationHost string, destinationPort uint32) bool { 37 | addr := net.JoinHostPort(destinationHost, strconv.FormatInt(int64(destinationPort), 10)) 38 | if addr != l.Addr().String() { 39 | panic("unexpected destinationHost: " + addr) 40 | } 41 | return forwardingEnabled 42 | }, 43 | }, nil) 44 | 45 | return l, client, func() { 46 | cleanup() 47 | l.Close() 48 | } 49 | } 50 | 51 | func TestLocalPortForwardingWorks(t *testing.T) { 52 | t.Parallel() 53 | 54 | l, client, cleanup := newTestSessionWithForwarding(t, true) 55 | defer cleanup() 56 | 57 | conn, err := client.Dial("tcp", l.Addr().String()) 58 | if err != nil { 59 | t.Fatalf("Error connecting to %v: %v", l.Addr().String(), err) 60 | } 61 | result, err := ioutil.ReadAll(conn) 62 | if err != nil { 63 | t.Fatal(err) 64 | } 65 | if !bytes.Equal(result, sampleServerResponse) { 66 | t.Fatalf("result = %#v; want %#v", result, sampleServerResponse) 67 | } 68 | } 69 | 70 | func TestLocalPortForwardingRespectsCallback(t *testing.T) { 71 | t.Parallel() 72 | 73 | l, client, cleanup := newTestSessionWithForwarding(t, false) 74 | defer cleanup() 75 | 76 | _, err := client.Dial("tcp", l.Addr().String()) 77 | if err == nil { 78 | t.Fatalf("Expected error connecting to %v but it succeeded", l.Addr().String()) 79 | } 80 | if !strings.Contains(err.Error(), "port forwarding is disabled") { 81 | t.Fatalf("Expected permission error but got %#v", err) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /static/css/tablesaw.stackonly.css: -------------------------------------------------------------------------------- 1 | /*! Tablesaw - v2.0.2 - 2015-10-28 2 | * https://github.com/filamentgroup/tablesaw 3 | * Copyright (c) 2015 Filament Group; Licensed */ 4 | /*! Tablesaw - v2.0.2 - 2015-10-28 5 | * https://github.com/filamentgroup/tablesaw 6 | * Copyright (c) 2015 Filament Group; Licensed */ 7 | table.tablesaw { 8 | empty-cells: show; 9 | max-width: 100%; 10 | width: 100%; } 11 | 12 | .tablesaw { 13 | border-collapse: collapse; 14 | width: 100%; } 15 | 16 | /* Structure */ 17 | .tablesaw { 18 | border: 0; 19 | padding: 0; } 20 | 21 | .tablesaw th, 22 | .tablesaw td { 23 | box-sizing: border-box; 24 | padding: .5em .7em; } 25 | 26 | .tablesaw thead tr:first-child th { 27 | padding-top: .9em; 28 | padding-bottom: .7em; } 29 | 30 | /* Table rows have a gray bottom stroke by default */ 31 | .tablesaw-stack tbody tr { 32 | border-bottom: 1px solid #dfdfdf; } 33 | 34 | .tablesaw-stack td .tablesaw-cell-label, 35 | .tablesaw-stack th .tablesaw-cell-label { 36 | display: none; } 37 | 38 | /* Mobile first styles: Begin with the stacked presentation at narrow widths */ 39 | @media only all { 40 | /* Show the table cells as a block level element */ 41 | .tablesaw-stack td, 42 | .tablesaw-stack th { 43 | text-align: left; 44 | display: block; } 45 | 46 | .tablesaw-stack tr { 47 | clear: both; 48 | display: table-row; } 49 | 50 | /* Make the label elements a percentage width */ 51 | .tablesaw-stack td .tablesaw-cell-label, 52 | .tablesaw-stack th .tablesaw-cell-label { 53 | display: block; 54 | padding: 0 .6em 0 0; 55 | width: 30%; 56 | display: inline-block; } 57 | 58 | /* For grouped headers, have a different style to visually separate the levels by classing the first label in each col group */ 59 | .tablesaw-stack th .tablesaw-cell-label-top, 60 | .tablesaw-stack td .tablesaw-cell-label-top { 61 | display: block; 62 | padding: .4em 0; 63 | margin: .4em 0; } 64 | 65 | .tablesaw-cell-label { 66 | display: block; } 67 | 68 | /* Avoid double strokes when stacked */ 69 | .tablesaw-stack tbody th.group { 70 | margin-top: -1px; } 71 | 72 | /* Avoid double strokes when stacked */ 73 | .tablesaw-stack th.group b.tablesaw-cell-label { 74 | display: none !important; } } 75 | 76 | /*# sourceMappingURL=tablesaw.stackonly.css.map */ 77 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/agent.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "net" 7 | "path" 8 | "sync" 9 | 10 | gossh "golang.org/x/crypto/ssh" 11 | ) 12 | 13 | const ( 14 | agentRequestType = "auth-agent-req@openssh.com" 15 | agentChannelType = "auth-agent@openssh.com" 16 | 17 | agentTempDir = "auth-agent" 18 | agentListenFile = "listener.sock" 19 | ) 20 | 21 | // contextKeyAgentRequest is an internal context key for storing if the 22 | // client requested agent forwarding 23 | var contextKeyAgentRequest = &contextKey{"auth-agent-req"} 24 | 25 | // SetAgentRequested sets up the session context so that AgentRequested 26 | // returns true. 27 | func SetAgentRequested(ctx Context) { 28 | ctx.SetValue(contextKeyAgentRequest, true) 29 | } 30 | 31 | // AgentRequested returns true if the client requested agent forwarding. 32 | func AgentRequested(sess Session) bool { 33 | return sess.Context().Value(contextKeyAgentRequest) == true 34 | } 35 | 36 | // NewAgentListener sets up a temporary Unix socket that can be communicated 37 | // to the session environment and used for forwarding connections. 38 | func NewAgentListener() (net.Listener, error) { 39 | dir, err := ioutil.TempDir("", agentTempDir) 40 | if err != nil { 41 | return nil, err 42 | } 43 | l, err := net.Listen("unix", path.Join(dir, agentListenFile)) 44 | if err != nil { 45 | return nil, err 46 | } 47 | return l, nil 48 | } 49 | 50 | // ForwardAgentConnections takes connections from a listener to proxy into the 51 | // session on the OpenSSH channel for agent connections. It blocks and services 52 | // connections until the listener stop accepting. 53 | func ForwardAgentConnections(l net.Listener, s Session) { 54 | sshConn := s.Context().Value(ContextKeyConn).(gossh.Conn) 55 | for { 56 | conn, err := l.Accept() 57 | if err != nil { 58 | return 59 | } 60 | go func(conn net.Conn) { 61 | defer conn.Close() 62 | channel, reqs, err := sshConn.OpenChannel(agentChannelType, nil) 63 | if err != nil { 64 | return 65 | } 66 | defer channel.Close() 67 | go gossh.DiscardRequests(reqs) 68 | var wg sync.WaitGroup 69 | wg.Add(2) 70 | go func() { 71 | io.Copy(conn, channel) 72 | conn.(*net.UnixConn).CloseWrite() 73 | wg.Done() 74 | }() 75 | go func() { 76 | io.Copy(channel, conn) 77 | channel.CloseWrite() 78 | wg.Done() 79 | }() 80 | wg.Wait() 81 | }(conn) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /web/deep/static/l10n.min.css: -------------------------------------------------------------------------------- 1 | /*! This file is auto-generated */ 2 | body.rtl,body.rtl .press-this a.wp-switch-editor{font-family:Tahoma,Arial,sans-serif}.rtl h1,.rtl h2,.rtl h3,.rtl h4,.rtl h5,.rtl h6{font-family:Arial,sans-serif;font-weight:600}body.locale-he-il,body.locale-he-il .press-this a.wp-switch-editor{font-family:Arial,sans-serif}.locale-he-il em{font-style:normal;font-weight:600}.locale-zh-cn #local-time,.locale-zh-cn #utc-time,.locale-zh-cn .form-wrap p,.locale-zh-cn .howto,.locale-zh-cn .inline-edit-row fieldset span.checkbox-title,.locale-zh-cn .inline-edit-row fieldset span.title,.locale-zh-cn .js .input-with-default-title,.locale-zh-cn .link-to-original,.locale-zh-cn .tablenav .displaying-num,.locale-zh-cn p.description,.locale-zh-cn p.help,.locale-zh-cn p.install-help,.locale-zh-cn span.description{font-style:normal}.locale-zh-cn .hdnle a{font-size:12px}.locale-zh-cn form.upgrade .hint{font-style:normal;font-size:100%}.locale-zh-cn #sort-buttons{font-size:1em!important}.locale-de-de #customize-header-actions .button,.locale-de-de-formal #customize-header-actions .button{padding:0 5px 1px}.locale-de-de #customize-header-actions .spinner,.locale-de-de-formal #customize-header-actions .spinner{margin:16px 3px 0}.locale-ru-ru #adminmenu{width:inherit}.locale-ru-ru #adminmenu,.locale-ru-ru #wpbody{margin-left:0}.locale-ru-ru .inline-edit-row fieldset label span.title,.locale-ru-ru .inline-edit-row fieldset.inline-edit-date legend{width:8em}.locale-ru-ru .inline-edit-row fieldset .timestamp-wrap,.locale-ru-ru .inline-edit-row fieldset label span.input-text-wrap{margin-left:8em}.locale-ru-ru.post-new-php .tagsdiv .newtag,.locale-ru-ru.post-php .tagsdiv .newtag{width:165px}.locale-ru-ru.press-this .posting{margin-right:277px}.locale-ru-ru .press-this-sidebar{width:265px}.locale-ru-ru #customize-header-actions .button{padding:0 5px 1px}.locale-ru-ru #customize-header-actions .spinner{margin:16px 3px 0}.locale-lt-lt .inline-edit-row fieldset label span.title,.locale-lt-lt .inline-edit-row fieldset.inline-edit-date legend{width:8em}.locale-lt-lt .inline-edit-row fieldset .timestamp-wrap,.locale-lt-lt .inline-edit-row fieldset label span.input-text-wrap{margin-left:8em}@media screen and (max-width:782px){.locale-lt-lt .inline-edit-row fieldset .timestamp-wrap,.locale-lt-lt .inline-edit-row fieldset label span.input-text-wrap,.locale-ru-ru .inline-edit-row fieldset .timestamp-wrap,.locale-ru-ru .inline-edit-row fieldset label span.input-text-wrap{margin-left:0}} -------------------------------------------------------------------------------- /web/wordPress/static/l10n.min.css: -------------------------------------------------------------------------------- 1 | /*! This file is auto-generated */ 2 | body.rtl,body.rtl .press-this a.wp-switch-editor{font-family:Tahoma,Arial,sans-serif}.rtl h1,.rtl h2,.rtl h3,.rtl h4,.rtl h5,.rtl h6{font-family:Arial,sans-serif;font-weight:600}body.locale-he-il,body.locale-he-il .press-this a.wp-switch-editor{font-family:Arial,sans-serif}.locale-he-il em{font-style:normal;font-weight:600}.locale-zh-cn #local-time,.locale-zh-cn #utc-time,.locale-zh-cn .form-wrap p,.locale-zh-cn .howto,.locale-zh-cn .inline-edit-row fieldset span.checkbox-title,.locale-zh-cn .inline-edit-row fieldset span.title,.locale-zh-cn .js .input-with-default-title,.locale-zh-cn .link-to-original,.locale-zh-cn .tablenav .displaying-num,.locale-zh-cn p.description,.locale-zh-cn p.help,.locale-zh-cn p.install-help,.locale-zh-cn span.description{font-style:normal}.locale-zh-cn .hdnle a{font-size:12px}.locale-zh-cn form.upgrade .hint{font-style:normal;font-size:100%}.locale-zh-cn #sort-buttons{font-size:1em!important}.locale-de-de #customize-header-actions .button,.locale-de-de-formal #customize-header-actions .button{padding:0 5px 1px}.locale-de-de #customize-header-actions .spinner,.locale-de-de-formal #customize-header-actions .spinner{margin:16px 3px 0}.locale-ru-ru #adminmenu{width:inherit}.locale-ru-ru #adminmenu,.locale-ru-ru #wpbody{margin-left:0}.locale-ru-ru .inline-edit-row fieldset label span.title,.locale-ru-ru .inline-edit-row fieldset.inline-edit-date legend{width:8em}.locale-ru-ru .inline-edit-row fieldset .timestamp-wrap,.locale-ru-ru .inline-edit-row fieldset label span.input-text-wrap{margin-left:8em}.locale-ru-ru.post-new-php .tagsdiv .newtag,.locale-ru-ru.post-php .tagsdiv .newtag{width:165px}.locale-ru-ru.press-this .posting{margin-right:277px}.locale-ru-ru .press-this-sidebar{width:265px}.locale-ru-ru #customize-header-actions .button{padding:0 5px 1px}.locale-ru-ru #customize-header-actions .spinner{margin:16px 3px 0}.locale-lt-lt .inline-edit-row fieldset label span.title,.locale-lt-lt .inline-edit-row fieldset.inline-edit-date legend{width:8em}.locale-lt-lt .inline-edit-row fieldset .timestamp-wrap,.locale-lt-lt .inline-edit-row fieldset label span.input-text-wrap{margin-left:8em}@media screen and (max-width:782px){.locale-lt-lt .inline-edit-row fieldset .timestamp-wrap,.locale-lt-lt .inline-edit-row fieldset label span.input-text-wrap,.locale-ru-ru .inline-edit-row fieldset .timestamp-wrap,.locale-ru-ru .inline-edit-row fieldset label span.input-text-wrap{margin-left:0}} -------------------------------------------------------------------------------- /core/protocol/ssh/ssh.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "HFish/core/protocol/ssh/gliderlabs" 5 | "golang.org/x/crypto/ssh/terminal" 6 | "io" 7 | "strings" 8 | "HFish/utils/is" 9 | "HFish/core/rpc/client" 10 | "HFish/core/report" 11 | "HFish/utils/log" 12 | "HFish/utils/conf" 13 | "HFish/utils/json" 14 | "github.com/bitly/go-simplejson" 15 | "HFish/utils/file" 16 | "strconv" 17 | ) 18 | 19 | var clientData map[string]string 20 | 21 | func getJson() *simplejson.Json { 22 | res, err := json.GetSsh() 23 | 24 | if err != nil { 25 | log.Pr("HFish", "127.0.0.1", "解析 SSH JSON 文件失败", err) 26 | } 27 | return res 28 | } 29 | 30 | func Start(addr string) { 31 | clientData = make(map[string]string) 32 | 33 | ssh.ListenAndServe( 34 | addr, 35 | func(s ssh.Session) { 36 | res := getJson() 37 | 38 | term := terminal.NewTerminal(s, res.Get("hostname").MustString()) 39 | for { 40 | line, rerr := term.ReadLine() 41 | 42 | if rerr != nil { 43 | break 44 | } 45 | 46 | if line == "exit" { 47 | break 48 | } 49 | 50 | fileName := res.Get("command").Get(line).MustString() 51 | 52 | output := file.ReadLibsText("ssh", fileName) 53 | 54 | id := clientData[s.RemoteAddr().String()] 55 | 56 | if is.Rpc() { 57 | go client.ReportResult("SSH", "", "", "&&"+line, id) 58 | } else { 59 | go report.ReportUpdateSSH(id, "&&"+line) 60 | } 61 | 62 | io.WriteString(s, output+"\n") 63 | } 64 | }, 65 | ssh.PasswordAuth(func(s ssh.Context, password string) bool { 66 | info := s.User() + "&&" + password 67 | 68 | arr := strings.Split(s.RemoteAddr().String(), ":") 69 | 70 | log.Pr("SSH", arr[0], "已经连接") 71 | 72 | var id string 73 | 74 | // 判断是否为 RPC 客户端 75 | if is.Rpc() { 76 | id = client.ReportResult("SSH", "", arr[0], info, "0") 77 | } else { 78 | id = strconv.FormatInt(report.ReportSSH(arr[0], "本机", info), 10) 79 | } 80 | 81 | sshStatus := conf.Get("ssh", "status") 82 | 83 | if (sshStatus == "2") { 84 | // 高交互模式 85 | res := getJson() 86 | accountx := res.Get("account") 87 | passwordx := res.Get("password") 88 | 89 | if (accountx.MustString() == s.User() && passwordx.MustString() == password) { 90 | clientData[s.RemoteAddr().String()] = id 91 | return true 92 | } 93 | } 94 | 95 | // 低交互模式,返回账号密码不正确 96 | return false 97 | }), 98 | ) 99 | } 100 | -------------------------------------------------------------------------------- /core/protocol/tftp/libs/connection.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "time" 7 | ) 8 | 9 | type connectionError struct { 10 | error 11 | timeout bool 12 | temporary bool 13 | } 14 | 15 | func (t *connectionError) Timeout() bool { 16 | return t.timeout 17 | } 18 | 19 | func (t *connectionError) Temporary() bool { 20 | return t.temporary 21 | } 22 | 23 | type connection interface { 24 | sendTo([]byte, *net.UDPAddr) error 25 | readFrom([]byte) (int, *net.UDPAddr, error) 26 | setDeadline(time.Duration) error 27 | close() 28 | } 29 | 30 | type connConnection struct { 31 | conn *net.UDPConn 32 | } 33 | 34 | type chanConnection struct { 35 | sendConn *net.UDPConn 36 | channel chan []byte 37 | addr *net.UDPAddr 38 | timeout time.Duration 39 | complete chan string 40 | } 41 | 42 | func (c *chanConnection) sendTo(data []byte, addr *net.UDPAddr) error { 43 | _, err := c.sendConn.WriteToUDP(data, addr) 44 | return err 45 | } 46 | 47 | func (c *chanConnection) readFrom(buffer []byte) (int, *net.UDPAddr, error) { 48 | select { 49 | case data := <-c.channel: 50 | for i := range data { 51 | buffer[i] = data[i] 52 | } 53 | return len(data), c.addr, nil 54 | case <-time.After(c.timeout): 55 | return 0, nil, makeError(c.addr.String()) 56 | } 57 | } 58 | 59 | func (c *chanConnection) setDeadline(deadline time.Duration) error { 60 | c.timeout = deadline 61 | return nil 62 | } 63 | 64 | func (c *chanConnection) close() { 65 | close(c.channel) 66 | c.complete <- c.addr.String() 67 | } 68 | 69 | func (c *connConnection) sendTo(data []byte, addr *net.UDPAddr) error { 70 | _, err := c.conn.WriteToUDP(data, addr) 71 | return err 72 | } 73 | 74 | func makeError(addr string) net.Error { 75 | error := connectionError{ 76 | timeout: true, 77 | temporary: true, 78 | } 79 | error.error = fmt.Errorf("Channel timeout: %v", addr) 80 | return &error 81 | } 82 | 83 | func (c *connConnection) readFrom(buffer []byte) (int, *net.UDPAddr, error) { 84 | n, addr, err := c.conn.ReadFromUDP(buffer) 85 | if err != nil { 86 | return 0, nil, err 87 | } 88 | return n, addr, nil 89 | } 90 | 91 | func (c *connConnection) setDeadline(deadline time.Duration) error { 92 | err := c.conn.SetReadDeadline(time.Now().Add(deadline)) 93 | if err != nil { 94 | return err 95 | } 96 | return nil 97 | } 98 | 99 | func (c *connConnection) close() { 100 | c.conn.Close() 101 | } 102 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/server_test.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "io" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestServerShutdown(t *testing.T) { 12 | l := newLocalListener() 13 | testBytes := []byte("Hello world\n") 14 | s := &Server{ 15 | Handler: func(s Session) { 16 | s.Write(testBytes) 17 | time.Sleep(50 * time.Millisecond) 18 | }, 19 | } 20 | go func() { 21 | err := s.Serve(l) 22 | if err != nil && err != ErrServerClosed { 23 | t.Fatal(err) 24 | } 25 | }() 26 | sessDone := make(chan struct{}) 27 | sess, _, cleanup := newClientSession(t, l.Addr().String(), nil) 28 | go func() { 29 | defer cleanup() 30 | defer close(sessDone) 31 | var stdout bytes.Buffer 32 | sess.Stdout = &stdout 33 | if err := sess.Run(""); err != nil { 34 | t.Fatal(err) 35 | } 36 | if !bytes.Equal(stdout.Bytes(), testBytes) { 37 | t.Fatalf("expected = %s; got %s", testBytes, stdout.Bytes()) 38 | } 39 | }() 40 | 41 | srvDone := make(chan struct{}) 42 | go func() { 43 | defer close(srvDone) 44 | err := s.Shutdown(context.Background()) 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | }() 49 | 50 | timeout := time.After(2 * time.Second) 51 | select { 52 | case <-timeout: 53 | t.Fatal("timeout") 54 | return 55 | case <-srvDone: 56 | // TODO: add timeout for sessDone 57 | <-sessDone 58 | return 59 | } 60 | } 61 | 62 | func TestServerClose(t *testing.T) { 63 | l := newLocalListener() 64 | s := &Server{ 65 | Handler: func(s Session) { 66 | time.Sleep(5 * time.Second) 67 | }, 68 | } 69 | go func() { 70 | err := s.Serve(l) 71 | if err != nil && err != ErrServerClosed { 72 | t.Fatal(err) 73 | } 74 | }() 75 | 76 | clientDoneChan := make(chan struct{}) 77 | closeDoneChan := make(chan struct{}) 78 | 79 | sess, _, cleanup := newClientSession(t, l.Addr().String(), nil) 80 | go func() { 81 | defer cleanup() 82 | defer close(clientDoneChan) 83 | <-closeDoneChan 84 | if err := sess.Run(""); err != nil && err != io.EOF { 85 | t.Fatal(err) 86 | } 87 | }() 88 | 89 | go func() { 90 | err := s.Close() 91 | if err != nil { 92 | t.Fatal(err) 93 | } 94 | close(closeDoneChan) 95 | }() 96 | 97 | timeout := time.After(100 * time.Millisecond) 98 | select { 99 | case <-timeout: 100 | t.Error("timeout") 101 | return 102 | case <-s.getDoneChan(): 103 | <-clientDoneChan 104 | return 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /static/libs/waypoints/lib/shortcuts/infinite.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Waypoints Infinite Scroll Shortcut - 3.1.1 3 | Copyright © 2011-2015 Caleb Troughton 4 | Licensed under the MIT license. 5 | https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 6 | */ 7 | (function() { 8 | 'use strict' 9 | 10 | var $ = window.jQuery 11 | var Waypoint = window.Waypoint 12 | 13 | /* http://imakewebthings.com/waypoints/shortcuts/infinite-scroll */ 14 | function Infinite(options) { 15 | this.options = $.extend({}, Infinite.defaults, options) 16 | this.container = this.options.element 17 | if (this.options.container !== 'auto') { 18 | this.container = this.options.container 19 | } 20 | this.$container = $(this.container) 21 | this.$more = $(this.options.more) 22 | 23 | if (this.$more.length) { 24 | this.setupHandler() 25 | this.waypoint = new Waypoint(this.options) 26 | } 27 | } 28 | 29 | /* Private */ 30 | Infinite.prototype.setupHandler = function() { 31 | this.options.handler = $.proxy(function() { 32 | this.options.onBeforePageLoad() 33 | this.destroy() 34 | this.$container.addClass(this.options.loadingClass) 35 | 36 | $.get($(this.options.more).attr('href'), $.proxy(function(data) { 37 | var $data = $($.parseHTML(data)) 38 | var $newMore = $data.find(this.options.more) 39 | 40 | var $items = $data.find(this.options.items) 41 | if (!$items.length) { 42 | $items = $data.filter(this.options.items) 43 | } 44 | 45 | this.$container.append($items) 46 | this.$container.removeClass(this.options.loadingClass) 47 | 48 | if (!$newMore.length) { 49 | $newMore = $data.filter(this.options.more) 50 | } 51 | if ($newMore.length) { 52 | this.$more.replaceWith($newMore) 53 | this.$more = $newMore 54 | this.waypoint = new Waypoint(this.options) 55 | } 56 | else { 57 | this.$more.remove() 58 | } 59 | 60 | this.options.onAfterPageLoad() 61 | }, this)) 62 | }, this) 63 | } 64 | 65 | /* Public */ 66 | Infinite.prototype.destroy = function() { 67 | if (this.waypoint) { 68 | this.waypoint.destroy() 69 | } 70 | } 71 | 72 | Infinite.defaults = { 73 | container: 'auto', 74 | items: '.infinite-item', 75 | more: '.infinite-more-link', 76 | offset: 'bottom-in-view', 77 | loadingClass: 'infinite-loading', 78 | onBeforePageLoad: $.noop, 79 | onAfterPageLoad: $.noop 80 | } 81 | 82 | Waypoint.Infinite = Infinite 83 | }()) 84 | ; -------------------------------------------------------------------------------- /core/rpc/core/debug.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package rpc 6 | 7 | /* 8 | Some HTML presented at http://machine:port/debug/rpc 9 | Lists services, their methods, and some statistics, still rudimentary. 10 | */ 11 | 12 | import ( 13 | "fmt" 14 | "html/template" 15 | "net/http" 16 | "sort" 17 | ) 18 | 19 | const debugText = ` 20 | 21 | Services 22 | {{range .}} 23 |
      24 | Service {{.Name}} 25 |
      26 | 27 | 28 | {{range .Method}} 29 | 30 | 31 | 32 | 33 | {{end}} 34 |
      MethodCalls
      {{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error{{.Type.NumCalls}}
      35 | {{end}} 36 | 37 | ` 38 | 39 | var debug = template.Must(template.New("RPC debug").Parse(debugText)) 40 | 41 | // If set, print log statements for internal and I/O errors. 42 | var debugLog = false 43 | 44 | type debugMethod struct { 45 | Type *methodType 46 | Name string 47 | } 48 | 49 | type methodArray []debugMethod 50 | 51 | type debugService struct { 52 | Service *service 53 | Name string 54 | Method methodArray 55 | } 56 | 57 | type serviceArray []debugService 58 | 59 | func (s serviceArray) Len() int { return len(s) } 60 | func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name } 61 | func (s serviceArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 62 | 63 | func (m methodArray) Len() int { return len(m) } 64 | func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name } 65 | func (m methodArray) Swap(i, j int) { m[i], m[j] = m[j], m[i] } 66 | 67 | type debugHTTP struct { 68 | *Server 69 | } 70 | 71 | // Runs at /debug/rpc 72 | func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) { 73 | // Build a sorted version of the data. 74 | var services serviceArray 75 | server.serviceMap.Range(func(snamei, svci interface{}) bool { 76 | svc := svci.(*service) 77 | ds := debugService{svc, snamei.(string), make(methodArray, 0, len(svc.method))} 78 | for mname, method := range svc.method { 79 | ds.Method = append(ds.Method, debugMethod{method, mname}) 80 | } 81 | sort.Sort(ds.Method) 82 | services = append(services, ds) 83 | return true 84 | }) 85 | sort.Sort(services) 86 | err := debug.Execute(w, services) 87 | if err != nil { 88 | fmt.Fprintln(w, "rpc: error executing template:", err.Error()) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 |

      2 | 3 | 4 | 5 |

      6 | 7 | 8 | 9 |

      HFish

      10 |

      一个最便捷的蜜罐平台

      11 | 12 | 13 |

      14 | 文档 15 | | 16 | Github 17 | | 18 | 码云 19 | | 20 | 下载 21 | | 22 | English 23 |

      24 | 25 | 26 | 27 | ## 介绍 28 | 29 | 30 | > 本项目使用 **GPL** 协议,未经授权,禁止使用商业用途。 31 | > 32 | > *本 Team 研发此平台,仅为企业安全测试使用,禁止其他人员使用非法用途!一切行为与本 Team 无关。* 33 | 34 | **HFish** 是一款基于 Golang 开发的跨平台蜜罐平台,为了企业安全做出了精心的打造 35 | 36 | 37 | - **多功能**: 不仅仅支持 `HTTP(S)` 蜜罐,还支持 `SSH`、`SFTP`、`Redis`、`Mysql`、`FTP`、`Telnet`、`暗网` 等 38 | - **扩展性**: 提供 `API` 接口,使用者可以随意扩展蜜罐模块 ( `WEB`、`PC`、`APP` ) 39 | - **便捷性**: 使用 **Golang** 开发,使用者可以在 `Win` + `Mac` + `Linux` 上快速部署一套蜜罐平台 40 | 41 | ## 支持蜜罐 42 | 43 | - **`SSH`** 蜜罐 44 | - **`Redis`** 蜜罐 45 | - **`Mysql`** 蜜罐 46 | - **`MemCache`** 蜜罐 47 | - **`Telnet`** 蜜罐 48 | - **`FTP`** 蜜罐 49 | - **`WEB`** 蜜罐 50 | - **`暗网`** 蜜罐 51 | - **`HTTP`** 蜜罐 52 | - **`TFTP`** 蜜罐 53 | - **`VNC`** 蜜罐 54 | - **`ES`** 蜜罐 55 | - **`自定义`** 蜜罐 56 | 57 | ## 快速部署 58 | 59 | 60 | - 下载当前系统二进制压缩包 61 | - **`cd`** 到程序根目录,修改 **`config.ini`** 配置文件 62 | - 执行 **`./HFish run`** 启动服务 63 | - 浏览器输入 **http://localhost:9001** 打开 64 | 65 | 66 | ## 部分界面展示 67 | 68 | 69 | ### 命令行帮助 70 | 71 | 72 | ![](./images/help.png) 73 | 74 | 75 | ### 启动服务 76 | 77 | 78 | ![](./images/run.png) 79 | 80 | 81 | ### 登录页 82 | 83 | 84 | ![](./images/login.png) 85 | 86 | 87 | ### 仪表盘 88 | 89 | 90 | ![](./images/dashboard.png) 91 | 92 | 93 | ### 态势感知 94 | 95 | 96 | ![](./images/data.png) 97 | 98 | 99 | ### 上钩页 100 | 101 | 102 | ![](./images/fish.png) 103 | 104 | 105 | ### 分布式集群 106 | 107 | 108 | ![](./images/colony.png) 109 | 110 | 111 | ### 邮件群发 112 | 113 | 114 | ![](./images/mail.png) 115 | 116 | 117 | ### 设置页 118 | 119 | 120 | ![](./images/setting.png) 121 | 122 | 123 | ## 关于 124 | 125 | 126 | > 目前只有我一个人 127 | 128 | 129 | **Team:** HackLC 130 | 131 | 132 | **官网:** https://hack.lc 133 | 134 | 135 | **专注安全行业,一心打造好产品** 136 | 137 | 138 | ## 联系我 139 | 140 | **E-mail:** **`lauixData#gmail.com`** 141 | 142 | 143 | ## 反馈群 144 | 145 | 146 | 加微信拉人,请备注 **`蜜罐`** 147 | 148 | 149 | ![](./images/wx.jpg) -------------------------------------------------------------------------------- /core/protocol/ftp/ftp.go: -------------------------------------------------------------------------------- 1 | package ftp 2 | 3 | import ( 4 | "io" 5 | "fmt" 6 | "time" 7 | "os" 8 | "strings" 9 | "strconv" 10 | "HFish/core/protocol/ftp/graval" 11 | ) 12 | 13 | const ( 14 | fileOne = "This is the first file available for download.\n\nBy Jàmes" 15 | fileTwo = "This is file number two.\n\n2012-12-04" 16 | ) 17 | 18 | type MemDriver struct{} 19 | 20 | func (driver *MemDriver) Authenticate(user string, pass string) bool { 21 | //return user == "test" && pass == "1234" 22 | return false 23 | } 24 | 25 | func (driver *MemDriver) Bytes(path string) (bytes int) { 26 | switch path { 27 | case "/one.txt": 28 | bytes = len(fileOne) 29 | break 30 | case "/files/two.txt": 31 | bytes = len(fileTwo) 32 | break 33 | default: 34 | bytes = -1 35 | } 36 | return 37 | } 38 | 39 | func (driver *MemDriver) ModifiedTime(path string) (time.Time, error) { 40 | return time.Now(), nil 41 | } 42 | 43 | func (driver *MemDriver) ChangeDir(path string) bool { 44 | return path == "/" || path == "/files" 45 | } 46 | 47 | func (driver *MemDriver) DirContents(path string) (files []os.FileInfo) { 48 | files = []os.FileInfo{} 49 | switch path { 50 | case "/": 51 | files = append(files, graval.NewDirItem("files")) 52 | files = append(files, graval.NewFileItem("one.txt", len(fileOne))) 53 | case "/files": 54 | files = append(files, graval.NewFileItem("two.txt", len(fileOne))) 55 | } 56 | return files 57 | } 58 | 59 | func (driver *MemDriver) DeleteDir(path string) bool { 60 | return false 61 | } 62 | 63 | func (driver *MemDriver) DeleteFile(path string) bool { 64 | return false 65 | } 66 | 67 | func (driver *MemDriver) Rename(fromPath string, toPath string) bool { 68 | return false 69 | } 70 | 71 | func (driver *MemDriver) MakeDir(path string) bool { 72 | return false 73 | } 74 | 75 | func (driver *MemDriver) GetFile(path string) (data string, err error) { 76 | switch path { 77 | case "/one.txt": 78 | data = fileOne 79 | case "/files/two.txt": 80 | data = fileTwo 81 | } 82 | return 83 | } 84 | 85 | func (driver *MemDriver) PutFile(destPath string, data io.Reader) bool { 86 | return false 87 | } 88 | 89 | type MemDriverFactory struct{} 90 | 91 | func (factory *MemDriverFactory) NewDriver() (graval.FTPDriver, error) { 92 | return &MemDriver{}, nil 93 | } 94 | 95 | func Start(addr string) { 96 | arr := strings.Split(addr, ":") 97 | port, _ := strconv.Atoi(arr[1]) 98 | 99 | factory := &MemDriverFactory{} 100 | ftpServer := graval.NewFTPServer(&graval.FTPServerOpts{Factory: factory, Hostname: arr[0], Port: port}) 101 | 102 | err := ftpServer.ListenAndServe() 103 | if err != nil { 104 | fmt.Print(err) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /static/data/css/app.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | /********** Global **********/ 4 | /* 5 | *常用背景色: #0b0f34 (6,64,102) (29,45,57) (7,33,58) (8,13,28) (15,43,36) 6 | */ 7 | html, body { 8 | width: 100%; 9 | height: 100%; 10 | min-height: 635px; 11 | font-family: "microsoft yahei", arial, sans-serif; 12 | background-color: #192440; 13 | background-repeat: no-repeat; 14 | background-position: center; 15 | background-size: 100% 100%; 16 | overflow-x: hidden; 17 | overflow-y: auto; 18 | } 19 | 20 | body.bg01 { 21 | background-image: url("../img/bg01.png"); 22 | } 23 | 24 | body.bg02 { 25 | background-image: url("../img/bg02.png"); 26 | } 27 | 28 | body.bg03 { 29 | background-image: url("../img/bg03.png"); 30 | } 31 | 32 | body.bg04 { 33 | background-image: url("../img/bg04.png"); 34 | } 35 | 36 | .header { 37 | margin: 0 auto; 38 | width: 100%; 39 | height: 65px; 40 | max-width: 1920px; 41 | background: url("../img/header.png") center no-repeat; 42 | } 43 | 44 | .header h3 { 45 | margin: 0; 46 | padding: 0; 47 | line-height: 50px; 48 | text-align: center; 49 | font-size: 24px; 50 | color: #fff; 51 | } 52 | 53 | .wrapper { 54 | position: absolute; 55 | top: 80px; 56 | bottom: 0; 57 | left: 0; 58 | right: 0; 59 | min-height: 555px; 60 | } 61 | 62 | .container-fluid { 63 | height: 100%; 64 | min-height: 100%; 65 | } 66 | 67 | .row { 68 | margin-left: -7px; 69 | margin-right: -8px; 70 | } 71 | 72 | .row > div { 73 | padding-left: 7px; 74 | padding-right: 8px; 75 | } 76 | 77 | .xpanel-wrapper { 78 | padding-bottom: 15px; 79 | box-sizing: border-box; 80 | } 81 | 82 | .xpanel-wrapper-1 { 83 | height: 100%; 84 | } 85 | 86 | .xpanel-wrapper-2 { 87 | height: 50%; 88 | } 89 | 90 | .xpanel-wrapper-3 { 91 | height: 33.33333%; 92 | } 93 | 94 | .xpanel { 95 | padding: 15px; 96 | height: 100%; 97 | min-height: 170px; 98 | background: url("../img/panel.png") center no-repeat; 99 | background-size: 100% 100%; 100 | box-sizing: border-box; 101 | } 102 | 103 | /* tool */ 104 | .fill-h { 105 | height: 100%; 106 | min-height: 100%; 107 | } 108 | 109 | .no-margin { 110 | margin: 0 !important; 111 | } 112 | 113 | .no-padding { 114 | padding: 0 !important; 115 | } 116 | 117 | /* scrollbar */ 118 | ::-webkit-scrollbar { 119 | width: 0; 120 | height: 0; 121 | } 122 | 123 | ::-webkit-scrollbar-track { 124 | background-color: transparent; 125 | } 126 | 127 | ::-webkit-scrollbar-thumb { 128 | border-radius: 5px; 129 | background-color: rgba(0, 0, 0, 0.3); 130 | } -------------------------------------------------------------------------------- /view/url.go: -------------------------------------------------------------------------------- 1 | package view 2 | 3 | import ( 4 | "HFish/view/api" 5 | "HFish/view/dashboard" 6 | "HFish/view/fish" 7 | "HFish/view/mail" 8 | "HFish/view/colony" 9 | "HFish/view/setting" 10 | "github.com/gin-gonic/gin" 11 | "HFish/view/login" 12 | "HFish/utils/cors" 13 | "HFish/view/data" 14 | ) 15 | 16 | func LoadUrl(r *gin.Engine) { 17 | /* RPC 服务端 */ 18 | // 登录 19 | r.GET("/login", login.Html) 20 | r.POST("/login", login.Login) 21 | r.GET("/logout", login.Logout) 22 | 23 | // 仪表盘 24 | r.GET("/", login.Jump, dashboard.Html) 25 | r.GET("/dashboard", login.Jump, dashboard.Html) 26 | r.GET("/get/dashboard/data", login.Jump, dashboard.GetFishData) 27 | r.GET("/get/dashboard/pie_data", login.Jump, dashboard.GetFishPieData) 28 | 29 | // 蜜罐列表 30 | r.GET("/fish", login.Jump, fish.Html) 31 | r.GET("/get/fish/list", login.Jump, fish.GetFishList) 32 | r.GET("/get/fish/info", login.Jump, fish.GetFishInfo) 33 | r.GET("/get/fish/typeList", login.Jump, fish.GetFishTypeInfo) 34 | r.POST("/post/fish/del", login.Jump, fish.PostFishDel) 35 | 36 | // 大数据仪表盘 37 | r.GET("/data", login.Jump, data.Html) 38 | r.GET("/data/get/china", login.Jump, data.GetChina) 39 | r.GET("/data/get/country", login.Jump, data.GetCountry) 40 | r.GET("/data/get/ip", login.Jump, data.GetIp) 41 | r.GET("/data/get/type", login.Jump, data.GetType) 42 | r.GET("/data/get/info", login.Jump, data.GetNewInfo) 43 | r.GET("/data/get/account", login.Jump, data.GetAccountInfo) 44 | r.GET("/data/get/password", login.Jump, data.GetPasswdInfo) 45 | r.GET("/data/get/word", login.Jump, data.GetWordInfo) 46 | r.GET("/data/ws", data.Ws) 47 | 48 | // 分布式集群 49 | r.GET("/colony", login.Jump, colony.Html) 50 | r.GET("/get/colony/list", login.Jump, colony.GetColony) 51 | r.POST("/post/colony/del", login.Jump, colony.PostColonyDel) 52 | 53 | // 邮件群发 54 | r.GET("/mail", login.Jump, mail.Html) 55 | r.POST("/post/mail/sendEmail", login.Jump, mail.SendEmailToUsers) 56 | 57 | // 设置 58 | r.GET("/setting", login.Jump, setting.Html) 59 | r.GET("/get/setting/info", login.Jump, setting.GetSettingInfo) 60 | r.POST("/post/setting/update", login.Jump, setting.UpdateEmailInfo) 61 | r.POST("/post/setting/updateAlertMail", login.Jump, setting.UpdateAlertMail) 62 | r.POST("/post/setting/checkSetting", login.Jump, setting.UpdateStatusSetting) 63 | r.POST("/post/setting/updateWebHook", login.Jump, setting.UpdateWebHook) 64 | r.POST("/post/setting/updateWhiteIp", login.Jump, setting.UpdateWhiteIp) 65 | r.POST("/post/setting/updatePasswdTM", login.Jump, setting.UpdatePasswdTM) 66 | r.POST("/post/setting/clearData", login.Jump, setting.ClearData) 67 | 68 | // API 接口 69 | // 解决跨域问题 70 | r.Use(cors.Cors()) 71 | r.GET("/api/v1/get/ip", api.GetIpList) 72 | r.GET("/api/v1/get/fish_info", api.GetFishInfo) 73 | r.GET("/api/v1/get/passwd_list", api.GetAccountPasswdInfo) 74 | } 75 | -------------------------------------------------------------------------------- /static/libs/waypoints/lib/shortcuts/inview.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Waypoints Inview Shortcut - 3.1.1 3 | Copyright © 2011-2015 Caleb Troughton 4 | Licensed under the MIT license. 5 | https://github.com/imakewebthings/waypoints/blog/master/licenses.txt 6 | */ 7 | (function() { 8 | 'use strict' 9 | 10 | function noop() {} 11 | 12 | var Waypoint = window.Waypoint 13 | 14 | /* http://imakewebthings.com/waypoints/shortcuts/inview */ 15 | function Inview(options) { 16 | this.options = Waypoint.Adapter.extend({}, Inview.defaults, options) 17 | this.axis = this.options.horizontal ? 'horizontal' : 'vertical' 18 | this.waypoints = [] 19 | this.createWaypoints() 20 | } 21 | 22 | /* Private */ 23 | Inview.prototype.createWaypoints = function() { 24 | var configs = { 25 | vertical: [{ 26 | down: 'enter', 27 | up: 'exited', 28 | offset: '100%' 29 | }, { 30 | down: 'entered', 31 | up: 'exit', 32 | offset: 'bottom-in-view' 33 | }, { 34 | down: 'exit', 35 | up: 'entered', 36 | offset: 0 37 | }, { 38 | down: 'exited', 39 | up: 'enter', 40 | offset: function() { 41 | return -this.adapter.outerHeight() 42 | } 43 | }], 44 | horizontal: [{ 45 | right: 'enter', 46 | left: 'exited', 47 | offset: '100%' 48 | }, { 49 | right: 'entered', 50 | left: 'exit', 51 | offset: 'right-in-view' 52 | }, { 53 | right: 'exit', 54 | left: 'entered', 55 | offset: 0 56 | }, { 57 | right: 'exited', 58 | left: 'enter', 59 | offset: function() { 60 | return -this.adapter.outerWidth() 61 | } 62 | }] 63 | } 64 | 65 | for (var i = 0, end = configs[this.axis].length; i < end; i++) { 66 | var config = configs[this.axis][i] 67 | this.createWaypoint(config) 68 | } 69 | } 70 | 71 | /* Private */ 72 | Inview.prototype.createWaypoint = function(config) { 73 | var self = this 74 | this.waypoints.push(new Waypoint({ 75 | element: this.options.element, 76 | handler: (function(config) { 77 | return function(direction) { 78 | self.options[config[direction]].call(this, direction) 79 | } 80 | }(config)), 81 | offset: config.offset, 82 | horizontal: this.options.horizontal 83 | })) 84 | } 85 | 86 | /* Public */ 87 | Inview.prototype.destroy = function() { 88 | for (var i = 0, end = this.waypoints.length; i < end; i++) { 89 | this.waypoints[i].destroy() 90 | } 91 | this.waypoints = [] 92 | } 93 | 94 | Inview.defaults = { 95 | enter: noop, 96 | entered: noop, 97 | exit: noop, 98 | exited: noop 99 | } 100 | 101 | Waypoint.Inview = Inview 102 | }()) 103 | ; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

      2 | 3 | 4 | 5 |

      6 | 7 |

      HFish

      8 |

      A Most Convenient Honeypot Platform

      9 | 10 |

      11 | Document 12 | | 13 | Github 14 | | 15 | Gitee 16 | | 17 | Download 18 | | 19 | 中文 20 |

      21 | 22 | 23 | ## Introduce 24 | 25 | **HFish** It is a cross platform honeypot platform developed based on golang, which has been meticulously built for enterprise security 26 | 27 | - **Multi-function**: Not just support `HTTP(S)` Pot,It also supports `SSH`、`SFTP`、`Redis`、`Mysql`、`FTP`、`Telnet`、`Deep` etc. 28 | - **Expansibility**: Provide `API` Interface,Users can expand honeypot module at will ( `WEB`、`PC`、`APP` ) 29 | - **Convenience**: Use **Golang** Development , Users can 30 | `Win` + `Mac` + `Linux` Quickly deploy a honeypot platform on 31 | 32 | ## Support honeypot 33 | 34 | - **`SSH`** Pot 35 | - **`Redis`** Pot 36 | - **`Mysql`** Pot 37 | - **`MemCache`** Pot 38 | - **`Telnet`** Pot 39 | - **`FTP`** Pot 40 | - **`WEB`** Pot 41 | - **`Deep`** Pot 42 | - **`HTTP`** Pot 43 | - **`TFTP`** Pot 44 | - **`VNC`** Pot 45 | - **`ES`** Pot 46 | - **`Custom`** Pot 47 | 48 | ## Rapid deployment 49 | 50 | 51 | - Download current system binary compression package 52 | - **`cd`** To program root , Update **`config.ini`** file 53 | - Implement **`./HFish run`** Start service 54 | - Browser input **http://localhost:9001** open 55 | 56 | 57 | ## Partial interface display 58 | 59 | ### Help 60 | 61 | ![](./images/help.png) 62 | 63 | 64 | ### Start service 65 | 66 | 67 | ![](./images/run.png) 68 | 69 | 70 | ### Landing page 71 | 72 | 73 | ![](./images/login.png) 74 | 75 | 76 | ### Dashboard 77 | 78 | 79 | ![](./images/dashboard.png) 80 | 81 | 82 | ### Situational awareness 83 | 84 | 85 | ![](./images/data.png) 86 | 87 | 88 | ### Upper hook page 89 | 90 | 91 | ![](./images/fish.png) 92 | 93 | 94 | ### Distributed cluster 95 | 96 | 97 | ![](./images/colony.png) 98 | 99 | 100 | ### Mass mailing 101 | 102 | 103 | ![](./images/mail.png) 104 | 105 | 106 | ### settings page 107 | 108 | 109 | ![](./images/setting.png) 110 | 111 | 112 | ## About 113 | 114 | 115 | > I'm the only one right now 116 | 117 | 118 | **Team:** HackLC 119 | 120 | 121 | **Website:** https://hack.lc 122 | 123 | 124 | **Focus on the safety industry, focus on building good products** 125 | 126 | 127 | ## Contact me 128 | 129 | **E-mail:** **`lauixData#gmail.com`** -------------------------------------------------------------------------------- /core/protocol/tftp/libs/netascii/netascii_test.go: -------------------------------------------------------------------------------- 1 | package netascii 2 | 3 | import ( 4 | "bytes" 5 | "io/ioutil" 6 | "strings" 7 | "testing" 8 | "testing/iotest" 9 | ) 10 | 11 | var basic = map[string]string{ 12 | "\r": "\r\x00", 13 | "\n": "\r\n", 14 | "la\nbu": "la\r\nbu", 15 | "la\rbu": "la\r\x00bu", 16 | "\r\r\r": "\r\x00\r\x00\r\x00", 17 | "\n\n\n": "\r\n\r\n\r\n", 18 | } 19 | 20 | func TestTo(t *testing.T) { 21 | for text, netascii := range basic { 22 | to := ToReader(strings.NewReader(text)) 23 | n, _ := ioutil.ReadAll(to) 24 | if bytes.Compare(n, []byte(netascii)) != 0 { 25 | t.Errorf("%q to netascii: %q != %q", text, n, netascii) 26 | } 27 | } 28 | } 29 | 30 | func TestFrom(t *testing.T) { 31 | for text, netascii := range basic { 32 | r := bytes.NewReader([]byte(netascii)) 33 | b := &bytes.Buffer{} 34 | from := FromWriter(b) 35 | r.WriteTo(from) 36 | n, _ := ioutil.ReadAll(b) 37 | if string(n) != text { 38 | t.Errorf("%q from netascii: %q != %q", netascii, n, text) 39 | } 40 | } 41 | } 42 | 43 | const text = ` 44 | Therefore, the sequence "CR LF" must be treated as a single "new 45 | line" character and used whenever their combined action is 46 | intended; the sequence "CR NUL" must be used where a carriage 47 | return alone is actually desired; and the CR character must be 48 | avoided in other contexts. This rule gives assurance to systems 49 | which must decide whether to perform a "new line" function or a 50 | multiple-backspace that the TELNET stream contains a character 51 | following a CR that will allow a rational decision. 52 | (in the default ASCII mode), to preserve the symmetry of the 53 | NVT model. Even though it may be known in some situations 54 | (e.g., with remote echo and suppress go ahead options in 55 | effect) that characters are not being sent to an actual 56 | printer, nonetheless, for the sake of consistency, the protocol 57 | requires that a NUL be inserted following a CR not followed by 58 | a LF in the data stream. The converse of this is that a NUL 59 | received in the data stream after a CR (in the absence of 60 | options negotiations which explicitly specify otherwise) should 61 | be stripped out prior to applying the NVT to local character 62 | set mapping. 63 | ` 64 | 65 | func TestWriteRead(t *testing.T) { 66 | var one bytes.Buffer 67 | to := ToReader(strings.NewReader(text)) 68 | one.ReadFrom(to) 69 | two := &bytes.Buffer{} 70 | from := FromWriter(two) 71 | one.WriteTo(from) 72 | text2, _ := ioutil.ReadAll(two) 73 | if text != string(text2) { 74 | t.Errorf("text mismatch \n%x \n%x", text, text2) 75 | } 76 | } 77 | 78 | func TestOneByte(t *testing.T) { 79 | var one bytes.Buffer 80 | to := iotest.OneByteReader(ToReader(strings.NewReader(text))) 81 | one.ReadFrom(to) 82 | two := &bytes.Buffer{} 83 | from := FromWriter(two) 84 | one.WriteTo(from) 85 | text2, _ := ioutil.ReadAll(two) 86 | if text != string(text2) { 87 | t.Errorf("text mismatch \n%x \n%x", text, text2) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /core/protocol/ssh/gliderlabs/options_test.go: -------------------------------------------------------------------------------- 1 | package ssh 2 | 3 | import ( 4 | "net" 5 | "strings" 6 | "sync/atomic" 7 | "testing" 8 | 9 | gossh "golang.org/x/crypto/ssh" 10 | ) 11 | 12 | func newTestSessionWithOptions(t *testing.T, srv *Server, cfg *gossh.ClientConfig, options ...Option) (*gossh.Session, *gossh.Client, func()) { 13 | for _, option := range options { 14 | if err := srv.SetOption(option); err != nil { 15 | t.Fatal(err) 16 | } 17 | } 18 | return newTestSession(t, srv, cfg) 19 | } 20 | 21 | func TestPasswordAuth(t *testing.T) { 22 | t.Parallel() 23 | testUser := "testuser" 24 | testPass := "testpass" 25 | session, _, cleanup := newTestSessionWithOptions(t, &Server{ 26 | Handler: func(s Session) { 27 | // noop 28 | }, 29 | }, &gossh.ClientConfig{ 30 | User: testUser, 31 | Auth: []gossh.AuthMethod{ 32 | gossh.Password(testPass), 33 | }, 34 | HostKeyCallback: gossh.InsecureIgnoreHostKey(), 35 | }, PasswordAuth(func(ctx Context, password string) bool { 36 | if ctx.User() != testUser { 37 | t.Fatalf("user = %#v; want %#v", ctx.User(), testUser) 38 | } 39 | if password != testPass { 40 | t.Fatalf("user = %#v; want %#v", password, testPass) 41 | } 42 | return true 43 | })) 44 | defer cleanup() 45 | if err := session.Run(""); err != nil { 46 | t.Fatal(err) 47 | } 48 | } 49 | 50 | func TestPasswordAuthBadPass(t *testing.T) { 51 | t.Parallel() 52 | l := newLocalListener() 53 | srv := &Server{Handler: func(s Session) {}} 54 | srv.SetOption(PasswordAuth(func(ctx Context, password string) bool { 55 | return false 56 | })) 57 | go srv.serveOnce(l) 58 | _, err := gossh.Dial("tcp", l.Addr().String(), &gossh.ClientConfig{ 59 | User: "testuser", 60 | Auth: []gossh.AuthMethod{ 61 | gossh.Password("testpass"), 62 | }, 63 | HostKeyCallback: gossh.InsecureIgnoreHostKey(), 64 | }) 65 | if err != nil { 66 | if !strings.Contains(err.Error(), "unable to authenticate") { 67 | t.Fatal(err) 68 | } 69 | } 70 | } 71 | 72 | type wrappedConn struct { 73 | net.Conn 74 | written int32 75 | } 76 | 77 | func (c *wrappedConn) Write(p []byte) (n int, err error) { 78 | n, err = c.Conn.Write(p) 79 | atomic.AddInt32(&(c.written), int32(n)) 80 | return 81 | } 82 | 83 | func TestConnWrapping(t *testing.T) { 84 | t.Parallel() 85 | var wrapped *wrappedConn 86 | session, _, cleanup := newTestSessionWithOptions(t, &Server{ 87 | Handler: func(s Session) { 88 | // nothing 89 | }, 90 | }, &gossh.ClientConfig{ 91 | User: "testuser", 92 | Auth: []gossh.AuthMethod{ 93 | gossh.Password("testpass"), 94 | }, 95 | HostKeyCallback: gossh.InsecureIgnoreHostKey(), 96 | }, PasswordAuth(func(ctx Context, password string) bool { 97 | return true 98 | }), WrapConn(func(conn net.Conn) net.Conn { 99 | wrapped = &wrappedConn{conn, 0} 100 | return wrapped 101 | })) 102 | defer cleanup() 103 | if err := session.Shell(); err != nil { 104 | t.Fatal(err) 105 | } 106 | if atomic.LoadInt32(&(wrapped.written)) == 0 { 107 | t.Fatal("wrapped conn not written to") 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /core/protocol/memcache/LinkedHashMap/linklist.go: -------------------------------------------------------------------------------- 1 | package LinkedHashMap 2 | 3 | type LinkListNode struct { 4 | last *LinkListNode 5 | next *LinkListNode 6 | val interface{} 7 | } 8 | 9 | func NewLinkListNode(last *LinkListNode, next *LinkListNode, val interface{}) *LinkListNode { 10 | node := &LinkListNode{ 11 | last: last, 12 | next: next, 13 | val: val, 14 | } 15 | return node 16 | } 17 | 18 | func (this *LinkListNode) SetLast(node *LinkListNode) { 19 | this.last = node 20 | } 21 | 22 | func (this *LinkListNode) SetNext(node *LinkListNode) { 23 | this.next = node 24 | } 25 | 26 | func (this *LinkListNode) GetLast() *LinkListNode { 27 | return this.last 28 | } 29 | 30 | func (this *LinkListNode) GetNext() *LinkListNode { 31 | return this.next 32 | } 33 | 34 | func (this *LinkListNode) GetVal() interface{} { 35 | return this.val 36 | } 37 | 38 | func (this *LinkListNode) IsHead() bool { 39 | return this.last == nil 40 | } 41 | 42 | func (this *LinkListNode) IsTail() bool { 43 | return this.next == nil 44 | } 45 | 46 | type LinkList struct { 47 | head *LinkListNode 48 | tail *LinkListNode 49 | length int 50 | } 51 | 52 | func NewLinkList() *LinkList { 53 | return &LinkList{ 54 | head: nil, 55 | tail: nil, 56 | length: 0, 57 | } 58 | } 59 | 60 | func (this *LinkList) GetHead() *LinkListNode { 61 | return this.head 62 | } 63 | 64 | func (this *LinkList) GetTail() *LinkListNode { 65 | return this.tail 66 | } 67 | 68 | func (this *LinkList) AddToHead(val interface{}) *LinkListNode { 69 | if this.head == nil && this.tail == nil { 70 | return this.addFirstNode(val) 71 | 72 | } 73 | node := NewLinkListNode(nil, this.head, val) 74 | this.head.SetLast(node) 75 | this.head = node 76 | this.length++ 77 | return node 78 | } 79 | 80 | func (this *LinkList) AddToTail(val interface{}) *LinkListNode { 81 | if this.head == nil && this.tail == nil { 82 | return this.addFirstNode(val) 83 | 84 | } 85 | node := NewLinkListNode(this.tail, nil, val) 86 | this.tail.SetNext(node) 87 | this.tail = node 88 | this.length++ 89 | return node 90 | } 91 | 92 | func (this *LinkList) RemoveNode(node *LinkListNode) { 93 | defer func() { 94 | this.length-- 95 | }() 96 | 97 | /* LinkList中只有1个元素 */ 98 | if node.IsHead() && node.IsTail() { 99 | this.head = nil 100 | this.tail = nil 101 | return 102 | } 103 | 104 | /* 节点是头节点 */ 105 | if node.IsHead() { 106 | nextNode := node.GetNext() 107 | this.head = nextNode 108 | nextNode.SetLast(nil) 109 | node.SetNext(nil) 110 | return 111 | } 112 | 113 | /* 节点是尾节点 */ 114 | if node.IsTail() { 115 | lastNode := node.GetLast() 116 | this.tail = lastNode 117 | lastNode.SetNext(nil) 118 | node.SetLast(nil) 119 | return 120 | } 121 | 122 | lastNode := node.GetLast() 123 | nextNode := node.GetNext() 124 | 125 | lastNode.SetNext(nextNode) 126 | nextNode.SetLast(lastNode) 127 | node.SetLast(nil) 128 | node.SetNext(nil) 129 | } 130 | 131 | func (this *LinkList) GetLength() int { 132 | return this.length 133 | } 134 | 135 | func (this *LinkList) addFirstNode(val interface{}) *LinkListNode { 136 | node := NewLinkListNode(nil, nil, val) 137 | this.head = node 138 | this.tail = node 139 | this.length++ 140 | return node 141 | } 142 | -------------------------------------------------------------------------------- /web/deep/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 登录 ‹ 内部管理平台 — WordPress 11 | 12 | 14 | 16 | 18 | 20 | 22 | 23 | 24 | 25 | 47 | 48 | 49 |
      50 |

      基于WordPress

      51 | 52 |
      53 |

      54 | 57 |

      58 |

      59 | 61 |

      62 |

      64 |

      65 | 66 |

      67 |
      68 | 69 | 70 | 71 |
      72 | 73 | 74 |
      75 | 76 | 77 | -------------------------------------------------------------------------------- /web/wordPress/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 登录 ‹ 内部管理平台 — WordPress 11 | 12 | 14 | 16 | 18 | 20 | 22 | 23 | 24 | 25 | 47 | 48 | 49 |
      50 |

      基于WordPress

      51 | 52 |
      53 |

      54 | 57 |

      58 |

      59 | 61 |

      62 |

      64 |

      65 | 66 |

      67 |
      68 | 69 | 70 | 71 |
      72 | 73 | 74 |
      75 | 76 | 77 | -------------------------------------------------------------------------------- /core/protocol/telnet/telnet.go: -------------------------------------------------------------------------------- 1 | package telnet 2 | 3 | import ( 4 | "net" 5 | "fmt" 6 | "bufio" 7 | "strings" 8 | "os" 9 | "HFish/utils/is" 10 | "HFish/core/rpc/client" 11 | "HFish/core/report" 12 | "HFish/utils/log" 13 | "github.com/bitly/go-simplejson" 14 | "HFish/utils/json" 15 | "HFish/utils/file" 16 | "strconv" 17 | "time" 18 | "HFish/core/pool" 19 | ) 20 | 21 | // 服务端连接 22 | func server(address string, exitChan chan int) { 23 | l, err := net.Listen("tcp", address) 24 | 25 | if err != nil { 26 | fmt.Println(err.Error()) 27 | exitChan <- 1 28 | } 29 | 30 | defer l.Close() 31 | 32 | wg, poolX := pool.New(10) 33 | defer poolX.Release() 34 | 35 | for { 36 | wg.Add(1) 37 | poolX.Submit(func() { 38 | time.Sleep(time.Second * 2) 39 | 40 | conn, err := l.Accept() 41 | 42 | if err != nil { 43 | log.Pr("Telnet", "127.0.0.1", "Telnet 连接失败", err) 44 | } 45 | 46 | arr := strings.Split(conn.RemoteAddr().String(), ":") 47 | 48 | var id string 49 | 50 | // 判断是否为 RPC 客户端 51 | if is.Rpc() { 52 | id = client.ReportResult("TELNET", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0") 53 | } else { 54 | id = strconv.FormatInt(report.ReportTelnet(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10) 55 | } 56 | 57 | log.Pr("Telnet", arr[0], "已经连接") 58 | 59 | // 根据连接开启会话, 这个过程需要并行执行 60 | go handleSession(conn, exitChan, id) 61 | 62 | wg.Done() 63 | }) 64 | } 65 | } 66 | 67 | func getJson() *simplejson.Json { 68 | res, err := json.GetTelnet() 69 | 70 | if err != nil { 71 | log.Pr("HFish", "127.0.0.1", "解析 Telnet JSON 文件失败", err) 72 | } 73 | return res 74 | } 75 | 76 | // 会话处理 77 | func handleSession(conn net.Conn, exitChan chan int, id string) { 78 | fmt.Println("Session started") 79 | reader := bufio.NewReader(conn) 80 | 81 | for { 82 | str, err := reader.ReadString('\n') 83 | 84 | // telnet命令 85 | if err == nil { 86 | str = strings.TrimSpace(str) 87 | 88 | if is.Rpc() { 89 | go client.ReportResult("TELNET", "", "", "&&"+str, id) 90 | } else { 91 | go report.ReportUpdateTelnet(id, "&&"+str) 92 | } 93 | 94 | if !processTelnetCommand(str, exitChan) { 95 | conn.Close() 96 | break 97 | } 98 | 99 | res := getJson() 100 | 101 | fileName := res.Get("command").Get(str).MustString() 102 | 103 | if (fileName == "") { 104 | fileName = res.Get("command").Get("default").MustString() 105 | } 106 | 107 | output := file.ReadLibsText("telnet", fileName) 108 | 109 | conn.Write([]byte(output + "\r\n")) 110 | } else { 111 | // 发生错误 112 | fmt.Println("Session closed") 113 | conn.Close() 114 | break 115 | } 116 | } 117 | } 118 | 119 | // telent协议命令 120 | func processTelnetCommand(str string, exitChan chan int) bool { 121 | // @close指令表示终止本次会话 122 | if strings.HasPrefix(str, "@close") { 123 | fmt.Println("Session closed") 124 | // 告知外部需要断开连接 125 | return false 126 | // @shutdown指令表示终止服务进程 127 | } else if strings.HasPrefix(str, "@shutdown") { 128 | fmt.Println("Server shutdown") 129 | // 往通道中写入0, 阻塞等待接收方处理 130 | exitChan <- 0 131 | return false 132 | } 133 | return true 134 | } 135 | 136 | func Start(addr string) { 137 | // 创建一个程序结束码的通道 138 | exitChan := make(chan int) 139 | 140 | // 将服务器并发运行 141 | go server(addr, exitChan) 142 | 143 | // 通道阻塞,等待接受返回值 144 | code := <-exitChan 145 | 146 | // 标记程序返回值并退出 147 | os.Exit(code) 148 | } 149 | -------------------------------------------------------------------------------- /core/rpc/client/client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "HFish/utils/log" 5 | "HFish/utils/conf" 6 | "HFish/core/rpc/core" 7 | "strings" 8 | "fmt" 9 | ) 10 | 11 | // 上报状态结构 12 | type Status struct { 13 | AgentIp string 14 | AgentName string 15 | Web, Deep, Ssh, Redis, Mysql, Http, Telnet, Ftp, MemCahe, Plug, ES, TFtp, Vnc, Custom string 16 | } 17 | 18 | // 上报结果结构 19 | type Result struct { 20 | AgentIp string 21 | AgentName string 22 | Type string 23 | ProjectName string 24 | SourceIp string 25 | Info string 26 | Id string // 数据库ID,更新用 0 为新插入数据 27 | } 28 | 29 | var rpcClient *rpc.Client 30 | var ipAddr string 31 | 32 | func RpcInit() { 33 | rpcAddr := conf.Get("rpc", "addr") 34 | c, conn, err := rpc.Dial("tcp", rpcAddr) 35 | 36 | if err != nil { 37 | rpcClient = nil 38 | log.Pr("RPC", "127.0.0.1", "连接 RPC Server 失败") 39 | ipAddr = "" 40 | } else { 41 | rpcClient = c 42 | ipAddr = strings.Split(conn.LocalAddr().String(), ":")[0] 43 | fmt.Println("连接RPC Server 成功") 44 | } 45 | } 46 | 47 | func reportStatus(rpcName string, ftpStatus string, telnetStatus string, httpStatus string, mysqlStatus string, redisStatus string, sshStatus string, webStatus string, darkStatus string, memCacheStatus string, plugStatus string, esStatus string, tftpStatus string, vncStatus string, customStatus string) { 48 | if (rpcClient != nil) { 49 | status := Status{ 50 | ipAddr, 51 | rpcName, 52 | webStatus, 53 | darkStatus, 54 | sshStatus, 55 | redisStatus, 56 | mysqlStatus, 57 | httpStatus, 58 | telnetStatus, 59 | ftpStatus, 60 | memCacheStatus, 61 | plugStatus, 62 | esStatus, 63 | tftpStatus, 64 | vncStatus, 65 | customStatus, 66 | } 67 | 68 | var reply string 69 | err := rpcClient.Call("HFishRPCService.ReportStatus", status, &reply) 70 | 71 | if err != nil { 72 | log.Pr("RPC", "127.0.0.1", "上报服务状态失败", err) 73 | RpcInit() 74 | } else { 75 | fmt.Println("上报服务状态成功") 76 | } 77 | } else { 78 | RpcInit() 79 | } 80 | } 81 | 82 | func ReportResult(typex string, projectName string, sourceIp string, info string, id string) string { 83 | var reply string 84 | 85 | if (rpcClient != nil) { 86 | // projectName 只有 WEB 才需要传项目名 其他协议空即可 87 | // id 0 为 新插入数据,非 0 都是更新数据 88 | // id 非 0 的时候 sourceIp 为空 89 | rpcName := conf.Get("rpc", "name") 90 | 91 | result := Result{ 92 | ipAddr, 93 | rpcName, 94 | typex, 95 | projectName, 96 | sourceIp, 97 | info, 98 | id, 99 | } 100 | 101 | err := rpcClient.Call("HFishRPCService.ReportResult", result, &reply) 102 | 103 | if err != nil { 104 | log.Pr("RPC", "127.0.0.1", "上报上钩结果失败") 105 | RpcInit() 106 | } else { 107 | fmt.Println("上报上钩结果成功") 108 | } 109 | 110 | return reply 111 | } else { 112 | return "0" 113 | } 114 | } 115 | 116 | func Start(rpcName string, ftpStatus string, telnetStatus string, httpStatus string, mysqlStatus string, redisStatus string, sshStatus string, webStatus string, darkStatus string, memCacheStatus string, plugStatus string, esStatus string, tftpStatus string, vncStatus string, customStatus string) { 117 | reportStatus(rpcName, ftpStatus, telnetStatus, httpStatus, mysqlStatus, redisStatus, sshStatus, webStatus, darkStatus, memCacheStatus, plugStatus, esStatus, tftpStatus, vncStatus, customStatus) 118 | } 119 | -------------------------------------------------------------------------------- /core/rpc/core/jsonrpc/client.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package jsonrpc implements a JSON-RPC 1.0 ClientCodec and ServerCodec 6 | // for the rpc package. 7 | // For JSON-RPC 2.0 support, see https://godoc.org/?q=json-rpc+2.0 8 | package jsonrpc 9 | 10 | import ( 11 | "encoding/json" 12 | "fmt" 13 | "io" 14 | "net" 15 | "net/rpc" 16 | "sync" 17 | ) 18 | 19 | type clientCodec struct { 20 | dec *json.Decoder // for reading JSON values 21 | enc *json.Encoder // for writing JSON values 22 | c io.Closer 23 | 24 | // temporary work space 25 | req clientRequest 26 | resp clientResponse 27 | 28 | // JSON-RPC responses include the request id but not the request method. 29 | // Package rpc expects both. 30 | // We save the request method in pending when sending a request 31 | // and then look it up by request ID when filling out the rpc Response. 32 | mutex sync.Mutex // protects pending 33 | pending map[uint64]string // map request id to method name 34 | } 35 | 36 | // NewClientCodec returns a new rpc.ClientCodec using JSON-RPC on conn. 37 | func NewClientCodec(conn io.ReadWriteCloser) rpc.ClientCodec { 38 | return &clientCodec{ 39 | dec: json.NewDecoder(conn), 40 | enc: json.NewEncoder(conn), 41 | c: conn, 42 | pending: make(map[uint64]string), 43 | } 44 | } 45 | 46 | type clientRequest struct { 47 | Method string `json:"method"` 48 | Params [1]interface{} `json:"params"` 49 | Id uint64 `json:"id"` 50 | } 51 | 52 | func (c *clientCodec) WriteRequest(r *rpc.Request, param interface{}) error { 53 | c.mutex.Lock() 54 | c.pending[r.Seq] = r.ServiceMethod 55 | c.mutex.Unlock() 56 | c.req.Method = r.ServiceMethod 57 | c.req.Params[0] = param 58 | c.req.Id = r.Seq 59 | return c.enc.Encode(&c.req) 60 | } 61 | 62 | type clientResponse struct { 63 | Id uint64 `json:"id"` 64 | Result *json.RawMessage `json:"result"` 65 | Error interface{} `json:"error"` 66 | } 67 | 68 | func (r *clientResponse) reset() { 69 | r.Id = 0 70 | r.Result = nil 71 | r.Error = nil 72 | } 73 | 74 | func (c *clientCodec) ReadResponseHeader(r *rpc.Response) error { 75 | c.resp.reset() 76 | if err := c.dec.Decode(&c.resp); err != nil { 77 | return err 78 | } 79 | 80 | c.mutex.Lock() 81 | r.ServiceMethod = c.pending[c.resp.Id] 82 | delete(c.pending, c.resp.Id) 83 | c.mutex.Unlock() 84 | 85 | r.Error = "" 86 | r.Seq = c.resp.Id 87 | if c.resp.Error != nil || c.resp.Result == nil { 88 | x, ok := c.resp.Error.(string) 89 | if !ok { 90 | return fmt.Errorf("invalid error %v", c.resp.Error) 91 | } 92 | if x == "" { 93 | x = "unspecified error" 94 | } 95 | r.Error = x 96 | } 97 | return nil 98 | } 99 | 100 | func (c *clientCodec) ReadResponseBody(x interface{}) error { 101 | if x == nil { 102 | return nil 103 | } 104 | return json.Unmarshal(*c.resp.Result, x) 105 | } 106 | 107 | func (c *clientCodec) Close() error { 108 | return c.c.Close() 109 | } 110 | 111 | // NewClient returns a new rpc.Client to handle requests to the 112 | // set of services at the other end of the connection. 113 | func NewClient(conn io.ReadWriteCloser) *rpc.Client { 114 | return rpc.NewClientWithCodec(NewClientCodec(conn)) 115 | } 116 | 117 | // Dial connects to a JSON-RPC server at the specified network address. 118 | func Dial(network, address string) (*rpc.Client, error) { 119 | conn, err := net.Dial(network, address) 120 | if err != nil { 121 | return nil, err 122 | } 123 | return NewClient(conn), err 124 | } 125 | -------------------------------------------------------------------------------- /core/protocol/tftp/libs/single_port.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | func (s *Server) singlePortProcessRequests() error { 8 | var ( 9 | localAddr net.IP 10 | cnt int 11 | srcAddr net.Addr 12 | err error 13 | buf []byte 14 | ) 15 | defer func() { 16 | if r := recover(); r != nil { 17 | // We've received a new connection on the same IP+Port tuple 18 | // as a previous connection before garbage collection has occured 19 | s.handlers[srcAddr.String()] = make(chan []byte) 20 | go func(localAddr net.IP, remoteAddr *net.UDPAddr, buffer []byte, n, maxBlockLen int, listener chan []byte) { 21 | err := s.handlePacket(localAddr, remoteAddr, buffer, n, maxBlockLen, listener) 22 | if err != nil && s.hook != nil { 23 | s.hook.OnFailure(TransferStats{ 24 | SenderAnticipateEnabled: s.sendAEnable, 25 | }, err) 26 | } 27 | 28 | }(localAddr, srcAddr.(*net.UDPAddr), buf, cnt, blockLength, s.handlers[srcAddr.String()]) 29 | s.singlePortProcessRequests() 30 | } 31 | }() 32 | for { 33 | select { 34 | case q := <-s.quit: 35 | q <- struct{}{} 36 | return nil 37 | case handlersToFree := <-s.runGC: 38 | for _, handler := range handlersToFree { 39 | delete(s.handlers, handler) 40 | } 41 | default: 42 | buf = s.bufPool.Get().([]byte) 43 | cnt, localAddr, srcAddr, err = s.getPacket(buf) 44 | if err != nil || cnt == 0 { 45 | if s.hook != nil { 46 | s.hook.OnFailure(TransferStats{ 47 | SenderAnticipateEnabled: s.sendAEnable, 48 | }, err) 49 | } 50 | s.bufPool.Put(buf) 51 | continue 52 | } 53 | if receiverChannel, ok := s.handlers[srcAddr.String()]; ok { 54 | select { 55 | case receiverChannel <- buf[:cnt]: 56 | default: 57 | // We don't want to block the main loop if a channel is full 58 | } 59 | } else { 60 | s.handlers[srcAddr.String()] = make(chan []byte, datagramLength) 61 | go func(localAddr net.IP, remoteAddr *net.UDPAddr, buffer []byte, n, maxBlockLen int, listener chan []byte) { 62 | err := s.handlePacket(localAddr, remoteAddr, buffer, n, maxBlockLen, listener) 63 | if err != nil && s.hook != nil { 64 | s.hook.OnFailure(TransferStats{ 65 | SenderAnticipateEnabled: s.sendAEnable, 66 | }, err) 67 | } 68 | 69 | }(localAddr, srcAddr.(*net.UDPAddr), buf, cnt, blockLength, s.handlers[srcAddr.String()]) 70 | } 71 | } 72 | } 73 | } 74 | 75 | func (s *Server) getPacket(buf []byte) (int, net.IP, *net.UDPAddr, error) { 76 | if s.conn6 != nil { 77 | cnt, control, srcAddr, err := s.conn6.ReadFrom(buf) 78 | if err != nil || cnt == 0 { 79 | return 0, nil, nil, err 80 | } 81 | var localAddr net.IP 82 | if control != nil { 83 | localAddr = control.Dst 84 | } 85 | return cnt, localAddr, srcAddr.(*net.UDPAddr), nil 86 | } else if s.conn4 != nil { 87 | cnt, control, srcAddr, err := s.conn4.ReadFrom(buf) 88 | if err != nil || cnt == 0 { 89 | return 0, nil, nil, err 90 | } 91 | var localAddr net.IP 92 | if control != nil { 93 | localAddr = control.Dst 94 | } 95 | return cnt, localAddr, srcAddr.(*net.UDPAddr), nil 96 | } else { 97 | cnt, srcAddr, err := s.conn.ReadFromUDP(buf) 98 | if err != nil { 99 | return 0, nil, nil, err 100 | } 101 | return cnt, nil, srcAddr, nil 102 | } 103 | } 104 | 105 | // internalGC collects all the finished signals from each connection's goroutine 106 | // The main loop is sent the key to be nil'ed after the gcInterval has passed 107 | func (s *Server) internalGC() { 108 | var completedHandlers []string 109 | for { 110 | select { 111 | case newHandler := <-s.gcCollect: 112 | completedHandlers = append(completedHandlers, newHandler) 113 | if len(completedHandlers) > s.gcThreshold { 114 | s.runGC <- completedHandlers 115 | completedHandlers = nil 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /core/rpc/core/jsonrpc/server.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package jsonrpc 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | "io" 11 | "net/rpc" 12 | "sync" 13 | ) 14 | 15 | var errMissingParams = errors.New("jsonrpc: request body missing params") 16 | 17 | type serverCodec struct { 18 | dec *json.Decoder // for reading JSON values 19 | enc *json.Encoder // for writing JSON values 20 | c io.Closer 21 | 22 | // temporary work space 23 | req serverRequest 24 | 25 | // JSON-RPC clients can use arbitrary json values as request IDs. 26 | // Package rpc expects uint64 request IDs. 27 | // We assign uint64 sequence numbers to incoming requests 28 | // but save the original request ID in the pending map. 29 | // When rpc responds, we use the sequence number in 30 | // the response to find the original request ID. 31 | mutex sync.Mutex // protects seq, pending 32 | seq uint64 33 | pending map[uint64]*json.RawMessage 34 | } 35 | 36 | // NewServerCodec returns a new rpc.ServerCodec using JSON-RPC on conn. 37 | func NewServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec { 38 | return &serverCodec{ 39 | dec: json.NewDecoder(conn), 40 | enc: json.NewEncoder(conn), 41 | c: conn, 42 | pending: make(map[uint64]*json.RawMessage), 43 | } 44 | } 45 | 46 | type serverRequest struct { 47 | Method string `json:"method"` 48 | Params *json.RawMessage `json:"params"` 49 | Id *json.RawMessage `json:"id"` 50 | } 51 | 52 | func (r *serverRequest) reset() { 53 | r.Method = "" 54 | r.Params = nil 55 | r.Id = nil 56 | } 57 | 58 | type serverResponse struct { 59 | Id *json.RawMessage `json:"id"` 60 | Result interface{} `json:"result"` 61 | Error interface{} `json:"error"` 62 | } 63 | 64 | func (c *serverCodec) ReadRequestHeader(r *rpc.Request) error { 65 | c.req.reset() 66 | if err := c.dec.Decode(&c.req); err != nil { 67 | return err 68 | } 69 | r.ServiceMethod = c.req.Method 70 | 71 | // JSON request id can be any JSON value; 72 | // RPC package expects uint64. Translate to 73 | // internal uint64 and save JSON on the side. 74 | c.mutex.Lock() 75 | c.seq++ 76 | c.pending[c.seq] = c.req.Id 77 | c.req.Id = nil 78 | r.Seq = c.seq 79 | c.mutex.Unlock() 80 | 81 | return nil 82 | } 83 | 84 | func (c *serverCodec) ReadRequestBody(x interface{}) error { 85 | if x == nil { 86 | return nil 87 | } 88 | if c.req.Params == nil { 89 | return errMissingParams 90 | } 91 | // JSON params is array value. 92 | // RPC params is struct. 93 | // Unmarshal into array containing struct for now. 94 | // Should think about making RPC more general. 95 | var params [1]interface{} 96 | params[0] = x 97 | return json.Unmarshal(*c.req.Params, ¶ms) 98 | } 99 | 100 | var null = json.RawMessage([]byte("null")) 101 | 102 | func (c *serverCodec) WriteResponse(r *rpc.Response, x interface{}) error { 103 | c.mutex.Lock() 104 | b, ok := c.pending[r.Seq] 105 | if !ok { 106 | c.mutex.Unlock() 107 | return errors.New("invalid sequence number in response") 108 | } 109 | delete(c.pending, r.Seq) 110 | c.mutex.Unlock() 111 | 112 | if b == nil { 113 | // Invalid request so no id. Use JSON null. 114 | b = &null 115 | } 116 | resp := serverResponse{Id: b} 117 | if r.Error == "" { 118 | resp.Result = x 119 | } else { 120 | resp.Error = r.Error 121 | } 122 | return c.enc.Encode(resp) 123 | } 124 | 125 | func (c *serverCodec) Close() error { 126 | return c.c.Close() 127 | } 128 | 129 | // ServeConn runs the JSON-RPC server on a single connection. 130 | // ServeConn blocks, serving the connection until the client hangs up. 131 | // The caller typically invokes ServeConn in a go statement. 132 | func ServeConn(conn io.ReadWriteCloser) { 133 | rpc.ServeCodec(NewServerCodec(conn)) 134 | } 135 | -------------------------------------------------------------------------------- /core/protocol/tftp/libs/client.go: -------------------------------------------------------------------------------- 1 | package libs 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "strconv" 8 | "time" 9 | ) 10 | 11 | // NewClient creates TFTP client for server on address provided. 12 | func NewClient(addr string) (*Client, error) { 13 | a, err := net.ResolveUDPAddr("udp", addr) 14 | if err != nil { 15 | return nil, fmt.Errorf("resolving address %s: %v", addr, err) 16 | } 17 | return &Client{ 18 | addr: a, 19 | timeout: defaultTimeout, 20 | retries: defaultRetries, 21 | }, nil 22 | } 23 | 24 | // SetTimeout sets maximum time client waits for single network round-trip to succeed. 25 | // Default is 5 seconds. 26 | func (c *Client) SetTimeout(t time.Duration) { 27 | if t <= 0 { 28 | c.timeout = defaultTimeout 29 | } 30 | c.timeout = t 31 | } 32 | 33 | // SetRetries sets maximum number of attempts client made to transmit a packet. 34 | // Default is 5 attempts. 35 | func (c *Client) SetRetries(count int) { 36 | if count < 1 { 37 | c.retries = defaultRetries 38 | } 39 | c.retries = count 40 | } 41 | 42 | // SetBackoff sets a user provided function that is called to provide a 43 | // backoff duration prior to retransmitting an unacknowledged packet. 44 | func (c *Client) SetBackoff(h backoffFunc) { 45 | c.backoff = h 46 | } 47 | 48 | // SetBlockSize sets a custom block size used in the transmission. 49 | func (c *Client) SetBlockSize(s int) { 50 | c.blksize = s 51 | } 52 | 53 | // RequestTSize sets flag to indicate if tsize should be requested. 54 | func (c *Client) RequestTSize(s bool) { 55 | c.tsize = s 56 | } 57 | 58 | // Client stores data about a single TFTP client 59 | type Client struct { 60 | addr *net.UDPAddr 61 | timeout time.Duration 62 | retries int 63 | backoff backoffFunc 64 | blksize int 65 | tsize bool 66 | } 67 | 68 | // Send starts outgoing file transmission. It returns io.ReaderFrom or error. 69 | func (c Client) Send(filename string, mode string) (io.ReaderFrom, error) { 70 | conn, err := net.ListenUDP("udp", &net.UDPAddr{}) 71 | if err != nil { 72 | return nil, err 73 | } 74 | s := &sender{ 75 | send: make([]byte, datagramLength), 76 | receive: make([]byte, datagramLength), 77 | conn: &connConnection{conn: conn}, 78 | retry: &backoff{handler: c.backoff}, 79 | timeout: c.timeout, 80 | retries: c.retries, 81 | addr: c.addr, 82 | mode: mode, 83 | } 84 | if c.blksize != 0 { 85 | s.opts = make(options) 86 | s.opts["blksize"] = strconv.Itoa(c.blksize) 87 | } 88 | n := packRQ(s.send, opWRQ, filename, mode, s.opts) 89 | addr, err := s.sendWithRetry(n) 90 | if err != nil { 91 | return nil, err 92 | } 93 | s.addr = addr 94 | s.opts = nil 95 | return s, nil 96 | } 97 | 98 | // Receive starts incoming file transmission. It returns io.WriterTo or error. 99 | func (c Client) Receive(filename string, mode string) (io.WriterTo, error) { 100 | conn, err := net.ListenUDP("udp", &net.UDPAddr{}) 101 | if err != nil { 102 | return nil, err 103 | } 104 | if c.timeout == 0 { 105 | c.timeout = defaultTimeout 106 | } 107 | r := &receiver{ 108 | send: make([]byte, datagramLength), 109 | receive: make([]byte, datagramLength), 110 | conn: &connConnection{conn: conn}, 111 | retry: &backoff{handler: c.backoff}, 112 | timeout: c.timeout, 113 | retries: c.retries, 114 | addr: c.addr, 115 | autoTerm: true, 116 | block: 1, 117 | mode: mode, 118 | } 119 | if c.blksize != 0 || c.tsize { 120 | r.opts = make(options) 121 | } 122 | if c.blksize != 0 { 123 | r.opts["blksize"] = strconv.Itoa(c.blksize) 124 | // Clean it up so we don't send options twice 125 | defer func() { delete(r.opts, "blksize") }() 126 | } 127 | if c.tsize { 128 | r.opts["tsize"] = "0" 129 | } 130 | n := packRQ(r.send, opRRQ, filename, mode, r.opts) 131 | l, addr, err := r.receiveWithRetry(n) 132 | if err != nil { 133 | return nil, err 134 | } 135 | r.l = l 136 | r.addr = addr 137 | return r, nil 138 | } 139 | -------------------------------------------------------------------------------- /db/sql/hfish_db.sql: -------------------------------------------------------------------------------- 1 | SET NAMES utf8; 2 | SET FOREIGN_KEY_CHECKS = 0; 3 | 4 | -- ---------------------------- 5 | -- Table structure for `hfish_colony` 6 | -- ---------------------------- 7 | DROP TABLE IF EXISTS `hfish_colony`; 8 | CREATE TABLE `hfish_colony` ( 9 | `id` int(11) NOT NULL AUTO_INCREMENT, 10 | `agent_name` varchar(20) NOT NULL DEFAULT '', 11 | `agent_ip` varchar(20) NOT NULL DEFAULT '', 12 | `web_status` int(2) NOT NULL DEFAULT '0', 13 | `deep_status` int(2) NOT NULL DEFAULT '0', 14 | `ssh_status` int(2) NOT NULL DEFAULT '0', 15 | `redis_status` int(2) NOT NULL DEFAULT '0', 16 | `mysql_status` int(2) NOT NULL DEFAULT '0', 17 | `http_status` int(2) NOT NULL DEFAULT '0', 18 | `telnet_status` int(2) NOT NULL DEFAULT '0', 19 | `ftp_status` int(2) NOT NULL DEFAULT '0', 20 | `mem_cache_status` int(2) NOT NULL DEFAULT '0', 21 | `plug_status` int(2) NOT NULL DEFAULT '0', 22 | `es_status` int(2) NOT NULL DEFAULT '0', 23 | `tftp_status` int(2) NOT NULL DEFAULT '0', 24 | `vnc_status` int(2) NOT NULL DEFAULT '0', 25 | `custom_status` int(2) NOT NULL DEFAULT '0', 26 | `last_update_time` datetime NOT NULL, 27 | PRIMARY KEY (`id`), 28 | UNIQUE KEY `un_agent` (`agent_name`) USING BTREE 29 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 30 | 31 | -- ---------------------------- 32 | -- Table structure for `hfish_info` 33 | -- ---------------------------- 34 | DROP TABLE IF EXISTS `hfish_info`; 35 | CREATE TABLE `hfish_info` ( 36 | `id` int(11) NOT NULL AUTO_INCREMENT, 37 | `type` varchar(20) NOT NULL DEFAULT '', 38 | `project_name` varchar(20) NOT NULL DEFAULT '', 39 | `agent` varchar(20) NOT NULL DEFAULT '', 40 | `ip` varchar(20) NOT NULL DEFAULT '', 41 | `country` varchar(10) NOT NULL DEFAULT '', 42 | `region` varchar(10) NOT NULL DEFAULT '', 43 | `city` varchar(10) NOT NULL, 44 | `info` text NOT NULL, 45 | `create_time` datetime NOT NULL, 46 | PRIMARY KEY (`id`), 47 | KEY `info_index_1` (`type`) USING BTREE, 48 | KEY `info_index_2` (`country`) USING BTREE, 49 | KEY `info_index_3` (`type`,`create_time`) USING BTREE, 50 | KEY `info_index_4` (`ip`) USING BTREE, 51 | KEY `info_index_5` (`agent`) USING BTREE 52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 53 | 54 | -- ---------------------------- 55 | -- Table structure for `hfish_passwd` 56 | -- ---------------------------- 57 | DROP TABLE IF EXISTS `hfish_passwd`; 58 | CREATE TABLE `hfish_passwd` ( 59 | `id` int(11) NOT NULL AUTO_INCREMENT, 60 | `type` varchar(50) NOT NULL DEFAULT '', 61 | `account` varchar(50) NOT NULL DEFAULT '', 62 | `password` varchar(50) NOT NULL DEFAULT '', 63 | `create_time` datetime NOT NULL, 64 | PRIMARY KEY (`id`), 65 | KEY `index_key_1` (`account`) USING BTREE, 66 | KEY `index_key_2` (`password`) USING BTREE, 67 | KEY `index_key_3` (`type`) USING BTREE 68 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 69 | 70 | -- ---------------------------- 71 | -- Table structure for `hfish_setting` 72 | -- ---------------------------- 73 | DROP TABLE IF EXISTS `hfish_setting`; 74 | CREATE TABLE `hfish_setting` ( 75 | `id` int(11) NOT NULL AUTO_INCREMENT, 76 | `type` varchar(50) NOT NULL DEFAULT '', 77 | `info` text, 78 | `update_time` datetime NOT NULL, 79 | `status` int(2) NOT NULL DEFAULT '0', 80 | `setting_name` varchar(50) NOT NULL DEFAULT '', 81 | `setting_dis` varchar(50) NOT NULL DEFAULT '', 82 | PRIMARY KEY (`id`), 83 | UNIQUE KEY `index_key` (`type`) 84 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4; 85 | 86 | -- ---------------------------- 87 | -- Records of `hfish_setting` 88 | -- ---------------------------- 89 | BEGIN; 90 | INSERT INTO `hfish_setting` VALUES ('1', 'mail', '', '2019-09-02 20:15:00', '0', 'E-mail 群发', '群发邮件SMTP服务器配置'), ('2', 'alertMail', '', '2019-09-02 18:58:12', '0', 'E-mail 通知', '蜜罐告警会通过邮件告知信息'), ('3', 'webHook', '', '2019-09-03 11:49:00', '0', 'WebHook 通知', '蜜罐告警会请求指定API告知信息'), ('4', 'whiteIp', '', '2019-09-02 20:15:00', '0', 'IP 白名单', '蜜罐上钩会过滤掉白名单IP'), ('5', 'passwdTM', '', '2020-02-24 12:04', '0', '密码脱敏', '发送邮件如果有密码内容自动加星'); 91 | COMMIT; 92 | 93 | SET FOREIGN_KEY_CHECKS = 1; 94 | -------------------------------------------------------------------------------- /view/fish/view.go: -------------------------------------------------------------------------------- 1 | package fish 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | "HFish/core/dbUtil" 7 | "HFish/error" 8 | "HFish/utils/page" 9 | "strconv" 10 | "strings" 11 | "HFish/utils/log" 12 | ) 13 | 14 | // 蜜罐 页面 15 | func Html(c *gin.Context) { 16 | c.HTML(http.StatusOK, "fish.html", gin.H{}) 17 | } 18 | 19 | // 获取蜜罐列表 20 | func GetFishList(c *gin.Context) { 21 | p, _ := c.GetQuery("page") 22 | pageSize, _ := c.GetQuery("pageSize") 23 | typex, _ := c.GetQuery("type") 24 | colony, _ := c.GetQuery("colony") 25 | soText, _ := c.GetQuery("so_text") 26 | 27 | // 拼接 SQL 28 | db := dbUtil.DB().Table("hfish_info").Fields("id", "type", "project_name", "agent", "ip", "country", "region", "city", "create_time", "info") 29 | dbCount := dbUtil.DB().Table("hfish_info") 30 | 31 | if typex != "all" { 32 | db.Where("type", "=", typex) 33 | dbCount.Where("type", "=", typex) 34 | } 35 | 36 | if colony != "all" { 37 | db.Where("agent", "=", colony) 38 | dbCount.Where("agent", "=", colony) 39 | } 40 | 41 | if soText != "" { 42 | db.Where("project_name", "like", "%"+soText+"%").OrWhere("ip", "like", "%"+soText+"%") 43 | dbCount.Where("project_name", "like", "%"+soText+"%").OrWhere("ip", "like", "%"+soText+"%") 44 | } 45 | 46 | // 统计查询数量 47 | totalCount, errCount := dbCount.Count() 48 | 49 | if errCount != nil { 50 | log.Pr("HFish", "127.0.0.1", "统计分页总数失败", errCount) 51 | } 52 | 53 | // 查询列表 54 | pInt, _ := strconv.Atoi(p) 55 | pageSizeInt, _ := strconv.Atoi(pageSize) 56 | pageStart := page.Start(pInt, pageSizeInt) 57 | 58 | result, err := db.OrderBy("id desc").Limit(pageSizeInt).Offset(pageStart).Get() 59 | 60 | if err != nil { 61 | log.Pr("HFish", "127.0.0.1", "查询上钩信息列表失败", err) 62 | } 63 | 64 | totalCountString := strconv.FormatInt(totalCount, 10) 65 | totalCountInt, _ := strconv.Atoi(totalCountString) 66 | 67 | pageCount := page.TotalPage(totalCountInt, pageSizeInt) 68 | 69 | data := map[string]interface{}{ 70 | "result": result, 71 | "pageCount": pageCount, 72 | "totalCount": totalCount, 73 | "page": p, 74 | } 75 | 76 | c.JSON(http.StatusOK, gin.H{ 77 | "code": error.ErrSuccessCode, 78 | "msg": error.ErrSuccessMsg, 79 | "data": data, 80 | }) 81 | } 82 | 83 | // 删除蜜罐 84 | func PostFishDel(c *gin.Context) { 85 | id := c.PostForm("id") 86 | 87 | idx := strings.Split(id, ",") 88 | inId := make([]interface{}, 20) 89 | 90 | for _, x := range idx { 91 | inId = append(inId, x) 92 | } 93 | 94 | _, err := dbUtil.DB().Table("hfish_info").WhereIn("id", inId).Delete() 95 | 96 | if err != nil { 97 | log.Pr("HFish", "127.0.0.1", "删除蜜罐失败", err) 98 | } 99 | 100 | c.JSON(http.StatusOK, gin.H{ 101 | "code": error.ErrSuccessCode, 102 | "msg": error.ErrSuccessMsg, 103 | }) 104 | } 105 | 106 | // 获取蜜罐信息 107 | func GetFishInfo(c *gin.Context) { 108 | id, _ := c.GetQuery("id") 109 | 110 | result, err := dbUtil.DB().Table("hfish_info").Fields("info").Where("id", "=", id).First() 111 | 112 | if err != nil { 113 | log.Pr("HFish", "127.0.0.1", "获取蜜罐信息失败", err) 114 | } 115 | 116 | c.JSON(http.StatusOK, gin.H{ 117 | "code": error.ErrSuccessCode, 118 | "msg": error.ErrSuccessMsg, 119 | "data": result, 120 | }) 121 | } 122 | 123 | // 获取蜜罐分类信息,集群信息 124 | func GetFishTypeInfo(c *gin.Context) { 125 | resultType, errType := dbUtil.DB().Table("hfish_info").Fields("type").GroupBy("type").Get() 126 | 127 | if errType != nil { 128 | log.Pr("HFish", "127.0.0.1", "获取蜜罐分类失败", errType) 129 | } 130 | 131 | resultAgent, errAgent := dbUtil.DB().Table("hfish_info").Fields("agent").GroupBy("agent").Get() 132 | 133 | if errAgent != nil { 134 | log.Pr("HFish", "127.0.0.1", "获取集群分类失败", errAgent) 135 | } 136 | 137 | data := map[string]interface{}{ 138 | "resultInfoType": resultType, 139 | "resultColonyName": resultAgent, 140 | } 141 | 142 | c.JSON(http.StatusOK, gin.H{ 143 | "code": error.ErrSuccessCode, 144 | "msg": error.ErrSuccessMsg, 145 | "data": data, 146 | }) 147 | } 148 | -------------------------------------------------------------------------------- /core/alert/alert.go: -------------------------------------------------------------------------------- 1 | package alert 2 | 3 | import ( 4 | "HFish/utils/try" 5 | "strings" 6 | "HFish/utils/send" 7 | "bytes" 8 | "net/http" 9 | "HFish/utils/log" 10 | "encoding/json" 11 | "HFish/view/data" 12 | "github.com/gin-gonic/gin" 13 | "HFish/error" 14 | "HFish/utils/cache" 15 | "HFish/utils/passwd" 16 | ) 17 | 18 | func AlertMail(model string, typex string, agent string, ipx string, country string, region string, city string, infox string) { 19 | // 判断邮件通知 20 | try.Try(func() { 21 | // 只有新加入才会发送邮件通知 22 | if (model == "new") { 23 | status, _ := cache.Get("MailConfigStatus") 24 | 25 | // 判断是否启用通知 26 | if status == "1" { 27 | info, _ := cache.Get("MailConfigInfo") 28 | config := strings.Split(info.(string), "&&") 29 | 30 | if (country == "本地地址") { 31 | region = "" 32 | city = "" 33 | } else if (country == "局域网") { 34 | region = "" 35 | city = "" 36 | } 37 | 38 | // 判断是否开启脱敏 39 | passwdConfigStatus, _ := cache.Get("PasswdConfigStatus") 40 | 41 | if (passwdConfigStatus == "1") { 42 | if (typex == "FTP" || typex == "SSH") { 43 | // 获取脱敏加密字符 44 | passwdConfigInfo, _ := cache.Get("PasswdConfigInfo") 45 | 46 | arr := strings.Split(infox, "&&") 47 | 48 | infox = arr[0] + "&&" + passwd.Desensitization(arr[1], passwdConfigInfo.(string)) 49 | } 50 | } 51 | 52 | text := ` 53 |
      Hi,上钩了!
      54 |

      55 |
      集群名称:` + agent + `
      56 |
      攻击IP:` + ipx + `
      57 |
      地理信息:` + country + ` ` + region + ` ` + city + `
      58 |
      上钩内容:` + infox + `
      59 |

      60 |
      (HFish 自动发送)
      61 | ` 62 | 63 | send.SendMail(config[4:], "[HFish]提醒你,"+typex+"有鱼上钩!", text, config) 64 | } 65 | } 66 | }).Catch(func() { 67 | }) 68 | } 69 | 70 | func AlertWebHook(id string, model string, typex string, projectName string, agent string, ipx string, country string, region string, city string, infox string, time string) { 71 | // 判断 WebHook 通知 72 | try.Try(func() { 73 | status, _ := cache.Get("HookConfigStatus") 74 | 75 | // 判断是否启用通知 76 | if status == "1" { 77 | info, _ := cache.Get("HookConfigInfo") 78 | 79 | song := make(map[string]interface{}) 80 | song["id"] = id 81 | song["model"] = model 82 | song["project"] = projectName 83 | song["type"] = typex 84 | song["agent"] = agent 85 | song["ip"] = ipx 86 | song["country"] = country 87 | song["region"] = region 88 | song["city"] = city 89 | song["info"] = infox 90 | song["time"] = time 91 | 92 | bytesData, _ := json.Marshal(song) 93 | 94 | reader := bytes.NewReader(bytesData) 95 | 96 | request, _ := http.NewRequest("POST", info.(string), reader) 97 | request.Header.Set("Content-Type", "application/json;charset=UTF-8") 98 | 99 | client := http.Client{} 100 | resp, err := client.Do(request) 101 | 102 | if err != nil { 103 | log.Pr("HFish", "127.0.0.1", "WebHook 调用失败", err) 104 | } else { 105 | log.Pr("HFish", "127.0.0.1", "WebHook 调用成功") 106 | } 107 | 108 | defer resp.Body.Close() 109 | //defer request.Body.Close() 110 | } 111 | }).Catch(func() { 112 | }) 113 | } 114 | 115 | // 大数据展示 116 | func AlertDataWs(model string, typex string, projectName string, agent string, ipx string, country string, region string, city string, time string) { 117 | if (model == "new") { 118 | // 拼接字典 119 | d := data.MakeDataJson("center_data", map[string]interface{}{ 120 | "type": typex, 121 | "projectName": projectName, 122 | "agent": agent, 123 | "ipx": ipx, 124 | "country": country, 125 | "region": region, 126 | "city": city, 127 | "time": time, 128 | }) 129 | 130 | // 发送到客户端 131 | data.Send(gin.H{ 132 | "code": error.ErrSuccessCode, 133 | "msg": error.ErrSuccessMsg, 134 | "data": d, 135 | }) 136 | } 137 | } 138 | --------------------------------------------------------------------------------