2016kxctf第16题

2016kxctf第16题

Posted by gxkyrftx on January 17, 2019

0.前言

首先应该知道虚拟机的一些基本知识,参考1 然后使用动态调试。

1.脱壳

1.1 od附加调试

这个程序无法直接将程序拖入od调试,因为作者在题目中说了加了壳,而且直接拖入之后,会弹窗不允许反调试,附加进程进行调试可以有效的避免AntiDebuggers检测。具体方法:

1.双击运行程序。
2.file——>attach——>找到运行的程序进程

1.2 脱壳

1.使用strong od
2.plugins——>OllyDump——>脱壳再当前调试的进程——>脱壳

2.调试

2.1 查看dump的程序

使用ida查看,从整体架构来看,如图

1

与虚拟机的整体架构几乎一样,上面的圈出来的部分,即为虚拟机的VMDispatcher,下面的是各个handler,跳转执行;上面是字节码的输入+初始化。典型的虚拟机。点进去VMDispatcher,可以看一眼,是一个跳转表. 下面是Dispatcher

.text:00421224 loc_421224:                             ; CODE XREF: sub_420CE0+53Fj
.text:00421224                 jmp     off_42271B[eax*4] 
//根据eax(opcode)的取值,判断跳转到哪一个handler

下面是跳转表

.text:0042271B off_42271B      dd offset loc_42196F    ; DATA XREF: sub_420CE0:loc_421224r
.text:0042271F                 dd offset loc_421582
.text:00422723                 dd offset loc_4219EE
.text:00422727                 dd offset loc_4218D9
.text:0042272B                 dd offset loc_4216FB
.text:0042272F                 dd offset loc_421F12
.text:00422733                 dd offset loc_4218FF
.text:00422737                 dd offset loc_421A83
.text:0042273B                 dd offset loc_4226D8
.text:0042273F                 dd offset loc_4213E1
.text:00422743                 dd offset loc_421E66
.text:00422747                 dd offset loc_421FF8
.text:0042274B                 dd offset loc_4214A4
.text:0042274F                 dd offset loc_4215B9
.text:00422753                 dd offset loc_421815
.text:00422757                 dd offset loc_42140B
.text:0042275B                 dd offset loc_421EAC
.text:0042275F                 dd offset loc_421B83
.text:00422763                 dd offset loc_421F4E
.text:00422767                 dd offset loc_422041
.text:0042276B                 dd offset sub_421765
.text:0042276F                 dd offset sub_421BDC
.text:00422773                 dd offset sub_4215A0
.text:00422777                 dd offset sub_421C02
.text:0042277B                 dd offset sub_4219D0
.text:0042277F                 dd offset sub_421C3B
.text:00422783                 dd offset sub_42195F
.text:00422787                 dd offset sub_421928
.text:0042278B                 dd offset sub_4218B7
.text:0042278F                 dd offset sub_421B62
.text:00422793                 align 4
.text:00422794                 dd 55004216h, 61004216h, 6700421Fh, 40004215h, 0B2004214h
.text:00422794                 dd 5A004219h, 0DD004220h, 0F9004214h, 0B1004213h, 0E800421Ah
.text:00422794                 dd 0FFFF48DCh, 6558CE9h
.text:004227C4                 db 0

2.2 run trace 分析虚拟机指令

因为oddump出来的程序在与ida的入口地址一致,ida中的VMDispatcher的地址,在od中也是相同的。在od中0x00421224处下断点,运行查看eax为0x0000001B,然后使用run trace,对单个的handler进行追踪,方法如下:

    调试——>打开或清楚RUN追踪——>单步步入

结果如下:

地址  线程  命令  寄存器和注释
    清除收集的信息
