VulnImage is an obscure (I can't even find a 'homepage' as such for it!) "boot-to-root" operating system which has purposely crafted weakness(es) inside itself. The user's end goal is to interact with it and get the highest user privilege they can.
The 'manual' tag is due to the way the login system is bypassed as well as privilege escalation (via Linux exploit development, covering fuzzing to metasploit module). Another method is located here.
Links
Watch video on-line:
Download video: http://download.g0tmi1k.com/videos_archive/VulnImage-Manual.mp4
Method
- Scanned network for the target [NetDiscover]
- Port scanned the target [UnicornScan]
- Banner grabbed the services running on the open port(s) [NMap]
- Bypass login system [Firefox]
- Modified page requests to the web server [Tamper Data]
- Manipulate the blog to upload an backdoor [Pentestmonkey's PHP-Reverse-Shell]
- Brute forced directories & files on the web server [DirBuster]
- Discovered a custom application running and downloaded the source code ['buffd']
- Escalated privileges via a vulnerable kernel version [udp_sendmsg]
- Exploit development starts at 5:28
- Fuzzed the custom application until it crashed [NetCat & Python]
- Verified and located which part of the buffer is overwriting the EIP address in the registers [Metasploit's pattern_create & pattern_offset & GDB]
- Created shellcode to be executed [Metasploit's msfvenom]
- Updated the buffer with the shellcode and verified everything so far [Python & GDB]
- Final update of the buffer to include the ESP address [GDB]
- Escalated privileges via the new exploit ['buffd']
- Restart the target machine to verified the exploit
- Created metasploit module [Geany]
- Escalated privileges via the new exploit using metasploit ['buffd']
- Restored the targets machine back to its original state
- Instantly gained root access via the new exploit [metasploit]
Tools
- VulnImage.zip (MD5: 8CB0E628AEB3C7E1F771764D07280655).
- A virtual machine (Example: VMware Player or Virtual Box).
- NetDiscover – (Can be found in BackTrack 5).
- UnicornScan – (Can be found in BackTrack 5's repository).
- NMap – (Can be found in BackTrack 5).
- Firefox – (Can be found in BackTrack 5).
- Tamper Data – (Can be found in BackTrack 5).
- PHP-Reverse-Shell – (Can be found in BackTrack 5).
- NetCat – (Can be found in BackTrack 5).
- DirBuster – (Can be found in BackTrack 5).
- udp_sendmsg – (Found on exploit-db.com & Can be found in BackTrack 5).
- Python – (Can be found in BackTrack 5).
- Metasploit – (Can be found in BackTrack 5).
- A Text Editor (e.g. Geany) – (Can be found in BackTrack 5's repository).
Walkthrough
The first stage is to locate the target, which the attacker does by using "NetDiscover" as this quickly scans all the subnets for IP's, Media Access Control (MAC) addresses and any known vendors that relate to their MAC address. The attacker knows that the target is using VMware, as there aren’t any other virtual machines in use and the target hasn't spoofed their MAC address, therefore they have successfully identified the target.
The attacker then port scans the target as this discovers any services which are listening on the exposed interface. The attacker chooses to use "UnicornScan" as it is accurate & efficient whilst scanning at speed. The port scan shows there are 7 open TCP ports; 22 (SSH), 25 (SMTP), 80 (HTTP), 139 (NETBIOS), 445 (SAMBA), 3306 (MySQL) and 7777 (CBT). There is only 1 UDP port open, 137 (NETBIOS). The attacker then chooses to verify the TCP results by using "nmap" to do another port scan. At the same time, the attacker takes advantage of some other features built into nmap, such as its scripting engine. This enumerates the open port's protocols and services which have been detected, as well as banner grabbing. The attacker chooses to interact with the web service which is running on the default TCP port 80. The justification for this is because it is a very graphical, friendly and common way in allowing the end user to interact, because of this there could be lots of information which could be enumerated as well as poorly written code which could be taken advantage of.
The attacker starts "DirBuster" to brute force directories and files on the web server by connecting to a list of common paths used on a web server and to then analyse the HTTP response codes. As this takes a while, it is left running in the background.
The web service responds normally when the attacker interacts with it using a web browser, for example "firefox". The attacker then explores the web application structure by clicking through on links and soon sees the web service is running a blog, and, at the same time sees that two posts have been posted by the user, blogger. The attacker keeps on following links on the blog and soon is presented with a login page for user profiles. The first thing the attacker looks at is the page source code, which they notice has a hidden field called "fname" and a value of "sig.txt", which appears to be a text document for signatures. Next they test the login system by entering data which wouldn't be correct as this can be used to see if the login system is working as well as the error message(s) for an incorrect login. The attacker uses the possible username, 'blogger' and the password, 'password'. The attacker then goes back and repeats the request, however; this time uses a different password to attempt to alter the login process. Editor's note: Before recording the video, the attacker noticed that phpMyAdmin was running on the web server (due to DirBuster). This is a GUI to manage MySQL databases, which are commonly used to validate credentials. The attacker then replaces their password with a MySQL statement in which to modify (by 'injecting' their code) the MySQL statement which has been hardcoded on the server side. This "password" will cause the original MySQL statement to return true, therefore it will login as the chosen user without the correct password being present. Editor's note: An explanation of the vulnerable code is below:
File: /var/www/admin/profile.php, line 31
Original statement:
$sql = "SELECT * FROM blog_users WHERE poster = '$username' AND password = '$password'";
Expected input (user: blogger, Password: password):
$sql = "SELECT * FROM blog_users WHERE poster = 'blogger' AND password = 'password'";
Injected input (user: blogger, Password: ' or 1=1-- -):
$sql = "SELECT * FROM blog_users WHERE poster = 'blogger' AND password = '' or 1=1-- -'";
In the MySQL statement the 'WHERE' clause needs two parts to equal true due to the 'AND' operator. The username is known and valid but the password is not. The reason why the injected input works is due to the 'OR' operator as this allows another value that will always be true, as 1 will always equal 1. Now the statement will return true, therefore logging in as blogger. The ending of the injected code, comments out any possible remaining queries in the original statement (as it turns out there isn't anything) plus there is no a need to fix the MySQL syntax.
To verify that the attacker managed to login without knowing the password, they quickly check the blog to see if the signature has been updated - which it has been. The attacker then wishes to take advantage of the blog's system of using files to store signatures, however, they need to know the location of where they are stored. By altering the hidden "fname" in the page source code to an incorrect path, forcing an error to be produced, they hope that the error message will contain sensitive information relating to the location. As fname is stored on the client's web page (not hidden when the server processes the page), the attacker is able to modify their local version which is sent back to the server. The attacker could use the firefox addon "firebug" to alter the source code on-the-fly, thus when the page is sent back, it would have the modified variable. However the attacker chooses to use "Tamper Data" to intercept the traffic to modify the data before it is sent back. The reason why the attacker went with Tamper Data is because it is already included with the default install of backtrack 5 r1 (The addon has just been disabled).
'Normal'
Attacker (Firefox) ---> Target (Web server)
Attacker (Firefox) <--- Target (Web server)
Attacker (Firefox) ---> Target (Web server)
'Intercepted'
Attacker (Firefox) ---> Target (Web server)
Attacker (Firefox) <--- Target (Web server)
Attacker (Firefox) ---> Tamper Data ---> Target (Web server)
By using tamper data, when the attacker submits the page, they are now able to edit the data which is sent in the POST request and takes advantage of this by editing the hidden text field "fname" to have an additional forward slash. Slashes are used to indicate folders, now when the blog tries to use the path, there isn't a folder at the location, forcing an error. This produces a message informing the end user that the blog isn't able to access the file or folder (which is due to the modified request), along with detailed paths such as the file which failed to access the location as well as the location which failed. The attacker copies the failed location and amends the path to view the content which should have been requested. The attacker now knows the location of a writeable folder which they have access to. The attacker goes back and tries to see if they are able to execute PHP functions by a simple command to just print a message on the screen. Upon submission they alter the fname field to reflect the file format is now PHP. After which the attacker tries to view the new file, by doing so they discover that they are now able to write PHP functions and the target executes it.
Pentest monkey has created "php-reverse-shell" which allows for an interactive shell to spawn by using PHP commands. The attacker makes a copy of it, making sure the original version isn't edited. Due to the nature of the shell (as it is "reverse") this means communication comes back to the attacker, thus the shell needs to be able to locate the attacker, which is done so by updating the "IP" and "port" field.
Before the attacker views the new signature which would trigger the shell to be executed, the attacker needs to set up a listener, which will capture the request from the target with an interactive shell. The attacker uses "netcat" to be the handler as it is a 'swiss army knife' on the same port used in the shell. The attacker then requests the php shell signature to be displayed. The target then executes the PHP commands causing a shell to be sent back to the attacker. The end result being the attacker is now able to execute commands locally on the target machine using an interactive shell.
The attacker starts checking the local user's home folder, and discovers a C source code, for a program called 'buffd'. After checking to see the running processes, the attacker notices not only the program is being executed, but also by the super-user, root. The current user which the attacker is logged in as (www-data), doesn't have permission to view the file. However the attacker checks the results from DirBuster and notices that the web server also has a file with the same name, and downloads that copy instead. Upon viewing the contents of the source code, the attacker notices that the program uses port "7777". The attacker checks locally on the target to see if TCP port 7777 is open, which it is, but is unable to confirm if the PID matches to the running process. At the same time looking at the source code, the attacker notices a vulnerable function - which is called "vulnerable". Editor's note: An explanation of the vulnerable code is below:
1 2 3 4 5 6 |
|
The function is vulnerable because of the buffer 'local_buffer', has been set to '120', therefore when the argument 'net_buffer', is copied into the buffer anything greater than 120 will 'overflow' it. The extra bytes will run past the buffer and overwrite the space set aside for the frame pointer, return address etc. This causes the process stack to be corrupt which potentially alters the program's execution path as the functions return address is the address of the next instruction in memory, which is immediately executed after the function returns. When using 'strcpy' it doesn't check the bounds, so the solution would be to use 'strncpy'.
The attacker checks the file type of the potential binary version of buffd, as well as the folder in which it is being executed from. The attacker notices the binary was compiled on Linux 2.6.8 as well as having a 'core' file in the same folder. The attacker knows that a core file is a 'memory dump' and is produced when a program crashes and is able to extract key information about how and why the program crashed (which is useful to know when creating an exploit as the attacker needs to understand what is happening).
The attacker then decides that they are going to attempt to create an exploit for the vulnerable program, buffd. They chose to develop the exploit locally on the target, as its the environment the exploit will be used in. The first thing the attacker does, is to disable any file and memory protection such as 'Address Space Layout Randomization (ASLR)' as it moves segments about, creating randomness in addresses thus making it harder to exploit applications. The attacker tries to disable ASLR, however they notice that the file '/proc/sys/kernel/randomize_va_space', which is used to temporarily disable ASLR is missing. They then check the kernel version to see its 2.6.8 (which hints that the binary file could of been compiled locally and not imported) which by default doesn't have ASRL (ASLR got added into the Linux kernel by default from 2.6.12 onwards), therefore the attacker doesn't have to worry about ASLR. Editor's note: I was unable to exploit buffd locally on the attackers machine.
As the buffd is being executed as the super-user, the current user (same as the web service they exploited) they are logged in as isn't going to have permission to control the program. The attacker needs to escape privileges another way to gain a higher level of access in the system. One common method is by exploiting the kernel (ONLY if it is vulnerable!). The attacker searches their local copy of a public exploit database, "exploit-db.com". Upon searching for the exact same kernel version, it only returned one known exploit (which was un-successful). The attacker carries on by searching for the same "major.intermediate" versions (removed ".minor"), and sorts them in ascending order. This returns results for kernel versions that are higher and lower than the target version as well as "generic" ones. The justification for this is that lots of exploits are available for a certain version and/or lower, the ones which are higher than the one used on the target could work. After searching the results, the attacker finds a suitable exploit that will potentially work. After viewing the exploit, it requires additional files to be downloaded. The attacker downloads the exploit package and moves it to their local root folder website path. They make sure the exploit is able to be read, by anyone by giving it certain permissions, as the web server uses a different user than the one which the attacker is currently logged in as and executing commands from. The web server is then started.
The attacker controls the target to download the exploit package from the attacker and then extracts it. The included bash script does all the necessary commands and the end result is that the attacker has now gained root access to the target. When the attacker discovered the running process and network connections, they saw that TCP port 22 was open (which by default is used for SSH) as well as the SSH daemon running; as a result they change the password to something which they know, allowing the attacker to login via SSH. The advantage of SSH is that it is a TTY shell to interact with the target as well as acting like a backdoor into the system, so they don't have to exploit the target again.
After login into the box again the attacker prepares the target's environment by removing the old core file (Editor's note: This is actually a mistake that will be explained later), allowing unlimited sized core files to be produced as well as killing all instances of the program. The attacker then executes buffd.
The attacker then connects back into the target using the backdoor. If the program "screen" was installed locally on the target, then this wouldn't be needed as the attacker would only need one terminal to work in. In the new window, the attacker watches the local folder that buffd is being executed in, as this will notify the attacker if something happens in the folder.
The attacker then remotely starts to interact with the target's buffd. By using netcat the attacker is able to see how the program would normally function. Then by piping commands into netcat they are able to automate the procedure which speeds up development time. The attacker then checks to see the status of the target and buffd. The program itself gives notification of connection and that they have not had any changes to the folder. The attacker carries on by using python to script the automated input to buffd. They start off using 10 "A"s, then move onto 100, then 1000. At this stage the "watch" window has notified that there has been a change. When the attacker views the output, they spot that a core file has been created thus the attacker has caused the program to crash! The attacker goes back and sends a further 10 "A"s to the target, and it appears to response normally, meaning only a thread crashed, not the complete program. Editor's note: It is good practice to restart the program each time it crashes - just in case something 'more' crashed.
1 2 3 4 |
|
The attacker connects back into the target, this time this window is used to debug the core file that was produced. This allows the attacker to see the state the registers were in when the core file was created. Upon inspection the attacker notices the EIP has been overwritten with 41 (which is HEX for the ASCII A, which matches the data being sent). This means the attacker controls EIP, which results in the attacker being able to control the 'flow' of the program!
The next stage is to see which part of the buffer that was sent to the target has overwritten the EIP address. The attacker uses metasploit's aid to locate this address, as 'pattern_create.rb' creates a unique random string for the given length. As the program crashed when the attacker sent 1000 "A"s the attacker uses the same number again. This time, instead of sending the same thing over and over again, the attacker uses metasploit's output. When this is sent to the target, this also causes the program to create another core file, hinting that it's crashed again, however this time, EIP is different. The attacker copies the EIP value and passes it back into metasloit, this time using the other half of the script, 'pattern_offset.rb'. As the string is unique, metasploit is able to calculate the exact part of the buffer which caused EIP to be over written, which is 124. This can be verified as the attacker has the potential source code to the program (the buffer was set to 120). The attacker then verifies metasploit's result by sending 124 "A"s, then the next 4 "B"s, and calculates the remaining values to be "C"s, which means if everything is correct, when the attacker causes the program to crash again, the only 4 "B"s will be in the EIP address. buffer #5: <A * 124>< B * 4> <C * 872>
Another feature of metasploit is its ability to produce shellcode from its payloads. This is the code that the attacker wants the vulnerable code to execute. The attacker chooses to use a bind shell, which opens a port locally and allows for remote communication to execute commands. When creating the shellcode, the attacker chooses not to use '00' or 'ff' as when it is being injected into a process it could have an effect on the existing running code, for example, '00 ' terminate strcpy(), which is the vulnerable function in buffd. Editor's note: I will do another guide explaining how to find bad characters at a later date. The attacker then prepares the buffer by adding NOPs in after the second part of the buffer, the Bs. Editor's note: The amount, 26 was chosen at random. A NOP or 'No Operation' command effectively doesn't do anything. The reason why NOPs are used is to create a 'NOP slide' (sometimes referred to a 'NOP sled') and is used to 'pad' when the exact position in memory can't be determined with absolute accuracy. It doesn't matter if the pointer is set to the start or the middle of the NOP slide, it will still perform the same, thus making the exploit more universal in different environments as memory addresses can be different. The attacker then adds in 4 Cs, which are used for debugging purposes as they signal the position in memory. Afterwards the attacker places the shellcode from metasploit and along with some more NOPs. As the original buffer was 1000 bytes, the buffer always needs to equal 1000, and the remaining amount is set to Cs to help with debugging the buffer. The attacker then sends the new buffer to cause the program to crash, creating a core file once more. buffer #6: <A * 124>< B * 4><NOP * 26><C * 4><SHELLCODE * 105><NOP * 40><C * 697>
The attacker uses the debugger "GDB", to see the values that are set at the various registers. By viewing the first 200 bytes at the EAX register, the attacker is able to see the start of the buffer which they sent to the target, as it contains As. Then it's the EIP address which contains 4 Bs, then the NOP sled, then the debugging Cs that indicates the next stage is the shellcode, which takes up the rest of the view. By viewing the ESP register, we can see it's pointing into the NOP sled which will result in executing the shellcode, therefore by replacing the Bs with the address in ESP, the program should execute the injected shellcode. After the shellcode is the rest of the padding to cause the buffer to equal 1000 bytes. buffer #7: <A * 124>< B * 4><NOP * 30> <SHELLCODE * 105><NOP * 737>
The buffer gets updated to remove the debug Cs thus extended to the NOPs. The attacker restarts buffd and does a test to verify the progress so far. After examining the core file, the attacker copies the EIP address to replace the Bs in the buffer. Before sending the final buffer to the target, the attacker restarts the program, closes all connections to the target and checks that the bind port is currently closed. Once the attacker sends the buffer to the target, the response hangs this time. The attacker then repeats connecting to the bind port, and this time the attacker is able to execute commands. As soon as the connection on the bind shell is closed, the buffd program also finishes. buffer #8: <A * 124><EIP * 4><NOP * 30> <SHELLCODE * 105><NOP * 737>
The attacker then restarts the target's machine as the attacker has affected multiple aspects of the environment, and would like to make sure the exploit works in a normal clean setup. As the target's machine is starting up again, the attacker takes the time to create a metasploit module. Some advantages of using the metasploit framework is its built in handler, as well as automatically updating the exploit, for example, the attacker is able now to customize the shellcode (the payload) which is executed on the client, without having to update the padding to reflect the difference in shellcode size. Once the module has been created, the attacker starts up metasploit, selects the new exploit and fills in the target's details. This time, the attacker uses a different payload, as originally it was a bind connection, however they now test out the module by using a reserve connection. The attacker now tries the original buffer re-created in metasploit, however it fails.
The attacker now connects back via SSH, enables core files to be created once more and restarts the buffd service this time instead of executing the program directly. The attacker sends the original python buffer to the target before the "B"s were replaced, which caused buffd to crash. Upon looking at the EIP in the core file, the attacker sees the value this time is different. The attacker updates the metasploit module to reflect the changes and reloads the exploit in the framework. The attacker tries again to send the exploit using metasploit, this time they are presented with a shell.
*See 'vulnimage.rb' for the source code*
Game over
The attacker then restores the targets machine, back to its original state and starts it up. After exploiting the complete system again, the attacker is able to gain access to the original core file - which was deleted the first time. After opening the core file in the debugger, the attacker is able to update the exploit to reflex the EIP register. Therefore the attacker has a permanent backdoor into this target's virtual machine. Editor's note: I didn't originally plan to explain the video to include creating a metasploit module, which is why the core file wasn't needed, therefore it wasn't moved into a safe location for use later... Lesson learnt: Move files, don't delete them ;)
Game over... again
Commands
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
|
vulnimage.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | buffd Daemon)',
'Description' => %q{
A simple exploit for the 'boot to root', vulnimage.zip.
The vulnerability is in daemon service, 'buffd', which runs as root at startup.
},
'License' => MSF_LICENSE,
'Author' => [ 'g0tmi1k' ],
'Version' => '$Revision: 1 $',
'References' =>
[
[ 'Download', 'http://ds.mathematik.uni-marburg.de/~lbaumgaertner/vulnimage.zip' ],
],
'Payload' =>
{
'Space' => 672,
'BadChars' => "\x00\xff",
},
'Platform' => 'lin',
'Targets' =>
[
[ 'VulnImage.zip Virtual Machine',{'Ret' => 0xbffff380, } ] # Direct address (NOP sled!)
],
'Privileged' => false,
'DisclosureDate' => 'Nov 17 2011',
'DefaultOptions' =>
{
'RPORT' => '7777',
'EXITFUNC' => 'process',
},
'DefaultTarget' => 0,
'Privileged' => false
))
end
def check
return Exploit::CheckCode::Vulnerable # Will always return true
end
def exploit
connect
# Feedback to user
print_status("Sending #{payload.encoded.length} byte payload...")
# Crafting exploit
buf = "A" * 124
buf += [ target.ret ].pack('V')
buf += make_nops(30)
buf += payload.encoded
# Sending exploit!
sock.put(buf)
sock.get
handler
disconnect
end
end
|
Notes
- When starting the VM for the first time with VMware, select "I Moved It" - otherwise it could cause issues (e.g. the target might not be 'visible'!).
- Some mistakes in the video are more obvious.
- Instead of using "php-reverse-shell" & "netcat", "PHP Meterpreter" & "Metasploit" could of been used.
- Could of viewed the page (profile.php - line 28) source to find the MySQL credentials, e.g. "mysql_connect ('localhost', 'root', 'toorcon') ;"
- By default the VM is set to use the network adapter to be in "NAT" mode, lots of people like to use it in "bridged" mode.
- The VM uses DHCP to acquire an IP address
- This isn't the best guide for learning the basics to exploit development. To fully understand it, its worth reading corelan website as well as sickn3ss's guides.
- The exploit uses an static address to jump to, as I don't locate an ESP address to use.
- 0xbffff330 = Direct
- 0xbffff320 = Daemon
- 0xbffff380 = Orignal VM
Song(s): W&W - Manhattan (Original Mix) & Armin van Buuren - Full Focus & Above & Beyond ft Richard Bedford - Sun & Moon (Marcus Schossow Remix Edit) & Armin van Buuren Presents Gaia - Status Excessu D (ASOT 500 Theme)
Video length: 21:58
Capture length: 71:40
Blog Post: https://blog.g0tmi1k.com/2011/12/vulnimage-manual-method/