首页
社区
课程
招聘
[原创]CTF 丛林的秘密:算法分析
2024-1-19 15:52 7876

[原创]CTF 丛林的秘密:算法分析

2024-1-19 15:52
7876

一、 背景

这一题很有迷惑性,设置了很多陷阱,看似正常的逻辑其实是假象。里面用到了Webassembly逆向,我也是第一次遇到这种,之前没有触过wasm汇编语言,看到代码也是无从下手,也是一边学习一边算法逆向。

二、 代码分析

java层分析

从代码可以看出满足native int check_key(String str) 为真时候,则验证通过,同时也调用了sayHello(),调用的具体作用还看不出来。
图片描述

so层分析

从导出函数列表中,找到我们的目标函数:
图片描述

Java_com_example_assemgogogo_gogogoJNI_sayHello

这段代码的意思就是返回字符串:http://127.0.0.1:8000
图片描述

Java_com_example_assemgogogo_gogogoJNI_check_key

图片描述
主要步骤如下:

通过 JNI 调用 Java 中的方法(通过函数指针调用),返回结果存储在 result 变量中。
如果调用成功,进入密钥检查的逻辑。
使用 srand(0x32u) 设置随机数生成器的种子。
在循环中,生成随机数 v8,然后根据一些条件检查当前密钥字节是否符合预期。
如果所有密钥字节都通过检查,返回 0;否则,关闭套接字并返回 1。
v8是一个随机数,if ( *(_BYTE *)(v6 + v7) != (v8 - (v9 & 0xFFFFFF80) != (unsigned __int8)aD584a68d4e213d[v7]) )
结果肯定是不相等的,那么通过分析返回值永远都是0,那么不成立,这个函数岂不是无解?

三、hook验证

既然通过代码分析,我们知道他们调用了_check_key、sayHello这个2个函数,那么我们就hook他们,验证下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function hook_jiami() {
    Java.perform(function () {
        var gogogoJNI = Java.use("com.example.assemgogogo.gogogoJNI");
        gogogoJNI["sayHello"].implementation = function () {
            console.log("gogogoJNI.sayHello is called");
            var result = this["sayHello"]();
            console.log("gogogoJNI.sayHello result=${result}", result);
            return result;
        };
        gogogoJNI["check_key"].implementation = function (str) {
            console.log("gogogoJNI.check_key is called: str=${str}", str);
            var result = this["check_key"](str);
            console.log("gogogoJNI.check_key result=${result}", result);
            return result;
        };
    });
}

图片描述
通过结果可以看出,只调用了sayHello函数并没有调用check_key函数,结合之前的分析可以得出,此处并非是真正的位置,check_key函数又在哪调用的呢?
再来看java层代码中:
((WebView) findViewById(R.id.text1View)).loadUrl(this.u);
((WebView) findViewById(R.id.text1View)).getSettings().setJavaScriptEnabled(true);
this.u = :http://127.0.0.1:8000 setJavaScriptEnabled 启用了JavaScript。接着分析:
在so文件JNI_OnLoad中调用了inti_proc函数:
图片描述

使用一个循环,将一系列向量进行初始化,涉及到按位异或操作。
使用一系列操作配置了套接字相关的参数,包括套接字类型、协议等。
通过 getaddrinfo 获取了本地主机(IP地址为0)在端口8000上的地址信息,并将结果存储在 v19 中。
在获取的地址信息上循环,尝试创建套接字并设置一些选项。
套接字创建和配置成功,创建了多个线程。
返回值 nullsub_
图片描述
mm0 是关键 我们hook之

1
2
3
4
5
6
7
8
9
10
11
12
function hook_jiami() {
    Java.perform(function () {
        var module_addr = Module.findBaseAddress("libgogogo.so");
        var mm0__addr = Module.findExportByName("libgogogo.so","mm0");
 
        console.log("module_addr = ", module_addr);
  
        var get_html = mm0__addr.readByteArray(35000);
 
        console.log("mm0__addr_addr 3333 ",get_html)
    });
}

