Real World CTF 2018 bookhub 总结
挖坑必须填,虽然已久过去比较久了,但是我还是得简单写一下。
这个题目一共4个考点,文中图借用了参赛者的WP。
信息搜集
我一向出代码审计相关的题目,所以一般都直接给源码。打开源码,并简单浏览页面,发现后台登录用白名单限制了IP。
这其实是第一个考点,来源于之前遇到的一个案例:拿到目标的源码后发现无法访问,但在源码(Nginx配置文件)里找到了白名单的IP段,其中就包括目标办公网的IP。然后对这些IP进行扫描,发现了一些漏洞。
这个题也类似,登录的时候会爆出白名单的IP,其中有一个外网IP:
对这个IP进行扫描,发现开放了5000端口,这个端口运行的是debug模式的bookhub。我的原意是模拟了一个开发者,在本地(办公室)及线上运行了两个同样的系统,只是线上关闭了debug模式。
这里面我获取IP用的是X-Forwarded-For
,很多人认为XFF一定可以伪造,其实不然,原因懒得说。
Flask 装饰器顺序问题
这是出本题的目的。其实已经有师傅说的比较清楚了:
http://blog.evalbug.com/2018/08/07/flask_decorator_sequence/
被Flask的@route
装饰器修饰的函数,将作为一个view被外面访问。如果这个view需要鉴权,则增加@login_required
修饰器。
但如果@login_required
加在外层,将没有任何意义:因为@route
只会将自己修饰的方法放入路由中。
redis eval注入
Flask-Session将session序列化后存入redis,如果控制redis,将可以执行任意命令。这也是我从之前遇到的案例里提取出来,可以参考这几篇文章:
- https://www.leavesongs.com/PENETRATION/zhangyue-python-web-code-execute.html
- https://www.leavesongs.com/PENETRATION/getshell-via-ssrf-and-redis.html
第一篇文章是通过redis未授权访问控制redis,第二篇文章是通过SSRF控制redis。这个题目里面是通过redis.eval的任意lua代码注入来控制redis,其实核心没太大差别。
redis.eval注入点出现在debug模式下,用户可以清空redis中除了自己的sessionid以外其他所有的session。为了不多次读取redis,所以用到了redis.eval执行一个lua循环,其中自己的sessionid是拼接进去的。
反序列化
我们需要向redis中注入一个session,然后带上sessionid访问,触发python反序列化,最终执行任意命令。
python反序列化有几个点要注意:
- python2.7和3默认protocol变化,所以你需要用python3生成payload
- windows和linux下os是不一样的,所以你需要用linux生成payload
- payload中有一些控制字符,所以你需要用lua代码来表示
这些坑慢慢试一下也就解决了,不再赘述。
总结
整个题目都是用了一些老考点,但我自认为还是比较贴近实战的,因为几个知识点都是比较常见的错误,也有遇到案例。
一些其他人的WP:
- https://xz.aliyun.com/t/2504
- http://blog.evalbug.com/2018/08/07/flask_decorator_sequence/
- https://xz.aliyun.com/t/2513
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CSS中重要的BFC概念
- Redis哨兵集群中哨兵挂了,主从库还能切换吗?
- 你的 Redis 为什么变慢了?
- 解决Maven依赖冲突的好帮手,这款IDEA插件了解一下?
- Python爬虫实现HTTP网络请求多种实现方式
- 在tensorflow以及keras安装目录查询操作(windows下)
- Python调用OpenCV实现图像平滑代码实例
- php微信公众号开发之音乐信息
- Laravel关联模型中过滤结果为空的结果集(has和with区别)
- php微信公众号开发之二级菜单
- django中的ajax组件教程详解
- php微信公众号开发之校园图书馆
- 查看keras的默认backend实现方式
- Python包和模块的分发详细介绍
- PHP cookie,session的使用与用户自动登录功能实现方法分析