Skip to content

Instantly share code, notes, and snippets.

@klondi
Created December 9, 2020 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klondi/88a7f1615f13863fe8edf00da54ecfa6 to your computer and use it in GitHub Desktop.
Save klondi/88a7f1615f13863fe8edf00da54ecfa6 to your computer and use it in GitHub Desktop.
Show solution to the Hack It 1! From Araba Encounter 07
By klondike of ChaGU
Use wasm-decompile from wabt to get the DCMP files (I also used the was2c to get the static sections in a format that worked for python).
Find the relevant function:
function f_1(a:int):int {
var e:int;
var d:int;
var f:int;
var c:int;
var b:int = g_a - 48;
g_a = b;
b[5]:long = 0L;
b[4]:long = 0L;
b[3]:long = 0L;
b[2]:long = 0L;
b[1]:long = 0L;
b[0]:long = 0L;
if (f_d(a) <= 48) {
c = b | 2;
f_k(b, a);
a = b;
loop L_b {
b[9]:short = (e = b[9]:ushort) + 1;
b[4]:short = b[4]:ushort * (b[3]:ushort | 1);
b[10]:short = (d = b[10]:ushort) << 11 | d >> 5;
b[1]:short =
(d = b[1]:ushort) + b[14]:ushort % ((b[5]:ushort & 15) + 1);
b[7]:short = (d = d ^ b[7]:ushort);
b[13]:short = b[13]:ushort - (b[8]:ushort | (b[15]:ushort ^ d));
b[2]:short = b[2]:ushort + e / ((d & 65535) + 1);
var g:long = c[4]:long@2;
var h:long = c[8]:long@2;
var i:long = c[12]:long@2;
var j:long = c[16]:long@2;
d = c[20]:int@2;
var k:long = c[0]:long@2;
e = b[0]:ushort;
a[22]:short = c[22]:ushort;
a[20]:int@2 = d;
a[16]:long@2 = j;
a[12]:long@2 = i;
a[8]:long@2 = h;
a[4]:long@2 = g;
a[0]:long@2 = k;
b[23]:short = e;
f = f + 1;
if (f != 1337) continue L_b;
}
c = eqz(f_l(a));
}
g_a = b + 48;
return c;
}
Notice that the other two functions are basically a strcpy (which 0-sets the rest of the memory) and a strcmp which compares against the "hashed" password in memory.
function test_pw(a:int):int {
var e:int;
var d:int;
var f:int;
var c:int;
var b:int = g_a - 48; //Stack
g_a = b;
b[5]:long = 0L;
b[4]:long = 0L;
b[3]:long = 0L;
b[2]:long = 0L;
b[1]:long = 0L;
b[0]:long = 0L;
if (strlen(a) <= 48) {
c = b + 2; //Because it is not aligned
//Sets also remaining chars of b to 0
strcpy(b, a);
a=b;
//Note that all the accesses have to multiply the index by 2 to get the real index
loop L_b {
b[9]:short = (e = b[9]:ushort) + 1;
b[4]:short = b[4]:ushort * (b[3]:ushort | 1);
b[10]:short = (d = b[10]:ushort) << 11 | d >> 5;
b[1]:short =
(d = b[1]:ushort) + b[14]:ushort % ((b[5]:ushort & 15) + 1);
b[7]:short = (d = d ^ b[7]:ushort);
b[13]:short = b[13]:ushort - (b[8]:ushort | (b[15]:ushort ^ d));
b[2]:short = b[2]:ushort + e / ((d & 65535) + 1);
var g:long = c[4]:long@2;
var h:long = c[8]:long@2;
var i:long = c[12]:long@2;
var j:long = c[16]:long@2;
d = c[20]:int@2;
var k:long = c[0]:long@2;
e = b[0]:ushort;
a[22]:short = c[22]:ushort;
a[20]:int@2 = d;
a[16]:long@2 = j;
a[12]:long@2 = i;
a[8]:long@2 = h;
a[4]:long@2 = g;
a[0]:long@2 = k;
b[23]:short = e;
f = f + 1;
if (f != 1337) continue L_b;
}
c = eqz(strcmppwd_48(b));
}
g_a = b + 48;
return c;
}
Now start cleaning up the main loop and make indexes clearer to keep track of dependencies
function test_pw(a:int):int {
var e:int;
var d:int;
var f:int;
var c:int;
var b:int = g_a - 48; //Stack
g_a = b;
if (strlen(a) <= 48) {
c = b + 2; //Because it is not aligned
//Sets also remaining chars of b to 0
strcpy(b, a);
a=b;
loop L_b {
e = b[18,19]:ushort
b[18,19]:short = e + 1;
b[8,9]:short = b[8,9]:ushort * (b[6,7]:ushort | 1);
d = b[20,21]:ushort
b[20,21]:short = d << 11 | d >> 5;
d = b[2,3]:ushort
b[2,3]:short = d + b[28,29]:ushort % ((b[10,11]:ushort & 15) + 1);
d = d ^ b[14,15]:ushort
b[14,15]:short = d;
b[26,27]:short = b[26,27]:ushort - (b[16,17]:ushort | (b[30,31]:ushort ^ d));
b[4,5]:short = b[4,5]:ushort + e / ((d & 65535) + 1);
var g:long = c[8-15]:long@2;
var h:long = c[16-23]:long@2;
var i:long = c[24-31]:long@2;
var j:long = c[32-39]:long@2;
d = c[40-43]:int@2;
var k:long = c[0-7]:long@2;
e = b[0,1]:ushort;
a[44,45]:short = c[44,45]:ushort;
a[40-43]:int@2 = d;
a[32-39]:long@2 = j;
a[24-31]:long@2 = i;
a[16-23]:long@2 = h;
a[8-15]:long@2 = g;
a[0-7]:long@2 = k;
b[46,47]:short = e;
f = f + 1;
if (f != 1337) continue L_b;
}
c = eqz(strcmppwd_48(b));
}
g_a = b + 48;
return c;
}
Reorder instructions to avoid unnecessary dependencies so that the hash can be reversed
function test_pw(a:int):int {
var e:int;
var d:int;
var f:int;
var c:int;
var b:int = g_a - 48; //Stack
g_a = b;
if (strlen(a) <= 48) {
c = b + 2; //Because it is not aligned
//Sets also remaining chars of b to 0
strcpy(b, a);
a=b;
loop L_b {
# Variable mixing
b[8,9]:short *= (b[6,7]:ushort | 1);
b[20,21]:short = b[20,21]:ushort << 11 | b[20,21]:ushort >> 5;
b[14,15]:short ^= b[2,3]:ushort;
b[26,27]:short -= (b[16,17]:ushort | (b[30,31]:ushort ^ b[14,15]:short));
b[2,3]:short += b[28,29]:ushort % ((b[10,11]:ushort & 15) + 1);
b[4,5]:short += b[18,19]:ushort / ((b[14,15]:short & 65535) + 1);
b[18,19]:short += 1;
#Rotate 2 bytes to the left
e = b[0,1]:ushort;
b[0-7]:long@2 = b[2-9]:long@2;
b[8-15]:long@2 = b[10-17]:long@2;
b[16-23]:long@2 = b[18-25]:long@2;
b[24-31]:long@2 = b[26-33]:long@2;
b[32-39]:long@2 = b[34-41]:long@2;
b[40-43]:int@2 = b[42-45]:int@2;
b[44,45]:short = b[46,47]:ushort;
b[46,47]:short = e;
f = f + 1;
if (f != 1337) continue L_b; # repeat 1337 times exactly
}
c = eqz(strcmppwd_48(b));
}
g_a = b + 48;
return c;
}
#Implement on python fix a ton of bugs an the result becomes this.
import struct
def gets(i):
global c
return struct.unpack("<H",c[i:][:2])[0]
def sets(i,v):
global c
c = c[:i] + struct.pack("<H",v&0xffff) + c[i+2:]
rvc={}
def revmul(a,b):
if (a,b) in rvc:
return rvc[(a,b)]
for i in range(65536):
if ((i*b)& 0xffff) == a:
rvc[(a,b)] = i
return i
b = bytes([0x74, 0x35, 0xbb, 0x86, 0xec, 0xa2, 0x2b, 0xa2, 0xc6, 0x59, 0x20, 0xfa,
0xf1, 0xba, 0xdb, 0xbe, 0x41, 0x0b, 0x22, 0xc1, 0xfa, 0x2d, 0xb9, 0x25,
0x69, 0x70, 0xc1, 0x28, 0xb4, 0xec, 0x31, 0x36, 0xea, 0x21, 0xd2, 0x9b,
0xdd, 0x02, 0x3b, 0x27, 0xfd, 0x02, 0x4d, 0x1b, 0xa9, 0x35, 0xf7, 0x37,
0x62, 0x6d, 0x6c, 0x6a, 0x5a, 0x53, 0x42, 0x30, 0x63, 0x6e, 0x6b, 0x73,
0x49, 0x48, 0x52, 0x79, 0x65, 0x53, 0x42, 0x6f, 0x59, 0x58, 0x4a, 0x6b,
0x5a, 0x58, 0x49, 0x4b, 0x00, 0x48, 0x69, 0x21, 0x00, 0x00, 0x00, 0x00,
0x58, 0x04])
c=b[:48]
for i in range(1337):
c=c[46:]+c[:46]
sets(18,gets(18)-1)
sets(4,gets(4)-(gets(18)//(((gets(14)&65535)+1)&0xffff)))
sets(26,gets(26)+(gets(16)|(gets(30)^gets(14))))
sets(2,gets(2)-(gets(28)%(((gets(10)&15)+1)&0xffff)))
sets(14,gets(14)^gets(2))
sets(20,((gets(20)>>11)&0xffff)|((gets(20)<<5)&0xffff))
sets(8,revmul(gets(8),gets(6)|1))
print(c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment