2008-09-15 18:50:34 +00:00
|
|
|
##
|
2017-07-24 13:26:21 +00:00
|
|
|
# This module requires Metasploit: https://metasploit.com/download
|
2013-10-15 18:50:46 +00:00
|
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
2008-09-15 18:50:34 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
require 'metasm'
|
|
|
|
|
2016-03-08 13:02:44 +00:00
|
|
|
class MetasploitModule < Msf::Encoder::Xor
|
2008-09-15 18:50:34 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
def initialize
|
|
|
|
super(
|
|
|
|
'Name' => 'XOR Encoder',
|
|
|
|
'Description' => %q{
|
|
|
|
Mips Web server exploit friendly xor encoder
|
|
|
|
},
|
2018-12-18 13:35:16 +00:00
|
|
|
'Author' =>
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
[ 'Julien Tinnes <julien[at]cr0.org>', # original shellcode
|
|
|
|
'Pedro Ribeiro <pedrib@gmail.com>', # fix Linux >= 2.6.11 and toupper() compat
|
|
|
|
],
|
2013-08-30 21:28:54 +00:00
|
|
|
'Arch' => ARCH_MIPSBE,
|
|
|
|
'License' => MSF_LICENSE,
|
|
|
|
'Decoder' =>
|
|
|
|
{
|
|
|
|
'KeySize' => 4,
|
|
|
|
'BlockSize' => 4,
|
|
|
|
'KeyPack' => 'N',
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Returns the decoder stub that is adjusted for the size of the buffer
|
|
|
|
# being encoded.
|
|
|
|
#
|
|
|
|
def decoder_stub(state)
|
|
|
|
|
|
|
|
# add one xor operation for the key (see comment below)
|
|
|
|
number_of_passes=state.buf.length/4+1
|
2015-05-18 20:36:15 +00:00
|
|
|
raise EncodingError.new("The payload being encoded is too long (#{state.buf.length} bytes)") if number_of_passes > 10240
|
|
|
|
raise EncodingError.new("The payload is not padded to 4-bytes (#{state.buf.length} bytes)") if state.buf.length%4 != 0
|
2013-08-30 21:28:54 +00:00
|
|
|
|
|
|
|
# 16-bits not (again, see below)
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
reg_10 = (number_of_passes+1)^0xFFFF
|
|
|
|
reg_5 = state.buf.length^0xFFFF
|
2013-08-30 21:28:54 +00:00
|
|
|
decoder = Metasm::Shellcode.assemble(Metasm::MIPS.new(:big), <<EOS).encoded.data
|
2008-09-15 18:50:34 +00:00
|
|
|
;
|
|
|
|
; MIPS nul-free xor decoder
|
|
|
|
;
|
|
|
|
; (C) 2006 Julien TINNES
|
|
|
|
; <julien at cr0.org>
|
|
|
|
;
|
|
|
|
; The first four bytes in encoded shellcode must be the xor key
|
|
|
|
; This means that you have to put the xor key right after
|
|
|
|
; this xor decoder
|
|
|
|
; This key will be considered part of the encoded shellcode
|
|
|
|
; by this decoder and will be xored, thus becoming 4NULs, meaning nop
|
|
|
|
;
|
|
|
|
; This is Linux-only because I use the cacheflush system call
|
|
|
|
;
|
|
|
|
; You can use shellforge to assemble this, but be sure to discard all
|
|
|
|
; the nul bytes at the end (everything after x01\\x4a\\x54\\x0c)
|
|
|
|
;
|
|
|
|
; change 2 bytes in the first instruction's opcode with the number of passes
|
|
|
|
; the number of passes is the number of xor operations to apply, which should be
|
|
|
|
; 1 (for the key) + the number of 4-bytes words you have in your shellcode
|
|
|
|
; you must encode ~(number_of_passes + 1) (to ensure that you're nul-free)
|
|
|
|
|
|
|
|
|
|
|
|
;.text
|
|
|
|
;.align 2
|
|
|
|
;.globl main
|
|
|
|
;.ent main
|
|
|
|
;.type main,@function
|
|
|
|
|
|
|
|
main:
|
|
|
|
|
|
|
|
li macro reg, imm
|
|
|
|
; lui reg, ((imm) >> 16) & 0ffffh
|
|
|
|
; ori reg, reg, (imm) & 0ffffh
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
addiu reg, $0, imm ; sufficient if imm.abs <= 0x7fff
|
2008-09-15 18:50:34 +00:00
|
|
|
endm
|
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
li( $10, #{reg_10}) ; load number of passes ^ 0xffff
|
2018-12-18 13:35:16 +00:00
|
|
|
nor $10, $10, $0 ; put number of passes in $10
|
2008-09-15 18:50:34 +00:00
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
li( $11,-89) ; addend to calculated PC is 73
|
2008-09-15 18:50:34 +00:00
|
|
|
;.set noreorder
|
|
|
|
next:
|
2013-08-30 21:28:54 +00:00
|
|
|
bltzal $8, next
|
2008-09-15 18:50:34 +00:00
|
|
|
;.set reorder
|
2013-08-30 21:28:54 +00:00
|
|
|
slti $8, $0, 0x8282
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
nor $11, $11, $0 ; addend in $9
|
|
|
|
addu $25, $31, $11 ; $25 points to encoded shellcode +4
|
|
|
|
addu $16, $31, $11 ; $16 too (used to set up the cacheflush() arg down below)
|
2008-09-15 18:50:34 +00:00
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
; lui $2, 0xDDDD ; first part of the xor (old method)
|
|
|
|
slti $23, $0, 0x8282 ; store 0 in $23 (our counter)
|
|
|
|
; ori $17, $2, 0xDDDD ; second part of the xor (old method)
|
|
|
|
lw $17, -4($25) ; load xor key in $17
|
2008-09-15 18:50:34 +00:00
|
|
|
|
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
li( $9, -5)
|
|
|
|
nor $9, $9, $0 ; 4 in $9
|
2008-09-15 18:50:34 +00:00
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
addi $15, $9, -3 ; 1 in $15
|
2008-09-15 18:50:34 +00:00
|
|
|
loop:
|
2013-08-30 21:28:54 +00:00
|
|
|
lw $8, -4($25)
|
2008-09-15 18:50:34 +00:00
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
addu $23, $23, $15 ; increment counter
|
2013-08-30 21:28:54 +00:00
|
|
|
xor $3, $8, $17
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
sltu $30, $23, $10 ; enough loops?
|
2013-08-30 21:28:54 +00:00
|
|
|
sw $3, -4($25)
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
addi $6, $9, -1 ; 3 in $6 (for cacheflush)
|
2013-08-30 21:28:54 +00:00
|
|
|
bne $0, $30, loop
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
addu $25, $25, $9 ; next instruction to decode :)
|
2008-09-15 18:50:34 +00:00
|
|
|
|
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
addiu $4, $16, -4 ; cacheflush() addr parameter
|
|
|
|
li( $10,#{reg_5}) ; cacheflush() nbytes parameter
|
|
|
|
nor $5, $10, $0 ; same as above
|
|
|
|
; li $6,3 ; $6 is set above, 3rd arg for cacheflush()
|
2008-09-15 18:50:34 +00:00
|
|
|
|
|
|
|
; .set noreorder
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
li( $2, 4147) ; cacheflush
|
|
|
|
; .ascii "\\x01JT\\x0c" ; nul-free syscall
|
2013-08-30 21:28:54 +00:00
|
|
|
syscall 0x52950
|
2008-09-15 18:50:34 +00:00
|
|
|
; .set reorder
|
|
|
|
|
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
; write last decoder opcode and decoded shellcode
|
|
|
|
; li $4,1 ; stdout
|
2008-09-15 18:50:34 +00:00
|
|
|
; addi $5, $16, -8
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
; li $6,40 ; how much to write
|
2008-09-15 18:50:34 +00:00
|
|
|
; .set noreorder
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
; li $2, 4004 ; write
|
2008-09-15 18:50:34 +00:00
|
|
|
; syscall
|
|
|
|
; .set reorder
|
2010-04-30 08:40:19 +00:00
|
|
|
|
2008-09-15 18:50:34 +00:00
|
|
|
|
Make longxor encoder great again
The longxor encoder for mipsbe does not work correctly. At the end of the decoding, it should invoke cacheflush() with the correct parameters:
int cacheflush(char *addr, int nbytes, int cache)
The encoder previously did not setup the arguments, as it even said so in the comments:
; addiu $4, $16, -4 ; not checked by Linux
; li $5,40 ; not checked by Linux
; li $6,3 ; $6 is set above
I think this is because the encoder is pretty old (2008), and before kernel 2.6.11, cacheflush() did not need any parameters (from the cacheflush man page):
BUGS
Linux kernels older than version 2.6.11 ignore the addr and nbytes arguments, making this function fairly expensive. Therefore, the
whole cache is always flushed.
This commit fixes that by setting up the parameters correctly. As an unfortunate side effect this increases the shellcode by 16 bytes, but it is absolutely necessary for it to work properly.
Note that this bug is not present when testing the encoder output on an emulator like qemu; emulators do not need to flush the caches to work properly.
As an added bonus I have also made it compatible with toupper() restrictions, which is common in web server exploits too. This did not add any extra bytes to the encoder.
2018-12-18 12:30:55 +00:00
|
|
|
nop ; encoded shellcoded must be here (xor key right here ;)
|
2008-09-15 18:50:34 +00:00
|
|
|
; $t9 (aka $25) points here
|
|
|
|
|
|
|
|
EOS
|
2013-08-30 21:28:54 +00:00
|
|
|
# put the key at the end of the decoder
|
|
|
|
state.decoder_key_offset = decoder.length - 4
|
2008-09-15 18:50:34 +00:00
|
|
|
|
2013-08-30 21:28:54 +00:00
|
|
|
return decoder
|
|
|
|
end
|
2010-04-30 08:40:19 +00:00
|
|
|
end
|