01 Feb 2016 @ 7:46 PM 

x64 ELF, probably obfuscated with LLVM Obfuscator. Hexrays will decompile it to a nested while-loop.

RE3-obfI spent sometime understanding how exactly it works. Basic idea about this obfuscation is to transform pieces of code into different loops, set a variable to identify which loop and condition to execute. Even though it looked confusing initially, with a bit of splicing decompiled code, it made better sense.

Essentially code reads 16 numbers, and calls a function (sub_400780())to see if that value is correct or not. If it is correct, the next number is checked. If the numbers are correct, it is used in some operation to finally calculate the flag string.

To solve this I decompiled sub_400780() and bruteforced it. Initially I thought there will be only 1 correct solution and I have figured all the checks, only to see that there are few other checks (like total length should be 26).

unsigned int cpow(int val, int pow)
{
	unsigned int pp = 1;
	while (pow)
	{
		pp *= val;
		pow--;
	}
	return pp;
}

int Brute(unsigned int loc)
{
	unsigned int HCArr[] = { 0xE2246054, 0x1DDB9FAF, 0x0E224604C, 0x1DDB9FA9, 0x0EB48CD5A, 0x0EB48CD66, 0x0EB48CD68, 0x14B732AC, 0x0E9682E7A, 0x0E9682E3A, 0x0E9682E37, 0x1697D1DA, 0x9E32D9, 0x0FF61CD00, 0x0FF61CD1F, 0x9E32FE, 0x3FDD8C9D, 0x0C0227348, 0x0C0227355, 0x3FDD8CAB, 0x108AE52C, 0x0EF751AFB, 0x0EF751AFA, 0x108AE52C, 0x0FED8F192, 0x1270E7E, 0x0FED8F1BE, 0x1270E73, 0x3D51216D, 0x3D51214B, 0x0C2AEDEBA, 0x3D512142, 0x0D63C4BCE, 0x29C3B40C, 0x29C3B42E, 0x29C3B42F, 0x0C93E69E2, 0x0C93E69AD, 0x36C19603, 0x36C19641, 0x1149F143, 0x0EEB60ED5, 0x0EEB60E9E, 0x1149F173, 0x0CB68709A, 0x0CB6870DE, 0x0CB6870B5, 0x34978F66, 0x0C163D0A7, 0x3E9C2F09, 0x3E9C2F02, 0x3E9C2F5F, 0x0D2CB22ED, 0x2D34DD3E, 0x0D2CB22F3, 0x2D34DD1B, 0x0F6BA6729, 0x0F6BA6721, 0x0F6BA6769, 0x94598CD, 0x0D302FAE3, 0x0D302FA82, 0x2CFD057C, 0x2CFD0554 };

	unsigned int val = 0;
	unsigned int res = 0;
	unsigned int eax, edx, ebx, ecx, esi, edi, r8d, r9d, r10d;

	while (val < 0xFFFFFFFF)
	{
		res = cpow(val, 3);
		eax = cpow(val, 2);
		edx = HCArr[loc * 4];
		ecx = HCArr[(loc * 4) + 3];

		esi = (~edx) & 0x6EFBE94D;
		edx = edx & 0x910416B2;
		edi = (~ecx) & 0x6EFBE94D;
		ecx = ecx & 0x910416B2;

		edx = edx | esi;
		ecx = ecx | edi;
		ecx = ecx ^ edx;
		ecx = ecx * eax;
		ecx = -ecx;
		ecx -= res;
		ecx = -ecx;
		res = ecx;

		eax = cpow(val, 2);
		edx = HCArr[(loc * 4) + 1];
		ecx = HCArr[(loc * 4) + 3];
		esi = (~edx) & ecx;
		ecx = (~ecx) & edx;
		ecx |= esi;
		ecx *= eax;
		res += ecx;

		eax = cpow(val, 2);
		edx = HCArr[(loc * 4) + 2];
		ecx = HCArr[(loc * 4) + 3];
		esi = (~edx) & 0x43B37B1;
		edx &= 0x0FBC4C84E;
		edi = (~ecx) & 0x43B37B1;
		ecx &= 0x0FBC4C84E;
		edx |= esi;
		ecx |= edi;
		ecx ^= edx;
		ecx *= eax;
		ecx = -ecx;
		res -= ecx;

		esi = HCArr[(loc * 4)];
		edi = (~esi) & 0x59C0DD4B;
		esi &= 0x0A63F22B4;

		ebx = HCArr[(loc * 4) + 3];
		ecx = (~ebx) & 0x59C0DD4B;
		eax = ebx & 0x0A63F22B4;
		esi |= edi;
		eax |= ecx;
		eax ^= esi;

		ecx = HCArr[(loc * 4) + 1];
		edx = (~ecx) & 0x0BA0892CF;
		ecx &= 0x45F76D30;
		ebx = (~HCArr[(loc * 4) + 3]) & 0x0BA0892CF;
		r8d = HCArr[(loc * 4) + 3] & 0x45F76D30;
		ecx |= edx;
		r8d |= ebx;
		r8d ^= ecx;
		r8d *= eax;
		r8d *= val;
		res += r8d;

		ecx = HCArr[(loc * 4) + 2];
		esi = (~ecx) & 0x0EFD60EC8;
		ecx &= 0x1029F137;
		eax = HCArr[(loc * 4) + 3];
		edi = ~eax;
		ebx = (edi)& 0x0EFD60EC8;
		edx = eax & 0x1029F137;
		ecx |= esi;
		edx |= ebx;
		edx ^= ecx;
		ecx = HCArr[(loc * 4) + 1];
		esi = (~ecx) & 0x6F5BEF81;
		ecx &= 0x90A4107E;
		edi &= 0x6F5BEF81;
		eax &= 0x90A4107E;
		ecx |= esi;
		eax |= edi;
		eax ^= ecx;
		eax *= edx;
		eax *= val;
		res += eax;

		ecx = HCArr[(loc * 4)];
		edx = (~ecx) & 0x50C0D70D;
		ecx &= 0x0AF3F28F2;
		eax = HCArr[(loc * 4) + 3];
		edi = ~eax;
		ebx = edi & 0x50C0D70D;
		esi = eax & 0x0AF3F28F2;
		ecx |= edx;
		esi |= ebx;
		esi ^= ecx;

		ecx = HCArr[(loc * 4) + 2];
		edx = ecx;
		edx = (~edx) & eax;
		edi &= ecx;
		edi |= edx;
		edi *= esi;
		edi *= val;
		res += edi;

		r10d = HCArr[(loc * 4)];
		ecx = ~r10d;
		eax = HCArr[(loc * 4) + 3];
		ecx &= eax;
		esi = ~eax;
		r10d &= esi;
		r10d |= ecx;

		ecx = HCArr[(loc * 4) + 1];
		ebx = (~ecx) & 0x73E6034A;
		ecx &= 0x8C19FCB5;
		edx = esi & 0x73E6034A;
		edi = eax & 0x8C19FCB5;
		ecx |= ebx;
		edi |= edx;
		edi ^= ecx;
		edi *= r10d;

		ecx = HCArr[(loc * 4) + 2];
		edx = (~ecx) & 0x0AC23EFC0;
		ecx &= 0x53DC103F;
		esi &= 0x0AC23EFC0;
		eax &= 0x53DC103F;
		ecx |= edx;
		eax |= esi;
		eax ^= ecx;
		eax *= edi;
		res += eax;

		if (res == 0x0)
		{
			printf("%x-", val);
			//return val;
		}
		val++;
	}
	return 0;
}

int main()
{
	printf("%d\n", Brute(11));
	printf("%d\n", Brute(12));
	printf("%d\n", Brute(6));
	printf("%d\n", Brute(7));

	printf("%d\n", Brute(4));
	printf("%d\n", Brute(0xd));
	printf("%d\n", Brute(5));
	printf("%d\n", Brute(0));

	printf("%d\n", Brute(1));
	printf("%d\n", Brute(0xf));
	printf("%d\n", Brute(8));
	printf("%d\n", Brute(0xe));

	printf("%d\n", Brute(0xa));
	printf("%d\n", Brute(2));
	printf("%d\n", Brute(9));
	printf("%d\n", Brute(3));
	return 0;
}

Now I had a list of solutions for each of 16 numbers, and I needed to make a combination of them and  bruteforce the binary directly. I removed large numbers as it won’t fit the 26 length criteria.
import sys
import subprocess
import itertools

a = [[4, 45, 72], [8], [31, 51], [8], [2, 29], [10, 24], [0, 41, 42], [3, 27], [10, 53, 60], [42, 73], [31], [20, 28, 92], [19, 90], [19, 32, 96], [20, 93], [2, 31]]

vals = list(itertools.product(*a))
count = 0;
while count < len(vals):
	p = subprocess.Popen("./donfos_reversing", stdin=subprocess.PIPE)
	p.stdin.write(str(vals[count][0]) + '\n')
	p.stdin.write(str(vals[count][1]) + '\n')
	p.stdin.write(str(vals[count][2]) + '\n')
	p.stdin.write(str(vals[count][3]) + '\n')
	p.stdin.write(str(vals[count][4]) + '\n')
	p.stdin.write(str(vals[count][5]) + '\n')
	p.stdin.write(str(vals[count][6]) + '\n')
	p.stdin.write(str(vals[count][7]) + '\n')
	p.stdin.write(str(vals[count][8]) + '\n')
	p.stdin.write(str(vals[count][9]) + '\n')
	p.stdin.write(str(vals[count][10]) + '\n')
	p.stdin.write(str(vals[count][11]) + '\n')
	p.stdin.write(str(vals[count][12]) + '\n')
	p.stdin.write(str(vals[count][13]) + '\n')	
	p.stdin.write(str(vals[count][14]) + '\n')
	p.stdin.write(str(vals[count][15]) + '\n')
	p.stdin.close()
	ret = p.wait()
	count = count+1

Runnin it for sometime gave possible flags:

Good Job!!
flag=nullcon{d0n_f05ijg[65\5rt_t0_n8?qo1}
Good Job!!
flag=nullcon{d0n_f05ing_15_4rt_t0_l34rn}
Good Job!!
flag=nullcon{d0h_f0=kna]22Z6uw^u3Vd:?tn02}
Good Job!!
flag=nullcon{g:e]o:6hje^74[1rv\v1_m;?{o31}
Good Job!!
flag=nullcon{g:e]o:6hja^33[2sv\v1_m94pl2}

nullcon{d0n_f05ing_15_4rt_t0_l34rn} it is!

Posted By: Dan
Last Edit: 01 Feb 2016 @ 07:46 PM

EmailPermalink
Tags
Categories: CTF, HackIM2016


 

Responses to this post » (None)

 
Post a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


 Last 50 Posts
Change Theme...
  • Users » 1
  • Posts/Pages » 19
  • Comments » 41
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

About



    No Child Pages.