A forum for reverse engineering, OS internals and malware analysis 

Forum for analysis and discussion about malware.
 #22391  by EP_X0FF
 Sun Mar 09, 2014 11:00 am
Other WinNT/Turla decrypted exploits and NTFS support tool attached.

decrypted_ms10_015_Win32.dll
decrypted_ms09_025_Win32.dll
decrypted_format_ntfs_Win32.dll
vdm.dll
Attachments
pass: infected
(40.7 KiB) Downloaded 146 times
 #22392  by R136a1
 Sun Mar 09, 2014 2:51 pm
Not only, but particularly after BAE systems released their (excellent) report which also mentions some numbers based on the uploads of samples to online scan services by country (#1 Ukraine), together with some russian related artifacts found in the samples, it was only a matter of time till the media propaganda started in the current events taking place in Ukraine:

NY Times
"Suspicion Falls on Russia as ‘Snake’ Cyberattacks Target Ukraine’s Government"
http://www.nytimes.com/2014/03/09/world ... tw-nytimes

Fox News
"Ukraine computers targeted by aggressive 'Snake' virus"
http://www.foxnews.com/tech/2014/03/09/ ... ake-virus/

CNet
"Security firm claims Russian government makes malware"
http://news.cnet.com/8301-1009_3-576197 ... s-malware/

Graham Cluley
"Anti-virus firm finds alleged Kremlin cyberweapon, undetected for at least three years"
http://grahamcluley.com/2014/03/russian-spyware/

...

And of course no major malware event without the comments of "Mr. attention whore" Mikko Hypponen:

Reuters
"Suspected Russian spyware Turla targets Europe, United States"
http://www.reuters.com/article/2014/03/ ... YI20140307
 #22394  by EP_X0FF
 Sun Mar 09, 2014 5:23 pm
Few funny things about this malware:

1) Why it revealed to mass public just now (in relation to Ukraine mass propaganda by manipulated mass media, from any sides of conflict).

This malware is known for years. It is sophisticated enough only in Turla version (distributed since 2009 and known from that time as Pfinet).
http://www.microsoft.com/security/porta ... et.A#tab=1
http://www.microsoft.com/security/porta ... N32/BOOZ.A

Known for years exactly as malware and specifically as backdoor and rootkit. It even was briefly analyzed few years ago.
https://www.microsoft.com/security/port ... et.B#tab=2

2) Why BAE did so _fast_ analysis and so in time.

Coupe of days? Are you serious? They have nothing else to do? I believe they did this analysis long time ago for internal usage and published it only now with quickly added few "details".

3) Why mass producer of "cyberwarfare" discoveries -> Kaspersky lab <- is speechless.

They known to do media hype about every piece of crap they found in relation to APT. Why not do some well PR on this? How it turned that they missed this crap? Or they are speechless because they can't go against their patrons and their toolkits?

All the above made ​​me think this Turla/Snake whatever campaign is just a act of information war and used right now to make a media hype about "Kremlin bloody cyber hand" which is simple hilarious. Seriosly, governments spying on each other? What a suprise! Impossible thing! I even do not want to comment mass media trash about count of files uploaded from Ukraine. Lets say, I do several thousand copies of the original dropper from this topic, making them different hash sum and upload all of them from Uganda IP to the virustotal. Can you imagine the following title in for example Fox News (bullshit propaganda chanell just like Russia Today): "Uganda computers targeted by aggressive 'Snake' virus" or NY Times write-up "Suspicion Falls on Russia as ‘Snake’ Cyberattacks Target Uganda's Government"? Excuse me, but to make any conclusions by the number of uploaded files from country IP's is not professional to put it mildly. You can do any conclusions (they will be somehow justified) only when you intercept and inspect traffic from this botnet and/or sinkhole their C&C. But of course for media mass propaganda any kind of shit is acceptible.

And who is that Mikko Hypponen? Except I know he is a famous "security expert" aka i.d.i.o.t. from a sort of Fake/AV company.
 #22396  by r3shl4k1sh
 Sun Mar 09, 2014 6:05 pm
In regard to your second point here's a quote from the Reuters article:
BAE said it has collected over 100 unique samples of Turla since 2010, including 32 from Ukraine, 11 from Lithuania and 4 from Great Britain. It obtained smaller numbers from other countries.
They have been playing with Turla for 4 years before releasing their report.

