mirror of
https://gitee.com/lauix/HFish
synced 2025-05-11 04:18:02 +08:00
206 lines
7.0 KiB
Go
206 lines
7.0 KiB
Go
package elasticsearch
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
"strings"
|
|
"HFish/utils/is"
|
|
"HFish/core/rpc/client"
|
|
"HFish/core/report"
|
|
)
|
|
|
|
// Config represents the configuration information.
|
|
type Config struct {
|
|
LogFile string `json:"logfile"`
|
|
UseRemote bool `json:"use_remote"`
|
|
Remote Remote `json:"remote"`
|
|
HpFeeds HpFeeds `json:"hpfeeds"`
|
|
InstanceName string `json:"instance_name"`
|
|
Anonymous bool `json:"anonymous"`
|
|
SensorIP string `json:"honeypot_ip"`
|
|
SpoofedVersion string `json:"spoofed_version"`
|
|
PublicIpUrl string `json:"public_ip_url"`
|
|
}
|
|
|
|
// Remote is a struct used to contain the details for a remote server connection
|
|
type Remote struct {
|
|
URL string `json:"url"`
|
|
UseAuth bool `json:"use_auth"`
|
|
Auth Auth `json:"auth"`
|
|
}
|
|
|
|
type HpFeeds struct {
|
|
Host string `json:"host"`
|
|
Port int `json:"port"`
|
|
Channel string `json:"channel"`
|
|
Ident string `json:"ident"`
|
|
Secret string `json:"secret"`
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
// Auth contains the details in case basic auth is to be used when connecting
|
|
// to the remote server
|
|
type Auth struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
// Conf holds the global config
|
|
var Conf Config
|
|
|
|
// Attack is a struct that contains the details of an attack entry
|
|
type Attack struct {
|
|
SourceIP string `json:"source"`
|
|
Timestamp time.Time `json:"@timestamp"`
|
|
URL string `json:"url"`
|
|
Method string `json:"method"`
|
|
Form string `json:"form"`
|
|
Payload string `json:"payload"`
|
|
Headers Headers `json:"headers"`
|
|
Type string `json:"type"`
|
|
SensorIP string `json:"honeypot"`
|
|
}
|
|
|
|
// Headers contains the filtered headers of the HTTP request
|
|
type Headers struct {
|
|
UserAgent string `json:"user_agent"`
|
|
Host string `json:"host"`
|
|
ContentType string `json:"content_type"`
|
|
AcceptLanguage string `json:"accept_language"`
|
|
}
|
|
|
|
func FakeBanner(w http.ResponseWriter, r *http.Request) {
|
|
printInfo(r)
|
|
response := fmt.Sprintf(`{
|
|
"status" : 200,
|
|
"name" : "%s",
|
|
"cluster_name" : "elasticsearch",
|
|
"version" : {
|
|
"number" : "%s",
|
|
"build_hash" : "89d3241d670db65f994242c8e838b169779e2d4",
|
|
"build_snapshot" : false,
|
|
"lucene_version" : "4.10.2"
|
|
},
|
|
"tagline" : "You Know, for Search"
|
|
}`, Conf.InstanceName, Conf.SpoofedVersion)
|
|
WriteResponse(w, response)
|
|
return
|
|
}
|
|
|
|
// FakeNodes presents a fake /_nodes result
|
|
// TODO: Change IP Address with actual server IP address
|
|
func FakeNodes(w http.ResponseWriter, r *http.Request) {
|
|
printInfo(r)
|
|
response := fmt.Sprintf(`
|
|
{
|
|
"cluster_name" : "elasticsearch",
|
|
"nodes" : {
|
|
"x1JG6g9PRHy6ClCOO2-C4g" : {
|
|
"name" : "%s",
|
|
"transport_address" : "inet[/
|
|
%s:9300]",
|
|
"host" : "elk",
|
|
"ip" : "127.0.1.1",
|
|
"version" : "%s",
|
|
"build" : "89d3241",
|
|
"http_address" : "inet[/%s:9200]",
|
|
"os" : {
|
|
"refresh_interval_in_millis" : 1000,
|
|
"available_processors" : 12,
|
|
"cpu" : {
|
|
"total_cores" : 24,
|
|
"total_sockets" : 48,
|
|
"cores_per_socket" : 2
|
|
}
|
|
},
|
|
"process" : {
|
|
"refresh_interval_in_millis" : 1000,
|
|
"id" : 2039,
|
|
"max_file_descriptors" : 65535,
|
|
"mlockall" : false
|
|
},
|
|
"jvm" : {
|
|
"version" : "1.7.0_65"
|
|
},
|
|
"network" : {
|
|
"refresh_interval_in_millis" : 5000,
|
|
"primary_interface" : {
|
|
"address" : "%s",
|
|
"name" : "eth0",
|
|
"mac_address" : "08:01:c7:3F:15:DD"
|
|
}
|
|
},
|
|
"transport" : {
|
|
"bound_address" : "inet[/0:0:0:0:0:0:0:0:9300]",
|
|
"publish_address" : "inet[/%s:9300]"
|
|
},
|
|
"http" : {
|
|
"bound_address" : "inet[/0:0:0:0:0:0:0:0:9200]",
|
|
"publish_address" : "inet[/%s:9200]",
|
|
"max_content_length_in_bytes" : 104857600
|
|
}}
|
|
}
|
|
}`, Conf.InstanceName, Conf.SensorIP, Conf.SpoofedVersion, Conf.SensorIP, Conf.SensorIP, Conf.SensorIP, Conf.SensorIP)
|
|
WriteResponse(w, response)
|
|
return
|
|
}
|
|
|
|
// FakeSearch returns fake search results
|
|
func FakeSearch(w http.ResponseWriter, r *http.Request) {
|
|
printInfo(r)
|
|
response := fmt.Sprintf(`
|
|
{
|
|
"took" : 6,
|
|
"timed_out" : false,
|
|
"_shards" : {
|
|
"total" : 6,
|
|
"successful" : 6,
|
|
"failed" : 0
|
|
},
|
|
"hits" : {
|
|
"total" : 1,
|
|
"max_score" : 1.0,
|
|
"hits" : [ {
|
|
"_index" : ".kibana",
|
|
"_type" : "index-pattern",
|
|
"_id" : "logstash-*",
|
|
"_score" : 1.0,
|
|
"_source":{"title":"logstash-*","timeFieldName":"@timestamp","customFormats":"{}","fields":"[{\"type\":\"string\",\"indexed\":true,\"analyzed\":true,\"doc_values\":false,\"name\":\"host\",\"count\":0},{\"type\":\"string\",\"indexed\":false,\"analyzed\":false,\"name\":\"_source\",\"count\":0},{\"type\":\"string\",\"indexed\":true,\"analyzed\":false,\"doc_values\":false,\"name\":\"message.raw\",\"count\":0},{\"type\":\"string\",\"indexed\":false,\"analyzed\":false,\"name\":\"_index\",\"count\":0},{\"type\":\"string\",\"indexed\":true,\"analyzed\":false,\"doc_values\":false,\"name\":\"@version\",\"count\":0},{\"type\":\"string\",\"indexed\":true,\"analyzed\":true,\"doc_values\":false,\"name\":\"message\",\"count\":0},{\"type\":\"date\",\"indexed\":true,\"analyzed\":false,\"doc_values\":false,\"name\":\"@timestamp\",\"count\":0},{\"type\":\"string\",\"indexed\":true,\"analyzed\":false,\"name\":\"_type\",\"count\":0},{\"type\":\"string\",\"indexed\":true,\"analyzed\":false,\"name\":\"_id\",\"count\":0},{\"type\":\"string\",\"indexed\":true,\"analyzed\":false,\"doc_values\":false,\"name\":\"host.raw\",\"count\":0},{\"type\":\"geo_point\",\"indexed\":true,\"analyzed\":false,\"doc_values\":false,\"name\":\"geoip.location\",\"count\":0}]"}
|
|
}]
|
|
}
|
|
}`)
|
|
WriteResponse(w, response)
|
|
return
|
|
}
|
|
|
|
func WriteResponse(w http.ResponseWriter, d string) {
|
|
w.WriteHeader(200)
|
|
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
|
w.Write([]byte(d))
|
|
return
|
|
}
|
|
|
|
func printInfo(r *http.Request) {
|
|
info := "URL:" + r.URL.String() + "&&Method:" + r.Method + "&&RemoteAddr:" + r.RemoteAddr
|
|
|
|
arr := strings.Split(r.RemoteAddr, ":")
|
|
|
|
// 判断是否为 RPC 客户端
|
|
if is.Rpc() {
|
|
go client.ReportResult("ES", "ES蜜罐", arr[0], info, "0")
|
|
} else {
|
|
go report.ReportEs("ES蜜罐", "本机", arr[0], info)
|
|
}
|
|
}
|
|
|
|
func Start(address string) {
|
|
// Create the handlers
|
|
http.HandleFunc("/", FakeBanner)
|
|
http.HandleFunc("/_nodes", FakeNodes)
|
|
http.HandleFunc("/_search", FakeSearch)
|
|
|
|
// Start the server
|
|
http.ListenAndServe(address, nil)
|
|
}
|