2022年全国大学生信息安全竞赛创新实践能力赛 —— 复赛WriteUp

已更新官方WriteUP 代码浏览 - 20220619-National - CTF赛事文件合集 - GamerNoTitle的团队 (coding.net)

Break部分

(好的,啥也不会)

Web

Try2ReadFlag

小明创建了一个测试站点,但是这个站点有什么用呢?

打开来是个网页,我没看出啥,不过我们队里搞Web的那位说是CSRF跨站攻击

joomla

建站勿用弱口令!

这个是个CMS框架,整不出,提示写着建站勿用弱口令!,但是我没爆破出来……

(忘记截图了)

EzRome

经过上次的战“疫”,你们已经对rome很了解了,现在他又带着新的waf卷土重来了。

这是一个WAF下的题目,还是不会嗯

EzLogin

登陆成功就有flag哟~

一开始以为是弱口令,等到进了fix环节才发现我好像忘记了robots.txt也可以访问,可以大致看到路径下有什么文件,fix环节在讲这个

PWN

小明的加密器

小明写了一个字符串加密器,但不知道效果如何,大家来测一测吧!

nc进去后是一个加密器,但是没整出来

weirdheap

A Little Weird

nc进去是一个程序,是一个建楼的背景

1. Build up
2. visit big house
3. construct
4. tear down
Ur choice:

chats_store

为什么我的og不能getshell啊?

nc进去是一个聊天备份程序,但是没整出来

+================================+
+ Emergency Chats Backup Program +
+============hope there's no vuln+
+1.store chats
+2.delete chats
+3.exit

printf_hhh

格式化字符串,hhh

nc进去是一个字符串的格式化软件,如果选择1会出来一串字符(忘记截图了),2的话就是打啥显示啥(echo服务)

REVERSE

ob!

ob而已!

这个用ida逆向一下,出来的是个JavaScript语言的内容

