前记
最近拿到了一个比较有意思的站点,所以就想着写一篇博客分享一下渗透思路,文内的一些厂商信息我已经打上了码,但是相信还是会有眼尖的小伙伴。关于上传的一些木马文件在测试后我也会删除,目前漏洞已经提交,所以大家可以放心阅读。
初见站点
首先,在我们已经确定了目标站点的时候,需要做的第一步自然就是信息收集,这在整个渗透过程中,十分重要。
以上就是我们本次的目标站点,一般来讲,对于一些较大的厂商的,主站通常不会有漏洞。所以我们可以从旁站入手,通过子域名以及ip反查等手段进行收集信息。
通过子域名查询,我们可以看到一共有16个子域名,箭头所指就是我们本次发现漏洞的站点了,下面我们去访问这个站点。
发现是一个管理系统,但是只是只是连接的一些其他子域名的系统管理。尝试注册账号,发现也并不是开放式注册。
所以继续把焦点放到刚才那个站点,尝试对其进行端口主机扫描。对于获取其ip信息的方法也比较简单,可以直接ping,没有发现CDN,并且可以直接通过ip访问站点。
发现漏洞
现在我们对目标站点尝试扫描端口服务及主机信息。
通过上述扫描我们可知,他们安了很多http服务和tomcat服务,事实上在后面的渗透里越发能感受到,他网站搭建的给人一种混乱的感觉。通过对以上端口的逐个访问,我们发现在5000端口上可以进行任意文件访问。
通过翻阅这些文件,我们不难发现这个站点仍然有人在维护更新。也找到了一些比较有意思的东西。
例如这样一个任意路径文件上传,没有过滤手段。
亦或是这样一个任意SQL语句执行的接口,不得不说,维护人员在给给自己提供便利的同时也给了攻击者提供了大便利。
顺藤摸瓜
通过对上述文件任意查看处,我们获得了一个很有意思的情报。
可以看到一个名为测试的文件中记录着一处上传点是在7766端口上的。问我为什么下面那个没打码?那是它内网的ip,知道了也访问不到哈哈,说到这一把泪不争气的流了出来,我们继续往下看。
果然又是一个无过滤上传点,这里我们上传了一个asp的大马(测完就删了)。
看到他的这些目录名,我还是想吐槽一句,站搭的乱,名起的也乱。
这里我们发现他的站点用户是admin?但是奇怪的是我们在后续的渗透中没有办法执行系统命令。显示的是存取被拒,估计应该是需要管理员权限才可以。
在测试过程中有一个坑,我不知道是个例还是普遍,我使用菜刀没有办法连接一句话木马,但是使用蚁剑却连接成功了,这也让我走了一段弯路。当然,我尝试上传msfvenom生成的木马想要拿到meterpreter进行内网渗透,但是上传的asp文件显示的是http 500,我想可能是维护人员禁用了某些函数?比如execute我尝试确实不能正常使用。
峰回路转
当测到上面的时候本来以为没有希望了,但是灵机一动,我们想起了5000端口那里不也有一个任意上传点吗?于是我们就去尝试一下。
然后我们发现已经成功上传了。
使用蚁剑尝试连接,这里我们获取到的是D盘的服务器,所以我们可以查看D盘了,上面的上传点获取的shell是C盘的。
这里想到之前有一处任意SQL查询的接口,于是我们去看一下那个文件代码。
箭头处我们得到信息,数据库的用户名为pdaadmin,密码为pa180330,前面的ip告诉我们SQL Server并不在本地服务器,本地服务器的内网ip是172.27.0.10。
通过蚁剑的数据库连接模块,我们用刚才lzx.asp文件获取到的代码进行连接,成功连接到目标数据库。继续审计我们又得到了一个数据库用户,在渗透时发现有一些数据库我们是无权访问的,因为分配了多个数据库用户,但是随着我们获得数据库用户增加,对于数据库的控制权也会增加。
继续审计服务器内一些网站源码,我们发现服务器内包含了许多其他站点的源码通过对比数据库我们得到了这些站点的用户信息(如下图)
其中也包含了企业内的信息,这我就不看了。继续向下进行提权操作。
这里同样惊喜的发现,我们可以执行系统命令了,通过上图创建用户并提权,这里创建的用户已经提升至administrator组中了。
继续上传一个pr.exe提权工具,发现提升到system了。哈哈有360安全卫士,我说怎么3389端口转发了也没法连接。
如下图所示,存在域。
关于渗透域控的操作会放到下面来讲,我们继续往下看。
迷惑行为
没错下面这个就是那个名字起得很乱的目录,我把他打包下来了。下面我们审计一下代码看看有没有漏洞吧。
我把代码直接贴出来吧。
<%
'-------------------------------------------------------------------------------
'本文件是NLS-PT-850远程数据传输和查询的asp演示脚本程序,其功能为接收NLS-PT-850
'发起的URL请求,并作出相应的处理。实际应用中,可以修改本文件,或把本文件
'嵌入到其他文件中,以实现更加复杂的功能。
'
'运行本演示程序之前,需在数据库中建立一名为"temp"的表,共3个字段。
' 字段1:
' 名称:id
' 类型:INT, 自动编号
' 字段2:
' 名称:data
' 类型:String 或 Memo, 存放条码数据
' 字段3:
' 名称:dt
' 类型:Date, 存放服务器接收到数据的时间
'-------------------------------------------------------------------------------
tmpdbFile = Server.MapPath("temp.mdb")
Set objFSO = Server.CreateObject("Scripting.FileSystemObject") '先查看数据库是否存在
If not objFSO.FileExists(tmpdbFile) Then
Set cat=server.CreateObject("ADOX.Catalog")
cat.Create "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tmpdbFile '不存在先创建数据库
Set cat=nothing
Set conn=Server.CreateObject("ADODB.Connection")
connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tmpdbFile
conn.Open connstr
sqlstr = "create table temp (id int IDENTITY(1,1),data String,dt date default Date()+time() )"
conn.execute(sqlstr)
conn.close
set conn = nothing
End If
Set conn=Server.CreateObject("ADODB.Connection")
'创建SQL SERVER数据库连接。这个连接串需要根据具体的服务器环境做相应修改。
connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & tmpdbFile
conn.Open connstr
'开始处理客户端提交的数据
action = request("action")
outstr = ""
'区分客户端欲完成的动作
select case action
case "insert" '插入动作
data = request("data") '获得客户端传送的data参数值
'--------------------------------------------------------------
' 采集器送上来的数据用","隔开,如:
' tmp.asp?action=insert&data=11111111,222222,333333,444444,55555
'--------------------------------------------------------------
schar = ","
'根据客户端传送参数值的个数(1个或多个),循环获取参数
Do
if instr(data,schar) > 0 then '参数数量大于1
pos = instr(data,schar)
ins = mid(data,1,pos-1)
if ins = "" then
else
sqlstr = "insert into temp (data) values ('" & ins & " ')"
conn.execute(sqlstr) '执行sql语句
data = mid(data,pos+1)
end if
else '参数数量等于1
if data = "" then
else
sqlstr = "insert into temp (data) values ('" & data & " ')"
conn.execute(sqlstr)
end if
Exit Do
end if
Loop
response.write "<RAW name=resp>OK</RAW>" '返回成功信息
case "query" '查询动作
'------------------------------------------------------------------
'根据客户端传送参数值的个数构造不同的sql语句
'参数例子:
' tmp.asp?action=query&field=1d,data
' 上面的例子表示客户端想查询id和data字段,要查询的字段用 "," 隔开
'------------------------------------------------------------------
if request("field") = "" then '无参数值,查询所有列
sqlstr = "select * from temp order by id desc"
set rs = conn.execute(sqlstr) '取得数据集
else '有参数值,查询相应的列
field = request("field")
sqlstr = "select "
schar = ","
'根据客户端传送参数值的个数(1个或多个),循环获取参数
Do
if instr(field,schar) > 0 then
pos = instr(field,schar)
codition = mid(field,1,pos)
sqlstr = sqlstr & codition
field = mid(field,pos+1)
else
sqlstr = sqlstr & field
Exit Do
end if
Loop
sqlstr = sqlstr & " from temp order by id desc"
set rs = conn.execute(sqlstr) '取得数据集
end if
'输出HTML代码,格式化数据。
response.write ("<TABLE bordercolorlight=#FFFFFF bordercolordark=#FFFFFF align=center border=1 bgcolor=#ACD8FF>")
response.write ("<TR bgcolor=#008080>")
'根据数据集的列名确定表格头信息
for intloop = 0 to rs.fields.count - 1
response.write ("<TH>" & rs.fields(intloop).name & "</TH>")
next
response.write ("</TR>")
'循环输出每一条数据
while not rs.eof
response.write ("<TR>")
for intloop = 0 to rs.fields.count - 1
response.write ("<TD>" & trim (rs.fields(intloop).value) & "</TD>")
next
response.write ("</TR>")
rs.movenext
wend
'关闭数据集
rs.close
set rs = nothing
response.write ("</TABLE>")
case "queryByID" '查询动作
'------------------------------------------------------------------
'根据客户端传送参数值的个数构造不同的sql语句
'参数例子:
' tmp.asp?action=queryByID&id=1103
'------------------------------------------------------------------
id = request("id") '获得客户端传送的data参数值
if id = "" then
sqlstr = "select * from temp"
set rs = conn.execute(sqlstr) '取得数据集
else
sqlstr = "select * from temp where id = " & id
set rs = conn.execute(sqlstr) '取得数据集
end if
'输出HTML代码,格式化数据。
response.write ("<TABLE bordercolorlight=#FFFFFF bordercolordark=#FFFFFF align=center border=1 bgcolor=#ACD8FF>")
response.write ("<TR bgcolor=#008080>")
'根据数据集的列名确定表格头信息
for intloop = 0 to rs.fields.count - 1
response.write ("<TH>" & rs.fields(intloop).name & "</TH>")
next
response.write ("</TR>")
'循环输出每一条数据
while not rs.eof
response.write ("<TR>")
for intloop = 0 to rs.fields.count - 1
response.write ("<TD>" & trim (rs.fields(intloop).value) & "</TD>")
next
response.write ("</TR>")
rs.movenext
wend
'关闭数据集
rs.close
set rs = nothing
response.write ("</TABLE>")
case "delete" '删除所有的数据
sqlstr = "delete from temp"
conn.execute(sqlstr)
response.write "<RAW name=resp>OK</RAW>" '返回操作成功标志
case default
response.write "<RAW name=resp>OK</RAW>"
end select
'关闭数据库连接
conn.close
set conn = nothing
%>
目录名从1-56都可以在网站上正常访问,从上面的代码中我们可以发现,该脚本接收action变量通过switch进行判断并进行相应的数据库操作,如果是插入操作就设置action为insert通过data传值即可,而且维护人员也很贴心的把payload都给我们贴上了,下面总结一下利用方式
查询内容
http://218.66.xx.x:7766/4/tmp.asp?action=query
增加内容
http://218.66.xx.x:7766/4/tmp.asp?action=insert&data=1111
删除内容
http://218.66.xx.x:7766/4/tmp.asp?action=delete
目录1-56都是这样的,存在一个数据库和一个操作文件,通过和上面相似的payload进行操作。
这里其实还有一个存储型xss的存在,我们来看一下
通过上述的插入方式,构建payload,如下图。
然后返回访问查询信息,发现成功弹窗。
这里我们了解到了之前那个迷惑行为的一堆目录。然后我们继续往下看。
一段插曲
说到这里我就一句mmp,我们来看一下,通过文件搜索admin关键词,我们找到了一个管理员登录界面。
然后我就去搜索这个目录,去查看源码。
如图所示,时间也确实久远了。
本段代码中,我们发现他进行了数据库查询,说实话,典型的SQL注入,这我不多说了。
我们看第一行他包含了conn.asp文件,这应该是是他数据库连接文件,我们再去查看一些conn.asp文件。
看到这里我们,是一段经典的数据库连接代码 ,下面有一个分页方法。在箭头所指处我们可以看到他查询的是data/news.mdb数据库文件。然后我们再去查看这个mdb文件。
我们拿到了后台密码,现在去登陆试一试吧。
讲道理,看到这个的时候,我真想一走了之。
这里告诉我们唯一有用的信息就是他的内网地址了,但是我到不了内网啊。说到这里又是一把伤心泪。擦掉眼泪后,默默地合上了笔记本。
不知是什么又支撑着我打开了一个界面,他捆绑的是8090端口,本来想着继续代码审计找到密码,但是测试的时候又让我心凉了一截。
尝试任意输入一个文件名,没想到猜对了。讲道理看到这个的时候我高兴了一下下,阅读报错,我们可以知道说我们对象引用未设置为对象的实例,那咱们就给他赋值呗。
随着赋值的过程还能往下看几段代码。
。。。。。
不知道小伙伴注没注意上面那个箭头?这个端口的http服务器是安装在E盘的,所以咱们也不能通过代码审计了。当然,我也知道他可能存在SQL注入,但是不知道各位想没想到上面那个任意SQL执行的窗口,一想到他数据库那奇怪的命名方式,抱手告辞!(那个SQL里几十个数据库,没法一个一个找啊)。说完,我又默默的合上了笔记本。
域控渗透
这里我们上传msfvenom生成的木马,通过之前拿到的shell使用pr提权工具去执行,在公网中搭建msf去获取meterpreter,这里我们发现已经获取到system权限的meterpreter了。
然后使用run getgui -e打开3389端口并使用portfwd将目标3389端口转发至本地6666端口。
继续使用load mimikatz命令获取管理员密码。
远程桌面进行连接
发现成功连接,继续去探寻域的踪迹。
使用ping命令探寻域控服务器内网地址。
得到内网地址为172.27.0.12,然后我们返回meterpreter界面,通过获取到的web服务器作为跳板机进行扫描域控服务器端口。
域控服务器3389开放。继续扫描发现服务器同时开放445端口,并且服务器版本为Windows 2003 SP2那么这里我们不妨试一下ms08-067漏洞。
发现利用失败,尝试直接连接3389端口,想起之前远程登录时存在两个域webs和dev那么不妨使用获取到的dev的那个administrator用户密码登录。
成功登陆域控服务器。
上面我们获取到了dev/administrator的密码,通过代码审计我们知道该站采用站库分离原则,172.27.0.64就是数据库服务器,尝试登录,发现成功远程登陆,可获取到服务器上数据库信息。
以下域内开放3389的主机都可以远程连接。
这里其实有一个疑问。
我们登陆webs但其实并没有E盘,这说明有两个内网ip共用一个公网ip。
后记
本次渗透讲解就到这里了,这个站其实如果深入渗透仍有很大的利用空间,正常来讲可以添加持久性后门,方便后面利用,但是这里没有这么做。我们所做的是测试而非破坏,做任何事情都要有底线,并不能因为一点利益就去做违法乱纪的事情,正如我坚定的拒绝那些想拉拢我做黑产的人一样,不干就是不干。
最近个人的事情比较多,在家把所学的知识从头复习,说实话收获不小。可能大家觉得文章写的短了一些,确实如此。写文章的今天,在晚上还要去考一下360众测的入驻考核,所以时间仓促,写的也就比较赶吧,希望大家多多见谅!那么就先讲到这里了。
最后祝大家心想事成,美梦成真!