Skip to content

Commit 69f12a0

Browse files
author
Kaizhe Huang
committed
kh: init
1 parent 418a396 commit 69f12a0

12 files changed

+196
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.swp
2+
sqlidetect
3+
.idea
4+
./container/bin/sqlidetect

Makefile

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.PHONY: all
2+
3+
all: deps test build
4+
5+
deps:
6+
@echo "+ $@"
7+
./scripts/deps
8+
test:
9+
@echo "+ $@"
10+
./scripts/test
11+
build:
12+
@echo "+ $@"
13+
./scripts/build
14+

SQLFingerPrint.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package main
2+
3+
import (
4+
"log"
5+
6+
sqlParser "github.com/youtube/vitess/go/vt/sqlparser"
7+
)
8+
9+
const (
10+
// DML is SQL DML type statement
11+
DML = iota
12+
// DDL is SQL DDL type statement
13+
DDL
14+
)
15+
16+
// SQLStatementFP is SQL Statement Fingerprint structure
17+
type SQLStatementFP struct {
18+
StatementFP string
19+
SQLType int
20+
}
21+
22+
func fingerprintSQL(matchedSQL string) SQLStatementFP {
23+
var sqlType int
24+
25+
tokens := sqlParser.NewStringTokenizer(matchedSQL)
26+
for {
27+
stmt, err := sqlParser.ParseNext(tokens)
28+
//if err == io.EOF {
29+
// break
30+
//}
31+
32+
if err == nil {
33+
buf := sqlParser.NewTrackedBuffer(nil)
34+
buf.Myprintf("%v", stmt)
35+
36+
switch stmt.(type) {
37+
case *sqlParser.Select:
38+
sqlType = DML
39+
case *sqlParser.Insert:
40+
sqlType = DML
41+
case *sqlParser.Update:
42+
sqlType = DML
43+
case *sqlParser.Delete:
44+
sqlType = DML
45+
default:
46+
sqlType = DDL // treat all non-DML sql statements as DDL for now
47+
}
48+
49+
// walk through the parsed nodes in the SQL statement and replace the value node with ?
50+
_ = sqlParser.Walk(func(node sqlParser.SQLNode) (kontinue bool, err error) {
51+
switch node := node.(type) {
52+
case *sqlParser.SQLVal:
53+
node.Val = []byte("?")
54+
}
55+
56+
return true, nil
57+
}, stmt)
58+
59+
// rest buffer to empty
60+
buf.Reset()
61+
buf.Myprintf("%v", stmt)
62+
63+
return SQLStatementFP{buf.ParsedQuery().Query, sqlType}
64+
65+
} else {
66+
log.Println("something wrong here: " + matchedSQL)
67+
break
68+
}
69+
}
70+
return SQLStatementFP{}
71+
}

build.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
docker build -t nodejs-sqldetect -f Dockerfile-web .

container/Dockerfile

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM ubuntu:latest
2+
3+
RUN apt-get update && apt-get install -y tshark net-tools sudo
4+
5+
ADD ./bin/sqlidetect /
6+
7+
ADD ./entrypoint.sh /
8+
9+
CMD ["/entrypoint.sh"]

container/entrypoint.sh

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
RET=$(ifconfig | grep docker0 | wc -l)
6+
while [ $RET -eq 0 ]
7+
do
8+
sleep 1
9+
RET=$(ifconfig | grep docker0 | wc -l)
10+
done
11+
12+
#tshark -i docker0 -Y "mysql.command==3" -T fields -e mysql.query
13+
/sqlidetect

fp_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func TestFP(t *testing.T) {
9+
stmt := "select a, b, c from table1 where a = 5 and b > 6"
10+
11+
fp := fingerprintSQL(stmt)
12+
assert.Equal(t, fp.StatementFP, "select a, b, c from table1 where a = ? and b > ?")
13+
assert.Equal(t, fp.SQLType, DML)
14+
}

main.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"io"
7+
"log"
8+
"os/exec"
9+
)
10+
11+
func main() {
12+
fmt.Println("SQLi Detector is running...")
13+
14+
pr, pw := io.Pipe()
15+
defer pw.Close()
16+
17+
// tell the command to write to our pipe
18+
cmd := exec.Command("tshark", "-i", "docker0", "-Y", "mysql.command==3", "-T", "fields", "-e", "mysql.query")
19+
cmd.Stdout = pw
20+
21+
go func() {
22+
defer pr.Close()
23+
r := bufio.NewReader(pr)
24+
for {
25+
line, _, err := r.ReadLine()
26+
// process buf
27+
if err != nil && err != io.EOF {
28+
log.Fatal(err)
29+
}
30+
// s is the sql statement passed in from tshark
31+
fp := fingerprintSQL(string(line))
32+
fmt.Println(fp.StatementFP)
33+
}
34+
35+
}()
36+
37+
// run the command, which writes all output to the PipeWriter
38+
// which then ends up in the PipeReader
39+
if err := cmd.Run(); err != nil {
40+
log.Fatal(err)
41+
}
42+
}

run.sh

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
# This is the script to run the SQLi Detector container on localhost and listen on docker0 interface
4+
5+
docker run -it --rm --net=host --cap-add=NET_ADMIN --name sqli kaizheh/sqlidetect

scripts/build

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/sh
2+
3+
set -eux
4+
5+
rm -f container/bin/sqlidetect
6+
7+
go fmt ./
8+
9+
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o container/bin/sqlidetect .
10+
11+
cd container
12+
13+
docker build -t kaizheh/sqlidetect .
14+
15+
docker push kaizheh/sqlidetect

scripts/deps

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
go get github.com/youtube/vitess/go/vt/sqlparser
4+
go get github.com/stretchr/testify/assert

scripts/test

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/bash
2+
3+
go test ./...

0 commit comments

Comments
 (0)