function _0x15f8(_0x1cdd90, _0x29a14a) {
  var _0x55fe3f = _0x55fe();
  return (
    (_0x15f8 = function (_0x15f885, _0x2046fc) {
      _0x15f885 = _0x15f885 - 0x139;
      var _0x273cae = _0x55fe3f[_0x15f885];
      return _0x273cae;
    }),
    _0x15f8(_0x1cdd90, _0x29a14a)
  );
}
function _0x55fe() {
  var _0x47407e = [
    "1434380GTSaRX",
    "split",
    "sZuqf",
    "toString",
    "6092LqZrwr",
    "charCodeAt",
    "2298DprXBL",
    "6108172ZkGjDt",
    "1326TZBtUd",
    "cdcMv",
    "length",
    "DASCTF{********************************}",
    "log",
    "8xppuAQ",
    "reverse",
    "LHAkM",
    "3528396BuNtWV",
    "gOHVz",
    "5507440MXfrBq",
    "esJvd",
    "BZTwo",
    "6940hAoqHl",
    "1815832yyeHHB",
  ];
  _0x55fe = function () {
    return _0x47407e;
  };
  return _0x55fe();
}
(function (_0x1df8a4, _0x20dfb3) {
  var _0x67a2d4 = _0x15f8,
    _0xcc66c3 = _0x1df8a4();
  while (!![]) {
    try {
      var _0x23a480 =
        -parseInt(_0x67a2d4(0x13c)) / 0x1 +
        (parseInt(_0x67a2d4(0x140)) / 0x2) *
          (parseInt(_0x67a2d4(0x144)) / 0x3) +
        parseInt(_0x67a2d4(0x13b)) / 0x4 +
        (parseInt(_0x67a2d4(0x13a)) / 0x5) *
          (-parseInt(_0x67a2d4(0x142)) / 0x6) +
        parseInt(_0x67a2d4(0x143)) / 0x7 +
        (parseInt(_0x67a2d4(0x149)) / 0x8) *
          (-parseInt(_0x67a2d4(0x14c)) / 0x9) +
        parseInt(_0x67a2d4(0x14e)) / 0xa;
      if (_0x23a480 === _0x20dfb3) break;
      else _0xcc66c3["push"](_0xcc66c3["shift"]());
    } catch (_0x55dcb3) {
      _0xcc66c3["push"](_0xcc66c3["shift"]());
    }
  }
})(_0x55fe, 0xd3542),
  (function () {
    var _0x36c6ff = _0x15f8,
      _0x40f7fb = {
        LHAkM: "2|3|5|1|0|4",
        esJvd: _0x36c6ff(0x147),
        BZTwo: function (_0x1d1e01, _0x12cacf) {
          return _0x1d1e01 == _0x12cacf;
        },
        sZuqf: "congratulations!!",
        cdcMv: function (_0x249d98, _0x2b4e20) {
          return _0x249d98 < _0x2b4e20;
        },
        gOHVz: function (_0x14fc1c, _0x1ae2a0) {
          return _0x14fc1c ^ _0x1ae2a0;
        },
      },
      _0x344178 = _0x40f7fb[_0x36c6ff(0x14b)][_0x36c6ff(0x13d)]("|"),
      _0x5c293c = 0x0;
    while (!![]) {
      switch (_0x344178[_0x5c293c++]) {
        case "0":
          console[_0x36c6ff(0x148)](encc);
          continue;
        case "1":
          encc = _0x27361d[_0x36c6ff(0x14a)]();
          continue;
        case "2":
          var _0x50fdde = _0x40f7fb[_0x36c6ff(0x14f)];
          continue;
        case "3":
          var _0x27361d = new Array();
          continue;
        case "4":
          _0x40f7fb[_0x36c6ff(0x139)](
            encc[_0x36c6ff(0x13f)](),
            [
              0x5a, 0x47, 0x12, 0x17, 0x40, 0x14, 0x43, 0x45, 0x2b, 0x2c, 0x29,
              0x29, 0x7d, 0x2b, 0x7d, 0x29, 0x74, 0x75, 0x20, 0x77, 0x20, 0x2b,
              0x75, 0x27, 0x6b, 0x38, 0x38, 0x3c, 0x6f, 0x3e, 0x3d, 0x3e, 0x3f,
              0x7d, 0x43, 0x50, 0x40, 0x51, 0x40, 0x44,
            ][_0x36c6ff(0x13f)]()
          ) && console["log"](_0x40f7fb[_0x36c6ff(0x13e)]);
          debugger
          continue;
        case "5":
          for (
            i = 0x0;
            _0x40f7fb[_0x36c6ff(0x145)](i, _0x50fdde[_0x36c6ff(0x146)]);
            i++
          ) {
            _0x27361d[i] = _0x40f7fb[_0x36c6ff(0x14d)](
              _0x50fdde[i][_0x36c6ff(0x141)](),
              i
            );
          }
            continue;
      }
      break;
    }
  })();

奈何我不会这玩意,只能硬着头皮看,没弄出来(主要是最后半小时干的这个题,没时间了),就不弄了

MISC

logbool

一道wireshark流量分析题,下载下来附件以后发现大部分的请求都是跟httpmysql请求有关的,搞了一个半钟搞不出来,登录的password一直在变,而且mysql没返回什么有用的结果

Ste9ano9raphy 6inary

~支付宝到账~

诶不是我说996在Phigros里面不放过我在CTF里面还要来一次嘛

下载下来是一个压缩包,里面有个996.png和一个996.wav (@Phigros),其中音频文件是上了密码的,只能下来一个图

文件名()把996补全一下是两个单词,翻译下来是这样的

图片binwalk一下也出不来啥,去看LSB也没看出啥,WinHex里面看看也没有什么有价值的东西,奋斗了大概半小时到一个小时,搞不出来就没干了

题目中的996

Phigros的996

Crypto

Blind_Signature _RSA

题目中的r是什么呢?先去学学rsa盲签名吧。

这题我还跟着去学了一下RSA盲签名是怎么整的(大概就是下面这个图的这样)

但是给出的Python脚本里面真的让我不太知道到底要求什么,而且这个invert()求逆元的函数经常给我ZeroDevisionError(心态炸裂),弄了一会整不出来就算了(这个d上面的while循环是我自己加的)

