近期对平台安全渗透测试中遇到有java+mysql架构的网站,针对此架构我们sine安全渗透工程师整理了下具体的漏洞检测方法和防护修复方法,很多像执行框架漏洞获取到系统权限,以及跨权限写入木马后门等等操作,希望大家在渗透测试的道路中发现更多的知识和经验。
4.2.1. 格式化字符串
在python中,有两种格式化字符串的方式,在python2的较低版本中,格式化字符串的方式为 this is a %s % test ,之后增加了format的方式, 语法为 this is a {}.format('test') 或者 this is a {test}.format(test='test')
当格式化字符串由用户输入时,则可能会造成一些问题,下面是一个最简单的例子
>>> 'class of {0} is {0.__class__}'.format(42)
class of 42 is
从上面这个简单的例子不难知道,当我们可以控制要format的字符串时,则可以使用 __init__ / __globals__ 等属性读取一些比较敏感的值,甚至任意执行代码。
4.2.2. 反序列化
4.2.2.1. pickle
>>> class a(object):
... a = 1
... b = 2
... def __reduce__(self):
... return (subprocess.popen, (('cmd.exe',),))
>>> cpickle.dumps(a())
csubprocess\npopen\np1\n((s'cmd.exe'\np2\ntp3\ntp4\nrp5\n.
4.2.2.2. 其他
pyyaml
marshal
shelve
4.2.3. 沙箱
4.2.3.1. 常用函数
eval / exec / compile
dir / type
globals / locals / vars
getattr / setattr
4.2.3.2. 绕过
最简单的思路是在已有的模块中import,如果那个模块中已经 import 可以利用的模块就可以使用了
在父类中寻找可用的模块,最常见payload是 ().__class__.__bases__[0].__subclasses__() 或者用魔术方法获取全局作用域 __init__.__func__.__globals__
有些网站没有过滤 pickle 模块,可以使用 pickle 实现任意代码执行,生成 payload 可以使用
有的沙箱把相关的模块代码都被删除了,则可以使用libc中的函数,python 中调用一般可以使用 ctypes 或者 cffi。
ab == ab
4.2.3.3. 防御
python官方给出了一些防御的建议
使用jython并尝试使用java平台来锁定程序的权限
使用fakeroot来避免
使用一些rootjail的技术
4.2.4. 框架
4.2.4.1. django
4.2.4.1.1. 历史漏洞
cve-2016-7401 csrf bypass
cve-2017-7233/7234 open redirect vulnerability
cve-2017-12794 debug page xss
4.2.4.1.2. 配置相关
nginx 在为 django 做反向代理时,静态文件目录配置错误会导致源码泄露。访问 /static.. 会 301 重定向到 /static../
4.2.4.2. flask
flask默认使用客户端session,使得session可以被伪造
4.2.5. 危险函数 / 模块列表
4.2.5.1. 命令执行
os.popen
os.system
os.spawn
os.fork
os.exec
popen2
commands
subprocess
exec
execfile
eval
timeit.sys
timeit.timeit
platform.os
platform.sys
platform.
popen
pty.spawn
pty.os
bdb.os
cgi.sys
…
4.2.5.2. 危险第三方库
template
subprocess32
4.2.5.3. 反序列化
marshal
pyyaml
pickle
cpickle
shelve
pil
java
4.3.1. 基本概念
jvm是java平台的核心,以机器代码来实现,为程序执行提供了所需的所有基本功能,例如字节码解析器、jit编译器、垃圾收集器等。由于它是机器代码实现的,其同样受到二进制文件受到的攻击。
jcl是jvm自带的一个标准库,含有数百个系统类。默认情况下,所有系统类都是可信任的,且拥有所有的特权。
4.3.1.2. jndi
jndi(java naming and directory interface,java命名和目录接口)是为java应用程序提供命名和目录访问服务的api(application programing interface,应用程序编程接口)。
4.3.1.3. ognl
ognl(object-graph navigation language,对象导航语言)是一种功能强大的表达式语言,通过简单一致的表达式语法,提供了存取对象的任意属性、调用对象的方法、遍历整个对象的结构图、实现字段类型转化等功能。
struts2中使用了ognl,提供了一个valuestack类。valuestack分为root和context两部分。root中是当前的action对象,context中是actioncontext里面所有的内容。
4.3.1.4. rmi
rmi(remote method invocation,远程方法调用)能够让在客户端java虚拟机上的对象像调用本地对象一样调用服务端java虚拟机中的对象上的方法。
rmi远程调用步骤:
客户调用客户端辅助对象stub上的方法
客户端辅助对象stub打包调用信息(变量,方法名),通过网络发送给服务端辅助对象skeleton
服务端辅助对象skeleton将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象
调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象skeleton
服务端辅助对象将结果打包,发送给客户端辅助对象stub
客户端辅助对象将返回值解包,返回给调用者
客户获得返回值
4.3.2. 框架
4.3.2.1. servlet
4.3.2.1.1. 简介
servlet(server applet)是java servlet的简称,称为小服务程序或服务连接器,是用java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态web内容。
狭义的servlet是指java语言实现的一个接口,广义的servlet是指任何实现了这个servlet接口的类,一般情况下,人们将servlet理解为后者。servlet运行于支持java的应用服务器中。从原理上讲,servlet可以响应任何类型的请求,但绝大多数情况下servlet只用来扩展基于mons:commons-collections 4.0
com.mchange:c3p0 0.9.5.2
org.beanshell:bsh 2.0b5
org.codehaus.groovy:groovy 2.3.9
org.springframework:spring-aop 4.1.4.release
4.3.5.8. 网站漏洞修复和防护
4.3.5.8.1. hook resolveclass
在使用 readobject() 反序列化时会调用 resolveclass 方法读取反序列化的类名,可以通过hook该方法来校验反序列化的类,一个demo如下
以上的demo就只允许序列化 serialobject ,通过这种方式,就可以设置允许序列化的白名单
4.3.5.8.2. validatingobjectinputstream
apache commons io serialization包中的 validatingobjectinputstream 类提供了 accept 方法,可以通过该方法来实现反序列化类白/黑名单控制,一个demo如下
4.3.5.8.3. objectinputfilter
java 9提供了支持序列化数据过滤的新特性,可以继承 java.io.objectinputfilter 类重写 checkinput方法来实现自定义的过滤器,并使用 objectinputstream 对象的 setobjectinputfilter 设置过滤器来实现反序列化类白/黑名单控制,对java漏洞渗透测试有想进一步了解的可以咨询专业的网站安全公司,国内推荐sinesafe,绿盟,启明星辰等等专业的安全维护公司。