图片描述
得到一串代码,可以看出他是一个html页面,看来交互就是和他进行了。我们在弄出完整的html页面看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function bytesToString(arr) {
    if (typeof arr === 'string') {
        return arr;
    }
    var str = "";
    arr = new Uint8Array(arr);
    for (var i in arr) {
        str += String.fromCharCode(arr[i]);
    }
    return str
}
 
function hook_jiami() {
    Java.perform(function () {
        var module_addr = Module.findBaseAddress("libgogogo.so");
        var mm0__addr = Module.findExportByName("libgogogo.so","mm0");
        console.log("module_addr = ", module_addr);
        var get_html = mm0__addr.readByteArray(35000);
        var get_html1 = bytesToString(get_html);
        console.log("nmm0__addr_addr 4444 ",bytesToString(get_html))
    
    });
}

图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta charset="utf-8">
  <style>
    body {
      background-color: rgb(255, 255, 255);                                                                                                                          
    }
  </style>
</head>
<script>
 
 
var instance;
 
WebAssembly.compile(new Uint8Array(`
 00 61 73 6D 01 00 00 00 01 1B 05 60 00 00 60 04
7F 7F 7F 7F 01 7F 60 02 7F 7F 01 7F 60 01 7F 01
7F 60 00 01 7F 03 0E 0D 00 01 01 01 01 01 01 01
01 02 03 04 04 04 05 01 70 01 01 01 05 03 01 00
02 06 15 03 7F 01 41 D0 89 04 0B 7F 00 41 D0 89
 
...
 
00 00 00 83 01 04 6E 61 6D 65 01 7C 0D 00 11 5F
5F 77 61 73 6D 5F 63 61 6C 6C 5F 63 74 6F 72 73
01 01 6F 02 02 6F 6F 03 03 6F 6F 6F 04 04 6F 6F
6F 6F 05 05 6F 6F 6F 6F 6F 06 06 6F 6F 6F 6F 6F
6F 07 07 6F 6F 6F 6F 6F 6F 6F 08 08 6F 6F 6F 6F
6F 6F 6F 6F 09 0E 73 65 74 5F 69 6E 70 75 74 5F
66 6C 61 67 0A 12 73 65 74 5F 69 6E 70 75 74 5F
66 6C 61 67 5F 6C 65 6E 0B 09 63 68 65 63 6B 5F
6B 65 79 0C 03 78 78 78
`.trim().split(/[\s\r\n]+/g).map(str => parseInt(str, 16))
)).then(module => {
  new WebAssembly.instantiate(module).then(results => {
  instance = results;
}).catch(console.error);})
function check_flag(){
  var value = document.getElementById("key_value").value;
  if(value.length != 32)
  {
  document.getElementById("tips").innerHTML = "Not Correct!";
        return;
  }
  instance.exports.set_input_flag_len(value.length);
  for(var ii=0;ii<value.length;ii++){
      instance.exports.set_input_flag(value[ii].charCodeAt(),ii);
  }
  var ret =  instance.exports.check_key();
 
  if (ret == 1){
   document.getElementById("tips").innerHTML = "Congratulations!"
  }
  else{
    document.getElementById("tips").innerHTML = "Not Correct!"
  }
}
</script>
<body>
   <div>Key: <input id="key_value" type="text" name="key" style="width:60%" ;="" value=""> <input type="submit" value="check" onclick="check_flag()"></div>
   <div> <label id="tips"></label></div>
 
</body></html>

四、WebAssembly基本概念

WebAssembly(简称为Wasm)是一种面向Web的二进制指令格式。它是一种可移植、高性能的虚拟机,旨在在Web浏览器中执行底层代码,以提供接近本地代码执行速度的性能。以下是关于WebAssembly的基本概念:

二进制指令格式:

WebAssembly使用紧凑的二进制格式,可以更高效地传输和解码,同时减小加载时间。这使得WebAssembly成为Web平台上的一个通用执行格式。
独立于编程语言:

WebAssembly并不依赖于特定的编程语言,而是设计为与多种语言兼容。它可以被用作JavaScript之外的语言的目标,使得开发者可以使用各种语言编写Web应用的核心功能。
执行环境:

