Skip to content

Instantly share code, notes, and snippets.

@guillermo-menjivar
Last active April 15, 2020 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guillermo-menjivar/7ea3108714e68c305af03332119aed62 to your computer and use it in GitHub Desktop.
Save guillermo-menjivar/7ea3108714e68c305af03332119aed62 to your computer and use it in GitHub Desktop.
load and search
4+ basic_file_upload.go + !/b/zsh [running] X
~/lab/analysis $ cat basic_file_upload.go
package main
import (
"bufio"
"context"
"encoding/json"
"fmt"
"net/http"
"path/filepath"
"regexp"
"time"
"github.com/gin-gonic/gin"
"github.com/olivere/elastic"
)
const (
indexName = "gnql"
)
type Event struct {
IP string `json:"ip"`
FirstSeen string `json:"first_seen"`
LastSeen string `json:"last_seen"`
Metadata struct {
Asn string `json:"asn"`
City string `json:"city"`
Country string `json:"country"`
CountryCode string `json:"country_code"`
Organization string `json:"organization"`
Rdns string `json:"rdns"`
Category string `json:"category"`
Tor bool `json:"tor"`
} `json:"metadata"`
Actor string `json:"actor"`
Tags []string `json:"tags"`
Spoofable bool `json:"spoofable"`
Classification string `json:"classification"`
Seen bool `json:"seen"`
RawData struct {
Web struct {
} `json:"web"`
Scan []struct {
Port int `json:"port"`
Protocol string `json:"protocol"`
} `json:"scan"`
} `json:"raw_data"`
}
func query(service *elastic.SearchService, ipaddrs []string) *elastic.SearchService {
q := elastic.NewBoolQuery().MinimumNumberShouldMatch(1)
for _, ip := range ipaddrs {
q = q.Should(elastic.NewMatchQuery("ip", ip))
}
//q = q.Should(elastic.NewMatchQuery("ip", "31.56.96.195"))
service = service.Query(q)
return service
}
func aggs(service *elastic.SearchService) *elastic.SearchService {
//countries
agg := elastic.NewTermsAggregation().Field("metadata.country")
service = service.Aggregation("countries", agg)
//actors
agg = elastic.NewTermsAggregation().Field("actor")
service = service.Aggregation("actors", agg)
//classifications
agg = elastic.NewTermsAggregation().Field("classification")
service = service.Aggregation("classifications", agg)
//tags
agg = elastic.NewTermsAggregation().Field("tags")
service = service.Aggregation("tags", agg)
//os
agg = elastic.NewTermsAggregation().Field("os")
service = service.Aggregation("os", agg)
return service
}
func findRecords(ctx context.Context, client *elastic.Client, ips []string) (int, error) {
search := client.Search().Index(indexName).Pretty(true)
//search = search.DocvalueFields("classification", "ip", "metadata.organization", "actor", "last_seen")
search = query(search, ips)
search = aggs(search)
sr, err := search.Do(ctx)
if err != nil {
return -1, err
}
for _, hit := range sr.Hits.Hits {
var event Event
err := json.Unmarshal(*hit.Source, &event)
if err != nil {
fmt.Println("we failed to unmarshal event")
}
fmt.Println("thise are the eventss=====")
fmt.Println("")
fmt.Println(event)
data, err := json.Marshal(event)
fmt.Println(string(data))
}
fmt.Println(sr.Hits.Hits)
// retrieve all countries aggregates
var countries map[string]int64
if agg, found := sr.Aggregations.Terms("countries"); found {
countries = make(map[string]int64)
for _, bucket := range agg.Buckets {
countries[bucket.Key.(string)] = bucket.DocCount
}
}
fmt.Println("this is the aggregates")
fmt.Println(countries)
// retreive all actors aggregates
var actors map[string]int64
if agg, found := sr.Aggregations.Terms("countries"); found {
actors = make(map[string]int64)
for _, bucket := range agg.Buckets {
actors[bucket.Key.(string)] = bucket.DocCount
}
}
fmt.Println("this is the aggregates")
fmt.Println(actors)
return 0, nil
}
func extrapulateIp(record string) []string {
ips := []string{}
engine := regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`)
if engine.MatchString(record) {
submatchall := engine.FindAllString(record, -1)
for _, ip := range submatchall {
ips = append(ips, ip)
}
}
return ips
}
func submitQueryToElastic(ips []string) {
client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"), elastic.SetSniff(false), elastic.SetHealthcheck(false))
if err != nil {
panic(err)
}
//create a dummy context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
response, err := findRecords(ctx, client, ips)
fmt.Println(response)
fmt.Println(err)
}
func main() {
router := gin.Default()
// Set a lower memory limit for multipart forms (default is 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.Static("/", "./public")
router.POST("/upload", func(c *gin.Context) {
name := c.PostForm("name")
email := c.PostForm("email")
// Source
_, h, err := c.Request.FormFile("file")
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
return
}
filename := filepath.Base(h.Filename)
raw, err := h.Open()
scanner := bufio.NewScanner(raw)
scanner.Split(bufio.ScanLines)
totalIPs := []string{}
for scanner.Scan() {
ips := extrapulateIp(scanner.Text())
totalIPs = append(totalIPs, ips...)
}
fmt.Println(totalIPs)
fmt.Println(len(totalIPs))
submitQueryToElastic(totalIPs)
if err := c.SaveUploadedFile(h, filename); err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error()))
return
}
c.String(http.StatusOK, fmt.Sprintf("File %s uploaded successfully with fields name=%s and email=%s.", h.Filename, name, email))
})
router.Run(":8080")
}
@guillermo-menjivar
Copy link
Author

this is the test file

Apr 12 07:17:55 api sshd[32449]: Received disconnect from 5.41.254.198 port 37400:11: Bye Bye [preauth]                                                                  
Apr 12 07:17:55 api sshd[32449]: Disconnected from authenticating user root 94.177.235.23 port 37400 [preauth]                                                           
Apr 12 07:18:01 api sshd[32451]: Received disconnect from 46.101.26.21 port 53732:11: Bye Bye [preauth]                                                                  
Apr 12 07:18:01 api sshd[32451]: Disconnected from authenticating user root 46.101.26.21 port 53732 [preauth]                                                            
Apr 12 07:18:30 api sshd[32453]: Received disconnect from 80.180.160.92 port 54912:11: Bye Bye [preauth]                                                                 
Apr 12 07:18:30 api sshd[32453]: Disconnected from authenticating user root 31.193.129.189 port 54912 [preauth]                                                          
Apr 12 07:27:03 api sshd[32459]: Received disconnect from 200.146.215.26 port 32360:11: Bye Bye [preauth]                                                                
Apr 12 07:27:03 api sshd[32459]: Disconnected from authenticating user root 200.146.215.26 port 32360 [preauth]                                                          
Apr 12 07:28:18 api sshd[32461]: Received disconnect from 78.178.113.148 port 36360:11: Bye Bye [preauth]                                                                
Apr 12 07:28:18 api sshd[32461]: Disconnected from authenticating user gnats 195.12.135.38 port 36360 [preauth]                                                          
Apr 12 07:31:38 api sshd[32464]: Invalid user hadoop from 121.157.82.202 port 60566                                                                                      
Apr 12 07:31:38 api sshd[32464]: Received disconnect from 80.241.255.131 port 60566:11: Bye Bye [preauth]                                                                
Apr 12 07:31:38 api sshd[32464]: Disconnected from invalid user hadoop 121.157.82.202 port 60566 [preauth]                                                               
Apr 12 07:39:03 api sshd[32518]: Connection closed by 51.38.57.78 port 42090 [preauth] 

@guillermo-menjivar
Copy link
Author

curl -F 'file=@/Users/gmo/lab/analysis/file.txt' localhost:8080/upload

@guillermo-menjivar
Copy link
Author

this is the query I want

{
	"_source": ["classification", "ip", "metadata.organization", "actor", "last_seen"],
	"query": {
		"bool": {
			"minimum_should_match": 1,
			"should": [
				{
					"match": {
						"ip": "5.125.235.56"
					}
				},
				{"match": {
					"ip": "31.56.96.195"
				}}
			]
		}
	},
	"aggs": {
		"countries": {
		"terms": {"field": "metadata.country"}
	  },
		"actors": {
			"terms": {"field": "actor"}
		},
		"classification": {
			"terms": {"field": "classification"}
		},
		"tags": {
			"terms": {"field": "tags"}
		},
		"os": {
			"terms": {"field": "metadata.os"}
		}
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment