Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

Commit

Permalink
first commit code
Browse files Browse the repository at this point in the history
  • Loading branch information
Johan authored and Johan committed Jul 10, 2018
1 parent 8029b07 commit 87e26f2
Show file tree
Hide file tree
Showing 14 changed files with 888 additions and 5 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Expand Up @@ -2,6 +2,3 @@
*.a
*.so
.DS_Store

bin/*
pkg/*
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "src/vendor/github.com/urfave/cli"]
path = src/vendor/github.com/urfave/cli
url = https://github.com/urfave/cli.git
9 changes: 9 additions & 0 deletions Dockerfile
@@ -0,0 +1,9 @@
FROM golang:latest

ADD . $GOPATH/src/github.com/slowmist/blockchain-threat-intelligence
ENV GO15VENDOREXPERIMENT=1
RUN cd $GOPATH/src/github.com/slowmist/blockchain-threat-intelligence/src && go build -o /usr/bin/btisp-agent

EXPOSE 8545

ENTRYPOINT btisp-agent $0 $@
4 changes: 2 additions & 2 deletions README.md 100644 → 100755
Expand Up @@ -21,8 +21,8 @@ $ git clone https://github.com/slowmist/blockchain-threat-intelligence.git
```
$ cd blockchain-threat-intelligence
$ docker build --rm -t btisp-agent . //创建镜像
$ docker run -p 8545:8545 --name="btisp-agent-instance" btisp-agent //创建容器
$ docker start btisp-agent-instance --bounty 0x1234567890123456789012345678901234567800 //启动容器,并指定接收慢雾币激励的以太坊钱包地址
$ docker run -p 8545:8545 --name="btisp-agent-instance" btisp-agent --bounty 0x1234567890123456789012345678901234567800 //创建容器,并指定接收慢雾币激励的以太坊钱包地址
$ docker start btisp-agent-instance //启动容器
$ docker stop btisp-agent-instance //停止容器
$ docker rm btisp-agent-instance //删除容器
```
Expand Down
327 changes: 327 additions & 0 deletions src/etc/bindata.go

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions src/etc/rule.xml
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<rule>
<method>POST</method>
<match>eth_blockNumber</match>
<replace>{"jsonrpc":"2.0","id":%s,"result":"0x54af77"}</replace>
</rule>
<rule>
<method>POST</method>
<match>eth_accounts</match>
<replace>{"jsonrpc":"2.0","id":%s,"result":["0x7fa4cbba9a4f14040da18ffc6778c25e4cc71f39","0x568a63724670b9a475f56554d9d2e36c15bb3c5d","0xfc0fbd9a05b5bb2dfe2ed65fa1317db4f0096de3","0x3eaa9272865069233e9ae9355d7203ef61e12d45","0xc0d0ed068b74e00f9ff1a3645c2c290e3432fe53","0x683ec947d2a4039691ce7bda129706c02f3a6374"]}</replace>
</rule>
<rule>
<method>POST</method>
<match>eth_getBalance</match>
<replace>{"id":%s,"jsonrpc":"2.0","result":"0x031534c8a3397aab58"}</replace>
</rule>
<rule>
<method>POST</method>
<match>eth_sendTransaction</match>
<replace>{"jsonrpc":"2.0","id":%s,"error":{"code":-32000,"message":"account is locked"}}</replace>
</rule>
<rule>
<method>POST</method>
<match>eth_sendRawTransaction</match>
<replace>{"jsonrpc":"2.0","id":%s,"result":"0xfgggggc143b"}</replace>
</rule>
<rule>
<method>POST</method>
<match>eth_getBlockByNumber</match>
<replace>{"jsonrpc":"2.0","id":%s,"result":{"difficulty":"0x400000000","extraData":"0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa","gasLimit":"0x1388","gasUsed":"0x0","hash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","nonce":"0x0000000000000042","number":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x21c","stateRoot":"0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544","timestamp":"0x0","totalDifficulty":"0x400000000","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}}</replace>
</rule>
<rule>
<method>POST</method>
<match>net_version</match>
<replace>{"jsonrpc":"2.0","id":%s,"result":"1"}</replace>
</rule>
<rule>
<method>POST</method>
<match>0x00</match>
<replace></replace>
</rule>
<rule>
<match>rpc_modules</match>
<replace>{"jsonrpc":"2.0","id":%s,"result":{"admin":"1.0","debug":"1.0","eth":"1.0","miner":"1.0","net":"1.0","personal":"1.0","rpc":"1.0","txpool":"1.0","web3":"1.0"}}</replace>
</rule>
</resources>
20 changes: 20 additions & 0 deletions src/etc/server.crt
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDWjCCAkICCQDkgcKffToQJjANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJj
bjEPMA0GA1UECAwGZnVqaWFuMQ8wDQYDVQQHDAZ4aWFtZW4xCzAJBgNVBAoMAnNt
MQowCAYDVQQLDAF4MQowCAYDVQQDDAF4MRkwFwYJKoZIhvcNAQkBFgp4QGRlbW8u
Y29tMB4XDTE4MDYyMjA1MTAzN1oXDTI4MDYxOTA1MTAzN1owbzELMAkGA1UEBhMC
Y24xDzANBgNVBAgMBmZ1amlhbjEPMA0GA1UEBwwGeGlhbWVuMQswCQYDVQQKDAJz
bTEKMAgGA1UECwwBeDEKMAgGA1UEAwwBeDEZMBcGCSqGSIb3DQEJARYKeEBkZW1v
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs9V9d3+XwNN9IP
txm0/uMhnJYok+0BJdz0NjtdfoAhgScGZESd2PW50i8g+QuWcHNTexGRizgGD4SV
ai+DOJKsw0sBjReQE6qYnpkN1MvMSPqFh4owuCQzz9pAzpSIc3OOLfGZyDoq2MZk
oA59J8YVDj+iQ30nQnQ5URXIAkxMGvKG8o468T9sJk1fWs80k3TnA+Rm7nOLoISk
qauQdby8iXO6SpIQa0B+yp0ZBkxW4jDj6ehT0rS0HWiE5UBmtBNpsfnRqcAm9gPu
v3qHpSVH3Gy6s4O11QQwHbJGILXNZpl/UyHz/ntBbQfYQ6FFlTATKleXR3bCAAKz
4JHlU4ECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAJaQxMjTjnMvMJz0dNZZeIs8l
yy82bnWFy7kzKpBmofRNFvxoV6LuWLz9mKHIMeWGqTTmIXmMW/H0RQRC9XDaVo5A
+RGS/gl7cv02n8iT3mhPYKLiH7Bpq1Hvt3txW8j1Sp2KV/TkqQeHlsL6Kcd0B7UK
tfrvJ0av2Ubpd8sS9OgqXaKCBJUuzBgKVu8SEjBPOXvJqQjcXwBA1W2XymDQ5hJU
5hMvpd0LNl6N6LUTFbZV0ewSUSnnFdjH++DmegpZ8bAKQNQe+RHfCW8M5stRNffF
G/FhONQ3OJLWnhix3m7aFSBSU/5UPmnEJcrRbc2IsDYsshfkBC0ZxXRPLtqFNQ==
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions src/etc/server.key
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuz1X13f5fA030g+3GbT+4yGcliiT7QEl3PQ2O11+gCGBJwZk
RJ3Y9bnSLyD5C5Zwc1N7EZGLOAYPhJVqL4M4kqzDSwGNF5ATqpiemQ3Uy8xI+oWH
ijC4JDPP2kDOlIhzc44t8ZnIOirYxmSgDn0nxhUOP6JDfSdCdDlRFcgCTEwa8oby
jjrxP2wmTV9azzSTdOcD5Gbuc4ughKSpq5B1vLyJc7pKkhBrQH7KnRkGTFbiMOPp
6FPStLQdaITlQGa0E2mx+dGpwCb2A+6/eoelJUfcbLqzg7XVBDAdskYgtc1mmX9T
IfP+e0FtB9hDoUWVMBMqV5dHdsIAArPgkeVTgQIDAQABAoIBAQClr7WwhIjvfh7c
Mm3bQK+gO5j9wzCLNE3WBQCMbcJIDd3ks6I8mdVoNCPK8omO+HPPiZrIxBsG204W
C8Wn/50rJde24suAg0zz1BPb6kJYiRA3J7v1zADWgEa4okprY4eORM1hEqz80/d5
L4f26kcs4Gr4YlUIRZpnkGSxOojWC6nUv8xMHAQMMfv866m6hanitqgMMpMwh3z+
NT9y+AqOP++gOQMqgK34HklSumZE0aIOY66Xg1OKMD2Yf/c8wMdxtdJnBS/w/JDc
bL9nOzznSmB5Jz32A2/vAh036RoUl0mTmoJgs4nfy0/JTGN5uG2OEZjFsFi2RAU+
pJ2Nwn/BAoGBAOyWjzjRQ8/DvRJ3Ot93CL0HPgYSplCLCoDdoytmujNd1I+yTMLL
VyB+a/s6ew8PPC3dSBWxvfiU04XEvobEmknyzljlMDWWNgVGbcecJOt9TtKligq+
x3b6tOelu5TZ803i8Ef8KT5DThcgg9GzF0RrRwpRCAopuJbfwmPqBFH5AoGBAMqa
POAxFlSfRsZleipZfCeLWletkeFyaw3a6tBet0pa3onP3mPFT9hN6e1U+l7xiA+g
xJLBuatuko1r9krK4q8YOi3ov+rNb83riuIxxzwCREAiPcBriy6cqd15teG9qSZW
Ee7MQtFm7U2TVVMRwaNT4xbQ6oakakR/w5KaJm/JAoGAS1+AC3rn3rYec1aW5ACZ
QRegk/C3GaviUcHKrRYSNjEregg02k5L2KdOIYC1GcwhwP7haz/wJNTNOq2+gVL7
UJnRUZLatAfB+BZC/TfqrzeBuCxS+S9kfqxKnA4536c8E1E8ecKFJTfuFgIe3Nzw
ibSfslK0fABktXReCtTQQYkCgYB5QgbdR4PN8eYyJ9oOLrCYGldf0opVHF3mVPfk
7ktVPT2jzb2UiStYkolHemy/FmAQum/sRfYSHIOqEMu/x94UXbO0dnEm3v3jiO3+
ozxTNigTGmtLFxKeOzWPUKEDEriCMVFaUvZKzgeJPnz60s3KKxLnPPKg0xanGLC8
tXX7wQKBgD8k3dQWGMzR1Bh4TBT28o7gBS2ouZnZwLNh4aWm8amjlq8liWxXKQ+Q
i8PKBj5NmXhXSgELx7i2NhZauZEXAH1pkkqpUqQUvXxxDnOusCr/epVOqzT5m76/
bOMQL3Odr5iPse7ftG5aGZz6MzwDJa5jfDKV8uGOaX8lDFCRCptR
-----END RSA PRIVATE KEY-----
140 changes: 140 additions & 0 deletions src/filter/filter.go
@@ -0,0 +1,140 @@
package filter

/*
* 解析配置规则
*/