WebAssembly代码在浏览器中执行,但它不直接在JavaScript引擎上运行。相反,WebAssembly有自己的虚拟机,与浏览器的JavaScript引擎分开。这使得WebAssembly能够获得与本地代码相媲美的性能。
跨平台:

WebAssembly是一个跨平台的技术,可以在不同体系结构和操作系统上运行。这使得开发者可以编写一次代码,并在各种设备和环境中部署,而无需修改。
安全性:

WebAssembly被设计为在Web环境中运行,同时具有强大的安全性。它在一个受控的沙箱中运行,防止对计算机系统的恶意访问。此外,WebAssembly模块可以通过浏览器的同源策略限制来提高安全性。
JavaScript和WebAssembly的互操作性:

WebAssembly与JavaScript有良好的互操作性。JavaScript可以调用WebAssembly的函数,而WebAssembly也可以调用JavaScript的函数,使得两者可以共同工作。
使用场景:

WebAssembly广泛应用于需要高性能的Web应用程序,例如图形、游戏、模拟器、数据处理等。它允许开发者在Web上执行密集型计算任务,而不会损失性能。
工具链支持:

WebAssembly有完整的工具链,包括编译器和调试器,使得开发者能够方便地将其集成到现有的开发工作流程中。

五、处理 处理wasm文件

从github下载工具,对文件进行反编译 https://github.com/WebAssembly/wabt

1
./wasm2c /root/Desktop/hex.wasm -o web.c

此时代码看上去是又多又长,分析起来比较吃力。gcc编译web.c获得中间文件web.o

1
gcc -c web.c -o web.o

