首页
论坛
专栏
课程

[原创]看雪.Wifi万能钥匙 CTF 2017 第15题Writeup

2017-6-30 19:16 1498

[原创]看雪.Wifi万能钥匙 CTF 2017 第15题Writeup

2017-6-30 19:16
1498


此题壳及混淆比较麻烦,没搞定,但是可以dump绕过壳,主要算法在luajit虚拟机内,整体算法比较简单,就是两个异或。所以完全可以不用理会混淆。下面说下过程。

拖进ida,发现有壳,其中还有混淆,有大量跳转。于是动态了下,由于真实指令在就混淆跳转中,没找到入口,放弃此办法。

直接运行程序,查看了进程,只有一个进程,直接dump。原文件大小是999kb,dump出来的有3M之多。

将dump出来的文件直接拖进ida,查看字串,发现多处含有lua字样的字串,包括LuaJIT 2.1.0-beta3Lua 5.1,估计是lua的虚拟机了。继续翻看,发现了程序的输入提示Pls Input Serial Number:,其上下还有mainWrong!\r\nCongratulations!\r\n,查看其引用,只有main找到了显式引用,位置在4021EC,大致看了下,此位置代码很可疑,而且main这个词也很敏感啊,很有可以就是lua脚本的主函数名。

代码比较长,我就不全部上了。此函数或过程的入口应该在401000401005,一波跳转后,过两条nop,来到40103D40103D4021C0为向栈区写数据,这么大段的基本是硬编码的数据很可能是lua的脚本相关数据。

之后就是调用了几个函数,在402210处有个根据函数返回的条件跳转。如果不跳,则返回0。

