Loading

虎符CTF 2022 部分re

压箱底的文章 才发现没发
别的队的wp!

https://mp.weixin.qq.com/s/fliCABrUziXEfWfgkG8mwA

https://mp.weixin.qq.com/s/cP03dJHppwEjo0o4B2bU6g

fpbe

知识点:ebpf bpf

https://www.cnblogs.com/lfri/p/15402973.html

https://www.cnblogs.com/davad/articles/bpf-btf-xiang-xi-jie-shao.html

BPF程序经过Clang/LLVM编译成BPF字节码,然后通过BPF系统调用的方式加载进内核

表面逻辑是

image-20220329195857688

image-20220329195903672

实际上16位sha256几乎不可能被爆破

真实逻辑是

image-20220329201422096

hook了uprobed这个函数

根据前面bpf文章 可以找

fpbe_bpf__open_and_load()

fpbe_bpf__open()

fpbe_bpf__open_opts

fpbe_bpf__create_skeleton

(关于skeleton和rodata 参见https://nakryiko.com/posts/libbpf-bootstrap/ 译文 https://blog.csdn.net/sinat_38816924/article/details/122259826

)

image-20220329200029565

拿到unk_4f4018

dump出即可

(

看到别的队的wp中有ida插件可以直接反编译ebpf的字节码

https://github.com/saaph/eBPF_processor

运行在python2环境下 (但是我并没有调明白ida调用python2的环境(

还有队伍使用了bpftool直接导出

)

我使用LLVM-odjdump -d dump.o

image-20220329202553258

0000000000000000 <uprobe>:
       0:       79 12 68 00 00 00 00 00 r2 = *(u64 *)(r1 + 104)
       1:       67 02 00 00 20 00 00 00 r2 <<= 32
       2:       77 02 00 00 20 00 00 00 r2 >>= 32
       3:       79 13 70 00 00 00 00 00 r3 = *(u64 *)(r1 + 112)
       4:       67 03 00 00 20 00 00 00 r3 <<= 32
       5:       77 03 00 00 20 00 00 00 r3 >>= 32
       6:       bf 34 00 00 00 00 00 00 r4 = r3
       7:       27 04 00 00 c0 6d 00 00 r4 *= 28096
       8:       bf 25 00 00 00 00 00 00 r5 = r2
       9:       27 05 00 00 88 fb 00 00 r5 *= 64392
      10:       0f 45 00 00 00 00 00 00 r5 += r4
      11:       79 14 60 00 00 00 00 00 r4 = *(u64 *)(r1 + 96)
      12:       67 04 00 00 20 00 00 00 r4 <<= 32
      13:       77 04 00 00 20 00 00 00 r4 >>= 32
      14:       bf 40 00 00 00 00 00 00 r0 = r4
      15:       27 00 00 00 fb 71 00 00 r0 *= 29179
      16:       0f 05 00 00 00 00 00 00 r5 += r0
      17:       79 11 58 00 00 00 00 00 r1 = *(u64 *)(r1 + 88)
      18:       b7 00 00 00 00 00 00 00 r0 = 0
      19:       73 0a f8 ff 00 00 00 00 *(u8 *)(r10 - 8) = r0
      20:       7b 0a f0 ff 00 00 00 00 *(u64 *)(r10 - 16) = r0
      21:       7b 0a e8 ff 00 00 00 00 *(u64 *)(r10 - 24) = r0
      22:       67 01 00 00 20 00 00 00 r1 <<= 32
      23:       77 01 00 00 20 00 00 00 r1 >>= 32
      24:       bf 10 00 00 00 00 00 00 r0 = r1
      25:       27 00 00 00 8e cc 00 00 r0 *= 52366
      26:       0f 05 00 00 00 00 00 00 r5 += r0
      27:       b7 06 00 00 01 00 00 00 r6 = 1
      28:       18 00 00 00 95 59 73 a1 00 00 00 00 18 be 00 00 r0 = 209012997183893 ll
      30:       5d 05 42 00 00 00 00 00 if r5 != r0 goto +66 <LBB0_5>
      31:       bf 35 00 00 00 00 00 00 r5 = r3
      32:       27 05 00 00 bf f1 00 00 r5 *= 61887
      33:       bf 20 00 00 00 00 00 00 r0 = r2
      34:       27 00 00 00 e5 6a 00 00 r0 *= 27365
      35:       0f 50 00 00 00 00 00 00 r0 += r5
      36:       bf 45 00 00 00 00 00 00 r5 = r4
      37:       27 05 00 00 d3 ad 00 00 r5 *= 44499
      38:       0f 50 00 00 00 00 00 00 r0 += r5
      39:       bf 15 00 00 00 00 00 00 r5 = r1
      40:       27 05 00 00 84 92 00 00 r5 *= 37508
      41:       0f 50 00 00 00 00 00 00 r0 += r5
      42:       18 05 00 00 40 03 54 e5 00 00 00 00 56 a5 00 00 r5 = 181792633258816 ll
      44:       5d 50 34 00 00 00 00 00 if r0 != r5 goto +52 <LBB0_5>
      45:       bf 35 00 00 00 00 00 00 r5 = r3
      46:       27 05 00 00 85 dd 00 00 r5 *= 56709
      47:       bf 20 00 00 00 00 00 00 r0 = r2
      48:       27 00 00 00 28 80 00 00 r0 *= 32808
      49:       0f 50 00 00 00 00 00 00 r0 += r5
      50:       bf 45 00 00 00 00 00 00 r5 = r4
      51:       27 05 00 00 2d 65 00 00 r5 *= 25901
      52:       0f 50 00 00 00 00 00 00 r0 += r5
      53:       bf 15 00 00 00 00 00 00 r5 = r1
      54:       27 05 00 00 12 e7 00 00 r5 *= 59154
      55:       0f 50 00 00 00 00 00 00 r0 += r5
      56:       18 05 00 00 a3 4d 48 74 00 00 00 00 f3 a6 00 00 r5 = 183564558159267 ll
      58:       5d 50 26 00 00 00 00 00 if r0 != r5 goto +38 <LBB0_5>
      59:       bf 35 00 00 00 00 00 00 r5 = r3
      60:       27 05 00 00 2c 82 00 00 r5 *= 33324
      61:       bf 20 00 00 00 00 00 00 r0 = r2
      62:       27 00 00 00 43 ca 00 00 r0 *= 51779
      63:       0f 50 00 00 00 00 00 00 r0 += r5
      64:       bf 45 00 00 00 00 00 00 r5 = r4
      65:       27 05 00 00 8e 7c 00 00 r5 *= 31886
      66:       0f 50 00 00 00 00 00 00 r0 += r5
      67:       bf 15 00 00 00 00 00 00 r5 = r1
      68:       27 05 00 00 3a f2 00 00 r5 *= 62010
      69:       0f 50 00 00 00 00 00 00 r0 += r5
      70:       18 05 00 00 77 72 5a 48 00 00 00 00 9c b9 00 00 r5 = 204080879923831 ll
      72:       5d 50 18 00 00 00 00 00 if r0 != r5 goto +24 <LBB0_5>
      73:       63 1a f4 ff 00 00 00 00 *(u32 *)(r10 - 12) = r1
      74:       63 4a f0 ff 00 00 00 00 *(u32 *)(r10 - 16) = r4
      75:       63 2a ec ff 00 00 00 00 *(u32 *)(r10 - 20) = r2
      76:       63 3a e8 ff 00 00 00 00 *(u32 *)(r10 - 24) = r3
      77:       18 01 00 00 43 54 46 7b 00 00 00 00 25 73 7d 0a r1 = 755886917287302211 ll
      79:       7b 1a d8 ff 00 00 00 00 *(u64 *)(r10 - 40) = r1
      80:       18 01 00 00 46 4c 41 47 00 00 00 00 3a 20 48 46 r1 = 5064333215653776454 ll
      82:       7b 1a d0 ff 00 00 00 00 *(u64 *)(r10 - 48) = r1
      83:       18 01 00 00 45 21 20 59 00 00 00 00 4f 55 52 20 r1 = 2329017756590022981 ll
      85:       7b 1a c8 ff 00 00 00 00 *(u64 *)(r10 - 56) = r1
      86:       18 01 00 00 57 45 4c 4c 00 00 00 00 20 44 4f 4e r1 = 5642803763628229975 ll
      88:       7b 1a c0 ff 00 00 00 00 *(u64 *)(r10 - 64) = r1
      89:       b7 06 00 00 00 00 00 00 r6 = 0
      90:       73 6a e0 ff 00 00 00 00 *(u8 *)(r10 - 32) = r6
      91:       bf a1 00 00 00 00 00 00 r1 = r10
      92:       07 01 00 00 c0 ff ff ff r1 += -64
      93:       bf a3 00 00 00 00 00 00 r3 = r10
      94:       07 03 00 00 e8 ff ff ff r3 += -24
      95:       b7 02 00 00 21 00 00 00 r2 = 33
      96:       85 00 00 00 06 00 00 00 call 6

0000000000000308 <LBB0_5>:
      97:       bf 60 00 00 00 00 00 00 r0 = r6
      98:       95 00 00 00 00 00 00 00 exit

逻辑比较简单

from z3 import *
s = Solver()
flag = [BitVec('%d' % i, 32) for i in range(4)]
s.add(flag[0] * 52366 + flag[1] * 29179 + flag[2] * 28096 + flag[3] * 64392 == 209012997183893)
s.add(flag[0] * 37508 + flag[1] * 44499 + flag[2] * 61887 + flag[3] * 27365 == 181792633258816)
s.add(flag[0] * 59154 + flag[1] * 25901 + flag[2] * 56709 + flag[3] * 32808 == 183564558159267)
s.add(flag[0] * 62010 + flag[1] * 31886 + flag[2] * 33324 + flag[3] * 51779 == 204080879923831)
if s.check() == sat:
    s = s.model()
    for i in range(4):
        result = s[flag[i]].as_long().real
        print(hex(result))

shellcode

x64dbg 动调

scyllahide插件选themida

scylla直接dump下来分析

字符串定位

image-20220329203204532

长度0x160 v39是个快速base64算法 动调也容易看出

中间一路先略过

来到94行

先rol3

image-20220329203958076

一个很像xxtea 但是>>6

image-20220329204407445

最后比较

#include <iostream>
#include <string>
#include <fstream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>

using namespace std;
uint32_t key[4] = {'t', 'o', 'r', 'a'};
#define MX (((z >> 6 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)))
#define DELTA 0x9e3779b9
void btea(uint32_t *v, int n, uint32_t key[4])
{
    uint32_t y, z, sum;
    unsigned p, rounds, e;
    if (n > 1) /* Coding Part */
    {
        rounds = 6 + 52 / n;
        sum = 0;
        z = v[n - 1];
        do
        {
            sum += DELTA;
            e = (sum >> 2) & 3;
            for (p = 0; p < n - 1; p++)
            {
                y = v[p + 1];
                uint32_t tmp = MX;
                v[p] += tmp;
                z = v[p];
            }
            y = v[0];
            z = v[n - 1] += MX;
        } while (--rounds);
    }
    else if (n < -1) /* Decoding Part */
    {
        n = -n;
        rounds = 6 + 52 / n;
        sum = rounds * DELTA;
        y = v[0];
        do
        {
            e = (sum >> 2) & 3;
            for (p = n - 1; p > 0; p--)
            {
                z = v[p - 1];
                v[p] -= MX;
                y = v[p];
            }
            z = v[n - 1];
            y = v[0] -= MX;
            sum -= DELTA;
        } while (--rounds);
    }
}
// ror byte
uint8_t ror(uint8_t x, uint8_t n)
{
    return (x >> n) | (x << (8 - n));
}
const char *base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// base64加密
string base64_encode(const string &str)
{
    string out;
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];
    while (i < str.size())
    {
        char_array_3[0] = str.at(i++);
        char_array_3[1] = str.at(i++);
        char_array_3[2] = str.at(i++);
        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;
        for (j = 0; (j < 4); j++)
            out += base64_chars[char_array_4[j]];
    }
    while ((out.size() % 4) != 0)
        out += "=";
    return out;
}
int main(int argc, char const *argv[])
{
    uint32_t enc[66] = {
        0x4B6B89A1, 0x74C15453, 0x4092A06E, 0x429B0C07, 0x40281E84, 0x8B5B44C9, 0x66FEB37B, 0x3C77A603,
        0x79C5892D, 0x0D7ADA97, 0x1D51AA56, 0x02D4D703, 0x4FA526BA, 0x32FAD64A, 0x0C0F6091, 0x562B7593,
        0xDB9ADD67, 0x76165563, 0xA5F79315, 0x3AEB991D, 0x1AB721D4, 0xAACD9D2C, 0x825C2B27, 0x76A7761A,
        0xB4005F18, 0x117F3763, 0x512CC540, 0xC594A16F, 0xD0E24F8C, 0x9CA3E2E9, 0x0A9CC2D5, 0x4629E61D,
        0x637129E3, 0xCA4E8AD7, 0xF5DFAF71, 0x474E68AB, 0x542FBC3A, 0xD6741617, 0xAD0DBBE5, 0x62F7BBE3,
        0xC8D68C07, 0x880E950E, 0xF80F25BA, 0x767A264C, 0x9A7CE014, 0x5C8BC9EE, 0x5D9EF7D4, 0xB999ACDE,
        0xB2EC8E13, 0xEE68232D, 0x927C5FCE, 0xC9E3A85D, 0xAC74B56B, 0x42B6E712, 0xCD2898DA, 0xFCF11C58,
        0xF57075EE, 0x5076E678, 0xD4D66A35, 0x95105AB9, 0x1BB04403, 0xB240B959, 0x7B4E261A, 0x23D129D8,
        0xF5E752CD, 0x4EA78F70};

    btea((uint32_t *)enc, -66, key);
    //打印enc
    for (int i = 0; i < 66; i++)
    {
        // printf("0x%08x,", enc[i]);
    }
    uint8_t *str = (uint8_t *)enc;
    // str每项都ror3
    for (int i = 0; i < 66 * 4; i++)
    {
        str[i] = ror(str[i], 3);
    }
    //打印str
    for (int i = 0; i < 66 * 4; i++)
    {
        printf("0x%02x,", str[i]);
    }
    printf("\n");
    //将str转为string
    string s = string((char *)str, 66 * 4);
    //加密
    string base64_str = base64_encode(s);
    //打印base64_str
    printf("%s\n", base64_str.c_str());
}

拿到shellcode

之后就是执行该shellcode

写一个执行shellcode的demo

#include <stdio.h>  

char shellcode[] = { 0x60, 0xfc, 0x68, 0x4c, 0x77, 0x26, 0x7, 0x33, 0xd2, 0x64, 0x8b, 0x52, 0x30, 0x8b, 0x52, 0xc, 0x8b, 0x52, 0x14, 0x8b, 0x72, 0x28, 0xf, 0xb7, 0x4a, 0x26, 0x33, 0xff, 0x33, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x2, 0x2c, 0x20, 0xc1, 0xcf, 0xd, 0x3, 0xf8, 0xe2, 0xf0, 0x52, 0x57, 0x8b, 0x52, 0x10, 0x8b, 0x42, 0x3c, 0x3, 0xc2, 0x8b, 0x40, 0x78, 0x85, 0xc0, 0xf, 0x84, 0xbe, 00, 00, 00, 0x3, 0xc2, 0x50, 0x8b, 0x48, 0x18, 0x8b, 0x58, 0x20, 0x3, 0xda, 0x83, 0xf9, 00, 0xf, 0x84, 0xa9, 00, 00, 00, 0x49, 0x8b, 0x34, 0x8b, 0x3, 0xf2, 0x33, 0xff, 0x33, 0xc0, 0xac, 0xc1, 0xcf, 0xd, 0x3, 0xf8, 0x3a, 0xc4, 0x75, 0xf4, 0x3, 0x7c, 0x24, 0x4, 0x3b, 0x7c, 0x24, 0xc, 0x75, 0xd9, 0x33, 0xff, 0x33, 0xc9, 0x83, 0xc2, 0x50, 0xf, 0xb6, 0x4, 0xa, 0xc1, 0xcf, 0xd, 0x3, 0xf8, 0x41, 0x83, 0xf9, 0xe, 0x75, 0xf1, 0xc1, 0xcf, 0xd, 0x57, 0x33, 0xff, 0x33, 0xc9, 0x8b, 0x54, 0x24, 0x3c, 0x52, 0xf, 0xb6, 0x1c, 0xe, 0xb8, 0x67, 0x66, 0x66, 0x66, 0xf7, 0xeb, 0xd1, 0xfa, 0x8b, 0xc2, 0xc1, 0xe8, 0x1f, 0x3, 0xc2, 0x8d, 0x4, 0x80, 0x2b, 0xd8, 0x5a, 0xf, 0xb6, 0x4, 0xa, 0x2b, 0xc3, 0xc1, 0xcf, 0xd, 0x3, 0xf8, 0x41, 0x83, 0xf9, 0xe, 0x75, 0xd4, 0xc1, 0xcf, 0xd, 0x3b, 0x3c, 0x24, 0x74, 0x16, 0x68, 0x25, 0x73, 00, 00, 0x8b, 0xc4, 0x68, 0x6e, 0x6f, 00, 00, 0x54, 0x50, 0x8b, 0x5c, 0x24, 0x48, 0xff, 0xd3, 0xeb, 0x14, 0x68, 0x25, 0x73, 00, 00, 0x8b, 0xc4, 0x68, 0x79, 0x65, 0x73, 00, 0x54, 0x50, 0x8b, 0x5c, 0x24, 0x48, 0xff, 0xd3, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x61, 0xc3, 0x58, 0x5f, 0x5a, 0x8b, 0x12, 0xe9, 0xb, 0xff, 0xff, 0xff };
int main()
{
	__asm {
		lea eax, shellcode;
		push eax;
		ret
	}
	return 0;
}

并用010或其他工具更改区段为可读可写可执行

ida动调分析即可

image-20220515195647671

#include <iostream>
#include <string>
#include <fstream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;

int main(int argc, char const *argv[])
{

    char *a = "LoadLibraryExA";
    char *b = "is program can";
    char *c = (char *)malloc(strlen(a));
    // c[i] = a[i]%5 + b[i];
    for (int i = 0; i < strlen(a); i++)
    {
        c[i] = a[i] % 5 + b[i];
    }
    printf("%s\n", c);
}

至此 两部分相加md5即可

posted @ 2022-05-18 15:17  FW_ltlly  阅读(296)  评论(0编辑  收藏  举报