AIS3 Pre-exam & MyFirstCTF WriteUp

MyFirstCTF
6st place

alt text

misc

  • Quantum Nim Heist
    發現輸入時按enter好像會沒移除石頭,反正最後使自己移除最後一顆
    image

  • Three Dimensional Secret
    image
    追蹤TCP流,並另存為一個檔案
    https://ncviewer.com/ 開啟此檔案
    image

  • Emoji Console
    試了很久發現”:|”後的指令可以執行
    image

web

  • Evil Calculator
    image

rev

  • The Long Print
    這本來是一個很大的數字,patch成1,變每秒print一個字元
    image
    趕在消失不見前趕快截圖
    image
    最後的”}”大概一輸出就不見了,自己補上

  • 火拳のエース
    先執行,發現flag輸出了一小部份且輸出速度太慢
    IDA,從main進到print_flag(),patch輸出時要等待的時間,改成0
    image
    輸出正常後回到main繼續分析,找剩下的flag
    image
    首先是輸入四個字串空白分隔
    然後在 xor_strings() 這四個字串分別跟四個不同的東西做XOR,從IDA我不會看這4個東西是甚麼,用ghidra看到了,把他們的前8 bytes 記下來
    再來四個字串的每個字元經過 complex_function() 轉換
    最後判斷是否4個轉換後的字串都等於對應的字串
    => 於是4個字串分別暴力破解,找出輸入什麼最後會變成對應的字串
    每個字串的暴力破解程式有微調,以第四個字串為例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include <bits/stdc++.h>
    using namespace std;

    int xor_hex0[] = {0x0E, 0x0D, 0x7D, 0x06, 0x0F, 0x17, 0x76, 0x04};
    int xor_hex1[] = {0x6D, 0x00, 0x1B, 0x7C, 0x6C, 0x13, 0x62, 0x11};
    int xor_hex2[] = {0x1E, 0x7E, 0x06, 0x13, 0x07, 0x66, 0x0E, 0x71};
    int xor_hex3[] = {0x17, 0x14, 0x1D, 0x70, 0x79, 0x67, 0x74, 0x33};

    string target0 = "DHLIYJEG";
    string target1 = "MZRERYND";
    string target2 = "RUYODBAH";
    string target3 = "BKEMPBRE";

    void xor_strings(string input, int xor_hex[], int* result_int)
    {
    int i;
    int input_int[9];

    for ( i = 0; i <= 7; ++i )
    {
    input_int[i] = int(input[i]);
    result_int[i] = input_int[i] ^ xor_hex[i];
    }

    }

    int complex_function(int a1, int a2){
    int v2; // eax
    int v4; // [esp-Ch] [ebp-24h]
    int v5; // [esp-8h] [ebp-20h]
    int v6; // [esp-4h] [ebp-1Ch]
    int v7; // [esp+8h] [ebp-10h]
    int v8; // [esp+Ch] [ebp-Ch]

    if ( a1 <= 64 || a1 > 90 )
    {
    return 64;
    }

    v8 = (17 * a2 + a1 - 65) % 26;
    v7 = a2 % 3 + 3;
    v2 = a2 % 3;
    if ( a2 % 3 == 2 )
    {
    v8 = (v8 - v7 + 26) % 26;
    }
    else if ( v2 <= 2 )
    {
    if ( v2 )
    {
    if ( v2 == 1 )
    v8 = (2 * v7 + v8) % 26;
    }
    else
    {
    v8 = (v7 * v8 + 7) % 26;
    }
    }
    return v8 + 65;
    }

    int main(){
    string input = " ";
    string result = "AAAAAAAA";
    for(int i=0;i<8;i++){
    for(int j=33;j<127;j++){
    input[i] = char(j);
    int tmp[9];
    xor_strings(input, xor_hex3, tmp);
    result[i] = char(complex_function(tmp[i], i+96));
    if(result[i] == target3[i]){
    cout<<result<<endl;
    cout<<input<<endl;
    break;
    }
    }

    }
    }

輸出
image

crypto

  • babyRSA
    改編 babyRSA.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import random
    from Crypto.Util.number import getPrime

    def gcd(a, b):
    while b:
    a, b = b, a % b
    return a

    def generate_keypair(keysize):
    p = getPrime(keysize)
    q = getPrime(keysize)
    n = p * q
    phi = (p-1) * (q-1)

    e = random.randrange(1, phi)
    g = gcd(e, phi)
    while g != 1:
    e = random.randrange(1, phi)
    g = gcd(e, phi)
    d = pow(e, -1, phi)
    return ((e, n), (d, n))

    def encrypt(pk, plaintext):
    key, n = pk
    cipher = [pow(ord(char), key, n) for char in plaintext]
    return cipher

    e = 64917055846592305247490566318353366999709874684278480849508851204751189365198819392860386504785643859122396657301225094708026391204100352682992979425763157452255909781003406602228716107905797084217189131716198785709124050278116966890968003294485934472496151582084561439957513571043497031319413889856520421733
    n = 115676743153063753482251273007095369919613374531038288437295760314264647231038870203981488393720761532040569270340726478402172283300622527884543078194060647393394510524980830171230330673500741683492143805583694395504141751460090539868114454005046898551218623342425465650881666420408703144859108346202894384649

    public = (e, n)
    enc = [...] // 就是output.txt的Encrypted:[],太長,略

    flag = ""
    for c in enc:
    for i in range(128):

    encrypted_msg = encrypt(public, chr(i))
    if c in encrypted_msg:

    flag += chr(i)
    print(flag)
    image