SECCON Beginners CTF 2021 Write-up

技術

2021-05-22 14:00 – 2021-05-23 14:00 (JST)に開催されたSECCON Beginners CTF 2021のWrite-upです。

友人であるmaa氏との2人チームで出場し、2219pt獲得して全1095チーム中52位でした。

 

children

category: reversing

ELFファイルが与えられ、次々に作成される子プロセスのprocess IDを追いかける問題です。

straceを使って生成された新しい子プロセスのprocess IDを入力していき、最後に生成された子プロセスの総数を答えればフラグが獲得できます。

$ strace ./children
execve("./children", ["./children"], 0x7fff2cc240c0 /* 22 vars */) = 0
brk(NULL) = 0x55caadded000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=91823, ...}) = 0
mmap(NULL, 91823, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4627b28000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\35\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030928, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4627b26000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4627525000
mprotect(0x7f462770c000, 2097152, PROT_NONE) = 0
mmap(0x7f462790c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f462790c000
mmap(0x7f4627912000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4627912000
close(3) = 0
arch_prctl(ARCH_SET_FS, 0x7f4627b27500) = 0
mprotect(0x7f462790c000, 16384, PROT_READ) = 0
mprotect(0x55caacec5000, 4096, PROT_READ) = 0
mprotect(0x7f4627b3f000, 4096, PROT_READ) = 0
munmap(0x7f4627b28000, 91823) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
brk(NULL) = 0x55caadded000
brk(0x55caade0e000) = 0x55caade0e000
write(1, "I will generate 10 child process"..., 36I will generate 10 child processes.
) = 36
write(1, "They also might generate additio"..., 51They also might generate additional child process.
) = 51
write(1, "Please tell me each process id i"..., 58Please tell me each process id in order to identify them!
) = 58
write(1, "\n", 1
) = 1
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f4627b277d0) = 13958
write(1, "Please give me my child pid!\n", 29Please give me my child pid!
) = 29
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
read(0, 0x55caadded670, 1024) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=13958, si_uid=1000, si_status=1, si_utime=0, si_stime=0} ---
read(0,

===(略)===

"14367\n", 1024) = 6
write(1, "ok\n", 3ok
) = 3
wait4(-1, NULL, 0, NULL) = 13958
write(1, "How many children were born?\n", 29How many children were born?
) = 29
read(0, 11
"11\n", 1024) = 3
write(1, "ctf4b{p0werfu1_tr4sing_t0015_15_"..., 40ctf4b{p0werfu1_tr4sing_t0015_15_usefu1} ) = 40
lseek(0, -1, SEEK_CUR) = -1 ESPIPE (Illegal seek)
exit_group(0) = ?
+++ exited with 0 +++

→ ctf4b{p0werfu1_tr4sing_t0015_15_usefu1}

 

osoba

category: web

適当にページを開くとクエリにファイルパスらしきものが指定されています。

https://osoba.quals.beginners.seccon.jp/?page=public/wip.html
def index():
page = request.args.get('page', 'public/index.html') 
response = make_response(send_file(page))
response.content_type = "text/html"
return response

配布ファイルと問題文を参照すると/flagにフラグがあることがわかるので、ディレクトリトラバーサルでflagが取得できます。

https://osoba.quals.beginners.seccon.jp/?page=../flag

→ ctf4b{omisoshiru_oishi_keredomo_tsukuruno_taihen}

 

check_url

category: web

配布されたindex.phpの中に以下のような記述があります。

if ($_SERVER["REMOTE_ADDR"] === "127.0.0.1"){
  echo "Hi, Admin or SSSSRFer<br>";
  echo "********************FLAG********************";
}else{
  echo "Here, take this<br>";
  $url = $_GET["url"];
  if ($url !== "https://www.example.com"){
    $url = preg_replace("/[^a-zA-Z0-9\/:]+/u", "👻", $url); //Super sanitizing
  }
  if(stripos($url,"localhost") !== false || stripos($url,"apache") !== false){
  die("do not hack me!");
}
echo "URL: ".$url."<br>";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 2000);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
echo "<iframe srcdoc='";
curl_exec($ch);
echo "' width='750' height='500'></iframe>";
curl_close($ch);
}
?>

curl_execがあるのでSSRFでローカルからのアクセスだと判断させればフラグが得られそうですが、正規表現でアルファベットと数字以外が弾かれてしまうため127.0.0.1は指定できません。

127.0.0.1(localhost)を一番面白く表記できた奴が優勝 - Qiita
要約 もしも127.0.0.1(localhost)を一番面倒くさく面白くIPv4表記できた奴が優勝するとしたらと妄想してみた 個人的に 017700000001 が優勝!!! 前書き IPアドレスとは IPアド...

上記記事を参考にし、アルファベットと数字のみで127.0.0.1を表せる表記をいくつか試したところ、

https://check-url.quals.beginners.seccon.jp/?url=0x7F000001

→ ctf4b{5555rf_15_53rv3r_51d3_5up3r_54n171z3d_r3qu357_f0r63ry}

で通りました。ちなみに0x7F000001は16進表記バージョンです。

 

所感

メンバーの応援をしながらいけそうな問題にちょこちょこ手を付けてました。

reversingもう1問くらい解きたかったので今後の課題ということで。

タイトルとURLをコピーしました