-
Notifications
You must be signed in to change notification settings - Fork 0
/
MS12-020.go
136 lines (120 loc) · 3.44 KB
/
MS12-020.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
package rdp
import (
"encoding/binary"
"fmt"
"net"
)
var connection_request = []byte{
0x03, 0x00, // TPKT Header version 03, reserved 0
0x00, 0x0b, // Length
0x06, // X.224 Data TPDU length
0xe0, // X.224 Type (Connection request)
0x00, 0x00, // dst reference
0x00, 0x00, // src reference
0x00, // class and options
}
var connectInitial = []byte{
0x03, 0x00, 0x00, 0x65, // TPKT Header
0x02, 0xf0, 0x80, // Data TPDU, EOT
0x7f, 0x65, 0x5b, // Connect-Initial
0x04, 0x01, 0x01, // callingDomainSelector
0x04, 0x01, 0x01, // callingDomainSelector
0x01, 0x01, 0xff, // upwardFlag
0x30, 0x19, // targetParams + size
0x02, 0x01, 0x22, // maxChannelIds
0x02, 0x01, 0x20, // maxUserIds
0x02, 0x01, 0x00, // maxTokenIds
0x02, 0x01, 0x01, // numPriorities
0x02, 0x01, 0x00, // minThroughput
0x02, 0x01, 0x01, // maxHeight
0x02, 0x02, 0xff, 0xff, // maxMCSPDUSize
0x02, 0x01, 0x02, // protocolVersion
0x30, 0x18, // minParams + size
0x02, 0x01, 0x01, // maxChannelIds
0x02, 0x01, 0x01, // maxUserIds
0x02, 0x01, 0x01, // maxTokenIds
0x02, 0x01, 0x01, // numPriorities
0x02, 0x01, 0x00, // minThroughput
0x02, 0x01, 0x01, // maxHeight
0x02, 0x01, 0xff, // maxMCSPDUSize
0x02, 0x01, 0x02, // protocolVersion
0x30, 0x19, // maxParams + size
0x02, 0x01, 0xff, // maxChannelIds
0x02, 0x01, 0xff, // maxUserIds
0x02, 0x01, 0xff, // maxTokenIds
0x02, 0x01, 0x01, // numPriorities
0x02, 0x01, 0x00, // minThroughput
0x02, 0x01, 0x01, // maxHeight
0x02, 0x02, 0xff, 0xff, // maxMCSPDUSize
0x02, 0x01, 0x02, // protocolVersion
0x04, 0x00, // userData
}
var userRequest = []byte{
0x03, 0x00, // header
0x00, 0x08, // length
0x02, 0xf0, 0x80, // X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission)
0x28, // PER encoded PDU contents
}
var channelRequest = []byte{
0x03, 0x00, 0x00, 0x0c,
0x02, 0xf0, 0x80, 0x38,
}
func checkRDPVuln(ip string, port int) bool {
// rdp除了最早期的RDP标志位以外,其他的版本默认都会走tls,默认情况下,Windows自带的远程桌面服务里面自动生成的证书,名称对应的就是主机名
//所以这里的dialTCP是会不行的,对于后期的机器
// 建立 TCP 连接
sock, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: net.ParseIP(ip), Port: port})
if err != nil {
fmt.Println("Failed to connect to the target:", err)
return false
}
defer sock.Close()
sock.Write(connection_request)
res := make([]byte, 1024)
_, err = sock.Read(res)
if err != nil {
fmt.Println(err)
return false
}
sock.Write(connectInitial)
// Send userRequest
sock.Write(userRequest)
_, err = sock.Read(res)
if err != nil {
fmt.Println(err)
return false
}
user1 := binary.BigEndian.Uint16(res[9:11])
//chan1 := user1 + 1001
// Send second userRequest
sock.Write(userRequest)
_, err = sock.Read(res)
if err != nil {
fmt.Println(1)
return false
}
user2 := binary.BigEndian.Uint16(res[9:11])
chan2 := user2 + 1001
// Send channel request one
sock.Write(append(channelRequest, uint16ToBytes(user1, chan2)...))
_, err = sock.Read(res)
if err != nil {
fmt.Println(2)
return false
}
if res[7] == 0x3e && res[8] == 0x00 {
// Send ChannelRequestTwo - prevent BSoD
//sock.Write(append(channelRequest, uint16ToBytes(user2, chan2)...))
return true
} else {
fmt.Println(3)
return false
}
}
func uint16ToBytes(nums ...uint16) []byte {
b := make([]byte, len(nums)*2)
for i, num := range nums {
binary.BigEndian.PutUint16(b[i*2:], num)
}
return b
}