Full Disclosure mailing list archives
Re: Patriotic botnet with Orange's HADOPI software
From: no no <procrastinateur.fr () gmail com>
Date: Tue, 15 Jun 2010 20:20:45 +0200
Malware like **************** The service (cdtsvc) doesn't allow configuration change : if the user changes the service config, it is instantly reset to "default" values : restart when killed, user cannot stop it manually This behaviour is bypassable : create the following registry key and the service will no longer reset the configuration each time it is changed : HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\cdtsvc\DefaultAction value : 128 This way, the service can be killed and restarted "on demand" User Configuration ********************** During the install, the user has to set a secret question with the associated answer in case he forgets its password Even if the password is stored hashed in the registry, the secret question, the answer as well as other parameters are stored encrypted $ cat decrypt_configuration.py from ctypes import * from ctypes.wintypes import DWORD from _winreg import * import struct import sys LocalFree = windll.kernel32.LocalFree memcpy = cdll.msvcrt.memcpy CryptProtectData = windll.crypt32.CryptProtectData CryptUnprotectData = windll.crypt32.CryptUnprotectData CRYPTPROTECT_UI_FORBIDDEN = 0x01 aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE) aKey = OpenKey(aReg, r"SYSTEM\CurrentControlSet\Services\cdtsvc\Parameters") config = QueryValueEx(aKey,"Config")[0] class DATA_BLOB(Structure): _fields_ = [("cbData", DWORD), ("pbData", POINTER(c_char))] def getData(blobOut): cbData = int(blobOut.cbData) pbData = blobOut.pbData buffer = c_buffer(cbData) memcpy(buffer, pbData, cbData) LocalFree(pbData); return buffer.raw def Win32CryptUnprotectData(cipherText): bufferIn = c_buffer(cipherText, len(cipherText)) blobIn = DATA_BLOB(len(cipherText), bufferIn) blobOut = DATA_BLOB() if CryptUnprotectData(byref(blobIn), None, None, None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blobOut)): return getData(blobOut) else: return "" dec = Win32CryptUnprotectData(config) print "="*60 print "Configuration in HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\cdtsvc\\Parameters\\Config" print "="*60+"\n\n" # the encrypted message begins with the number of blocks (key/value) on 4 bytes nb_block = struct.unpack("<l",dec[:4])[0] dec = dec[4:] for i in range(nb_block): # then, each block : 2 bytes for the block size, 1 byte key length (each character of the key is 2 bytes long because widechar are used, and we also have a final \0 # so for key "MyKey" , lg_key = 0xC (12) ) # then the key (key name), the its value (we know the value length lg_value = lg_block - lg_key - 3 (2 bytes for lg_block et 1 byte for lg_key) lg_block = struct.unpack("<h",dec[:2])[0] lg_key = ord(dec[2]) # widechar so 2 bytes per char , and a final \0 so add 2 more bytes current = dec[:lg_block] key = current[3:lg_key*2].replace('\x00','') value = current[lg_key*2:].replace('\x00','') print "%s : %s"%(key,value) dec = dec[lg_block:] Unluckily, the config can be decrypted only by the SYSTEM account, so this script must be run as SYSTEM : either run this script as a service or, on Windows XP, use the "at" trick in a cmd : at XX:XX /interactive cmd.exe XX:XX being current time + 1 min in the shell that spawns, run this script What I haven't figured out yet is : why this RSA public key ? from your analysis, no signature or signature check is performed and I haven't figured it either
_______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/
Current thread:
- Patriotic botnet with Orange's HADOPI software cult dead hadopi (Jun 15)
- <Possible follow-ups>
- Re: Patriotic botnet with Orange's HADOPI software no no (Jun 15)