I must agree with your point that it seems like a western campaign in order to show Putin that they know about his secrets and once they decide to do so that they can embarrass him (probably by publishing more "reports" in relation to other countries...)

Probably we can conclude that G-Data and BAE have some governmental "support" behind them...
 #22414  by R136a1
 Mon Mar 10, 2014 6:38 pm
As already said, numbers based on the uploads by country should not be included in any report, since they can have various meanings:

- A security company works on an analysis and uploads from that country to check for AV detection
- Private security researcher works on an analysis and uploads from that country to check for AV detection
- A security company or private security researcher uploaded through a proxy server located in that country
- Someone intentionally uploads through a proxy server located in that country to distort statistics
- ...

As a result, mass media propaganda gratefully takes this steep template to make their own story out of this. Latest headline:
Ukraine attacked by cyberspies as tensions escalated in recent months
Ukrainian computer systems targeted by at least 22 attacks since January 2013, according to report from BAE Systems

http://www.theguardian.com/world/2014/m ... s-computer
And as the topic "cyber threat China" is exhausted, now Russia must serve as a sandbag for this.

That's all from my side, too.
 #22436  by kareldjag/michk
 Wed Mar 12, 2014 1:20 pm
hi
As an echo of some previous posts, the exploitation of APT by Mendiant about China IP origins, by an independent observer of Cyber WAR
http://jeffreycarr.blogspot.fr/2013/02/ ... tical.html
And about Russia implication in CyberWarfare
http://jeffreycarr.blogspot.fr/2014/03/ ... es-in.html
BAE Systems is known, and was an exhibitor of the last Milipol congress/exhibition in Paris a few months ago
http://en.milipol.com/Exhibitors-list-2 ... etter%29/B
Of course they do not work for the Russian Gvt...
Regarding EP favourite antivirus campany ;) , they are quite buzzy with Lojack these weeks
http://www.kernelmode.info/forum/viewto ... f=11&t=803

Uroburos rootkit or not, there is no sophisticated APT, but only weak systems...

Rgds
 #22447  by rinn
 Thu Mar 13, 2014 3:17 pm
Hello.

For everyone who interested :)


