TFTPWIN TFTP Server 0.4.2 Stack Buffer Overflow
As stated in the update of the previous post from now on I'm NOT going to post any functional exploit code for the vulnerabilities I cover in the reviews because the 400th article of the Spanish Law considers it to be a felony. Once this has been cleared out let's begin to analyze the vulnerability in question. This time we will review the Stack Based Buffer overflow that can be triggered remotely present in the 0.4.2 version of the TFTPWIN TFTP Server. The advisory from Secunia states "This can be exploited to cause a stack-based buffer overflow by requesting a resource with an overly long name (more than 280 bytes)". In my particular case I used this exploit by SkD as starting point to track down the issue. Since this exploit can be triggered remotely, our first move is to set breakpoints in the common network management API's, namely recv() and recvfrom(). Doing so and launching the exploit will make OllyDbg (the debugger of choice in my case) pop-up stopped in the instruction previous to recvfrom() with the following stack layout (Olly dump): 00E0FA78 000000B8 |Socket = B8 00E0FA7C 00BD1F60 |Buffer = 00BD1F60 00E0FA80 00000204 |BufSize = 204 (516.) 00E0FA84 00000000 |Flags = 0 00E0FA88 00BD1EBC |pFrom = 00BD1EBC 00E0FA8C 00BD1ECC \pFromLen = 00BD1ECC As we can see, the buffer that will receive our request from the network has a maximum storage space of 0x204 bytes, or 516 bytes in decimal notation. Further analysis with Wireshark will show us that the request in question is a RRQ Read Request. The TFTP protocol is defined in RFC 1350 and the general layout for such a request looks like this: | Opcode (2 bytes) | Filename (string) | 0 (null byte) | Mode (string) | 0 (null byte) After the packet is received and parsed, the application, after noticing that he just received a file read request, will try to build the full path of the file in the function beginning at address 0x0040638B. In order to construct the full path of the file, the function in question takes the filename as an argument and tries to construct the full name appending the root directory of the FTP to the filename. Unfortunately for the developers and fortunately for us, the function, even thought allocates 584 bytes, tries to copy the filename to a local variable located at esp-280. Since the copy in question is performed using the insecure strcpy() function, we can easily overflow the buffer. The disassembly of the aforementioned function looks like this:
.text:0040638B push ebp .text:0040638C mov ebp, esp .text:0040638E sub esp, 248h .text:00406394 mov eax, [ebp+filename] ; pointer to name of requested filename (path not included) .text:00406397 mov [esp+4], eax .text:0040639B lea eax, [ebp+localVar] ; (ebp - 280) -> 284 bytes to RET .text:004063A1 mov [esp], eax .text:004063A4 call strcpy ; trigger overflow .text:004063A9 lea eax, [ebp+localVar]And that is all there is to it. Constructing a working exploit at this point is not very dificult, we only need to keep in mind that we're sending a message across the network and that we need to build a application level message respecting the format defined in the mentioned RFC. Also note that since we can read a maximum of 516 bytes from the network, we have plenty of space after smashing the ret value to setup a trampoline.