import (
"bytes"
// "encoding/hex"
"encoding/xml"
"fmt"
"github.com/slowmist/blockchain-threat-intelligence/src/etc"
// "github.com/ethereum/go-ethereum/crypto"
"github.com/slowmist/blockchain-threat-intelligence/src/logger"
"io/ioutil"
"log"
"math/rand"
"net/http"
"regexp"
"strings"
"time"
)

const (
FILTER_CONFIG_FILE = "etc/rule.xml" //配置文件
)

var (
XML_RULES, _ = ReadConfig()
)

type Resources struct {
XMLName xml.Name `xml:"resources"`
Rule []Rule `xml:"rule"`
}

type Rule struct {
Method string `xml:"method"`
Match string `xml:"match"`
Replace string `xml:"replace"`
}

var idre1 = regexp.MustCompile("id\":")
var idre2 = regexp.MustCompile(",")
var idre3 = regexp.MustCompile("}")

//生成真实以太坊地址
// func RealEthAddress() (string, error) {
// key, err := crypto.GenerateKey()
// if err != nil {
// log.Fatal(err)
// return "", err
// }
// address := crypto.PubkeyToAddress(key.PublicKey).Hex()
// privateKey := hex.EncodeToString(key.D.Bytes())

// return address, nil
// }

//生成随机以太坊地址
func GenerateEthAddress() string {
str := "0123456789abcdef"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 40; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}

