首页
论坛
专栏
课程

[原创]看雪2018国庆题--叹息之墙 writeup

2018-9-30 08:44 1003

[原创]看雪2018国庆题--叹息之墙 writeup

2018-9-30 08:44
1003

看雪2018国庆题--叹息之墙 writeup

上IDA分析,发现有大量混淆,稍微翻一下就会发现流程控制关键在[esi+301Ch],如下代码:

.text:0040A091                 mov     dword ptr [esi+301Ch], 0C53FF2DBh
.text:0040A09B
.text:0040A09B loc_40A09B:                             ; CODE XREF: main_routing:loc_45C132↓j
.text:0040A09B                 mov     eax, [esi+301Ch]
.text:0040A0A1                 mov     ecx, eax
.text:0040A0A3                 sub     ecx, 8044FF2Eh
.text:0040A0A9                 mov     [esi+3010h], eax
.text:0040A0AF                 mov     [esi+300Ch], ecx
.text:0040A0B5                 jz      loc_45B4CC
.text:0040A0BB                 jmp     $+5
.text:0040A0C0 ; ---------------------------------------------------------------------------
.text:0040A0C0
.text:0040A0C0 loc_40A0C0:                             ; CODE XREF: main_routing+CB↑j
.text:0040A0C0                 mov     eax, [esi+3010h]
.text:0040A0C6                 sub     eax, 808E99FCh
.text:0040A0CB                 mov     [esi+3008h], eax
.text:0040A0D1                 jz      loc_45B6DC
.text:0040A0D7                 jmp     $+5



.text:0045B4C1                 mov     [esi+301Ch], edi
.text:0045B4C7                 jmp     loc_45C132
.text:0045B4CC ; ---------------------------------------------------------------------------
.text:0045B4CC
.text:0045B4CC loc_45B4CC:                             ; CODE XREF: main_routing+C5↑j
.text:0045B4CC                 mov     dword ptr [esi+301Ch], 0A978FD57h
.text:0045B4D6                 jmp     loc_45C132
.text:0045B4DB ; ---------------------------------------------------------------------------
.text:0045B4DB
.text:0045B4DB loc_45B4DB:                             ; CODE XREF: main_routing+7A9↑j
.text:0045B4DB                 mov     dword ptr [esi+301Ch], 61F141E9h
.text:0045B4E5                 jmp     loc_45C132
.text:0045B4EA ; ---------------------------------------------------------------------------
.text:0045B4EA
.text:0045B4EA loc_45B4EA:                             ; CODE XREF: main_routing+1341↑j
.text:0045B4EA                 mov     dword ptr [esi+301Ch], 0C80742B5h
.text:0045B4F4                 jmp     loc_45C132


.text:0045C132                 jmp     loc_40A09B

每个小流程结束后都会设置[esi+301Ch]jmp loc_45C132jmp loc_40A09B。于是OD跑一次并记录[esi+301Ch]的值变化。

 

通过IDA与流程记录文件,分析代码。里面大部分代码直接跳过,只看特别之处。如:

.text:0045B4F9                 lea     eax, aDN        ; "%d%n"
.text:0045B4FF                 xor     ecx, ecx
.text:0045B501                 mov     edx, 0C7DF5C6Bh
.text:0045B506                 mov     edi, 371F8DECh
.text:0045B50B                 lea     ebx, g_input_num
.text:0045B511                 mov     [esi+0E4h], eax
.text:0045B517                 mov     eax, [esi+3030h]
.text:0045B51D                 imul    eax, [eax], 190h
.text:0045B523                 add     ebx, eax
.text:0045B525                 mov     eax, [esi+3030h]
.text:0045B52B                 mov     eax, [eax]
.text:0045B52D                 mov     [esi+0E0h], eax
.text:0045B533                 mov     eax, dword_4A0610[eax*4]
.text:0045B53A                 mov     [esi+0DCh], eax
.text:0045B540                 mov     eax, ecx
.text:0045B542                 sub     eax, 0DFAB5958h
.text:0045B547                 add     eax, 28FC0ED5h
.text:0045B54C                 add     eax, 0DFAB5958h
.text:0045B551                 sub     eax, 8D162C02h
.text:0045B556                 mov     [esi+0D8h], ecx
.text:0045B55C                 mov     ecx, [esi+0DCh]
.text:0045B562                 sub     eax, ecx
.text:0045B564                 add     eax, 8D162C02h
.text:0045B569                 sub     eax, 5CFBC789h
.text:0045B56E                 sub     eax, 28FC0ED5h
.text:0045B573                 add     eax, 5CFBC789h
.text:0045B578                 add     edi, 0
.text:0045B57B                 sub     edi, 7C4BD394h
.text:0045B581                 sub     edi, 371F8DECh
.text:0045B587                 sub     edi, 309F9813h
.text:0045B58D                 sub     edi, 1
.text:0045B590                 add     edi, 309F9813h
.text:0045B596                 sub     edi, 38ECD947h
.text:0045B59C                 add     edi, 7C4BD394h
.text:0045B5A2                 add     edi, 38ECD947h
.text:0045B5A8                 add     edx, 0
.text:0045B5AB                 sub     edx, edi
.text:0045B5AD                 sub     edx, 0C7DF5C6Bh
.text:0045B5B3                 mov     edi, [esi+0D8h]
.text:0045B5B9                 sub     edi, edx
.text:0045B5BB                 add     eax, edi
.text:0045B5BD                 mov     edx, [esi+0D8h]
.text:0045B5C3                 sub     edx, 0B2E9173Dh
.text:0045B5C9                 add     edx, 0
.text:0045B5CC                 mov     edi, [esi+0D8h]
.text:0045B5D2                 sub     edi, eax
.text:0045B5D4                 add     edx, edi
.text:0045B5D6                 add     edx, 8B00383h
.text:0045B5DC                 add     edx, 0B2E9173Dh
.text:0045B5E2                 sub     edx, 8B00383h
.text:0045B5E8                 mov     eax, [esi+0E0h]
.text:0045B5EE                 mov     dword_4A0610[eax*4], edx
.text:0045B5F5                 shl     ecx, 2
.text:0045B5F8                 add     ebx, ecx
.text:0045B5FA                 mov     ecx, g_p_input
.text:0045B600                 mov     edx, [esi+3034h]
.text:0045B606                 sub     esp, 10h
.text:0045B609                 mov     [esp+3074h+var_3074], ecx
.text:0045B60C                 mov     ecx, [esi+0E4h]
.text:0045B612                 mov     [esp+3074h+var_3070], ecx
.text:0045B616                 mov     [esp+3074h+var_306C], ebx
.text:0045B61A                 mov     [esp+3074h+var_3068], edx
.text:0045B61E                 call    maybe_sscanf
.text:0045B623                 add     esp, 10h
.text:0045B626                 mov     ecx, [esi+3034h]
.text:0045B62C                 mov     ecx, [ecx]
.text:0045B62E                 add     ecx, g_p_input
.text:0045B634                 mov     g_p_input, ecx
.text:0045B63A                 mov     ecx, [esi+3030h]
.text:0045B640                 mov     dword ptr [esi+301Ch], 0DD3F6211h
.text:0045B64A                 mov     [esi+0D4h], eax
.text:0045B650                 mov     [esi+0D0h], ecx
.text:0045B656                 jmp     loc_45C132

以上代码作用只是调用了maybe_sscanf函数。

.text:0044C174                 mov     eax, 6C18C304h
.text:0044C179                 mov     ecx, 1EA9A8E1h
.text:0044C17E                 mov     dl, [esi+3052h]
.text:0044C184                 test    dl, 1
.text:0044C187                 cmovnz  eax, ecx
.text:0044C18A                 mov     [esi+301Ch], eax
.text:0044C190                 jmp     loc_45C132

以上是检查[esi+3052h]值,条件跳转的代码。

.text:0045BB71                 mov     dword ptr [esi+301Ch], 7315F665h
.text:0045BB7B                 jmp     loc_45C132

这仅仅是无条件跳转。

.text:0044F166                 mov     eax, 41895433h
.text:0044F16B                 mov     ecx, 1725F3FBh
.text:0044F170                 mov     dl, 1
.text:0044F172                 xor     edi, edi
.text:0044F174                 mov     ebx, 0BB4F0CFBh
.text:0044F179                 mov     [esi+828h], eax
.text:0044F17F                 mov     eax, dword_4A1894
.text:0044F184                 mov     [esi+824h], eax
.text:0044F18A                 mov     eax, dword_4A1890
.text:0044F18F                 add     ebx, 0
.text:0044F192                 sub     ebx, 0FB46ADCh
.text:0044F198                 sub     ebx, 0BB4F0CFBh
.text:0044F19E                 mov     [esi+820h], eax
.text:0044F1A4                 mov     eax, edi
.text:0044F1A6                 sub     eax, 1
.text:0044F1A9                 add     ebx, eax
.text:0044F1AB                 sub     edi, 0FB46ADCh
.text:0044F1B1                 sub     ebx, edi
.text:0044F1B3                 mov     eax, [esi+824h]
.text:0044F1B9                 add     eax, 6E2A6C24h
.text:0044F1BE                 add     eax, 0BF00A7B3h
.text:0044F1C3                 sub     eax, 6E2A6C24h
.text:0044F1C8                 sub     eax, 0FCF7B00Bh
.text:0044F1CD                 add     eax, ebx
.text:0044F1CF                 add     eax, 0FCF7B00Bh
.text:0044F1D4                 sub     eax, 8F760F48h
.text:0044F1D9                 sub     eax, 0BF00A7B3h
.text:0044F1DE                 add     eax, 8F760F48h
.text:0044F1E3                 mov     edi, [esi+824h]
.text:0044F1E9                 imul    edi, eax
.text:0044F1EC                 and     edi, 1
.text:0044F1EF                 cmp     edi, 0
.text:0044F1F2                 setz    dh
.text:0044F1F5                 mov     eax, [esi+820h]
.text:0044F1FB                 cmp     eax, 0Ah
.text:0044F1FE                 setl    al
.text:0044F201                 mov     ah, al
.text:0044F203                 xor     ah, 0FFh

这段代码实际上是条件跳转,以text:0044F170 mov dl, 1为条件,其它类似的只需关心dl的值。

 

小流程中的代码大多与以上类似。看一眼就能明白在干什么。

 

理完,程序过程大概是:

  • 输出题目信息,并要求用户输入(%1000s)
  • 将用户输入的整数按格式提取出来,以int存储
  • int数再按格式组成字串与输入原始串比较(防止多解,比如多0了)
  • int数为序号查常量表,所查结果相加,得sum
  • 校验 (0x65757832** sum)%0xFFA1CF8F == 0x6E616B34

用大步小步算法,算出一个sum的值0x55121c15,跑了下,结果没结果。
(0x65757832** r)%0xFFA1CF8F == 1得到检验式的值周期为0xFFA1CF8E

 

发现sum的个位始终是7(0x55121c15+0xFFA1CF8En = 1427250197 + 4288794510n)。

 

又发现表中数据基本都是个位为0;数据成对相加结果为0xFFA1CF8E;里面有多个等比数列,最后整理出9组数,每组的数都是此组最小元素的倍数。正合“正确的序列号由不超过9整数构成”的提示,从9组数中各选出一个数,这样就没有多解的情况(当然也有整数个数小于9的情况,只要每组选出不多于一个数,就没有多解的可能,可暂先不考虑)。

9组数的基数
15825810        270
138348210        30
252282030        16
329907270        12
389890410        10
612684930        6
857758902        4
1429598170        2
2144397255        1

最终得出答案:17x27x60x97x133x161x243x292x309X

 

用过的脚本,使用过程中一直在改变,前面用到的都在注释中:

# -*- coding:utf-8 -*-
import gmpy2
import struct
import itertools

#def crack_num():

def quick_mod(a,b,c):
  r = 1
  while b:
    if b % 2 == 1:
      r = (r*a)%c
    b /= 2
    a = (a**2)%c
  return r

def log_mod(a,b,n):
  e = 1
  m = int(gmpy2.root(n+0.5,2))
  v =  quick_mod(quick_mod(a,m,n),n-2,n)
  x = {}
  x[1] = 0
  for i in range(1,m):
    e = (e*a)%n
    if e not in x.keys():
      x[e] = i
  l = []
  for i in range(m):
    if b in x.keys():
      l.append(i*m+x[b])
#      return i*m+x[b]
    b = (b*v)%n
  return l

def main():

  c = 0x6E616B34
  a = 0x65757832
  n = 0xFFA1CF8F
  x = 0x55121c15
  m = 0xFFA1CF8E
#  print log_mod(a,1,n)
  d = file('table.bin','rb').read()
  d = list(struct.unpack('351I',d))

#  d1 = list(d)
#  for i in d:
#    if i % 15825810 == 0 or i % 0x083f06b2 == 0 :#or i % 252282030 == 0 or i % 329907270 == 0 or i % 389890410 == 0 or i%612684930==0 or i%857758902==0:
#      if i in d1:
#        d1.remove(i)
#        d1.remove(m-i)
#  d1.sort()
#  print d1,len(d1)
  ll = [15825810 ,138348210,252282030,329907270,389890410,612684930,857758902 ,1429598170,2144397255]
#  la = [[] for x in range(9)]   mmp   bullshit  xxxxxxxxxxxxxxxxxxxxxxxxx
  la = [[] for i in range(9)]
  for i in d:
    for j in xrange(9):
      if i%ll[j] == 0:
        la[j].append(i)
  it = itertools.product(*la)
  print len(la[0]),len(la[1]),len(la[2]),len(la[3]),len(la[4]),len(la[5]),len(la[6]),len(la[7]),len(la[8])

  for i in it:
    if sum(i)%m == x:
      print i
      tmp = []
      for j in i:
        tmp.append(d.index(j))
      tmp.sort()
      print tmp
      break

#  lr = [1171109940, 553392840, 3027384360L, 3958887240L, 1559561640, 2450739720L, 857758902, 2859196340L, 2144397255]
#  [17, 27, 60, 97, 133, 161, 243, 292, 309]
#  17x27x60x97x133x161x243x292x309X
  print 'end.'

if __name__ == '__main__':
  main()


[招聘]欢迎市场人员加入看雪学院团队!

最后于 2018-10-3 13:02 被poyoten编辑 ,原因:
上传的附件:
最新回复 (0)
游客
登录 | 注册 方可回帖
返回