00421224     主  jmp dword ptr ds:[eax*4+0x42271B]
00421928     主  and eax,0xED825741  FL=0, EAX=00000001
0042192E     主  mov ax,word ptr ds:[edi+0x8]    EAX=00000000
00421936     主  jmp short CrackMe_.0042193B
0042193B     主  sbb eax,0xED82D59D  FL=CPA, EAX=127D2A63
00421941     主  jmp CrackMe_.00421D12
00421D12     主  add eax,dword ptr ds:[esi+0x2]  FL=P, EAX=12982A63
00421D19     主  jmp CrackMe_.004219F6
004219F6     主  mov eax,dword ptr ds:[esi]  EAX=00000001
004219F8     主  jmp short CrackMe_.004219FE
004219FE     主  add esi,0x4 ESI=0043E56A
00421A01     主  jmp short CrackMe_.00421A05
00421A05     主  sub ebp,0x4 FL=A, EBP=0019FBBC
00421A08     主  jmp short CrackMe_.00421A0B
00421A0B     主  mov dword ptr ss:[ebp],eax
00421A0E     主  jmp CrackMe_.00421810
00421810     主  jmp CrackMe_.0042126B
0042126B     主  jmp short CrackMe_.00421270
00421270     主  jmp short CrackMe_.00421274
00421274     主  movsx eax,bl    EAX=00000000
00421277     主  mov eax,0xED636BF0  EAX=ED636BF0
0042127C     主  jmp CrackMe_.00421281
00421281     主  movsx eax,byte ptr ss:[esp+0x9] EAX=00000029
00421289     主  jmp short CrackMe_.0042128E
0042128E     主  movsx eax,byte ptr ss:[esp+0x5] EAX=00000037
00421296     主  jmp short CrackMe_.00421298
00421298     主  movsx eax,byte ptr ss:[esp+0x4] EAX=FFFFFFE3
004212A0     主  jmp CrackMe_.00421173
00421173     主  pushfd  ESP=0019FA54
00421174     主  clc
00421175     主  jmp short CrackMe_.00421178
00421178     主  adc ax,0x5725   FL=C, EAX=FFFF5708
0042117D     主  jmp short CrackMe_.00421182
00421182     主  inc al  FL=CP, EAX=FFFF5709
00421184     主  jmp CrackMe_.004210BD
004210BD     主  xor ax,0xBF77   FL=PS, EAX=FFFFE87E
004210C2     主  jmp short CrackMe_.004210C6
004210C6     主  lea eax,dword ptr ds:[edi+0x40] EAX=0019FAD8
004210C9     主  jmp short CrackMe_.004210CC
004210CC     主  cmp ebp,eax FL=P
004210CE     主  jmp short CrackMe_.004210D1
004210D1     主  ja CrackMe_.00421208
00421208     主  movzx eax,byte ptr ds:[esi] EAX=0000001B
0042120B     主  jmp CrackMe_.0042123A
0042123A     主  lea esi,dword ptr ds:[esi+0x1]  ESI=0043E56B
0042123D     主  jmp CrackMe_.0042121E
0042121E     主  popfd   FL=A, ESP=0019FA58
0042121F     主  jmp short CrackMe_.00421224
    信息收集完成, 开始动态记录

在这一段程序的执行中,可以使其简化分析,主要的handler代码是0x00421224——0x0042126B,0x0042126B之后的代码,是所有handler的公共的部分,不用考虑。而且在汇编代码中加入了一些混淆,经过分析之后的关键代码如下:

00421224       jmp dword ptr ds:[eax*4+0x42271B]
004219F6       mov eax,dword ptr ds:[esi]  EAX=00000001
00421A05       sub ebp,0x4 FL=A, EBP=0019FBBC
00421A0B       mov dword ptr ss:[ebp],eax

ebp是与栈相关,这段代码,将esi指向的内容放到ebp,然后栈减0x4,把eax的值放入栈中,所以opcode为1B的整体的功能应该是把一个立即数压入栈中。 再接下来是26,去混淆后的关键代码如下

地址  线程  命令  寄存器和注释
    清除收集的信息
00421224       jmp dword ptr ds:[eax*4+0x42271B]
004216AB       mov eax,dword ptr ss:[ebp+0x4]  EAX=00000001
00421713       mov edx,dword ptr ss:[ebp]  EDX=00000000
00421716       imul edx    EAX=00000000
0042171D       mov dword ptr ss:[ebp+0x4],eax
00421720       mov dword ptr ss:[ebp],edx
    信息收集完成, 开始动态记录

看到有一条关键的 imul指令,分析得出,这是将eax*edx,乘完之后放入栈中。

3.求解sn

程序将一个字符串WoJiuShiZheMe与输入的sn异或,然后判断结果是否为1B0602081C1F0D3E352C000A00,所以可以将判定结果与字符串异或,得到的sn如下:

2


本文访问量: