前言

个人赛新生赛道第二,总排名第九
image-20241026004953276

crypto

密码全是原题

rand

这么简单的一个数学方程式啊? 诶 解起来怎么感觉有点困难 (输入格式为x,y)

原题ASIS2023 Crypto - 知乎 (zhihu.com)

from Crypto.Util.number import *
import sys

def terminate(*args):
    print(*args)
    quit()


def receive():
    return sys.stdin.buffer.readline()

def main():
    NBIT = 32
    STEP = 40

    current_step = 1
    while current_step <= STEP:
        nbit = NBIT * current_step
        p = getPrime(nbit)
        print(f'The modulus p is: {p}')
        print('First, send the base g: ')
        g = receive().strip().decode()
        print('pow(g, x + y, p) = x * y, as x and y:')
        xy = receive().strip().decode().split(',')
        try:
            g, x, y = [int(_) for _ in [g] + xy]
        except:
            print('fail')
            exit(0)
        if (x >= p-1 or x <= 1) or (y >= p-1 or y <= 1) or x == y:
            exit(0)
        if g <= 2**24 or g >= p-1:
            exit(0)
        if pow(g, x + y, p) ==  x * y % p:
            if current_step == STEP:
                fp = open("/flag","r")
                print(fp.read())
                fp.close()
            else:
                print("good")
                current_step += 1


if __name__ == '__main__':
    main()

exp

from pwn import *
io = remote('challenge.yuanloo.com', 48145)

for _ in range(40):
    io.recvuntil(b' p is: ')
    p = int(io.recvline().decode())
    print(p)
    g = p-4
    io.sendline(str(g).encode())
    io.recv()
    io.sendline(f'{2},{p-2}')
io.interactive()

image-20241018150406741

ezAES

看起来你需要补充点什么

题目

this is a AES,you maybe need full padding.
key is YLCTF-CRYPTO
iv is YLCTF-IV
AES define is

from Crypto.Cipher import AES
AES.new(key,2,iv)
result = b""
padded_data = pad(flag, AES.block_size)
endata = aes.encrypt(padded_data)
print(endata)


\xed\x1d]\xe6p\xb7\xfa\x90/Gu\xf4\xe2\x96\x84\xef90\x92e\xb4\xf8]"\xfc6\xf8\x8cS\xe9b\x19

ai秒

exp

from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

# 补全密钥和 IV 到 16 字节
key = b'YLCTF-CRYPTO'.ljust(16, b'\0')  # 补充 '\0' 使其达到 16 字节
iv = b'YLCTF-IV'.ljust(16, b'\0')  # 补充 '\0' 使其达到 16 字节

# 已知的密文
ciphertext = b'\xed\x1d]\xe6p\xb7\xfa\x90/Gu\xf4\xe2\x96\x84\xef90\x92e\xb4\xf8]"\xfc6\xf8\x8cS\xe9b\x19'

# 创建 AES 对象
aes = AES.new(key, AES.MODE_CBC, iv)

# 解密数据
decrypted_data = aes.decrypt(ciphertext)

# 去除填充
try:
    original_data = unpad(decrypted_data, AES.block_size)
    print("解密结果:", original_data.decode())
except ValueError as e:
    print("解密出错,可能是填充不正确:", e)

ancat

跟我一起叱咤月海鱼鱼猫

题目源码

import matplotlib.pyplot as plt
import cv2
import numpy as np
from PIL import Image
def arnold_encode(image, shuffle_times, a, b):
    """ Arnold shuffle for rgb image
    Args:
        image: input original rgb image
        shuffle_times: how many times to shuffle
    Returns:
        Arnold encode image
    """
    arnold_image = np.zeros(shape=image.shape)

    h, w = image.shape[0], image.shape[1]
    N = h

    for time in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):

                new_x = (1*ori_x + b*ori_y)% N
                new_y = (a*ori_x + (a*b+1)*ori_y) % N

                arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]

        image = np.copy(arnold_image)

    cv2.imwrite('en_flag.png', arnold_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])
    return arnold_image

img = cv2.imread('flag.png')
arnold_encode(img,3,6,9)

用python设计图像加密技术之Arnold算法 - 知乎 (zhihu.com)

应该算misc

exp

import matplotlib.pyplot as plt
import cv2
import numpy as np
from PIL import Image

def arnold_decode(image, shuffle_times, a, b):
    """ decode for rgb image that encoded by Arnold
    Args:
        image: rgb image encoded by Arnold
        shuffle_times: how many times to shuffle
    Returns:
        decode image
    """
    # 1:创建新图像
    decode_image = np.zeros(shape=image.shape)

    # 2:计算N
    h, w = image.shape[0], image.shape[1]
    N = h  # 或N=w

    # 3:遍历像素坐标变换
    for time in range(shuffle_times):
        for ori_x in range(h):
            for ori_y in range(w):
                # 按照公式坐标变换
                new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % N
                new_y = ((-a) * ori_x + ori_y) % N
                decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]
        image = np.copy(decode_image)

    cv2.imwrite('flag.png', decode_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])

    return decode_image

img = cv2.imread('en_flag.png')
arnold_decode(img,3,6,9)

flag

hhhhhash

要hash? nonono0000000000000

原题,出题人很喜欢抄国际赛啊

IrisCTF-2024-Challenges/dhash/challenge/chal.py at main · IrisSec/IrisCTF-2024-Challenges (github.com)

from Crypto.Util.number import getPrime, isPrime

e = 65537
N = 1
while (N - 1) % e == 0:
    N = getPrime(2048)

def x(a, b):
    return bytes(x^y for x,y in zip(a,b))

class C():
    def __init__(self, N, e):
        self.N = N
        self.e = e
        self._state = b"\x00" * 256
        self.s = set()

    def _h(self, block):
        assert len(block) == 256

        if block in self.s:
            raise ValueError("bad")
        self.s.add(block)

        data = int.from_bytes(block, "big")
        if data < 2 or data >= N-1:
            raise ValueError("bad")

        data = pow(data, self.e, self.N)
        if data in self.s:
            raise ValueError("bad")
        self.s.add(data)

        return data.to_bytes(256, "big")

    def u(self, data):
        assert len(data) % 256 == 0

        for block in range(0, len(data), 256):
            block = data[block:block+256]
            self._state = x(self._state, self._h(block))

        return self

    def hd(self):
        return self._state.hex()

    def __repr__(self):
        return f"C({self.N}, {self.e})"

def m():
    h = C(N, e)
    print(h)

    print("Input the data you'd like to process:")
    p = bytes.fromhex(input("> "))
    if len(p) < 256 or len(p) % 256 != 0:
        raise ValueError("Invalid input!")

    z = h.u(p).hd()
    print("hash(input) == ", z)
    if z == "00" * 256:
        with open("/flag","r") as f:
            print(f.read())
    else:
        print("...")

m()

coding-challs/cryptogaphy/2024/irisctf/dhash-solution.py at master · mfocuz/coding-challs (github.com)

exp

from Crypto.Util.number import getPrime, isPrime, long_to_bytes

e = 65537
N = 1
while (N - 1) % e == 0:
    N = getPrime(2048)

def xor(a, b):
    return bytes(x^y for x,y in zip(a,b))

class MySeededHash():
    def __init__(self, N, e):
        self.N = N
        self.e = e
        self._state = b"\x00" * 256
        self.seen = set()

    def _hash_block(self, block):
        assert len(block) == 256

        if block in self.seen:
            raise ValueError("This looks too familiar... :o")
        self.seen.add(block)

        data = int.from_bytes(block, "big")
        if data < 2 or data >= N-1:
            raise ValueError("Please ensure data is supported by hash function :|")

        data = pow(data, self.e, self.N)
        if data in self.seen:
            raise ValueError("Collisions are cheating!!! >:(")
        self.seen.add(data)

        return data.to_bytes(256, "big")

    def update(self, data):
        assert len(data) % 256 == 0

        for block in range(0, len(data), 256):
            block = data[block:block+256]
            self._state = xor(self._state, self._hash_block(block))

        return self

    def hexdigest(self):
        return self._state.hex()

    def __repr__(self):
        return f"MySeededHash({self.N}, {self.e})"


def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)


def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m


def solution(e, N):
    d = modinv(e, N-1)

    block_1 = pow(0xf0, d, N)
    block_2 = pow(0x0f, d, N)
    block_3 = pow(0xff, d, N)
    return block_1.to_bytes(256, "big") + block_2.to_bytes(256, "big") + block_3.to_bytes(256, "big")


