蓝桥杯网安赛道部分WP

307 阅读4分钟

阅读须知:

探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者 本人负责,作者不为此承担任何责任,如有侵权烦请告知,我们会立即删除并致歉,创作不易转载请标明出处.感谢!

师傅: K1t0    k1t0111.github.io

packet

过滤http包 image.png 看到整个流程 其实就是个webshell的利用直接 直接看flag 那条 流量 image.png 看他最后的响应包 就可以看到一串 base编码的字符串解开就是flag

RC4

  1. 先查壳,无壳,并且是32位:

  2. 用32位的ida打开,直接定位到main函数:

  3. 重点关注sub_401005函数,这个应该就是加密函数无疑:

  4. 典型的RC4加密无疑,这里有两种方法进行逆向,第一种:可以在main函数中第52行打上断点,运行到这里后直接查看内存中的V5,即位flag。第二种:将需要的信息提取出来key=gamelab@,使用脚本进行解密:

  5. 第一种:

  6. 第二种:


#RC4加密

def rc4(key, ciphertext):

    # 初始化S盒

    sbox = list(range(256))

    j = 0

    for i in range(256):

        j = (j + sbox[i] + key[i % len(key)]) % 256

        sbox[i], sbox[j] = sbox[j], sbox[i]

    # 生成密钥流

    i = 0

    j = 0

    keystream = []

    for _ in range(len(ciphertext)):

        i = (i + 1) % 256

        j = (j + sbox[i]) % 256

        sbox[i], sbox[j] = sbox[j], sbox[i]

        k = sbox[(sbox[i] + sbox[j]) % 256]

        keystream.append(k)

    # print(keystream)

    # 解密密文

    plaintext = []

    for i in range(len(ciphertext)):

        m = ciphertext[i] ^ keystream[i]

        plaintext.append(m)

    print(plaintext)

    # 将明文转换为字符串

    return ''.join([chr(p) for p in plaintext])

  

# 测试

key = b"gamelab@"

ciphertext =[0xB6,0x42,0xB7,0xFC,0xF0,0xA2,0x5E,0xA9,0x3D,0x29,0x36,0x1F,0x54,0x29,

0x72,0xA8,0x63,0x32,0xF2,0x44,0x8B,0x85,0xEC,0xD,0xAD,0x3F,0x93,0xA3,0x92,

0x74,0x81,0x65,0x69,0xEC,0xE4,0x39,0x85,0xA9,0xCA,0xAF,0xB2,0xC6]

# for i in ciphertext:

#     print(chr(i),end="")

plaintext = rc4(key, ciphertext)

print(plaintext)

#flag{12601b2b-2f1e-468a-ae43-92391ff76ef3}

  1. 两个flag一样,说明正确。

题目:happytime

  1. 同样的流程,查壳无,64位的.elf程序,使用ida打开,直接进入main函数:

  2. printf输出提示信息Let's have a drink,pay your answer(flag):,read在键盘读取flag输入,重要的关键函数是cry加密函数,接受v5和输入的flag,这里的11应该是flag被分割成了11组,最后一个循环比较加密后的flag和V6,刚好和上面v6数组对应:

  3. 根据函数的特征,可以判定这是XXTEA加密无疑,找到其中的DELTA,密文(main函数中的v6),和key(前面main函数的V5),即可编写脚本解密(输出的时候注意大小端序):


#include <stdbool.h>

#include <stdio.h>

#define MX (((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4)) ^ (sum ^ y) + (k[(p & 3) ^ e] ^ z))

bool btea(unsigned int *v, int n, unsigned int *k)

{

    unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x61C88647;

    unsigned int p, q;

    if (n > 1)

    { /* enCoding Part */

        q = 415 / n + 114;

        while (q-- > 0)

        {

            sum += DELTA;

            e = (sum >> 2) & 3;

            for (p = 0; p < (n - 1); p++)

            {

                y = v[p + 1];

                z = v[p] += MX;

            }

  

            y = v[0];

            z = v[n - 1] += MX;

        }

        return 0;

    }

    else if (n < -1)

    { /* Decoding Part */

        n = -n;

        q = 415 / n + 114;

        sum = -q * DELTA;

        while (sum != 0)

        {

            e = (sum >> 2) & 3;

            for (p = n - 1; p > 0; p--)

            {

                z = v[p - 1];

                y = v[p] -= MX;

            }

  

            z = v[n - 1];

            y = v[0] -= MX;

            sum += DELTA;

        }

        return 0;

    }

    return 1;

}

  

int main()

{

    unsigned int v[11] = {0x480AC20C, 0xCE9037F2, 0x8C212018, 0xE92A18D, 0xA4035274, 0x2473AAB1, 0xA9EFDB58, 0xA52CC5C8, 0xE432CB51, 0xD04E9223, 0x6FD07093}, key[4] = {0x79696755, 0x67346F6C, 0x69231231, 0x5F674231};

    int n = 11;       // n为要加密的数据个数

    btea(v, -n, key); // 取正为加密,取负为解密

    char *p = (char *)v;

    for (int i = 0; i < 44; i++)

    {

        printf("%c", *p);

        p++;

    }

    return 0;

}

//flag{efccf8f0-0c97-12ec-82e0-0c9d9242e335}

  1. 最后输入验证flag成功!!!

密码

image.png