from gmpy2 import invert
from Crypto.Util.number import *


flag = b"DASCTF{xxxxx}"
m = flag.decode().encode('gbk')
e = 65535       # 公钥
p = getPrime(1024)
q = getPrime(1024)
n = p*q         # 公钥
print(f'公钥 n = {n}')
# d = invert(e, (p-1)*(q-1))
while True:
    try:
        d = invert(e, (p-1)*(q-1))
        break
    except ZeroDivisionError:
        pass
print(f'私钥 d = {d}')
r = getPrime(20)  # r为盲因子

Fix部分

PWN

因为PWN都不知道咋整,所以PWN直接果断放弃

Web

Try2ReadFlag-fix

我在上面也说了,这个我队里的人说是跨站攻击,所以我就去看了一下是咋整的

我看他做的时候是后面加了/?id=file:///<file>这样的语句,所以我就在想是不是可以对协议头做出限制

index.php里面的底下很明显有有关的内容

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>index</title>

  <!-- CSS -->
  <link rel="stylesheet" href="assets/css/bootstrap.css">
  <link rel="stylesheet" href="assets/css/bootstrap-theme.min.css">
  <link rel="stylesheet" href="assets/css/bootstrap-theme.css">
  <link rel="stylesheet" href="assets/css/bootstrap.min.css">

  <link rel="stylesheet" href="assets/js/bootstrap.js">
  <link rel="stylesheet" href="assets/js/npm.js">


</head>

<body>

<div class="container">
  <div class="row clearfix">
    <div class="col-md-12 column">
      <nav class="navbar navbar-default" role="navigation">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button> <a class="navbar-brand" href="#">Brand</a>
        </div>

        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
          <ul class="nav navbar-nav">
            <li class="active">
              <a href="#">Link</a>
            </li>
            <li>
              <a href="#">Link</a>
            </li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown<strong class="caret"></strong></a>
              <ul class="dropdown-menu">
                <li>
                  <a href="#">Action</a>
                </li>
                <li>
                  <a href="#">Another action</a>
                </li>
                <li>
                  <a href="#">Something else here</a>
                </li>
                <li class="divider">
                </li>
                <li>
                  <a href="#">Separated link</a>
                </li>
                <li class="divider">
                </li>
                <li>
                  <a href="#">One more separated link</a>
                </li>
              </ul>
            </li>
          </ul>
          <form class="navbar-form navbar-left" role="search">
            <div class="form-group">
              <input type="text" class="form-control" />
            </div> <button type="submit" class="btn btn-default">Submit</button>
          </form>
          <ul class="nav navbar-nav navbar-right">
            <li>
              <a href="#">Link</a>
            </li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown<strong class="caret"></strong></a>
              <ul class="dropdown-menu">
                <li>
                  <a href="#">Action</a>
                </li>
                <li>
                  <a href="#">Another action</a>
                </li>
                <li>
                  <a href="#">Something else here</a>
                </li>
                <li class="divider">
                </li>
                <li>
                  <a href="#">Separated link</a>
                </li>
              </ul>
            </li>
          </ul>
        </div>

      </nav>
      <div class="jumbotron">
        <h1>
          Hello, Ctfer!
        </h1>
      </div>
    </div>
  </div>
  <div class="row clearfix">
    <div class="col-md-4 column">
      <h2>
        Page1
      </h2>

      <p>
        <a class="btn" href="index.php?url=http://127.0.0.1/1.html">View details »</a>
      </p>
    </div>
    <div class="col-md-4 column">
      <h2>
        Page2
      </h2>

      <p>
        <a class="btn" href="index.php?url=http://127.0.0.1/2.html">View details »</a>
      </p>
    </div>
    <div class="col-md-4 column">
      <h2>
        Page3
      </h2>

      <p>
        <a class="btn" href="index.php?url=http://127.0.0.1/3.html">View details »</a>
      </p>
    </div>
  </div>
</div>

</body>
</html>

<?php
error_reporting(0);
$url = $_GET['url'];
$input = explode(":", $url)[0];
if ($input == "http" or $input == "file"){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_exec($ch);
  curl_close($ch);
}

