Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: TFTPD: Buffer Overflow(s)
In article <51D4618B.8020103%M00nBSD.net@localhost>,
Maxime Villard <max%M00nBSD.net@localhost> wrote:
>There is an error in the fix which has been committed. What
>if snprintf() returns -1 ?
Yes, fixed.
christos
>
>- - PATCH
>
>Index: tftpd.c
>===================================================================
>RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
>retrieving revision 1.40
>diff -u -r1.40 tftpd.c
>--- tftpd.c 28 Jun 2013 17:20:15 -0000 1.40
>+++ tftpd.c 3 Jul 2013 17:34:19 -0000
>@@ -488,7 +488,7 @@
>
> rexmtval = tout;
> if (asize > *ackl && (l = snprintf(ack + *ackl, asize - *ackl,
>- "timeout%c%lu%c", 0, tout, 0)))
>+ "timeout%c%lu%c", 0, tout, 0)) > 0)
> *ackl += l;
> else
> return -1;
>@@ -714,7 +714,7 @@
> if (sizeof(oackbuf) > alen &&
> (l = snprintf(oackbuf + alen,
> sizeof(oackbuf) - alen, "tsize%c%u%c", 0,
>- tftp_tsize, 0)))
>+ tftp_tsize, 0)) > 0)
> alen += l;
> }
> oack_h = (struct tftphdr *) oackbuf;
>
>- -
>
>Le 28/06/2013 11:10, Maxime Villard a écrit :
>> Hi,
>> one week ago, I was comparing OpenBSD's TFTPD with NetBSD's one when
>> I stumbled across several buffer overflows that may occur when dealing
>> with specially crafted packets. I'm gonna explain quickly what it
>> consists in.
>>
>> - - src/libexec/tftpd/tftpd.c - -
>>
>> Let's say you send this packet:
>>
>> /* header */
>> "\x00\x01" // OACK packet
>> "merde" // file name
>> "\x00" // blank
>> /* tm */
>> "netascii" // transfert mode
>> "\x00" // blank
>> /* blksize option */
>> "blksize" // option
>> "\x00" // blank
>> "\x39" // value = 9
>> "\x00" // blank
>>
>> The packet will be handled that way:
>>
>> at l.86 : "char oackbuf[PKTSIZE];" <-- Here, PKTSIZE = SEGSIZE + 4 = 516.
>> at l.669: get_options() is called with 'oackbuf' and 'alen'. Here, alen =
>> 2.
>> at l.600: get_options() parses the received packet and calls the
>> appropriate
>> handler. With our packet, blk_handler() will be called
>with 'oackbuf'
>> and 'alen' as arguments.
>> at l.453: "strcpy(ack + *ackl, "blksize");
>> *ackl += 8;"
>> Here, ack=oackbuf and ackl=alen. So, each time blk_handler() is
>> called, 'alen' is incremented of 8.
>>
>> Now, what if you send this packet:
>>
>> /* header */
>> "\x00\x01" // OACK packet
>> "merde" // file name
>> "\x00" // blank
>> /* tm */
>> "netascii" // transfert mode
>> "\x00" // blank
>> /* blksize option */
>> "blksize" // option
>> "\x00" // blank
>> "\x39" // value = 9
>> "\x00" // blank
>> /* blksize option, AGAIN */
>> "blksize" // option
>> "\x00" // blank
>> "\x39" // value = 9
>> "\x00" // blank
>>
>> ?
>>
>> blk_handler() will be called two times, and ackl will be incremented
>two times.
>> So, if you send a big packet with lots of blksize options in it,
>'alen' will be
>> incremented lots of times, so that it will end up being larger than
>sizeof(oackbuf).
>> At the end, you could get something like : strcpy(ack + 5000, blksize);
>>
>> Exploit here:
>>
>> http://M00nBSD.net/garbage/TFTPD-NetBSD.c
>>
>> You can patch locally your TFTPD to see how big the overflow is:
>>
>> -----
>>
>> Index: tftpd.c
>> ===================================================================
>> RCS file: /cvsroot/src/libexec/tftpd/tftpd.c,v
>> retrieving revision 1.39
>> diff -u -r1.39 tftpd.c
>> --- tftpd.c 29 Aug 2011 20:41:07 -0000 1.39
>> +++ tftpd.c 28 Jun 2013 08:15:05 -0000
>> @@ -450,6 +450,8 @@
>> }
>>
>> tftp_blksize = bsize;
>> + if (oackbuf == ack) syslog(LOG_ERR, "OK, same var: sizeof(ack) =
>%lu\n", sizeof(oackbuf));
>> + syslog(LOG_ERR, "strcpy'ing in ack + %d\n", *ackl);
>> strcpy(ack + *ackl, "blksize");
>> *ackl += 8;
>> l = sprintf(ack + *ackl, "%lu", bsize);
>>
>> -----
>>
>> With that, my tty tells me:
>> OK, same var: sizeof(ack) = 516
>> strcpy'ing in ack + 24992
>>
>> It seems that it could also occur in other places, but I did not investigate
>> further.
>>
>> Last thing: I think it would be better if the filename was validated BEFORE
>> parsing the options. With the previous exploit, the file specified by
>'filename'
>> does not even need to be present on the server. I suggest moving the block at
>> l.687 above l.666, with some changes.
>>
>> Maxime
>>
>
>
Home |
Main Index |
Thread Index |
Old Index