将web.o拖到IDA中分析。
w2c_check_key()就是核心代码了
图片描述
w2c_o内部逻辑都是一样的。
图片描述
函数签名:
函数名为 w2c_o。
返回一个64位整数 __int64。
使用 __fastcall 调用约定,表明一些参数可能会通过寄存器传递。
接受四个无符号整数参数 a1、a2、a3、a4。
局部变量和参数:
使用了一系列整数变量,如 v4、v5、v6、...、v28。
v26、v17、v16、v15、v23、v21 等变量在后续的运算中被使用。
内存操作:
使用 i32_load8_u 和 i32_load8_s 从内存中加载8位整数。
使用 i32_store8 将8位整数写入内存。
逻辑运算和条件判断:
对变量进行递增、逻辑与、逻辑或等操作,生成一系列的逻辑条件。
根据条件判断执行不同的逻辑分支。
循环:
使用 do-while 循环,在循环体内执行一系列的操作。
返回值:
最终返回一个64位整数 v18。
调用 wasm_rt_trap 函数:
在代码开头,使用 wasm_rt_call_stack_depth 变量判断调用深度,如果超过一定深度,就会调用 wasm_rt_trap 函数,并传递参数7。
数据处理和异或运算:
对参数进行一系列复杂的逻辑运算,包括位异或运算,与运算,或运算等。
条件判断:
根据条件的不同执行不同的逻辑分支。
最后的返回:
根据条件计算得到的最终结果 v18 作为函数的返回值。
w2c_xxx() 是一个32元方程组
图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import numpy as np
from scipy.linalg import solve
a = np.array(
    [[108, 111, 92, 194, 124, 240, 126, 81, 144, 103, 161, 50, 67, 15, 127, 232, 188, 19, 233, 153, 231, 40, 112, 106,
      135, 90, 67, 20, 248, 45, 48, 174],
     [227, 78, 195, 81, 10, 248, 186, 171, 148, 194, 40, 180, 17, 212, 104, 90, 178, 26, 225, 209, 32, 169, 94, 156,
      154, 56, 244, 149, 120, 131, 13, 101],
     [83, 44, 95, 131, 30, 55, 46, 36, 67, 109, 69, 251, 8, 248, 40, 154, 251, 86, 112, 9, 174, 197, 38, 14, 202, 60,
      117, 188, 136, 145, 240, 53],
     [152, 162, 112, 57, 102, 182, 10, 139, 30, 7, 145, 127, 148, 5, 165, 109, 110, 234, 113, 33, 192, 45, 65, 105, 140,
      116, 35, 48, 155, 25, 234, 25],
     [101, 189, 236, 118, 141, 148, 197, 7, 108, 104, 45, 130, 39, 164, 88, 241, 108, 107, 76, 34, 210, 29, 156, 90,
      139, 151, 10, 97, 209, 46, 82, 113],
     [182, 13, 50, 102, 155, 230, 3, 225, 237, 163, 38, 176, 115, 105, 203, 26, 72, 111, 96, 240, 139, 117, 153, 120,
      151, 25, 49, 90, 98, 7, 179, 72],
     [170, 150, 226, 101, 110, 99, 127, 101, 203, 209, 187, 100, 226, 186, 252, 39, 65, 67, 225, 174, 1, 187, 214, 22,
      74, 99, 129, 254, 13, 97, 156, 61],
     [1, 88, 118, 232, 60, 252, 133, 177, 185, 222, 32, 48, 1, 242, 240, 218, 81, 22, 73, 171, 139, 72, 106, 62, 156,
      134, 220, 19, 77, 94, 154, 117],
     [189, 173, 41, 39, 26, 232, 75, 75, 95, 7, 117, 96, 211, 130, 228, 143, 91, 247, 43, 122, 131, 52, 48, 29, 111, 38,
      19, 242, 162, 70, 220, 151],
     [236, 136, 147, 104, 79, 204, 220, 25, 38, 233, 165, 20, 174, 120, 214, 18, 233, 119, 244, 143, 126, 226, 77, 33,
      189, 5, 150, 160, 14, 112, 231, 92],
     [191, 38, 193, 250, 212, 175, 39, 94, 183, 172, 171, 163, 129, 165, 64, 170, 199, 2, 167, 2, 216, 252, 184, 187,
      97, 109, 98, 135, 192, 88, 50, 203],
     [203, 81, 252, 104, 248, 156, 199, 46, 208, 240, 149, 155, 102, 95, 51, 208, 208, 62, 58, 117, 72, 23, 193, 193,
      226, 217, 106, 147, 136, 16, 43, 196],
     [144, 69, 224, 107, 225, 83, 15, 10, 214, 152, 24, 136, 165, 208, 38, 67, 201, 180, 158, 75, 111, 65, 211, 220,
      135, 125, 216, 105, 122, 112, 80, 49],
     [143, 68, 127, 51, 152, 88, 153, 9, 149, 107, 178, 166, 190, 177, 99, 71, 63, 233, 58, 132, 109, 75, 152, 95, 74,
      195, 90, 251, 205, 8, 76, 129],
     [209, 146, 59, 38, 40, 56, 182, 245, 67, 202, 177, 183, 26, 126, 161, 95, 133, 123, 163, 30, 88, 219, 5, 86, 183,
      156, 253, 97, 43, 128, 31, 102],
     [146, 223, 137, 228, 226, 155, 170, 92, 77, 17, 22, 128, 20, 171, 142, 170, 192, 49, 200, 178, 154, 42, 5, 159,
      251, 152, 7, 247, 145, 39, 91, 136],
     [169, 204, 244, 26, 77, 134, 221, 205, 149, 47, 1, 197, 82, 195, 123, 219, 116, 80, 13, 231, 173, 192, 220, 224,
      108, 104, 56, 152, 84, 226, 121, 205],
     [184, 45, 176, 126, 118, 161, 142, 171, 215, 83, 233, 184, 171, 182, 126, 111, 118, 67, 92, 219, 70, 252, 194, 21,
      245, 204, 48, 150, 39, 85, 73, 95],
     [48, 224, 164, 138, 92, 3, 191, 94, 19, 50, 34, 167, 75, 72, 238, 15, 111, 216, 84, 40, 145, 112, 140, 204, 154,
      195, 175, 250, 202, 169, 170, 120],
     [112, 19, 189, 50, 247, 240, 164, 5, 139, 56, 19, 4, 23, 172, 96, 254, 63, 247, 149, 183, 128, 147, 213, 243, 172,
      144, 246, 25, 106, 176, 170, 68],
     [184, 22, 183, 128, 149, 174, 227, 113, 65, 159, 74, 170, 186, 174, 211, 1, 223, 156, 253, 223, 241, 252, 148, 93,
      41, 125, 27, 136, 78, 248, 41, 31],
     [155, 237, 242, 10, 145, 99, 239, 105, 3, 43, 46, 155, 208, 75, 140, 181, 197, 140, 10, 170, 142, 212, 186, 27,
      105, 118, 198, 243, 13, 113, 82, 39],
     [207, 206, 127, 58, 91, 87, 7, 17, 63, 180, 40, 96, 202, 185, 68, 72, 240, 36, 139, 199, 76, 229, 159, 136, 94, 19,
      3, 87, 45, 6, 136, 50],
     [115, 215, 40, 166, 87, 83, 74, 202, 235, 149, 114, 76, 204, 218, 63, 123, 9, 172, 38, 138, 35, 200, 221, 144, 235,
      108, 1, 245, 153, 184, 90, 12],
     [123, 190, 55, 180, 84, 231, 81, 116, 61, 3, 94, 85, 190, 187, 142, 62, 225, 240, 179, 150, 77, 85, 196, 12, 144,
      122, 28, 224, 248, 143, 114, 36],
     [2, 202, 40, 224, 154, 65, 30, 241, 13, 213, 176, 122, 30, 158, 14, 191, 80, 116, 74, 70, 32, 189, 76, 95, 158,
      103, 7, 201, 204, 91, 190, 122],
     [42, 154, 223, 165, 155, 101, 75, 95, 253, 14, 158, 199, 110, 89, 205, 202, 83, 162, 67, 30, 115, 83, 27, 31, 118,
      160, 248, 66, 88, 44, 5, 176],
     [34, 168, 72, 160, 243, 41, 146, 29, 62, 235, 185, 180, 10, 150, 208, 140, 125, 114, 35, 34, 38, 123, 163, 208, 5,
      29, 207, 111, 72, 65, 125, 84],
     [18, 11, 26, 175, 44, 128, 32, 100, 21, 116, 253, 213, 67, 16, 171, 178, 97, 7, 162, 152, 78, 167, 177, 97, 26,
      155, 127, 21, 243, 188, 140, 197],
     [140, 110, 164, 208, 72, 113, 9, 47, 179, 166, 51, 34, 91, 184, 89, 162, 233, 127, 156, 127, 244, 183, 193, 138,
      242, 90, 193, 7, 252, 113, 152, 7],
     [133, 105, 75, 146, 173, 27, 97, 142, 164, 15, 10, 177, 239, 141, 189, 67, 153, 108, 206, 210, 171, 252, 84, 249,
      7, 168, 100, 30, 196, 244, 197, 75],
     [147, 221, 57, 186, 69, 230, 167, 3, 220, 63, 218, 235, 156, 146, 75, 198, 204, 197, 59, 61, 179, 47, 221, 127,
      210, 218, 241, 135, 196, 185, 53, 79],
     ]
)
b = np.array([359512,387514,301487,296549,344514,346892,386678,348667,316884,372620,413102,428661,371484,350848,334408,382822,420160,402263,366968,384909,425203,372162,297509,372215,370337,314564,325974,307088,322340,380716,393331,430295])
x = solve(a, b)
print(x)

图片描述
对相应位进行异或

1
2
3
4
5
6
7
8
9
ss = "S0m3time_l1tt1e_c0de_1s_us3ful33"
 
yh=[0x18,9,3,0x6b,1,0x5a,0x32,0x57,0x30,0x5d,0x40,0x46,0x2b,0x46,0x56,0x3d,2,0x43,0x17,0,0x32,0x53,0x1f,0x26,0x2a,1,0,0x10,0x10,0x1e,0x40,0]
temp=[]
for i in range(32):
    x=ord(ss[i])^yh[i]
    temp.append(chr(x))
print(''.join(temp))
# 得到结果:K9nXu3_2o1q2_w3bassembly_r3vers3

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

上传的附件:
收藏
点赞4
打赏
分享
最新回复 (2)
雪    币: 11
活跃值: (1186)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
棒子面窝窝头 2024-1-20 01:14
2
0
Amazing , Thanks
雪    币: 19349
活跃值: (28971)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2024-1-20 21:43
3
1
感谢分享
游客
登录 | 注册 方可回帖
返回