欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ciscn 2020 reverse hyperthreading

程序员文章站 2022-05-12 14:01:53
...

hyperthreading

Start

搜索字符串找到关键函数:

int sub_401270()
{
  signed int v0; // eax
  HANDLE Handles; // [esp+8h] [ebp-Ch]
  HANDLE v3; // [esp+Ch] [ebp-8h]

  printf("plz input your flag:");
  scanf("%42s", byte_40336C);
  Handles = CreateThread(0, 0, StartAddress, 0, 0, 0);
  v3 = CreateThread(0, 0, loc_401200, 0, 0, 0);
  CreateThread(0, 0, sub_401240, 0, 0, 0);
  WaitForMultipleObjects(2u, &Handles, 1, 0xFFFFFFFF);
  v0 = 0;
  do
  {
    if ( byte_40336C[v0] != byte_402150[v0] )
    {
      printf("error");
      exit(0);
    }
    ++v0;
  }
  while ( v0 < 42 );
  printf("win");
  getchar();
  return 0;
}

看到关键句:
byte_40336C[v0] != byte_402150[v0]
找到加密后的字符串
ciscn 2020 reverse hyperthreading
这里创建了一堆线程:ciscn 2020 reverse hyperthreading
跟进sub_401240发现,这里用到了IsDebuggerPresent反调试函数

void __stdcall __noreturn sub_401240(LPVOID lpThreadParameter)
{
  while ( !IsDebuggerPresent() )
    ;
  printf("debug!\n");
  exit(0);
}

根据题名可以猜测,加密的线程被加密了,无法直接看到加密过程
将进程载入OD,在输入处下断点
ciscn 2020 reverse hyperthreading
运行,单步到007F1296,此时要求输入flag,随便输点东西ciscn 2020 reverse hyperthreading
之后一直单步,走到WaitForMultipleObjects,往下程序就会卡在这个位置,因为前面判断了程序处于调试模式,所以线程会一直占用,出不来。ciscn 2020 reverse hyperthreading
这里先按下暂停,然后再点运行,会发现程序就过了WaitForMultipleObject这个函数,上面那个判断反调式的线程没有占用资源了ciscn 2020 reverse hyperthreading
之后看到关键比较
ciscn 2020 reverse hyperthreading
dd 7f336c
ciscn 2020 reverse hyperthreading
dd 7f2150
ciscn 2020 reverse hyperthreading
通过比较后,发现7f2150开始的位置就是byte_402150
7f336c就是我们输入的flag经过处理后的结果。
经过多次尝试发现,对于每个字符,每一次的加密结果是固定的,那么就可以通过遍历有可能是flag的字符,查看每个字符加密后的结果,与真正flag加密后的结果进行逐一比较,最终可以得到flag

exp.py

encrypt = [0xDD,0x5B,0x9E,0x1D,0x20,0x9E,0x90,0x91,0x90,0x90,0x91,0x92,0xDE,0x8B,0x11,0xD1,0x1E,0x9E,0x8B,0x51,0x11,0x50,0x51,0x8B,0x9E,0x5D,0x5D,0x11,0x8B,0x90,0x12,0x91,0x50,0x12,0xD2,0x91,0x92,0x1E,0x9E,0x90,0xD2,0x9F]
key_dic = {'a':0x9E,'b':0xDE,'c':0x1E,'d':0x5D,'e':0x9D,'f':0xDD,'g':0x1D,'h':0x5C,'i':0x9C,'j':0xDC,'k':0x1C,'l':0x5B,'m':0x9B,'n':0xDB,'o':0x1B,'p':0x62,'q':0xA2,'r':0xE2,'s':0x22,'t':0x61,'u':0xA1,'v':0xE1,'w':0x21,'x':0x60,'y':0x0A,'z':0xE0,'_':0x17,'{':0x20,'}':0x9F,'0':0x52,'1':0x92,'2':0xD2,'3':0x12,'4':0x51,'5':0x91,'6':0xD1,'7':0x11,'8':0x50,'9':0x90,'-':0x8B}

flag = ''

for i in encrypt:
	for j in key_dic:
		if key_dic[j] == i:
			flag += j

print(flag)

# flag{a959951b-76ca-4784-add7-93583251ca92}
ps: 这道题的思路应该就是考的绕过isDebuggerPresent函数

ciscn 2020 reverse hyperthreading
这里可以发现,当EIP处于WaitForMultipleObjects之前时,0x0087336c的值还是我们输入的字符串,并没有进行处理。(这里是我之后补充的,所以基地址不同)

End