首页
社区
课程
招聘
[原创]看雪 2016 CTF 第五题 Solution
发表于: 2016-11-10 18:06 2497

[原创]看雪 2016 CTF 第五题 Solution

HHHso 活跃值
22
2016-11-10 18:06
2497
40KB 麻雀虽小,五脏俱全。
不知为何,这让想起了顾参数的顾桥教授给我们上量子力学时提的一句:"Less is More!"
6位密码,想不到比枚举更好的方法,直上Python跑出来。

(1)进门,跨过运行时环境初始化,进入作者写的代码 main 。
4012D0 start
  401399 call    _WinMain@16
    .text:004012B4 push    0               ; dwInitParam
    .text:004012B6 push    offset DialogFunc ; lpDialogFunc
    .text:004012BB push    0               ; hWndParent
    .text:004012BD push    65h             ; lpTemplateName
    .text:004012BF push    eax             ; hInstance
    .text:004012C0 call    ds:DialogBox

(2)由(1)进入对话框消息处理,文本的获取不是GetWindowText 或 GetWindowLong,而是发送请求消息获取
.text:0040115B lea     eax, [esp+120h+lParam]
.text:0040115F mov     edi, 1
.text:00401164 push    eax             ; lParam
.text:00401165 push    0FFh            ; wParam
.text:0040116A push    WM_GETTEXT      ; Msg
.text:0040116C push    3E9h            ; nIDDlgItem
.text:00401171 push    esi             ; hDlg
.text:00401172 call    ebx ; GetDlgItem
.text:00401174 mov     ebp, ds:SendMessageA
.text:0040117A push    eax             ; hWnd
.text:0040117B call    ebp ; SendMessa

(3)获取输入key后限定检测数字,后面要求长度为6
.text:00401187                 cmp     dl, 30h
.text:0040118A                 jl      short loc_401198
.text:0040118C                 cmp     dl, 39h
.text:0040118F                 jg      short loc_401198

(4)随后通过key发散得到异或矩阵,对保护代码解密(只有对的key扩散的矩阵才能得到正确的解密)
Hi_decrypt_EncDigest_with_P1lpszKey_P2size_sub_401000 解密后 进行校验和检测以验证是否用正确的key解密出正确的结果。
执行解码的代码,提示成功  "success!youareclever."
.text:004011A3 lea     ecx, [esp+120h+lParam]
.text:004011A7 push    eax
.text:004011A8 push    ecx
.text:004011A9 call    Hi_decrypt_EncDigest_with_P1lpszKey_P2size_sub_401000
.text:004011AE add     esp, 8
.text:004011B1 call    Hi_CheckCrc_sub_4010C0

(5)完成保护功能后,再加密回去。

getXorFromKey 直接返回由key扩散后进一步得到的异或解密矩阵
checkXorM 检测用相应异或矩阵的结果校验值,不正确继续

从IDA提取的加密方法体
"""
用于从IDA提取保护的加密方法体
a = []
for i in xrange(0,0x80):
  print "0x{:02X}, ".format(Byte(0x406030+i)),
  if ((i + 1) % 0x10) == 0:
    print ""
"""

CrcM = [0xF4,  0x12,  0x9D,  0x60,  0x45,  0xF8,  0x20,  0x6A,  0x6F,  0x67,  0x04,  0x71,  0xC0,  0x9B,  0x0C,  0x5A,  
  0x1D,  0x18,  0x6C,  0x96,  0x69,  0x01,  0x1C,  0xF4,  0x7F,  0x28,  0x5A,  0xFB,  0x29,  0x07,  0x40,  0x8B,  
  0xD3,  0xE1,  0xB1,  0x12,  0xFB,  0xCA,  0x7C,  0x89,  0xB9,  0x5A,  0x30,  0x70,  0x9D,  0x95,  0x2B,  0x95,  
  0x3C,  0x8D,  0x2E,  0x45,  0xEF,  0x70,  0xC6,  0xA3,  0xB9,  0xB2,  0x5A,  0x63,  0x5F,  0x03,  0x33,  0xB8,  
  0x64,  0x4A,  0x8F,  0xBC,  0xF7,  0x91,  0x69,  0x6A,  0x56,  0x2E,  0xD4,  0x6E,  0x82,  0x93,  0xE9,  0x76,  
  0xDC,  0xA3,  0x6C,  0x5E,  0x6B,  0x72,  0x64,  0x37,  0xE7,  0x15,  0x17,  0xAC,  0x64,  0x78,  0xD5,  0x4A,  
  0x60,  0x2D,  0xF0,  0x54,  0xA6,  0xF3,  0xE8,  0xE0,  0xE0,  0xB9,  0x8F,  0x85,  0x90,  0xE4,  0xEA,  0xD6,  
  0xBB,  0xB7,  0x15,  0x9E,  0x2A,  0x44,  0xE7,  0x31,  0x63,  0xAC,  0x80,  0x6C,  0x34,  0x82,  0xE9,  0xCF]

from ctypes import *
def getXorFromKey(keyi):
  buf100 = [ i for i in xrange(0,0x100)]
  cl = c_ubyte(0)
  bl = c_ubyte(0)
  dl = c_ubyte(0)
  bufi = 0
  ki = 0
  while True:
    cl.value = buf100[bufi]
    bl.value = keyi[ki]
    bl.value = bl.value + cl.value
    dl.value = dl.value + bl.value
    bl.value = buf100[dl.value]
    buf100[bufi] = bl.value
    buf100[dl.value] = cl.value
    ki = ki + 1
    if ki == 6:
      ki = 0
    bufi = bufi + 1
    if bufi == 0x100:
      break
  XorM = []
  for i in xrange(0,0x80):
    bl.value = buf100[i]
    dl.value = buf100[0xff-i]
    dl.value = dl.value + bl.value
    XorM.append(dl.value)
  return XorM

def checkXorM(XorM):
  global CrcM
  dl = c_ubyte(0)
  bl = c_ubyte(0)
  DecM = []
  esiedi = c_ulonglong(0)
  for i in xrange(0,0x80):
    dl.value = XorM[i]
    bl.value = CrcM[i]
    dl.value = dl.value ^ bl.value
    esiedi.value = esiedi.value + dl.value
    DecM.append(dl.value)
  if esiedi.value == 0x2979:
    return True
  else:
    return False

def Enum(cont = False):
  for i in xrange(0,0x1000000):
    keys = "{:06}".format(i)
    keyi = [ord(ch) for ch in keys]
    XorM = getXorFromKey(keyi)
    if checkXorM(XorM):
      print keys
      if cont:
        continue
      else:
        return

Enum(True) 得到结果 771535 (根据CPU情况,使用特定数量的并发线程分区枚举应该会快些)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//