return "0x" + string(result)
}

func Cutidstr(str string) string {
sstr := str[idre1.FindStringIndex(str)[1]:]
idstr := ""
if len(idre2.FindStringIndex(sstr)) > 0 {
idstr = sstr[:idre2.FindStringIndex(sstr)[0]]
} else if len(idre3.FindStringIndex(sstr)) > 0 {
idstr = sstr[:idre3.FindStringIndex(sstr)[0]]
}
return idstr
}

//根据请求特征码修改响应内容
func ModifyResponse(req *http.Request, resp *http.Response) {
//提取body req.Body是一个reader,所以只能读取一次后再赋值回
requestTextBuff, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Println("Error read buff:", err.Error())
return
}
requestText := string(requestTextBuff)
// reqestUri := req.RequestURI
// request.Body = ioutil.NopCloser(bytes.NewBufferString(requestText))
//空置时直接返回原值
idtext := ""
if len(idre1.FindString(requestText)) > 0 {
idtext = Cutidstr(requestText)
}
for _, o := range XML_RULES.Rule {
// m := o.Method
k := o.Match
v := o.Replace
var re = regexp.MustCompile(k)
if len(re.FindString(requestText)) > 0 {
v = strings.Replace(v, "0x7fa4cbba9a4f14040da18ffc6778c25e4cc71f39", GenerateEthAddress(), -1)
transresponseText := fmt.Sprintf(v, idtext) + "\n"
resp.ContentLength = int64(len(transresponseText))
newresponse := bytes.NewBufferString(transresponseText)
resp.Body = ioutil.NopCloser(newresponse)
//记录日志
_ip := req.RemoteAddr
_lg := &logger.SLOWLOG{
Ip: _ip,
RequestBody: requestText,
ReporterEthAddr: logger.BountyAddress,
Time: time.Now().Unix(),
}
_lg.Write()
log.Println("rewrite mode")
break
}
}
}