Turla container (in most of published papers named messages queue, we don't think it proper name) represent itself a combined container of linked data entries describing various parts of rootkit configuration, including payload libraries. Container contains: header (fields include full size, used container size, number of chains etc) and set of chains (entries).

The following structure describes container entry. Contents of data encrypted with CAST5 symmetric block cipher with small modification. Maybe in different variants of Turla there are other changes too.

Code: Select all
typedef struct _CONTAINER_ENTRY {
    ULONG    EntryTypeOrGroupId;
    ULONG    EntryId;
    ULONG    EntriesInGroup;
    ULONG    DataType;
    ULONG    GroupId;
    ULONG    Reserved1[3];
    ULONG    TimeStamp1;
    ULONG    TimeStamp2;
    ULONG    TimeStamp3;
    ULONG    EntrySize;
    ULONG    DataSize;
    ULONG    Reserved2[3];
    BYTE    Data[0];
} CONTAINER_ENTRY, *PCONTAINER_ENTRY;
Container extracts by dropper from dropper resource section and writes at rootkit contolled VFS as system.sav
Malware driver fully responsible for container parsing and is able both use encoding and decoding using CAST5.


Our goal was: find and extract payload libraries from Turla 2013 sample provided by R136a1 and learn basic principles how this malware manages it data.


Fully parsed container from sample
Code: Select all
 
= new group: ID=1/5501  count of entries: 11
> entry id=5501-1-2.bin  DataType:551  Size:16
> entry id=5501-2-2.bin  DataType:552  Size:16
> entry id=5501-3-2.bin  DataType:553  Size:16
> entry id=5501-4-2.bin  DataType:223  Size:9
> entry id=5501-5-2.bin  DataType:224  Size:9
> entry id=5501-6-2.bin  DataType:400  Size:9
> entry id=5501-7-2.bin  DataType:225  Size:9
> entry id=5501-8-2.bin  DataType:226  Size:9
> entry id=5501-9-2.bin  DataType:323  Size:9
> entry id=5501-10-2.bin  DataType:324  Size:9
> entry id=5501-11-2.bin  DataType:1  Size:9
= new group: ID=2/5502  count of entries: 11
> entry id=5502-1-2.bin  DataType:551  Size:16
> entry id=5502-2-2.bin  DataType:552  Size:16
> entry id=5502-3-2.bin  DataType:553  Size:16
> entry id=5502-4-2.bin  DataType:223  Size:9
> entry id=5502-5-2.bin  DataType:224  Size:9
> entry id=5502-6-2.bin  DataType:400  Size:9
> entry id=5502-7-2.bin  DataType:225  Size:9
> entry id=5502-8-2.bin  DataType:226  Size:9
> entry id=5502-9-2.bin  DataType:323  Size:9
> entry id=5502-10-2.bin  DataType:324  Size:9
> entry id=5502-11-2.bin  DataType:1  Size:9
= new group: ID=3/5503  count of entries: 11
> entry id=5503-1-2.bin  DataType:551  Size:16
> entry id=5503-2-2.bin  DataType:552  Size:16
> entry id=5503-3-2.bin  DataType:553  Size:16
> entry id=5503-4-2.bin  DataType:223  Size:9
> entry id=5503-5-2.bin  DataType:224  Size:9
> entry id=5503-6-2.bin  DataType:400  Size:9
> entry id=5503-7-2.bin  DataType:225  Size:9
> entry id=5503-8-2.bin  DataType:226  Size:9
> entry id=5503-9-2.bin  DataType:323  Size:9
> entry id=5503-10-2.bin  DataType:324  Size:9
> entry id=5503-11-2.bin  DataType:1  Size:9
= new group: ID=4/5504  count of entries: 11
> entry id=5504-1-2.bin  DataType:551  Size:16
> entry id=5504-2-2.bin  DataType:552  Size:16
> entry id=5504-3-2.bin  DataType:553  Size:16
> entry id=5504-4-2.bin  DataType:223  Size:9
> entry id=5504-5-2.bin  DataType:224  Size:9
> entry id=5504-6-2.bin  DataType:400  Size:9
> entry id=5504-7-2.bin  DataType:225  Size:9
> entry id=5504-8-2.bin  DataType:226  Size:9
> entry id=5504-9-2.bin  DataType:323  Size:9
> entry id=5504-10-2.bin  DataType:324  Size:9
> entry id=5504-11-2.bin  DataType:1  Size:9
> entry id=4294967293-1-2.bin  DataType:553  Size:16
> entry id=4294967293-1-3.bin  DataType:1000004  Size:33793
> entry id=5501-12-2.bin  DataType:500  Size:17
> entry id=5503-12-2.bin  DataType:500  Size:17
> entry id=5504-12-2.bin  DataType:500  Size:17
> entry id=4294967293-2-3.bin  DataType:1000005  Size:140801
> entry id=5501-13-2.bin  DataType:501  Size:17
> entry id=5503-13-2.bin  DataType:501  Size:17
> entry id=5504-13-2.bin  DataType:501  Size:17
> entry id=4294967293-3-3.bin  DataType:1000000  Size:148993
> entry id=5502-12-2.bin  DataType:651  Size:33
> entry id=5502-13-2.bin  DataType:652  Size:33
> entry id=5502-14-2.bin  DataType:653  Size:89
> entry id=4294967293-4-3.bin  DataType:1000001  Size:583681
> entry id=5502-15-2.bin  DataType:654  Size:33
> entry id=5502-16-2.bin  DataType:655  Size:33
> entry id=5502-17-2.bin  DataType:656  Size:89
> entry id=4294967293-5-3.bin  DataType:1000002  Size:49665
> entry id=5501-14-2.bin  DataType:502  Size:17
> entry id=4294967293-6-3.bin  DataType:1000003  Size:58369
> entry id=5501-15-2.bin  DataType:503  Size:17
> entry id=5502-18-2.bin  DataType:8  Size:17
> entry id=5502-19-2.bin  DataType:9  Size:9
> entry id=5501-16-2.bin  DataType:100  Size:9
> entry id=5501-17-2.bin  DataType:101  Size:33
> entry id=5501-18-2.bin  DataType:102  Size:49
> entry id=5501-19-2.bin  DataType:112  Size:97
> entry id=5501-20-2.bin  DataType:113  Size:41
> entry id=5502-20-2.bin  DataType:100  Size:9
> entry id=5502-21-2.bin  DataType:101  Size:49
> entry id=5502-22-2.bin  DataType:102  Size:57
> entry id=5502-23-2.bin  DataType:112  Size:97
> entry id=5502-24-2.bin  DataType:113  Size:41
> entry id=5502-25-2.bin  DataType:767  Size:73
> entry id=5502-26-2.bin  DataType:1034  Size:9
> entry id=5503-14-2.bin  DataType:100  Size:9
> entry id=5503-15-2.bin  DataType:101  Size:41
> entry id=5503-16-2.bin  DataType:102  Size:49
> entry id=5503-17-2.bin  DataType:112  Size:97
> entry id=5503-18-2.bin  DataType:113  Size:41
> entry id=5504-14-2.bin  DataType:100  Size:9
> entry id=5504-15-2.bin  DataType:101  Size:41
> entry id=5504-16-2.bin  DataType:102  Size:49
> entry id=5504-17-2.bin  DataType:112  Size:97
> entry id=5504-18-2.bin  DataType:113  Size:41


DataType (only we wanted):

553 is a key used to decrypt given group data. Always 16 bytes length.
500 is a DataType ID of payload dll X86 (stored as encrypted string)
501 is a DataType ID of payload dll X64 (stored as encrypted string)

Other types include different information: list of processes to inject payloads, xoring bytes, process+associated injected dll, varios configuration params.

You can notice 6 entries with big amount data inside.

Note odd sizes - this is because of special byte added to the data. CAST is block cipher and this implementation uses 8 bytes per block which means if you encode with it 1 byte as result you will have 8 bytes. This special byte added to the data and it determines significant number of bytes in the tail of encrypted data.


How we decrypt entries in container? We did it with help of rootkit itself -> decrypted X64 driver, patched it in several places and then used parts of it binary code. Code is simple and our goal wasn't creating cute looking Turla decoder as we don't see sense in it. So we are sorry for such code :)