.text:004021FE                 call    sub_4130E0
.text:00402203                 push    1
.text:00402205                 push    esi
.text:00402206                 call    sub_413DB0
.text:0040220B                 add     esp, 38h
.text:0040220E                 test    eax, eax
.text:00402210                 jz      short loc_40222C
.text:00402212                 pop     edi
.text:00402213                 pop     esi
.text:00402214                 xor     eax, eax
.text:00402216                 pop     ebx
.text:00402217                 mov     ecx, [esp+29Ch]
.text:0040221E                 xor     ecx, esp
.text:00402220                 call    sub_4023E0
.text:00402225                 add     esp, 2A0h
.text:0040222B                 retn
.text:0040222C ; ---------------------------------------------------------------------------
.text:0040222C
.text:0040222C loc_40222C:                             ; CODE XREF: .text:00402210j
.text:0040222C                 push    ebp
.text:0040222D                 push    0FFFFFFF4h
.text:0040222F                 push    esi
.text:00402230                 call    sub_412CE0
.text:00402235                 mov     edi, eax
.text:00402237                 push    0FFFFFFF5h
.text:00402239                 push    esi
.text:0040223A                 xor     edi, 5
.text:0040223D                 call    sub_412CE0
.text:00402242                 mov     ebx, eax
.text:00402244                 push    0FFFFFFF6h
.text:00402246                 push    esi
.text:00402247                 xor     ebx, 12h
.text:0040224A                 call    sub_412CE0
.text:0040224F                 mov     ebp, eax
.text:00402251                 push    0FFFFFFF7h
.text:00402253                 push    esi
.text:00402254                 xor     ebp, 0Ah
.text:00402257                 call    sub_412CE0
.text:0040225C                 xor     eax, 29h
.text:0040225F                 push    0FFFFFFF8h
.text:00402261                 push    esi
.text:00402262                 mov     [esp+58h], eax
.text:00402266                 call    sub_412CE0
.text:0040226B                 xor     eax, 42h
.text:0040226E                 push    0FFFFFFF9h
.text:00402270                 push    esi
.text:00402271                 mov     [esp+48h], eax
.text:00402275                 call    sub_412CE0
.text:0040227A                 xor     eax, 41h
.text:0040227D                 push    0FFFFFFFAh
.text:0040227F                 push    esi
.text:00402280                 mov     [esp+60h], eax
.text:00402284                 call    sub_412CE0
.text:00402289                 xor     eax, 75h
.text:0040228C                 push    0FFFFFFFBh
.text:0040228E                 push    esi
.text:0040228F                 mov     [esp+60h], eax
.text:00402293                 call    sub_412CE0
.text:00402298                 add     esp, 40h
.text:0040229B                 xor     eax, 61h
.text:0040229E                 push    0FFFFFFFCh
.text:004022A0                 push    esi
.text:004022A1                 mov     [esp+18h], eax
.text:004022A5                 call    sub_412CE0
.text:004022AA                 xor     eax, 35h
.text:004022AD                 push    0FFFFFFFDh
.text:004022AF                 push    esi
.text:004022B0                 mov     [esp+24h], eax
.text:004022B4                 call    sub_412CE0
.text:004022B9                 xor     eax, 83h
.text:004022BE                 push    0FFFFFFFEh
.text:004022C0                 push    esi
.text:004022C1                 mov     [esp+34h], eax
.text:004022C5                 call    sub_412CE0
.text:004022CA                 xor     eax, 55h
.text:004022CD                 push    0FFFFFFFFh
.text:004022CF                 push    esi
.text:004022D0                 mov     [esp+44h], eax
.text:004022D4                 call    sub_412CE0
.text:004022D9                 xor     eax, 94h
.text:004022DE                 push    0FFFFFFF3h
.text:004022E0                 push    esi
.text:004022E1                 mov     [esp+54h], eax
.text:004022E5                 call    sub_412810
.text:004022EA                 push    esi
.text:004022EB                 call    sub_414370
.text:004022F0                 add     esp, 2Ch
.text:004022F3                 cmp     edi, 18h
.text:004022F6                 jnz     short loc_40234C
.text:004022F8                 cmp     ebx, 16h
.text:004022FB                 jnz     short loc_40234C
.text:004022FD                 cmp     ebp, 1Eh
.text:00402300                 jnz     short loc_40234C
.text:00402302                 cmp     dword ptr [esp+30h], 2Fh
.text:00402307                 jnz     short loc_40234C
.text:00402309                 cmp     dword ptr [esp+18h], 48h
.text:0040230E                 jnz     short loc_40234C
.text:00402310                 cmp     dword ptr [esp+28h], 11h
.text:00402315                 jnz     short loc_40234C
.text:00402317                 cmp     dword ptr [esp+20h], 21h
.text:0040231C                 jnz     short loc_40234C
.text:0040231E                 cmp     dword ptr [esp+10h], 37h
.text:00402323                 jnz     short loc_40234C
.text:00402325                 cmp     dword ptr [esp+14h], 33h
.text:0040232A                 jnz     short loc_40234C
.text:0040232C                 cmp     dword ptr [esp+1Ch], 86h
.text:00402334                 jnz     short loc_40234C
.text:00402336                 cmp     dword ptr [esp+24h], 52h
.text:0040233B                 jnz     short loc_40234C
.text:0040233D                 cmp     dword ptr [esp+2Ch], 94h
.text:00402345                 jnz     short loc_40234C
.text:00402347                 lea     eax, [edi-17h]
.text:0040234A                 jmp     short loc_40234E
.text:0040234C ; ---------------------------------------------------------------------------
.text:0040234C
.text:0040234C loc_40234C:                             ; CODE XREF: .text:004022F6j
.text:0040234C                                         ; .text:004022FBj ...
.text:0040234C                 xor     eax, eax
.text:0040234E
.text:0040234E loc_40234E:                             ; CODE XREF: .text:0040234Aj
.text:0040234E                 mov     ecx, [esp+2ACh]
.text:00402355                 pop     ebp
.text:00402356                 pop     edi
.text:00402357                 pop     esi
.text:00402358                 pop     ebx
.text:00402359                 xor     ecx, esp
.text:0040235B                 call    sub_4023E0
.text:00402360                 add     esp, 2A0h
.text:00402366                 retn

再看跳转目标处loc_40222C的代码。先是12个sub_412CE0调用,再接着是12个比较,如果不相同则返回0。 根据此处代码,我们可以推测,输入可能是12个,输出肯定是12个,12个比较是最终的校验。 动态验证下,运行程序,od附加,在40103D下断并运行,程序中随便输入回车。成功断下。最后获得栈区的写入数据(前面似乎是luajit的头,也加上了)。