def main():
    
    N=int(input("N="))
    e=int(input("e="))
    print("Give me your string that hashes to 0...")
    preimage = solution(e, N)
    print("Solution block=%s" % preimage.hex())


main()

YLCTF{2ec29fca-5d05-45f9-9ebe-d488a6ab5a43}

web

Cmnts

F12

image-20241018152534579

base64解密拿到路由get_th1s_f1ag.php

<?php
include 'flag.php';
parse_str($_SERVER['QUERY_STRING']);

if (isset($pass)) {
    $key = md5($pass);
}
if (isset($key) && $key === 'a7a795a8efb7c30151031c2cb700ddd9') {
    echo $flag;
}
else {
    highlight_file(__FILE__);
}

parse_str函数会自动转化为变量

image-20241018152517018

PHUPE

从0CTF一道题看move_uploaded_file的一个细节问题-安全客 - 安全资讯平台 (anquanke.com)

image-20241018233708656

cmd.php/.绕过

image-20241018220215129

image-20241018220222098

YLCTF{22c414a4-59f4-4675-bc1f-b5b9f3f8a399}

re

三点几啦饮茶先

这个茶的味道有点怪异啊 最终提交格式为,解出来的uuid套上YLCTF{},YLCTF{uuid},deadbeef为填充字符串不用写入到flag中

魔改tea

屏幕截图 2024-10-19 041325

enc和key

屏幕截图 2024-10-19 041337

exp

#include<stdio.h>
#include<stdint.h>


void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
	unsigned int i;
	uint32_t v0 = v[0], v1 = v[1], delta = 0x114514B9, sum = delta * num_rounds;
	for (i = 0;i < num_rounds;i++) {
		v1 -= (((v0 * 16) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
		sum -= delta;
		v0 -= (((v1 * 4) ^ (v1 >> 3)) + v1) ^ (sum + key[sum & 3]);
	}
	v[0] = v0;v[1] = v1;
}

int main() {
	uint32_t v[2] = { 1913208188,-1240730499 };
	uint32_t const k[4] = { 4097,8194,12291,16388 };
	unsigned int r = 0x28;				//这里是加密轮数,自己设置 

	printf("加密后原始数据:%u %u\n", v[0], v[1]);
	decipher(r, v, k);
	printf("解密后原始数据:%u %u\n", v[0], v[1]);
	return 0;
}	

ezwasm

秒了

image-20241018190100962

ezapk

apkcheck不了flag,只能checkkey,不影响解题,即:YLCTF+KEY 到输入框中即可检测key是否正确,不用跟着+

hook出了enc-key,即vi

16元方程解不出来,哭

mmmmmmmov

你在移动个啥啊,这么得劲,我都看不懂了,能不能de一下

**demovfuscator**解完,断点打plt应该能出逻辑,不过缺库,麻烦

misc

Trace

base64

image-20241018172002646

image-20241018171951341

image-20241018223126339

rar5的文件头s

image-20241018223136962

hashcat爆破密码

image-20241018225036682

不得不说p的挺💩的

image-20241018232856790

IMGAI

致敬ISCC :respect:

挺简单的,二进制转图形后用给的模型预测一下

from pwn import *
import torch
import torch.nn as nn
from torchvision import transforms
from PIL import Image

# 连接远程服务器
p = remote("challenge.yuanloo.com", 26569)

s = p.recvline()


# CNN 模型定义
class MNISTCNN(nn.Module):
    def __init__(self):
        super(MNISTCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=5, padding=2)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=5)
        self.fc1 = nn.Linear(64 * 5 * 5, 1024)
        self.fc2 = nn.Linear(1024, 10)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))
        x = self.pool(self.relu(self.conv2(x)))
        x = x.view(-1, 64 * 5 * 5)  # 展平
        x = self.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 加载模型权重
model = MNISTCNN()
model.load_state_dict(torch.load('model.pth'))
model.eval()

