• 看雪CTF第十五题


    1、直接运行起来,再用OD附加

     在此处luajit加载并调用main函数

    004021C7    E8 64FE0000     call CrackMe.00412030                    ; luaL_newstate
    004021CC    8BF0            mov esi,eax
    004021CE    56              push esi
    004021CF    E8 9C000100     call CrackMe.00412270                    ; luaL_openlibs(lua_State *L)
    004021D4    53              push ebx
    004021D5    68 75020000     push 0x275
    004021DA    8D4424 3C       lea eax,dword ptr ss:[esp+0x3C]
    004021DE    50              push eax
    004021DF    56              push esi
    004021E0    E8 5B040100     call CrackMe.00412640                    ; int luaL_loadbuffer(lua_State*L,const char*buff,size_t size,const char*name
    004021E5    53              push ebx
    004021E6    56              push esi
    004021E7    E8 C41B0100     call CrackMe.00413DB0
    004021EC    68 883E4800     push CrackMe.00483E88                    ; ASCII "main"
    004021F1    68 EED8FFFF     push -0x2712
    004021F6    56              push esi
    004021F7    E8 84130100     call CrackMe.00413580                    ; void  (lua_getfield) (lua_State *L, int idx, const char *k);
    004021FC    57              push edi
    004021FD    56              push esi
    004021FE    E8 DD0E0100     call CrackMe.004130E0                    ; lua_pushstring
    00402203    6A 01           push 0x1
    00402205    56              push esi
    00402206    E8 A51B0100     call CrackMe.00413DB0                    ; lua_call

    2、在luaL_loadbuffer出下断开dump下luajit的bytecode

     使用luajit-decomp进行反编译,注意:可以此处是LuaJIT-2.1.0-beta3,需编译替换luajit-decomp中对应的文件

        在IDA中字符串列表中搜索lua可以知道lua和luajit的版本。注意:由于有反调试,先运行程序在用OD附加然后dump

    Address        Length   Type String                                       
    -------        ------   ---- ------                                       
    .text:00471CFC 0000002E C    PANIC: unprotected error in call to Lua API (
    .text:00473EA0 00000028 C    'module' not called from a Lua function      
    .text:00473F40 00000026 C    .\?.lua;!\lua\?.lua;!\lua\?\init.lua;  
    .text:00472097 00000016 C    Lua function expected                        
    .text:00473378 00000013 C    LuaJIT 2.1.0-beta3                           
    .text:00473D1C 0000000D C    luaJIT_BC_%s                                 
    .text:00473590 0000000C C    lua_debug>                                   
    .text:00473D2C 0000000B C    luaopen_%s                                   
    .text:00473F34 0000000A C    LUA_CPATH                                    
    .text:00473F74 0000000A C    LUA_NOENV                                    
    .text:00473F68 00000009 C    LUA_PATH                                     
    .text:00474240 00000008 C    Lua 5.1                                      

    dump下luajit的bytecode:

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

    可以看出

      someFunc0函数截取字符串指定位置的字符 并转换成byte

        someFunc1函数对字符串调用someFunc0函数每个字符截取 并 xor 

           someFunc2中可以看出 by = randomFunction0 应该就是 by = someFunc0,  main = randomFunction1 应该就是 main = someFunc1

    3、调用完lua中的main函数后,从lua栈中依次取出每个字符加密后的byte, 然后再次进行 xor

    0040222C    55              push ebp
    0040222D    6A F4           push -0xC
    0040222F    56              push esi
    00402230    E8 AB0A0100     call CrackMe.00412CE0                    ; lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum);
    00402235    8BF8            mov edi,eax
    00402237    6A F5           push -0xB
    00402239    56              push esi
    0040223A    83F7 05         xor edi,0x5
    0040223D    E8 9E0A0100     call CrackMe.00412CE0
    00402242    8BD8            mov ebx,eax
    00402244    6A F6           push -0xA
    00402246    56              push esi
    00402247    83F3 12         xor ebx,0x12
    0040224A    E8 910A0100     call CrackMe.00412CE0
    0040224F    8BE8            mov ebp,eax
    00402251    6A F7           push -0x9
    00402253    56              push esi
    00402254    83F5 0A         xor ebp,0xA
    00402257    E8 840A0100     call CrackMe.00412CE0
    0040225C    83F0 29         xor eax,0x29
    0040225F    6A F8           push -0x8
    00402261    56              push esi
    00402262    894424 58       mov dword ptr ss:[esp+0x58],eax
    00402266    E8 750A0100     call CrackMe.00412CE0
    0040226B    83F0 42         xor eax,0x42
    0040226E    6A F9           push -0x7
    00402270    56              push esi
    00402271    894424 48       mov dword ptr ss:[esp+0x48],eax
    00402275    E8 660A0100     call CrackMe.00412CE0
    0040227A    83F0 41         xor eax,0x41
    0040227D    6A FA           push -0x6
    0040227F    56              push esi
    00402280    894424 60       mov dword ptr ss:[esp+0x60],eax
    00402284    E8 570A0100     call CrackMe.00412CE0
    00402289    83F0 75         xor eax,0x75
    0040228C    6A FB           push -0x5
    0040228E    56              push esi
    0040228F    894424 60       mov dword ptr ss:[esp+0x60],eax
    00402293    E8 480A0100     call CrackMe.00412CE0
    00402298    83C4 40         add esp,0x40
    0040229B    83F0 61         xor eax,0x61
    0040229E    6A FC           push -0x4
    004022A0    56              push esi
    004022A1    894424 18       mov dword ptr ss:[esp+0x18],eax
    004022A5    E8 360A0100     call CrackMe.00412CE0
    004022AA    83F0 35         xor eax,0x35
    004022AD    6A FD           push -0x3
    004022AF    56              push esi
    004022B0    894424 24       mov dword ptr ss:[esp+0x24],eax
    004022B4    E8 270A0100     call CrackMe.00412CE0
    004022B9    35 83000000     xor eax,0x83
    004022BE    6A FE           push -0x2
    004022C0    56              push esi
    004022C1    894424 34       mov dword ptr ss:[esp+0x34],eax
    004022C5    E8 160A0100     call CrackMe.00412CE0
    004022CA    83F0 55         xor eax,0x55
    004022CD    6A FF           push -0x1
    004022CF    56              push esi
    004022D0    894424 44       mov dword ptr ss:[esp+0x44],eax
    004022D4    E8 070A0100     call CrackMe.00412CE0
    004022D9    35 94000000     xor eax,0x94
    004022DE    6A F3           push -0xD
    004022E0    56              push esi
    004022E1    894424 54       mov dword ptr ss:[esp+0x54],eax
    004022E5    E8 26050100     call CrackMe.00412810
    004022EA    56              push esi
    004022EB    E8 80200100     call CrackMe.00414370                    ; lua_close

    4、最后每个byte和固定的值进行比较

    004022F3    83FF 18         cmp edi,0x18
    004022F6    75 54           jnz short CrackMe.0040234C
    004022F8    83FB 16         cmp ebx,0x16
    004022FB    75 4F           jnz short CrackMe.0040234C
    004022FD    83FD 1E         cmp ebp,0x1E
    00402300    75 4A           jnz short CrackMe.0040234C
    00402302    837C24 30 2F    cmp dword ptr ss:[esp+0x30],0x2F
    00402307    75 43           jnz short CrackMe.0040234C
    00402309    837C24 18 48    cmp dword ptr ss:[esp+0x18],0x48
    0040230E    75 3C           jnz short CrackMe.0040234C
    00402310    837C24 28 11    cmp dword ptr ss:[esp+0x28],0x11
    00402315    75 35           jnz short CrackMe.0040234C
    00402317    837C24 20 21    cmp dword ptr ss:[esp+0x20],0x21
    0040231C    75 2E           jnz short CrackMe.0040234C
    0040231E    837C24 10 37    cmp dword ptr ss:[esp+0x10],0x37
    00402323    75 27           jnz short CrackMe.0040234C
    00402325    837C24 14 33    cmp dword ptr ss:[esp+0x14],0x33
    0040232A    75 20           jnz short CrackMe.0040234C
    0040232C    817C24 1C 86000>cmp dword ptr ss:[esp+0x1C],0x86
    00402334    75 16           jnz short CrackMe.0040234C
    00402336    837C24 24 52    cmp dword ptr ss:[esp+0x24],0x52
    0040233B    75 0F           jnz short CrackMe.0040234C
    0040233D    817C24 2C 94000>cmp dword ptr ss:[esp+0x2C],0x94
    00402345    75 05           jnz short CrackMe.0040234C

    5、可以提取3处xor的值

       lua中main函数对每个字符xor的值

        [112,101,100,105,121,49,50,51,52,53,54,55]

       0040222C   处对lua输出的每个值进行异或

        [0x5,0x12,0xa,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]

       004022F3    处对上面两次异或后的结果和下面的值进行比较

        [0x18,0x16,0x1e,0x2f,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]

    6、用python进行解码

    result = [0x18,0x16,0x1E,0x2F,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]
    luaxor = [112,101,100,105,121,49,50,51,52,53,54,55]
    codexor = [0x5,0x12,0xa,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]
    
    code = ''
    for i in range(len(result)):
        code += chr(result[i]^luaxor[i]^codexor[i])
    
    print code

    结果:maposafe2017

  • 相关阅读:
    MySQL5.6.26升级到MySQL5.7.9实战方案【转】
    bootstrap-markdown编辑器引入
    yii获取当前url和域名
    RabbitMQ消息队列在PHP下的应用
    解决 PHPExcel 长数字串显示为科学计数
    Linux实现https方式访问站点
    layui关闭弹出层
    vscode中iframe的使用
    tomcat运行超时问题解决
    Linux安装solr
  • 原文地址:https://www.cnblogs.com/qintangtao/p/7116434.html
Copyright © 2020-2023  润新知