mirror of
https://github.com/yunginnanet/HellPot
synced 2024-06-24 06:48:02 +00:00
Initial working version
This commit is contained in:
parent
4dd5c27adb
commit
7997e6373e
17
README.md
17
README.md
@ -1,6 +1,15 @@
|
||||
# heffalump
|
||||
Heffalump is an endless honeypot that gives malicious bots nightmares. To use, in your robots.txt tell robots not to go to a certain URL, which heffalump is reverse proxying. Any web agent that does go to the URL will receive an endless stream of random data, which will overflow its memory and/or storage if it doesn't have a max buffer size set.
|
||||
# Heffalump
|
||||
Heffalump is an endless honeypot that gives malicious bots nightmares. To use, in your robots.txt tell robots not to go to a certain URL, which heffalump is reverse proxying. Any web agent that does go to the URL will receive an endless stream of random data, which will overflow its memory and/or storage if it doesn't have a max buffer size set or at the very least severely waste its time.
|
||||
|
||||
## Todo
|
||||
The source of the honeypot data is [Once On a Time](http://www.gutenberg.org/files/27771/27771-h/27771-h.htm), one of A. A. Milne's most beloved and most public domain works.
|
||||
|
||||
Everything. I'm starting this repo just to make myself remember the idea.
|
||||
## Usage
|
||||
Usage of heffalump:
|
||||
|
||||
heffalump [<network address> [<path>]]
|
||||
|
||||
heffalump serves an endless HTTP honeypot
|
||||
|
||||
<network address> defaults to ":8080".
|
||||
|
||||
<path> defaults to "/". Paths ending in "/" will match all sub-pathes.
|
||||
|
9
heff/http.go
Normal file
9
heff/http.go
Normal file
@ -0,0 +1,9 @@
|
||||
package heff
|
||||
|
||||
import "net/http"
|
||||
|
||||
func Honeypot(w http.ResponseWriter, r *http.Request) {
|
||||
for {
|
||||
Generate(w, 10000)
|
||||
}
|
||||
}
|
95
heff/markov.go
Normal file
95
heff/markov.go
Normal file
@ -0,0 +1,95 @@
|
||||
package heff
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// ScanHTML is a basic split function for a Scanner that returns each
|
||||
// space-separated word of text or HTML tag, with surrounding spaces deleted.
|
||||
// It will never return an empty string. The definition of space is set by
|
||||
// unicode.IsSpace.
|
||||
func ScanHTML(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
// Skip leading spaces.
|
||||
var r rune
|
||||
start := 0
|
||||
for width := 0; start < len(data); start += width {
|
||||
r, width = utf8.DecodeRune(data[start:])
|
||||
if !unicode.IsSpace(r) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if r == '<' {
|
||||
// Scan until closing bracket
|
||||
for i := start; i < len(data); i++ {
|
||||
if data[i] == '>' {
|
||||
return i + 1, data[start : i+1], nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Scan until space, marking end of word.
|
||||
for width, i := 0, start; i < len(data); i += width {
|
||||
var r rune
|
||||
r, width = utf8.DecodeRune(data[i:])
|
||||
if unicode.IsSpace(r) {
|
||||
return i + width, data[start:i], nil
|
||||
}
|
||||
if r == '<' {
|
||||
return i, data[start:i], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
|
||||
if atEOF && len(data) > start {
|
||||
return len(data), data[start:], nil
|
||||
}
|
||||
// Request more data.
|
||||
return start, nil, nil
|
||||
}
|
||||
|
||||
const (
|
||||
nprefix = 2
|
||||
nonword = "\n"
|
||||
)
|
||||
|
||||
type tokenPair [nprefix]string
|
||||
|
||||
var markov = make(map[tokenPair][]string)
|
||||
|
||||
func init() {
|
||||
var w1, w2 = nonword, nonword
|
||||
var p tokenPair
|
||||
|
||||
s := bufio.NewScanner(strings.NewReader(Src))
|
||||
s.Split(ScanHTML)
|
||||
for s.Scan() {
|
||||
t := s.Text()
|
||||
p = tokenPair{w1, w2}
|
||||
markov[p] = append(markov[p], t)
|
||||
w1, w2 = w2, t
|
||||
}
|
||||
|
||||
p = tokenPair{w1, w2}
|
||||
markov[p] = append(markov[p], nonword)
|
||||
}
|
||||
|
||||
func Generate(w io.Writer, maxgen int) {
|
||||
var w1, w2 = nonword, nonword
|
||||
|
||||
for i := 0; i < maxgen; i++ {
|
||||
p := tokenPair{w1, w2}
|
||||
suffix := markov[p]
|
||||
r := rand.Intn(len(suffix))
|
||||
t := suffix[r]
|
||||
if t == nonword {
|
||||
break
|
||||
}
|
||||
fmt.Fprint(w, t, "\n")
|
||||
w1, w2 = w2, t
|
||||
}
|
||||
}
|
11705
heff/src.go
Normal file
11705
heff/src.go
Normal file
File diff suppressed because it is too large
Load Diff
44
heffalump.go
Normal file
44
heffalump.go
Normal file
@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/carlmjohnson/heffalump/heff"
|
||||
)
|
||||
|
||||
const usage = `Usage of heffalump:
|
||||
|
||||
heffalump [<network address> [<path>]]
|
||||
|
||||
heffalump serves an endless HTTP honeypot
|
||||
|
||||
<network address> defaults to ":8080".
|
||||
|
||||
<path> defaults to "/". Paths ending in "/" will match all sub-pathes.
|
||||
`
|
||||
|
||||
func main() {
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, usage)
|
||||
}
|
||||
flag.Parse()
|
||||
|
||||
addr := flag.Arg(0)
|
||||
if addr == "" {
|
||||
addr = ":8080"
|
||||
}
|
||||
|
||||
path := flag.Arg(1)
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
|
||||
http.HandleFunc(path, heff.Honeypot)
|
||||
|
||||
log.Fatal(http.ListenAndServe(addr, nil))
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user