-
Notifications
You must be signed in to change notification settings - Fork 13
/
SMBExec.nim
88 lines (68 loc) · 2.51 KB
/
SMBExec.nim
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
import net, strutils, hashlib/rhash/md4, encodings, random
import SMBExec/[SMBv1, SMBv2, NTLM, HelpUtil, ExecStages]
type
SMB2* = ref object
socket*: Socket
target*: string
domain*: string
user*: string
hash*: string
serviceName*: string
proc recvPacketForNTLM(socket: Socket, bufSize, timeout: int): string =
var buf: string
try:
while socket.recv(buf, 1, timeout) > 0:
result.add(buf)
except:
discard
proc randomServiceName: string =
for _ in .. 5:
add(result, char(rand(int('A') .. int('Z'))))
proc newSMB2*(target: string, domain: string, user: string, hash: string, serviceName: string = ""): SMB2 =
var newServiceName = serviceName
if serviceName == "":
newServiceName = randomServiceName()
echo newServiceName
result = SMB2(socket: newSocket(), target: target, domain: domain, user: user, hash: hash, serviceName: newServiceName)
proc connect*(smb: SMB2): seq[string] =
var
recvClient: seq[string]
response: string
## Connect
smb.socket.connect(smb.target, 445.Port)
## SMBv1 Init negotiate
smb.socket.send(getSMBv1NegoPacket())
recvClient = smb.socket.recvPacket(1024, 100)
## Check Dialect
printC(Info, "Dialect: " & checkDialect recvClient)
## Check Signing
signing = checkSigning recvClient
if signing:
printC Info, "Signing Enabled"
else:
printC Info, "Signing Disabled"
## SMBv2 negotiate
smb.socket.send(getSMBv2NegoPacket())
recvClient = smb.socket.recvPacket(1024, 100)
## SMBv2NTLM negotiate
smb.socket.send(getSMBv2NTLMNego(signing))
response = smb.socket.recvPacketForNTLM(1024, 100)
## Pass the hash
let authPacket = getSMBv2NTLMAuth(getSMBv2NTLMSSP(response, smb.hash, smb.domain, smb.user, signing))
smb.socket.send(authPacket)
recvClient = smb.socket.recvPacket(1024, 100)
if checkAuth recvClient:
printC Success, "Successfully logged on!"
stage = TreeConnect
else:
printC Error, "Login failed"
stage = Exit
result = recvClient
proc exec*(smb: SMB2, command: string, recvClient: seq[string]) =
execStages(smb.target, smb.serviceName, command, smb.socket, recvClient)
proc close*(smb: SMB2) =
smb.socket.close()
proc toNTLMHash*(password: string): string =
# Counts the hash for empty string, returns a RHASH_MD4 object
var hash = count[RHASH_MD4](password.convert("UTF-16"))
return $hash