# 定义图像变换
transform = transforms.Compose([
    transforms.Resize((28, 28)),
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])
aaa=""
for i in range(60):
    binary_str = p.recvuntil(b'\n')[:-1].decode()
    print(binary_str)
    print(p.recvline())
    # 将二进制字符串分割为 8 位一组
    byte_list = [binary_str[i:i + 8] for i in range(0, len(binary_str), 8)]

    # 将每个 8 位二进制数转换为十进制数
    pixel_values = [int(byte, 2) for byte in byte_list]

    # 确定图像的大小(例如 80x8 像素)
    width = 80
    height = len(pixel_values) // width
    print(f"图像高度: {height} 像素")

    # 创建图像对象并填充像素值
    img = Image.new('L', (width, height))  # 'L' 模式代表灰度图
    img.putdata(pixel_values)

    # 对图像进行变换
    image_tensor = transform(img).unsqueeze(0)  # 转换为模型输入

    # 通过模型预测
    output = model(image_tensor)
    prediction = torch.argmax(output, 1)
    print(f"模型预测结果: {prediction.item()}")
    p.sendline(str(prediction.item()))
    aaa+=str(prediction.item())
    print(aaa)
print(p.recv())

image-20241018213511302

LiteOS

好昂贵的系统,好小的系统
附件链接:https://wwqc.lanzouk.com/i5Pqz2clrbla

hint1 : pdu

hint2 : 注意联动hex

hint3 : 思考一下短信的pdu

hint4 : aes-ecb

hint5 : qemu-gdb

main解密脚本

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void rc4_ksa(unsigned char* key, int key_len, unsigned char* S)
{
    unsigned char extra[256];
    unsigned char temp;
    int j, i;

    for (i = 0; i <= 255; ++i)
        S[i] = i;

    j = 0;
    for (i = 0; i <= 255; ++i)
    {
        j = (S[i] + j + key[i % key_len]) % 256;
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }

    for (i = 0; i <= 255; ++i)
        S[i] = (i + S[i]) % 256;

    for (i = 0; i <= 255; ++i)
        S[i] ^= 2 * i % 256;

    for (i = 0; i <= 255; ++i)
    {
        S[i] += i % 5;
        S[i] ^= 3 * i % 256;
    }

    for (i = 0; i <= 255; ++i)
        extra[i] = (i + S[i]) % 256;

    for (i = 0; i <= 255; ++i)
        extra[i] *= 2;

    for (i = 0; i <= 255; ++i)
        S[i] += extra[i];
}
void print_data(unsigned char* data) {
    printf("数据: ");
    for (int i = 0; i < 44; i++) {
        printf("%02X", data[i]);
    }
    printf("\n");
}
void rc4_prga(unsigned char* S, unsigned char* data, int data_len)
{
    unsigned char K;
    unsigned char temp;
    int k, j, i;

    i = 0;
    j = 0;
    for (k = 0; k < data_len; ++k)
    {
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
        K = S[(unsigned char)(S[i] + S[j])];
        //printf(" k = %x\n", K);
        data[k] ^= K;
    }
    print_data(data);
    for (i = 0; i < data_len; ++i) {

        data[i] = (i + data[i]) % 256;

    }
    print_data(data);

    for (i = 0; i < data_len; ++i)
        data[i] ^= 3 * i % 256;
    print_data(data);

    unsigned char* p_junk = (unsigned char*)malloc(data_len);
    for (i = 0; i < data_len; ++i)
        p_junk[i] = 2 * data[i];
    print_data(p_junk);

    for (i = 0; i < data_len; ++i)
        data[i] += p_junk[i];
    print_data(data);

    for (i = 0; i < data_len; ++i) {
      //  printf("%02X ->", data[i]);
        data[i] ^= 5 * i % 256;
       // printf("%02X  ", data[i]);
    }
    print_data(data);

    free(p_junk);
}

void rc4_deprga(unsigned char* S, unsigned char* data, int data_len)
{
    unsigned char K;
    unsigned char temp;
    int k, j, i;


    for (i = 0; i < data_len; ++i) {
       // printf("%02X ->", data[i]);
        data[i] ^= 5 * i % 256;
        //printf("%02X  ", data[i]);
    }    
    print_data(data);

    for (i = 0; i < data_len; ++i) {
        data[i] = (171 * data[i]) % 256;
    }
    print_data(data);

    for (i = 0; i < data_len; ++i)
        data[i] ^= 3 * i % 256;
    print_data(data);

    for (i = 0; i < data_len; ++i)
        data[i] = (data[i] + 256 - i) % 256;
    print_data(data);
    i = 0;
    j = 0;
    for (k = 0; k < data_len; ++k)
    {
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
        K = S[(unsigned char)(S[i] + S[j])];
        //printf(" k = %x\n", K);
        data[k] ^= K;
    }
}

int encrypt()
{
    unsigned char tmp[256];
    unsigned char data[44];
    unsigned char S[256];
    unsigned char key[16];
    int data_len;
    int i, x;

    // Initialize key
    unsigned long long key_part1 = 0x6624C95E3420CB4A;
    unsigned long long key_part2 = 0x7A0A66FBD2898B0A;
    memcpy(key, &key_part1, 8);
    memcpy(key + 8, &key_part2, 8);

    // Initialize data
    strcpy((char*)data, "YLCTF{12345678-abcd-ABCD-XYZ!-ASDFghjkL;'\"}");
    data_len = strlen((const char*)data);
    for (i = 0; i < data_len; i++) {
        printf("%02X", data[i]);
    }
    printf("\n");
    // Perform encryption
    rc4_ksa(key, 16, S);
    rc4_prga(S, data, data_len);
    printf("Encrypted data: ");
    for (i = 0; i < data_len; i++) {
        printf("%02X", data[i]);
    }
    printf("\n");
    rc4_ksa(key, 16, S);
    rc4_prga(S, data, data_len);

    // Print encrypted data
    printf("Encrypted data: ");
    for (i = 0; i < data_len; i++) {
        printf("%02X", data[i]);
    }
    printf("\n");

    // Additional operations
    x = 0;
    for (i = 0; i <= 19; ++i)
    {
        x += i;
        printf("Sum: %d\n", x);
    }

    for (i = 0; i <= 255; ++i)
        tmp[i] = 4 * i % 256;

    for (i = 0; i <= 255; ++i)
        tmp[i] = (tmp[i] + i % 10) % 256;

    for (i = 0; i <= 255; ++i)
        tmp[i] ^= 6 * i % 256;
        
    return 0;
}
int hex_to_bytes(const char* hex_str, unsigned char* bytes, int max_len) {
    int len = strlen(hex_str) / 2;
    if (len > max_len) len = max_len;
    for (int i = 0; i < len; i++) {
        sscanf(hex_str + 2 * i, "%2hhx", &bytes[i]);
    }
    return len;
}
int decrypt() {
    unsigned char tmp[256];
    unsigned char data[44];
    unsigned char S[256];
    unsigned char key[16];
    unsigned char encrypted_data[44];
    unsigned char decrypted_data[44];
    int data_len;
    int i, x;

    // Initialize key
    unsigned long long key_part1 = 0x6624C95E3420CB4A;
    unsigned long long key_part2 = 0x7A0A66FBD2898B0A;
    memcpy(key, &key_part1, 8);
    memcpy(key + 8, &key_part2, 8);

    // 输入加密后的十六进制字符串
    printf("请输入加密后的十六进制字符串: ");
    char hex_input[89];  // 44 bytes * 2 + 1 for null terminator
    fgets(hex_input, sizeof(hex_input), stdin);
    hex_input[strcspn(hex_input, "\n")] = 0;  // 移除换行符

    // 将十六进制字符串转换为字节数组
    data_len = hex_to_bytes(hex_input, encrypted_data, sizeof(encrypted_data));

    // 复制加密数据到解密缓冲区
    memcpy(decrypted_data, encrypted_data, data_len);

    // 执行解密 (与加密过程相同)
    rc4_ksa(key, 16, S);
    rc4_deprga(S, decrypted_data, data_len);
    printf("解密后的数据: ");
    for (int i = 0; i < data_len; i++) {
        printf("%x", decrypted_data[i]);
    }
    printf("\n");
    rc4_ksa(key, 16, S);
    rc4_deprga(S, decrypted_data, data_len);

    // 打印解密后的数据
    printf("解密后的数据: ");
    for (int i = 0; i < data_len; i++) {
        printf("%X", decrypted_data[i]);
    }
    printf("\n");
    return 0;

}



int main() {
    decrypt();
}