0019FA0C                                      1B 4C 4A 02              J
0019FA1C  02 3B 00 02 07 00 03 00 09 36 02 00 00 39 02 01  ;....6..9
0019FA2C  02 36 03 00 00 39 03 02 03 12 04 00 00 12 05 01  6..9..
0019FA3C  00 12 06 01 00 42 03 04 00 43 02 00 00 08 73 75  ..B.C..su
0019FA4C  62 09 62 79 74 65 0B 73 74 72 69 6E 67 F3 03 00  b.bytestring?.
0019FA5C  01 19 00 05 01 75 36 01 00 00 39 01 01 01 12 02  .u6..9
0019FA6C  00 00 42 01 02 02 08 01 00 00 58 01 02 80 29 01  ..B..X€)
0019FA7C  00 00 4C 01 02 00 36 01 02 00 39 01 03 01 36 02  ..L.6.96
0019FA8C  04 00 12 03 00 00 29 04 01 00 42 02 03 02 29 03  ...).B)
0019FA9C  70 00 42 01 03 02 36 02 02 00 39 02 03 02 36 03  p.B6.96
0019FAAC  04 00 12 04 00 00 29 05 02 00 42 03 03 02 29 04  ...).B)
0019FABC  65 00 42 02 03 02 36 03 02 00 39 03 03 03 36 04  e.B6.96
0019FACC  04 00 12 05 00 00 29 06 03 00 42 04 03 02 29 05  ...).B)
0019FADC  64 00 42 03 03 02 36 04 02 00 39 04 03 04 36 05  d.B6.96
0019FAEC  04 00 12 06 00 00 29 07 04 00 42 05 03 02 29 06  ...).B)
0019FAFC  69 00 42 04 03 02 36 05 02 00 39 05 03 05 36 06  i.B6.96
0019FB0C  04 00 12 07 00 00 29 08 05 00 42 06 03 02 29 07  ...).B)
0019FB1C  79 00 42 05 03 02 36 06 02 00 39 06 03 06 36 07  y.B6.96
0019FB2C  04 00 12 08 00 00 29 09 06 00 42 07 03 02 29 08  ...)..B)
0019FB3C  31 00 42 06 03 02 36 07 02 00 39 07 03 07 36 08  1.B6.96
0019FB4C  04 00 12 09 00 00 29 0A 07 00 42 08 03 02 29 09  ....)..B).
0019FB5C  32 00 42 07 03 02 36 08 02 00 39 08 03 08 36 09  2.B6.96.
0019FB6C  04 00 12 0A 00 00 29 0B 08 00 42 09 03 02 29 0A  ....).B.).
0019FB7C  33 00 42 08 03 02 36 09 02 00 39 09 03 09 36 0A  3.B6..9..6.
0019FB8C  04 00 12 0B 00 00 29 0C 09 00 42 0A 03 02 29 0B  ...)...B.)
0019FB9C  34 00 42 09 03 02 36 0A 02 00 39 0A 03 0A 36 0B  4.B.6..9..6
0019FBAC  04 00 12 0C 00 00 29 0D 0A 00 42 0B 03 02 29 0C  ....)...B).
0019FBBC  35 00 42 0A 03 02 36 0B 02 00 39 0B 03 0B 36 0C  5.B.6.96.
0019FBCC  04 00 12 0D 00 00 29 0E 0B 00 42 0C 03 02 29 0D  ....).B.).
0019FBDC  36 00 42 0B 03 02 36 0C 02 00 39 0C 03 0C 36 0D  6.B6..9..6.
0019FBEC  04 00 12 0E 00 00 29 0F 0C 00 42 0D 03 02 29 0E  ...)..B.)
0019FBFC  37 00 42 0C 03 02 12 0D 01 00 12 0E 02 00 12 0F  7.B....
0019FC0C  03 00 12 10 04 00 12 11 05 00 12 12 06 00 12 13  ....
0019FC1C  07 00 12 14 08 00 12 15 09 00 12 16 0A 00 12 17  ......
0019FC2C  0B 00 12 18 0C 00 4A 0D 0D 00 07 62 79 09 62 78  ...J...by.bx
0019FC3C  6F 72 08 62 69 74 08 6C 65 6E 0B 73 74 72 69 6E  orbitlenstrin
0019FC4C  67 18 3D 03 00 02 00 06 00 08 36 00 00 00 27 01  g=...6...'
0019FC5C  01 00 42 00 02 01 33 00 02 00 37 00 03 00 33 00  .B.3..7..3.
0019FC6C  04 00 37 00 05 00 4B 00 01 00 09 6D 61 69 6E 00  .7..K...main.
0019FC7C  07 62 79 00 08 62 69 74 0C 72 65 71 75 69 72 65  by.bit.require
0019FC8C  00                                               .

继续往下走,最后到了校验的地方,全部改标志位通过,最后程序打印出成功信息。看来推测是正确的。

更新了下luajit,使用luajit-decomp反解数据,竟然解不出。 我想想觉得luajit太明显了,是不是坑,毕竟函数都没跟,不知道发生了什么,有可能只是luac的脚本。于是更改脚本数据,用luadec解,也是解不出。

