CTF-The-Climb

WriteUp来源

The-Climb | csictf 2020

by raghul-rajasekar

题目描述

We are not lost, we're right here somewhere on this little blue line. Wait, why do I feel like I'm being watched?

Files:

解题思路

Solution

theclimb.java contains the following code:

public class Main
{
    int kmatrix[][];
    int tmatrix[];
    int rmatrix[];
 
    public void div(String temp, int size)
    {
        while (temp.length() > size)
        {
            String substr = temp.substring(0, size);
            temp = temp.substring(size, temp.length());
            perf(substr);
        }
        if (temp.length() == size)
            perf(temp);
        else if (temp.length() < size)
        {
            for (int i = temp.length(); i < size; i++)
                temp = temp + 'x';
            perf(temp);
        }
    }
 
    public void perf(String text)
    {
        textconv(text);
        multiply(text.length());
        res(text.length());
    }
 
    public void keyconv(String key, int len)
    {
        kmatrix = new int[len][len];
        int c = 0;
        for (int i = 0; i < len; i++)
        {
            for (int j = 0; j < len; j++)
            {
                kmatrix[i][j] = ((int) key.charAt(c)) - 97;
                c++;
            }
        }
    }
 
    public void textconv(String text)
    {
        tmatrix = new int[text.length()];
        for (int i = 0; i < text.length(); i++)
        {
            tmatrix[i] = ((int) text.charAt(i)) - 97;
        }
    }
 
    public void multiply(int len)
    {
        rmatrix = new int[len];
        for (int i = 0; i < len; i++)
        {
            for (int j = 0; j < len; j++)
            {
                rmatrix[i] += kmatrix[i][j] * tmatrix[j];
            }
            rmatrix[i] %= 26;
        }
    }
 
    public void res(int len)
    {
        String res = "";
        for (int i = 0; i < len; i++)
        {
            res += (char) (rmatrix[i] + 97);
        }
        System.out.print(res);
    }
 
 
    public static void main(String[] args)
    {
        Main obj = new Main();
        System.out.println("Enter the plain text: ");
        String text = "fakeflag";
        System.out.println(text);
        System.out.println("Enter the key: ");
        String key = "gybnqkurp";
        System.out.println(key);
        double root = Math.sqrt(key.length());
        if (root != (long) root)
            System.out.println("Invalid key length.");
        else
        {
            int size = (int) root;
               
                System.out.println("Encrypted text = ");
                obj.keyconv(key, size);
                obj.div(text, size);
        }
    }
}

 总之,它取关键字gybnqkurp,将其转换为3x3矩阵,并通过取块与关键字矩阵的每一行的点积模26来编码每一块三个字符。为了扭转这种情况,我能想到的最简单的想法是简单地对每个密文块迭代所有可能的大小为3的块(总计263=17576),对其进行加密,看看它是否与密文块匹配。虽然我没有试图严格证明这一点,但我的想法是每个密文块的预图像数量会很低,所以我可以手动挑选出正确的明文块。幸运的是(或者不是,我仍然不确定),每个密文块恰好对应一个明文块。

import string
cipher = 'lrzlhhombgichae'
key = 'gybnqkurp'
def encrypt(text, key): 
    keylist = [] 
    for c in key: 
        keylist.append(ord(c) - ord('a')) 
    textlist = [] 
    for i in range(3): 
        for c in text: 
            textlist.append(ord(c) - ord('a')) 
    ret = '' 
    for i in range(3): 
        temp = 0 
        for j in range(3): 
            ind = i*3 + j 
            temp += keylist[ind]*textlist[ind] 
        ret += chr(temp%26 + ord('a')) 
    return ret
cipher = [cipher[i:i+3] for i in range(0, len(cipher), 3)]
for s in cipher: 
    for a1 in string.ascii_lowercase: 
        for a2 in string.ascii_lowercase: 
            for a3 in string.ascii_lowercase: 
                if encrypt(a1+a2+a3, key) == s: 
                    print(a1+a2+a3, end = '')

 输出是hillshaveyessxx,其中x表示填充。去掉填充并将其余部分包装成标志格式,得到了最终的flag。

Flag

csictf{hillshaveeyes}
  • 42
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值