//从xml文件中读取配置
func ReadConfig() (Resources, error) {
var rs Resources
content, err := etc.Asset(FILTER_CONFIG_FILE)
if err != nil {
log.Fatal(err)
return rs, err
}
err = xml.Unmarshal(content, &rs)
if err != nil {
log.Fatal(err)
return rs, err
}
return rs, err
}
33 changes: 33 additions & 0 deletions src/filter/filter_test.go
@@ -0,0 +1,33 @@
package filter

import (
"encoding/xml"
"github.com/slowmist/blockchain-threat-intelligence/src/etc"
// "io/ioutil"
"log"
// "regexp"
"testing"
)

//测试xml文件读取
func TestReadConfig(t *testing.T) {
content, err := etc.Asset(FILTER_CONFIG_FILE)
if err != nil {
t.Errorf("xml read error %s", err.Error())
}
var rs Resources
err = xml.Unmarshal(content, &rs)
if err != nil {
t.Errorf("xml parse error %s", err.Error())
}
log.Printf("total %d rules!", len(rs.Rule))
}

//测试生成以太坊地址
func TestGenerateEthAddress(t *testing.T) {
address := GenerateEthAddress()
log.Println("Eth address:", address)
// if err != nil {
// t.Errorf("generate eth address error %s", err.Error())
// }
}
49 changes: 49 additions & 0 deletions src/logger/logger.go
@@ -0,0 +1,49 @@
package logger

/*
* 报告攻击者信息
* 1. 地址 IP 节点钱包地址
*/

import (
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"time"
)

const (
LOG_SERVER_API = "https://dl.slowmist.com/upload/honeypot"
HTTP_TIMEOUT = 30 * time.Second
)

//奖励地址
var BountyAddress string

//日志结构
type SLOWLOG struct {
Ip string `json:"ip"`
RequestBody string `json:"body"`
ReporterEthAddr string `json:"bounty"`
Time int64 `json:"time"`
}

//记录攻击者
func (s *SLOWLOG) Write() {
_js, _ := json.Marshal(s)
go s.AsyncSend(_js)
}

func (s *SLOWLOG) AsyncSend(body []byte) {
str := string(body)
log.Println(str)
resp, err := http.Post(LOG_SERVER_API,
"application/x-www-form-urlencoded",
strings.NewReader(str))
defer resp.Body.Close()
if err != nil {
fmt.Println(err)
}
}
26 changes: 26 additions & 0 deletions src/logger/logger_test.go
@@ -0,0 +1,26 @@
package logger

import (
"io/ioutil"
"log"
"net/http"
"strings"
"testing"
)

//测试接口
func TestAPI(t *testing.T) {
log.Println(BountyAddress)
str := ""
resp, err := http.Post(LOG_SERVER_API,
"application/x-www-form-urlencoded",
strings.NewReader(str))
defer resp.Body.Close()
if err != nil {
t.Errorf("log api error %s", err.Error())
return
}
body, _ := ioutil.ReadAll(resp.Body)
log.Printf("HTTP CODE: %d", resp.StatusCode)
log.Println(string(body))
}

0 comments on commit 87e26f2

Please sign in to comment.