后来得到高人指点:应该是luajit,看看版本对不对。我边看边想:不应该啊,我刚更新的,然后就傻眼了:版本不对。我又上了luajit的官网下载页,原来第一个并不是最新版本,只是稳定版本,当时着急没看版本号,就直接下了第一个。

重新下载编译,用luajit-decomp反解,得到:

function someFunc0(INPUT_VAR_0_,INPUT_VAR_1_)
local var_0_4 = INPUT_VAR_0_
local var_0_5 = INPUT_VAR_1_
local var_0_6 = INPUT_VAR_1_
string.byte( string.sub(var_0_4, var_0_5, var_0_6) )
end
function someFunc1(INPUT_VAR_0_)
local var_1_2 = INPUT_VAR_0_
local var_1_1 = string.len(var_1_2)
if var_1_1 ~= 0 then
--jump to 0009 (if previous if statement is false)
return  0 
--location 0009
local var_1_3 = INPUT_VAR_0_
var_1_2 = by(var_1_3,  1 )
var_1_1 = bit.bxor(var_1_2,  112 )
local var_1_4 = INPUT_VAR_0_
var_1_3 = by(var_1_4,  2 )
var_1_2 = bit.bxor(var_1_3,  101 )
local var_1_5 = INPUT_VAR_0_
var_1_4 = by(var_1_5,  3 )
var_1_3 = bit.bxor(var_1_4,  100 )
local var_1_6 = INPUT_VAR_0_
var_1_5 = by(var_1_6,  4 )
var_1_4 = bit.bxor(var_1_5,  105 )
local var_1_7 = INPUT_VAR_0_
var_1_6 = by(var_1_7,  5 )
var_1_5 = bit.bxor(var_1_6,  121 )
local var_1_8 = INPUT_VAR_0_
var_1_7 = by(var_1_8,  6 )
var_1_6 = bit.bxor(var_1_7,  49 )
local var_1_9 = INPUT_VAR_0_
var_1_8 = by(var_1_9,  7 )
var_1_7 = bit.bxor(var_1_8,  50 )
local var_1_10 = INPUT_VAR_0_
var_1_9 = by(var_1_10,  8 )
var_1_8 = bit.bxor(var_1_9,  51 )
local var_1_11 = INPUT_VAR_0_
var_1_10 = by(var_1_11,  9 )
var_1_9 = bit.bxor(var_1_10,  52 )
local var_1_12 = INPUT_VAR_0_
var_1_11 = by(var_1_12,  10 )
var_1_10 = bit.bxor(var_1_11,  53 )
local var_1_13 = INPUT_VAR_0_
var_1_12 = by(var_1_13,  11 )
var_1_11 = bit.bxor(var_1_12,  54 )
local var_1_14 = INPUT_VAR_0_
var_1_13 = by(var_1_14,  12 )
var_1_12 = bit.bxor(var_1_13,  55 )
var_1_13 = var_1_1
var_1_14 = var_1_2
local var_1_15 = var_1_3
local var_1_16 = var_1_4
local var_1_17 = var_1_5
local var_1_18 = var_1_6
local var_1_19 = var_1_7
local var_1_20 = var_1_8
local var_1_21 = var_1_9
local var_1_22 = var_1_10
local var_1_23 = var_1_11
local var_1_24 = var_1_12
return var_1_13, var_1_14, var_1_15, var_1_16, var_1_17, var_1_18, var_1_19, var_1_20, var_1_21, var_1_22, var_1_23, var_1_24
end
function someFunc2()
require("bit")
local randomFunction0 = function() end -- starts at  test.luac:0
by = randomFunction0
local randomFunction1 = function() end -- starts at  test.luac:0
main = randomFunction1
return
end

脚本比较简单,也就没有整理成lua本来的样子。也就是输入的12字节分别与某常量异或,得到12字节的输出。 那sub_412CE0应该就是取输出,取了12次,取出的输出也分别与某常量异或,最后校验。

最后来个简单py脚本计算:

l1 = [0x18,0x16,0x1e,0x2f,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]
l2 = [112,101,100,105,121,49,50,51,52,53,54,55]
l3 = [0x05,0x12,0x0a,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]
s = ''
for i in range(12):
    s += chr(l1[i]^l2[i]^l3[i])
print 'The key is:'+s

最终结果为maposafe2017




[公告]安全测试和项目外包请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最新回复 (0)
游客
登录 | 注册 方可回帖
返回