Each group of entries encoded with the same key.
Another note: during decoding malware implementation does additional xor over supplied key, *(PDWORD)key ^= DataSize


CAST decoding procedure prototype.
Code: Select all
typedef unsigned long (__stdcall *RAW_CODE_PTR)(unsigned char *Key, unsigned long KeySize, unsigned char *OrigText, unsigned char *CipherText, unsigned long TextSize);
What we will do:

Enumerate all groups and entries, remember group key, apply group key for data of the group.

Code: Select all
typedef struct _RESIDKEY {
	ULONG	GroupId;
	BYTE	GroupKey[16];
} RESIDKEY, *PRESIDKEY;
Parsing and decoding:
Code: Select all
	HANDLE				f = INVALID_HANDLE_VALUE;
	DWORD				iobytes;
	LARGE_INTEGER		sz = {0};
	PBYTE				membuf = NULL, origText = NULL, dcode, pmemset = (PBYTE)&memset, pmemcpy = (PBYTE)&memcpy;
	WCHAR				textbuf[64];
	PCONTAINER_ENTRY	ent;
	unsigned long		i=0, k;
	RAW_CODE_PTR		malware_ucast = NULL, malware_dcast;

	RESIDKEY			keys[16];

	membuf = (PBYTE)VirtualAlloc(NULL, 2*1024*1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	origText = (PBYTE)VirtualAlloc(NULL, 2*1024*1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	dcode = (PBYTE)VirtualAlloc(GetModuleHandle(NULL) + 0x100000, 1*1024*1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

	f = CreateFile(TEXT("C:\\Malware\\UROBOROS\\root.dmp"), GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
	GetFileSizeEx(f, &sz);
	ReadFile(f, dcode, sz.LowPart, &iobytes, NULL);
	CloseHandle(f);

	/* fix memcpy, memset references */
	pmemset = (PBYTE)(pmemset-(dcode+0x1d030+0x2F+4));
	*(PDWORD)(dcode+0x1d030+0x2F)=(DWORD)pmemset;
	pmemcpy = (PBYTE)(pmemcpy-(dcode+0x10166));
	*(PDWORD)(dcode+0x10162)=(DWORD)pmemcpy;
	pmemcpy = (PBYTE)&memcpy;
	pmemcpy = (PBYTE)(pmemcpy-(dcode+0x1024a));
	*(PDWORD)(dcode+0x10246)=(DWORD)pmemcpy;

	malware_ucast = (RAW_CODE_PTR)(dcode+0x10130); /* encoding procedure, not used here */
	malware_dcast = (RAW_CODE_PTR)(dcode+0x10210); /* decoding procedure */ 

	do {
		f = CreateFile(TEXT("C:\\Malware\\UROBOROS\\root\\resources\\103.resource-unknown-container.bin"),
			GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
		
		if ( f == INVALID_HANDLE_VALUE )
			break;
		
		GetFileSizeEx(f, &sz);
		if ( !ReadFile(f, membuf, sz.LowPart, &iobytes, NULL) )
			OutputDebugString(TEXT("partial read\r\n"));

		CloseHandle(f);

		/* skip header */
		ent = (PCONTAINER_ENTRY)(membuf+0x2c);

		while ( ent->EntryTypeOrGroupId != 0 ) {

			switch ( ent->EntryTypeOrGroupId ) {
			case 0xfffffffe:
				OutputDebugString(TEXT("= new group: ID="));
				ultostrW(ent->EntryId, textbuf);
				OutputDebugString(textbuf);

				OutputDebugString(TEXT("/"));
				ultostrW(ent->GroupId, textbuf);
				OutputDebugString(textbuf);

				OutputDebugString(TEXT("  count of entries: "));
				ultostrW(ent->EntriesInGroup, textbuf);
				OutputDebugString(textbuf);

				OutputDebugString(TEXT("\r\n"));
				break;

			default:
				/* extract group key */
				if ( ent->DataType == 553 ) {
					keys[i].GroupId = ent->EntryTypeOrGroupId;
					memcpy(keys[i].GroupKey, ent->Data, 16);
					i++;
				}

				OutputDebugString(TEXT("> entry id="));

				ultostr(ent->EntryTypeOrGroupId, textbuf);
				_strcat(textbuf, TEXT("-"));
				ultostrW(ent->EntryId, _strend(textbuf));
				_strcat(textbuf, TEXT("-"));
				ultostrW(ent->EntriesInGroup, _strend(textbuf));
				_strcat(textbuf, TEXT(".bin"));
				OutputDebugString(textbuf);


				for (k=0; k<i; k++) {
					if ( keys[k].GroupId == ent->EntryTypeOrGroupId ) {
						f = CreateFile(textbuf, GENERIC_WRITE | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
						if ( f != INVALID_HANDLE_VALUE ) {
							malware_dcast(keys[k].GroupKey, 16, origText, ent->Data, ent->DataSize);
							WriteFile(f, origText, ent->DataSize-1, &iobytes, NULL);
							CloseHandle(f);
						}
						break;
					}
				}

				OutputDebugString(TEXT("  DataType:"));

				ultostrW(ent->DataType, textbuf);
				OutputDebugString(textbuf);
				OutputDebugString(TEXT("  Size:"));

				ultostrW(ent->DataSize, textbuf);
				OutputDebugString(textbuf);
				OutputDebugString(TEXT("\r\n"));
			}

			ent = (PCONTAINER_ENTRY)((PBYTE)ent+sizeof(CONTAINER_ENTRY)+ent->EntrySize);
		}

	} while (FALSE);

	if ( membuf != NULL )
		VirtualFree(membuf, 0, MEM_RELEASE);

	if ( origText != NULL )
		VirtualFree(origText, 0, MEM_RELEASE);

	if ( dcode != NULL )
		VirtualFree(dcode, 0, MEM_RELEASE);
Attached:

1) patched x64 rootkit driver we used for decryption
2) decrypted container data, including 6 MZ PE libraries (all mentioned in articles dll's)


Thanks to EP_X0FF & MP_ART.

Best Regards,
-rin
Attachments
pass: infected
(533.29 KiB) Downloaded 155 times
pass: infected
(191.17 KiB) Downloaded 152 times
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7