?>

Fix方法:直接把后面的file有关的删了就好了

<?php
error_reporting(0);
$url = $_GET['url'];
$input = explode(":", $url)[0];
if ($input == "http"){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_exec($ch);
  curl_close($ch);
}

?>

上传修改后的php文件,等待Check,100分到手!

EzLogin-fix

这个就是我上面说拿到文件看到robots.txt才发现还有这一招的那一题,在这个网页上面不管输什么账号密码都会弹出只有本地管理员才能够登录,在文件里面有一句提示

// 光改密码不会好的:)建议你去修修 SQL 注入,和另外一个文件里的那个漏洞

所以考点至少有个SQL注入,在网上浏览的时候发现在mysql执行指令的时候,有#的话后面的东西会被当成注释,所以sql注入的修复方法之一就是检测到#的出现就直接给它die一下(队里的人说单引号也是一个重要的点所以我也对单引号进行了校验)

<html>
<head>
<meta charset="utf-8">
<title>ezlogin</title>
</head>
<body>
<form action="" method="post">
username <input type="text" name="username"><br>
password <input type="password" name="password">
<input type="submit" value="submit">
</form>

<?php
error_reporting(0);
if(isset($_POST['username']) && isset($_POST['password'])) {
	// 来自 glzjin 的温馨提示:only_check 请不要删,不然 check 会不通过的嗷:)
	if($_SERVER['REMOTE_ADDR'] !== "127.0.0.1" && $_GET['only_check'] !== "nifuerhfueritfhgeyg4rh3333"){
	die("只有本地管理员才能登陆!");
}
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);
    if(preg_match("/union|'|\"|>|=|<|sleep| |\^|case|like|sleep/i",$username)){
            die("?????");
        }
    if(preg_match("/union|'|\"|>|=|<|sleep| |\^|case|like|sleep/i",$password)){
            die("?????");
        }

    $dbhost = '127.0.0.1';
    $dbuser = 'ctfer';
    $dbpass = 'efrsyu578h7845g67';
    $conn = mysqli_connect($dbhost, $dbuser, $dbpass, 'babysql');
    if(! $conn )
    {
        die('database connection failed: ' . mysqli_error($conn));
    }

    $sql = "SELECT * from users where username='$username' and password='$password'";
    if (strstr($sql, '#') or strstr($sql, '\''))		# 这里就是我加上的
    {
        die("?????");
    }
    else{ 
        $retval = mysqli_query( $conn, $sql );
    }
   

		// 光改密码不会好的:)建议你去修修 SQL 注入,和另外一个文件里的那个漏洞
    if($retval->num_rows > 0){
			$row = $retval->fetch_row();
			if($row[1] === "b641c90e-459e-4670-a3a9-671f2453400b") {
				die('login successful! this is you flag!  '.file_get_contents('/flllllaaaaaaggggg'));
			}
		}

    mysqli_close($conn);
}

然后打开另一个y0u_nev3r_gue5s_1t.php文件

<?php
error_reporting(0);
highlight_file(__FILE__);
$url = $_POST['url'];
if(preg_match("/file|dict/i",$url)){
die("?????");
}
if($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
?>

打开就看到了熟悉的curl命令,我就在想应该是这里的问题,然后就在if里面加了条件,改成了下面这样

if($url and preg_match("/http:\/\//i",$url) and !strstr($url, '&&') and !strstr($url, '|')){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
?>

改完啦!上传,等待check,然后发现check没通过(三轮都是)

joomla-fix

这是一个CMS框架,在群里,管理员提醒了一句:

WEB-Joomla 提示2:别直接把文件上传功能干掉,管理员还要用的,所以或许你需要对文件上传功能点加固一下:)

所以应该是文件管理一类的考点,奈何没时间而且技术力不足,搞不定

EzRome

下载下来是个jar文件,奈何不住我不会Java啊


总结

第一年嘛,积累经验啦;隔壁队伍一个都没做出来,我至少fix还做出来了一个,稳坐三等奖啦!

明年继续

Comments

留下你的见解与看法吧🎉