“Write” Disposition Permissions of a File FILE_WRITE_DATA Depending on file, possible elevation of privilege.. FILE_APPEND_DATA Depending on file, possible elevation of privilege.. WRITE
Trang 1First, the attackers copy their attack DLL into the directory where the tool will be run.Remember that these attackers have been granted FILE_ADD_FILE The attack.dll iscoded to do bad stuff in DllMain and then return execution back to the real DLL Nextthe attackers create a new file in this directory called [program-name].exe.manifest Inthis example, the attacker’s file will be accesschk.exe.manifest
C:\tools>type accesschk.exe.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
Microsoft (R) Windows Debugger Version 6.5.0003.7
Copyright (c) Microsoft Corporation All rights reserved.
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e70000 77f01000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll
Bingo! Our attack DLL (renamed to user32.dll) was loaded by accesschk.exe
Trang 2Attacking Weak File DACLs
File DACL attacks are similar to directory DACL attacks The focus is finding files
writable by untrusted or semi-trusted users and used by a higher-privileged entity Some
of the directory DACL attacks could be classified as file DACL attacks but we’ve chosen to
call attacks that add a file “directory DACL attacks” and attacks that tamper with an
exist-ing file “file DACL attacks.”
Enumerating Interesting Files’ DACLs
We can again use accesschk.exe to enumerate DACLs There are several interesting
attacks involving tampering with existing files
Write to executables or executable equivalent files (EXE, DLL, HTA,
BAT, CMD). Cases of vulnerable executables can be found fairly easily by scanning
with a similar AccessChk command as that used for directories
C:\tools>accesschk.exe -w -q -s users c:\ > weak-dacl-files.txt
When this command finishes, look for files ending in exe, dll, hta, bat, cmd, and
other equivalent files Here are some interesting results potentially vulnerable to
We know that FILE_ADD_FILE means we could launch directory attacks here (FILE_
ADD_FILE granted to Users on a directory inside %ProgramFiles% is bad news.)
How-ever, let’s think specifically about the file tampering and executable replacement attacks
Notice that FILE_DELETE_CHILD is not present in this directory DACL, so the directory
433
Trang 3DACL itself does not grant access to directly delete a file and replace it with an exe of ourown Let’s take a look at one of the file DACLs.
C:\Program Files\CA\SharedComponents\ScanEngine\Inocmd32.exe
RW BUILTIN\Users
FILE_ADD_FILE FILE_ADD_SUBDIRECTORY FILE_APPEND_DATA FILE_EXECUTE FILE_LIST_DIRECTORY FILE_READ_ATTRIBUTES FILE_READ_DATA FILE_READ_EA FILE_TRAVERSE FILE_WRITE_ATTRIBUTES FILE_WRITE_DATA FILE_WRITE_EA SYNCHRONIZE READ_CONTROLDELETE is not granted on the file DACL either So we can’t technically delete the exeand replace it with one of our own, but watch this:
C:\Program Files\CA\SharedComponents\ScanEngine>copy Inocmd32.exe inocmd32_ bak.exe
1 file(s) copied.
C:\Program Files\CA\SharedComponents\ScanEngine>echo hi > inocmd32.exe
C:\Program Files\CA\SharedComponents\ScanEngine>copy inocmd32_bak.exe
RW C:\Program Files\CA\SharedComponents\ScanEngine\Inodist.ini
FILE_ADD_FILE FILE_ADD_SUBDIRECTORY FILE_APPEND_DATA FILE_EXECUTE FILE_LIST_DIRECTORY FILE_READ_ATTRIBUTES FILE_READ_DATA FILE_READ_EA FILE_TRAVERSE434
Trang 4FILE_WRITE_EA
SYNCHRONIZE
READ_CONTROL
Writable configuration files are a fantastic source of privilege elevation Without
more investigation into how eTrust works, we can’t say for sure, but it’s likely that
con-trol over a scan engine initialization file could lead to privilege elevation Sometimes
you can even leverage only FILE_APPEND_DATA to add content that is run by the
appli-cation on its next start
TIP Remember that notepad.exe and common editing applications will
attempt to open for Generic Read If you have been granted FILE_APPEND_
DATA and the AccessCheck function returns “access denied” with the testing
tool you’re using, take a closer look at the passed-in desiredAccess
Tamper with data files to attack the data parser. The other files that
jumped out to me in this weak DACL list were the following:
RW c:\Program Files\CA\eTrust Antivirus\00000001.QSD
RW c:\Program Files\CA\eTrust Antivirus\00000002.QSD
RW c:\Program Files\CA\eTrust Antivirus\DB\evmaster.dbf
RW c:\Program Files\CA\eTrust Antivirus\DB\evmaster.ntx
RW c:\Program Files\CA\eTrust Antivirus\DB\rtmaster.dbf
RW c:\Program Files\CA\eTrust Antivirus\DB\rtmaster.ntx
We don’t know much about how eTrust works but these look like proprietary
signa-ture files of some type that are almost surely consumed by a parser running at a high
privilege level Unless the vendor is particularly cautious about security, it’s likely that
their trusted signature or proprietary database files have not been thoroughly tested
with a good file fuzzer If we were able to use Process Monitor or FileMon to find a
repeatable situation where these files are consumed, chances are good that we could
find vulnerabilities with a common file fuzzer Always be on the lookout for writable
data files that look to be a proprietary file format and are consumed by a parser running
with elevated privileges
“Write” Disposition Permissions of a File
FILE_WRITE_DATA Depending on file, possible elevation of privilege Allows an attacker
to overwrite file contents
FILE_APPEND_DATA Depending on file, possible elevation of privilege Allows an attacker
to append arbitrary content to the end of a file
WRITE_DAC Depending on file, possible elevation of privilege Allows attackers to
rewrite the DACL, granting themselves any file privilege
435
Trang 5WRITE_OWNER Depending on file, possible elevation of privilege Allows attacker to
become the object owner Object ownership implies WRITE_DAC.WRITE_DAC allows attacker to rewrite the DACL, granting any fileprivilege
GENERIC_WRITE Depending on file, possible elevation of privilege Grants FILE_
WRITE_DATA
GENERIC_ALL Depending on file, possible elevation of privilege Grants FILE_
WRITE_DATA
DELETE Depending on file, possible elevation of privilege Allows attackers to
delete and potentially replace the file with one of their choosing
“Read” Disposition Permissions of a File
FILE_READ_DATA Depending on the file, possible information disclosure Allows
attacker to view contents of the file
FILE_READ_ATTRIBUTES
FILE_READ_EA
Depending on the directory, possible information disclosure.These rights grant access to the metadata of the file Filenamescould contain sensitive info such as “layoff plan.eml” or “plan tosell company to google.doc.” An attacker might also find bits ofinformation like usernames usable in a multistage attack
GENERIC_READ Depending on the file, possible information disclosure This right
grants FILE_READ_DATA, FILE_READ_ATTRIBUTES, and FILE_READ_EA
There are lots of scenarios where read access should not be granted to unprivilegedattackers It might allow them to read (for example):
• User’s private data (user’s browser history, favorites, mail)
• Config files (might leak paths, configurations, passwords)
• Log data (might leak other users and their behaviors)
eTrust appears to store data in a logfile readable by all users Even if attackers couldnot write to these files, they might want to know which attacks were detected by eTrust
so they could hide their tracks
Attacking Weak File DACLs for Privilege Escalation
An attack was already demonstrated earlier in the enumeration section To recap, theprimary privilege escalation attacks against files are
• Write to executables or executable equivalent files (EXE, DLL, HTA, BAT, CMD)
• Tamper with configuration files
• Tamper with data files to attack the data parser
436
Trang 6What Other Object Types Are out There?
Services, registry keys, files, and directories are the big four object types that will expose
code execution vulnerabilities However, several more object types might be poorly
ACL’d Nothing is going to be as easy and shellcode-free as the objects listed already in
this chapter The remaining object types will expose code execution vulnerabilities but
you’ll probably need to write “real” exploits to leverage those vulnerabilities Having
said that, let’s briefly talk through how to enumerate each one
Enumerating Shared Memory Sections
Shared memory sections are blocks of memory set aside to be shared between two
appli-cations This is an especially handy way to share data between a kernel mode and user
mode process Programmers have historically considered this trusted, private data but a
closer look at these object DACLs shows that untrusted or semi-trusted users can write to
them
AccessChk could dump all objects in the object manager namespace but could not
yet filter by type at the time of this writing So here’s the easiest way to find all the shared
memory sections:
accesschk.exe -osv > allobjects.txt
Inside the output file, you can inspect each shared section by searching for “Type:
Section” Here’s an example:
It’s almost never a good idea to grant write access to the Everyone group but it would
take focused investigation time to determine if this shared section could hold up under
malicious input from an untrusted user An attacker might also want to check what type
of data is available to be read in this memory section
If you see a shared section having a NULL DACL, that is almost surely a security
vul-nerability For example, I just stumbled across this one on my laptop while doing
research for this chapter:
\BaseNamedObjects\INOQSIQSYSINFO
Type: Section
RW Everyone
SECTION_ALL_ACCESS
The first search engine link for information about INOQSIQSYSINFO was a recent
security advisory about how to supply malicious content to this memory section to
cause a stack overflow in the eTrust antivirus engine If there were no elevation of
privi-lege threat already, remember that SECTION_ALL_ACCESS includes WRITE_DAC,
437
Trang 7which would allow anyone in the Everyone group to change the DACL, locking out everyone else This would likely cause a denial of service in the AV product
Reference
INOQSIQSYSINFO exploit www.milw0rm.com/exploits/3897
Enumerating Named Pipes
Named pipes are similar to shared sections in that developers incorrectly used to think named pipes accepted only trusted, well-formed data The elevation of privilege threat with weakly ACL’d named pipes again is to write to the pipe to cause parsing or logic flaws that result in elevation of privilege Attackers also might find information dis-closed from the pipe that they wouldn’t otherwise be able to access
AccessChk does not appear to support named pipes natively, but SysInternals did cre-ate a tool specifically to enumercre-ate named pipes Here’s the output from PipeList.exe: PipeList v1.01
by Mark Russinovich
http://www.sysinternals.com
Pipe Name Instances Max Instances
- -
-TerminalServer\AutoReconnect 1 1
InitShutdown 2 -1
lsass 3 -1
protected_storage 2 -1
SfcApi 2 -1
ntsvcs 6 -1
scerpc 2 -1
net\NtControlPipe1 1 1
net\NtControlPipe2 1 1
net\NtControlPipe3 1 1
PipeList does not display the DACL of the pipe but BindView (recently acquired by Symantec) has built a free tool called pipeacl.exe It offers two run options—command-line dumping the raw ACEs, or a GUI with a similar permissions display as the Windows Explorer users Here’s the command-line option:
C:\tools>pipeacl.exe \??\Pipe\lsass
Revision: 1
Reserved: 0
Control : 8004
Owner: BUILTIN\Administrators (S-1-5-32-544)
Group: SYSTEM (S-1-5-18)
Sacl: Not present
Dacl: 3 aces
(A) (00) 0012019b : Everyone (S-1-1-0)
(A) (00) 0012019b : Anonymous (S-1-5-7)
(A) (00) 001f01ff : BUILTIN\Administrators (S-1-5-32-544)
The Process Explorer GUI will also display the security descriptor for named pipes 438
Trang 8References
PipeList download location http://download.sysinternals.com/Files/PipeList.zip
PipeACL download location www.bindview.com/Services/RAZOR/Utilities/Windows/
pipeacltools1_0.cfm
Enumerating Processes
Sometimes processes apply a custom security descriptor and get it wrong If you find a
process or thread granting write access to an untrusted or semi-trusted user, an attacker
can inject shellcode directly into the process or thread Or an attacker might choose to
simply commandeer one of the file handles that was opened by the process or thread to
gain access to a file they wouldn’t normally be able to access Weak DACLs enable many
different possibilities AccessChk is your tool to enumerate process DACLs
Cesar Cerrudo, an Argentinean pen-tester who focuses on Windows Access Control,
recently released a “Practical 10 minutes security audit” guide with one of the examples
being a NULL DACL on an Oracle process allowing code injection You can find a link to
it in the “Reference” section
Reference
Practical 10 minutes security audit Oracle case www.argeniss.com/research/
10MinSecAudit.zip
Enumerating Other Named Kernel Objects
(Semaphores, Mutexes, Events, Devices)
While there might not be an elevation of privilege opportunity in tampering with other
kernel objects, an attacker could very likely induce a denial-of-service condition if
Trang 9is used and what functions rely on this event not being tampered with And ProcessExplorer tells us that {69364682-1744-4315-AE65-18C5741B3F04} is a mutex owned
by Internet Explorer Would an untrusted user leveraging MUTANT_ALL_ACCESS ->WRITE_DAC -> “deny all” cause an Internet Explorer denial of service? There’s an easyway to find out! Another GUI SysInternals tool called WinObj allows you to changemutex security descriptors
Windows Access Control is a fun field to study because there is so much more tolearn! We hope this chapter whets your appetite to research access control topics Alongthe way, you’re bound to find some great security vulnerabilities
References
www.grayhathackingbook.com
WinObj download www.microsoft.com/technet/sysinternals/SystemInformation/
WinObj.mspx
Trang 10In Chapter 14, we have covered basic fuzzing The problem with basic fuzzing is that you
often only scratch the surface of a server’s interfaces and rarely get deep inside the server
to find bugs Most real servers have several layers of filters and challenge/response
mech-anisms that prevent basic fuzzers from getting very far Recently, a new type of fuzzing
has arrived called intelligent fuzzing Instead of blindly throwing everything but the
kitchen sink at a program, techniques have been developed to analyze how a server
works and to customize a fuzzer to get past the filters and reach deeper inside the server
to discover even more vulnerabilities To do this effectively, you need more than a fuzzer
First, you will need to conduct a protocol analysis of the target Next, you need a way to
fuzz that protocol and get feedback from the target as to how you are doing As we will
see, the Sulley fuzzing framework automates this process and allows you to intelligently
sling packets across the network
Protocol Analysis
Since most servers perform a routine task and need to interoperate with random clients
and other servers, most servers are based on some sort of standard protocol The Internet
Engineering Task Force (IETF) maintains the set of protocols that form the Internet as we
know it So the best way to find out how a server, for example, a LPR server, operates is to
look up the Request for Comments (RFC) document for the LPR protocol, which can be
found on www.ietf.org as RFC 1179
Trang 11Here is an excerpt from the RFC 1179 (see reference: www.ietf.org/rfc/rfc1179.txt):
"3.1 Message formats
LPR is a a TCP-based protocol The port on which a line printer
daemon listens is 515 The source port must be in the range 721 to
731, inclusive A line printer daemon responds to commands sent to
its port All commands begin with a single octet code, which is a
binary number which represents the requested function The code is
immediately followed by the ASCII name of the printer queue name on
which the function is to be performed If there are other operands
to the command, they are separated from the printer queue name with
white space (ASCII space, horizontal tab, vertical tab, and form
feed) The end of the command is indicated with an ASCII line feed
character."
NOTE As we can see in the preceding excerpt, the RFC calls for the sourceport to be in the range 721–731 inclusive This could be really important Ifthe target LPR daemon conformed to the standard; it would reject all requeststhat were outside this source port range The target we are using (NIPRINT3)does not conform to this standard If it did, no problem, we would have to ensure we sentpackets in that source port range
And further down in the RFC, you will see diagrams of LPR daemon commands:Source: http://www.ietf.org/rfc/rfc1179.txt
5.1 01 - Print any waiting jobs
+ + -+ +
| 01 | Queue | LF | + + -+ +
Command code - 1 Operand - Printer queue name This command starts the printing process if it not already running.
5.2 02 - Receive a printer job
+ + -+ +
| 02 | Queue | LF | + + -+ +
Command code - 2 Operand - Printer queue name Receiving a job is controlled by a second level of commands The
daemon is given commands by sending them over the same connection.
The commands are described in the next section (6).
After this command is sent, the client must read an acknowledgement
octet from the daemon A positive acknowledgement is an octet of
zero bits A negative acknowledgement is an octet of any other
pattern.
And so on…
442
Trang 12From this, we can see the format of commands the LPR daemon will accept We know
the first octet (byte) gives the command code Next comes the printer queue name,
fol-lowed by an ASCII line feed (LF) command (“\n”)
As we can see in the preceding, the command code of “\x02” tells the LPR daemon to
“receive a printer job.” At that point, the LPR daemon expects a series of subcommands,
which are defined in section (6) of the RFC
This level of knowledge is important, as now we know that if we want to fuzz deep
inside a LPR daemon, we must use this format with proper command codes and syntax
For example, when the LPR daemon receives a command to “receive a printer job,” it
opens up access to a deeper section of code as the daemon accepts and processes that
printer job
We have learned quite a bit about our target daemon that will be used throughout the
rest of this chapter As you have seen, the RFC is invaluable to understanding a protocol
and allows you to know your target
Reference
RFC for LPR protocol www.ietf.org/rfc/rfc1179.txt
Sulley Fuzzing Framework
Pedram Amini has done it again! He has brought us Sulley, the newest fuzzing
frame-work as of the writing of this book Sulley gets its name from the fuzzy character in the
movie Monsters Inc This tool is truly revolutionary in that it provides not only a great
fuzzer and debugger, but also the infrastructure to manage a fuzzing session and
con-duct postmortem analysis
Installing Sulley
Download the latest version of Sulley from www.fuzzing.org Install the Sulley program to
a folder in the path of both your host machine and your virtual machine target This is best
done by establishing a shared folder within the target virtual machine and pointing it to
the same directory in which you installed Sulley on the host To make things even easier,
you can map the shared folder to a drive letter from within your target virtual machine
Powerful Fuzzer
You will find that Sulley is a nimble yet very powerful fuzzer based on Dave Aitel’s
block-based fuzzing approach In fact, if you know Dave’s SPIKE fuzzing tool, you will find
yourself at home with Sulley Sulley organizes the fuzzing data into requests As we will
see later, you can have multiple requests and link them together into what is called a
ses-sion You can start a request by using the s_initialize function, for example:
Trang 13Primitives
Now that we have a request initialized, let’s build on that by adding primitives, the building
blocks of fuzzing We will start out simple and build up to more complex fuzzing structures
When you want to request a fixed set of data that is static, you can use the s_static function.
Syntax:
s_static("default value", <name>, <fuzzable>, <num_mutations>)
NOTE As with the other functions of this section, the required argumentsare shown in quotes and the optional arguments are shown in angle brackets
All of these provide the same thing, a static string “hello haxor” that will not be fuzzed
Using Binary Values
With Sulley it is easy to represent binary values in many formats using the s_binary
primitive
Syntax:
s_binary("default value", <name>, <fuzzable>, <num_mutations>)
Example:
s_binary("\xad 0x01 0x020x03 da be\x0a", name="crazy")
Generating Random Data
With Sulley it is easy to generate random chunks of data, using the s_random primitive.
This primitive will start with the default value, then generate from the minimum size to themaximum size of random blocks of data When it finishes, the default value will be pre-
sented If you want a fixed size of random data, then set min and max to the same value.
Trang 14Example:
s_random("\xad 0x01 0x020x03 da be\x0a", 1, 7, name="nuts")
Strings and Delimiters
When you want to fuzz a string, use the s_string function.
Syntax:
s_string("default value", <name>, <fuzzable>, <encoding>, <padding>, <size>)
The first fuzz request will be the default value; then if the fuzzable argument is set (On
by default), the fuzzer will randomly fuzz that string When finished fuzzing that string,
the default value will be sent thereafter
Some strings have delimiters within them; they can be designated with the s_delim()
function The s_delim() function accepts the optional arguments fuzzable and name.
Examples:
s_string("Hello", name="first_part")
s_delim(" ")
s_string("Haxor!", name="second_part")
The preceding sequence will fuzz all three portions of this string sequentially since the
fuzzable argument is True by default
Bit Fields
Bit fields are used to represent a set of binary flags Some network or file protocols call
for the use of bit fields In Sulley, you can use the s_bit_field function.
Trang 15Other sizes of integers:
• 2 bytes: s_word(), s_short()
• 4 bytes: s_dword(), s_long(), s_int()
• 8 bytes: s_qword(), s_double()
We can test this fuzz block with a simple test harness:
from sulley import *
############################################################################# s_initialize("foo request")
#######################################
Trang 16The preceding program is simple and will print our fuzz strings to the screen so we
can ensure the fuzzer is working as we desire The program works by first defining a basic
request called “foo request” Next the request is fetched from the stack with s_get
func-tion and a for loop is set up to iterate through the permutafunc-tions of the fuzzed block,
printing on each iteration We can run this program from the sulley directory
{common host-guest path to sulley}>python foo2.py
PressCTRL-Cto end the script As you can see, the script fuzzed the byte first; a while
later it started to fuzz the string, and so on
Groups
Groups are used to pre-append a series of values on the block For example, if we wanted
to fuzz an LPR request, we could use a group as follows:
from sulley import *
#############################################################################
s_initialize("LPR shallow request")
447
Trang 17When you need your script to make decisions based on a condition, then you can use
dependencies The dep argument of a block defines the name of the object to check and the dep_value argument provides the value to test against If the dependant object equals
the dependant value, then that block will be rendered This is like using the if/then struct in languages like C or Python
con-For example, to use a group and change the fuzz block for each command code, wecould do the following:
############################################################################# s_initialize("LPR deep request")
#Command Code (1 byte)|Operand|LF
s_group("command",values=['\x01','\x02','\x03','\x04','\x05'])
# Type 1,2: Receive Job
if s_block_start("rcv_request", dep="command", dep_values=['\x01', '\x02']): s_string("Queue")
s_delim(" ")
s_static("\n")
s_block_end()
#Type 3,4: Send Queue State
if s_block_start("send_queue_state", dep="command", dep_values=['\x03','\x04']): s_string("Queue")
s_static(" ")
s_string("List")
s_static("\n")
s_block_end()
#Type 5: Remove Jobs
if s_block_start("remove_job", dep="command", dep_value='\x05'):
Trang 18To use this fuzz script later, add the two earlier code blocks (“shallow request” and “deep
request” to a file called {common host-guest path to sulley}\request\lpr.py
NOTE There are many other helpful functions in Sulley but we have enough
to illustrate an intelligent LPR fuzzer at this point
Sessions
Now that we have defined several requests in a fuzz script called sulley\request\lpr.py,
let’s use them in a fuzzing session In Sulley, sessions are used to define the order in
which the fuzzing takes place Sulley uses a graph with nodes and edges to represent the
session and then walks each node of the graph to conduct the fuzz This is a very
power-ful feature of Sulley and will allow you to create some very complex fuzzing sessions We
will keep it simple and create the following session driver script in the sulley main
directory:
{common host-guest path to sulley}\fuzz_niprint_lpr_servert_515.py
import time
from sulley import *
from requests import lpr
# establish a new session
sess = sessions.session(session_filename="audits/niprint_lpr_515_a.session",\
crash_threshold=10)
# add nodes to session graph.
sess.connect(s_get("LPR shallow request")) #shallow fuzz
sess.connect(s_get("LPR deep request")) #deep fuzz, with correct formats
# render the diagram for inspection (OPTIONAL)
fh = open("LPR_session_diagram.udg", "w+")
fh.write(sess.render_graph_udraw())
fh.close()
print "graph is ready for inspection"
NOTE The crash_threshold option allows us to move on once we get a
certain number of crashes
Now we can run the program and produce the session graph for visual inspection
{common host-guest path to sulley}>mkdir audits # keep audit data here
{common host-guest path to sulley}>python fuzz_niprint_lpr_servert_515.py
graph is ready for inspection
Trang 19Open session graph with uDraw:
{common host-guest path to sulley}>"c:\Program Files\uDraw(Graph)\bin\
run-Monitoring the Process for Faults
Sulley provides a fantastic fault monitoring tool that works within the target virtualmachine and attaches to the target process and records any nonhandled exceptions asthey are found The request ID number is captured and feedback is given to the Sulleyframework through the PEDRPC custom binary network protocol
Figure 17-1 uDraw™ representation of the Sulley session graph
Trang 20NOTE To start the process_monitor script, you will need to run it from a
common directory with the host machine
We will create a place to keep our audit data and launch the process_monitor.py
script from within the target virtual machine as follows:
{common host-guest path to sulley}>mkdir audits # not needed if done
previously
{common host-guest path to sulley}>python process_monitor.py -c audits\
niprint_lpr_515_a.crashbin -l 5
[02:00.15] Process Monitor PED-RPC server initialized:
[02:00.15] crash file: audits\niprint_lpr_515_a.crashbin
[02:00.15] # records: 0
[02:00.15] proc name: None
[02:00.15] log level: 5
[02:00.15] awaiting requests
As you can see, we created a crashbin to hold all of our crash data for later inspection By
convention, use the audits folder to hold current fuzz data We have also set the logging
level to 5 in order to see more output during the process
At this point, the process_monitor.py script is up and running and ready to attach to a
process
Monitoring the Network Traffic
After the fuzzing session is over, we would like to inspect network traffic and quickly
find the malicious packets that caused a particular fault Sulley makes this easy by
pro-viding the network_monitor.py script
We will launch the network_monitor.py script from within the virtual machine as
follows:
{common host-guest path to sulley}>mkdir audits\niprint_lpr_515
{common host-guest path to sulley}>python network_monitor.py -d 1 -f "src or dst
port 515" -–log_path audits\niprint_lpr_515 -l 5
[02:00.27] Network Monitor PED-RPC server initialized:
Notice we have started sniffing on interface [1] We assigned a pcap storage directory and
a Berkley Packet Filter (BPF) of “src or dst port 515” since we are using the LPR protocol
Again, we set the logging level to 5
At this point, we ensure our target application (NIPRINT3) is up and running, ensure
we can successfully connect to it from our host, and we save a snapshot called “sulley”
Once the snapshot is saved, we close VMware
Trang 21[*] Entering interactive mode
[*] Please browse to the folder containing vmrun.exe
[*] Using C:\Program Files\VMware\VMware Workstation\vmrun.exe
[*] Please browse to the folder containing the vmx file
[*] Using G:\VMs\WinXP5\Windows XP Professional.vmx
[*] Please enter the snapshot name: sulley
[*] Please enter the log level (default 1): 5
[02:01.49] VMControl PED-RPC server initialized:
about this; it is all done automagically by Sulley.
NOTE if you get an error when running this script that says:
[!] Failed to import win32api/win32com modules, please install these! Bailing ,you need to install the win32 extensions to Python, which can be found at:http://starship.python.net/crew/mhammond/win32/
Putting It All Together
We are now ready to put it all together and start our fuzzing session Since we havealready built the session, we just need to enable a few more actions in the fuzzing ses-sion script
The following code can be placed at the bottom of the existing file:
{common host-guest path to sulley}\fuzz_niprint_lpr_servert_515.py
# "stop_commands" : ['net stop "NIPrint Service"'],
# "start_commands" : ['net start "NIPrint Service"'],
452
Trang 22print "virtual machine up and running"
# add target to session.
sess.add_target(target)
#start the fuzzing by walking the session graph.
sess.fuzz()
print "done fuzzing web interface still running."
This code sets up the target for the fuzzing session and provides arguments for the
process_monitor script Next the virtual machine target snapshot is reset, we add the
tar-get to the session, and the fuzzing begins We commented-out the service start and stop
commands, as the version of NIPRINT3 we are using has a demo banner that requires
user interaction when the process starts, so we will not be using the service start/stop
capability of Sulley for this server
We can run this program as before; however, now the fuzzing session will begin and
requests will be sent to the target host over port 515
{common host-guest path to sulley}>python fuzz_niprint_lpr_servert_515.py
graph is ready for inspection
virtual machine up and running
[02:02.17] current fuzz path: -> LPR shallow request
[02:02.18] fuzzed 0 of 12073 total cases
[02:02.56] netmon captured 414 bytes for test case #3
…truncated for brevity…
[02:03.09] netmon captured 5571 bytes for test case #9
[02:03.16] procmon detected access violation on test case #9
[02:03.16] [INVALID]:41414141 Unable to disassemble at 41414141 from thread 452
caused access violation
[02:03.17] restarting target virtual machine
PED-RPC> unable to connect to server 10.10.10.130:26002
PED-RPC> unable to connect to server 10.10.10.130:26002
[02:06.26] fuzzing 10 of 5595
[02:06.34] xmitting: [1.10]
[02:06.36] netmon captured 5630 bytes for test case #10
[02:06.43] procmon detected access violation on test case #10
[02:06.44] [INVALID]:41414141 Unable to disassemble at 41414141 from thread 452
caused access violation
Trang 23You should see your vmcontrol window react by showing the communication withVMware™ Next you should see the virtual machine target reset and start to register pack-ets and requests You will now see the request being sent to the target virtual machinefrom the host, as shown earlier
After the first request is sent, you may open your browser and point it to http://127.0.0.1:26000/ Here you should see the Sulley Fuzz Control
As of the writing of this book, you have to refresh this page manually to see updates
Postmortem Analysis of Crashes
When you have seen enough on the Sulley Fuzz Control screen, you may stop the ing by killing the fuzzing script or by clicking Pause on the Sulley Fuzz Control screen Atthis point, you can browse the crashes you found by clicking the links in the Sulley FuzzControl screen or by using the crash_explorer.py script
fuzz-You may view a summary of the crashes found by pointing the script to your crashbin.{common host-guest path to sulley}>python utils\crashbin_explorer.py audits\ niprint_lpr_515_a.crashbin
[2] [INVALID]:41414141 Unable to disassemble at 41414141 from thread 452 caused
access violation
9, 10, [1] [INVALID]:5c2f5c2f Unable to disassemble at 5c2f5c2f from thread 452 caused access violation
17,
Trang 24We stopped our fuzz session after a few minutes, but we already have some juicy results.
As you can see bolded in the preceding output, it looks like we controlled eip already.
Wow, as we know from Chapter 11, this is going to be easy from here
Now, if we wanted to see more details, we could drill-down on a particular test case
{common host-guest path to sulley}>python utils\crashbin_explorer.py audits\
EDX: 00080608 ( 525832) -> |ID{,9, (heap)
EDI: 004254e0 ( 4347104) -> Q|` (NIPRINT3.EXE.data)
ESI: 007c43a9 ( 8143785) -> /.:/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
The graphing option comes in handy when you have complex vulnerabilities and need
to visually identify the functions involved However, this is a straightforward buffer
overflow and eip was smashed.
Trang 25Analysis of Network Traffic
Now that we have found some bugs in the target server, let’s look at the packets that causedthe damage If you look in the sulley\audits\niprint_lpr_515 folder, you will find toomany pcap files to sort through manually Even though they are numbered, we would like
to filter out all benign requests and focus on the ones that caused crashes Sulley provides
a neat tool to do just that called pcap_cleaner.py We will use the script as follows:{common host-guest path to sulley}>python utils\pcap_cleaner.py audits\ niprint_lpr_515_a.crashbin audits\niprint_lpr_515
Now we are left with only pcap files containing the request that crashed the server Wecan open them in Wireshark and learn what caused the crash
From Figure 17-2 we can see that a request was made to “start print job,” which started
with ‘\x01’ and a queue name ‘\x2f\x2e\x3a\x2f’ and then many As The As overwrote eip
somewhere due to a classic buffer overflow At this point, we have enough information toproduce a vulnerability notice to the vendor…oh wait, it has already been done!
Way Ahead
As you have seen, we have rediscovered the NIPRINT3 buffer overflow used in Chapter
11 However, there may be more bugs in that server or any other LPR server We will leave
it to you to use the tools and techniques discussed in this chapter to explore further.456
Figure 17-2 Wireshark showing the packet that crashed the LPR server
Trang 26www.grayhathackingbook.com
Dave Aitel, Block Based Fuzzing www.immunitysec.com/downloads/advantages_of_block_
based_analysis.pdf
Sulley Framework www.fuzzing.org
Pedram Amini, Paimei paimei.openrce.org
Sutton, Greene, Amini, Fuzzing: Brute Force Vulnerability Discovery (Addison-Wesley Professional,
2007)
457
Trang 2818
From Vulnerability
to Exploit
• Determining whether a bug is exploitable
• Using a debugger efficiently
• Understanding the exact nature of the problem
• Preconditions and postconditions for exploitation
• Repeating the problem reliably
• Payload construction considerations
• How to properly document the nature of a vulnerability
Whether you use static analysis, dynamic analysis, or some combination of both to
dis-cover a problem with a piece of software, locating a potential problem or causing a
pro-gram to melt down in the face of a fuzzer onslaught is just the first step With static
analysis in particular you face the task of determining exactly how to reach the
vulnera-ble code while the program is executing Additional analysis followed by testing against
a running program is the only way to confirm that your static analysis is correct Should
you provoke a crash using a fuzzer, you are still faced with the task of dissecting the
fuzzer input that caused the crash and understanding any crash dumps yielded by the
program you are analyzing The fuzzer data needs to be dissected into the portions
re-quired strictly for code path traversal, and the portions that actually generate an error
condition with the program
Knowing that you can crash a program is a far cry from understanding exactly why the
program crashes If you hope to provide any useful information to assist in patching
the software, it is important to gain as detailed an understanding as possible about the
nature of the problem It would be nice to avoid this conversation:
Researcher: “Hey, your software crashes when I do this…”
Vendor: “Then don’t do that!”