0x00 之前

在 RealWorldCTF 里面看到一道白盒审计的题目, 漏洞在一处写反了 decorator 包裹函数的顺序, 而导致的权限绕过, 比较好发现.

0x01 最近

在实际开发中遇到了一个问题, 我们假设有一代码如下:

class User(object):
    username = StringField()
    user_type = StringField(choices=['高富帅', '舔狗'])
    soulmate = ReferenceField(User)

    def get_soulmate_id(self):
        with no_dereference(self) as this:
            if self.user_type == '舔狗':
                raise ValidationError('舔狗最后一无所有')
        return this.soulmate.id

这是一个简单的 Mongoengine Model, 并有一个帮助函数用于获取某用户灵魂伴侣的user id的例子.

在我们调用get_soulmate_id()时, 将判断是否为舔狗用户, 如果是则直接中断流程跳到全局的 Exception Handler 中返回错误信息.

并且我们为了减少数据库的查询次数, 使用 no_dereference() 来防止 ReferenceField 自动进行 dereference 的操作.

那么, 这段代码真的能防止舔狗用户获取到自己的 soulmate user id 吗?

前言

这是一篇面向大众的教程

对 bare vm supervisor 了解的不多,而ESXi的安装程序又有些智障,在x86软路由上,这安装程序的问题似乎尤为的突出...

这次折腾ESXi的途中被它坑了两下,这里简单的总结一下遇到的两个坑。

ESXi版本: 6.7.0 (官网 iso 镜像, rufus 写入 U 盘)
硬件: 小马 x86 软路由 V2

坑一

启动安装程序时,显示 Multiboot could not setup the video subsystem

router-esxi-issue-1.jpg

乍一看好像是不兼容显卡,或是缺了显卡驱动,但实际上是 ESXi 的安装程序需要当前显示器的分辨率不小于 1024x768

当 BIOS 的显卡设置为 Legacy 模式时,分辨率会被固定到 800x600,而 UEFI 模式是跟随当前显示器的。

于是我们在 BIOS 中找到显卡设置,把显卡模式改为 UEFI
在我的环境上,这个选项在 CSM Configuration -> Option ROM execution -> Video

router-bios-1.jpg

router-bios-2.jpg

坑二

显卡相关的问题解决了,可是启动安装程序的时候,还是卡在了 Relocating modules and Starting up kernel ...

router-exsi-issue-2.jpg

这同样是安装程序的问题,在检查当前硬件是否为 headless (无显示器) 时卡住了。
我们可以通过给安装程序添加启动参数来跳过 headless 检查。

在安装程序启动后,加载安装文件前(左下角在倒计时 5 秒),按下 Shift+o 编辑启动参数,在后面加上 ignoreHeadless=TRUE 后回车,即可正常进入安装程序。

esxi-installer-loaded.jpg

在安装的最后一步,ESXi安装程序会提醒你移除你用来安装的 U 盘,然后重启,这里我们照做。
但需要注意,headless 检查并不只在安装程序中才有,而是在 ESXi 的每一次启动中都存在。
于是我们在重启之后,准备再一次按 Shift+o 添加 ignoreHeadless=TRUE 来启动到 ESXi 中。

在成功的启动到 ESXi 之后,我们要为 ESXi 永久添加这个跳过 headless 检查的参数,这样就不用每次重启都手动改一遍参数了。

首先在主界面中按 F2
esxi-main-screen

然后使用刚刚安装时设置的密码登录到 root 账户

esxi-login.png

选择 Troubleshooting Options

esxi-troubleshooting-options.png

然后我们打开 ESXi Shell

esxi-enable-shell.png

这时我们按 Alt+F2 进入 Shell,依然是使用 root 登陆

执行 esxcfg-advcfg --set-kernel "TRUE" ignoreHeadless 就可以了

还可以执行 esxcfg-advcfg –get-kernel ignoreHeadless 看看是否正确的设置了参数
如果返回 ignoreHeadless = TRUE 表示一切 OK

然后就可以执行 exit 退出 Shell 了,之后你可以把 ESXi Shell 功能关闭来提升安全性。

参考

http://plain-virt.blogspot.ca/2012/11/vsphere-5x-errors-installing-esxi-5x.html

https://community.spiceworks.com/topic/513331-multiboot-could-not-set-up-the-video-subsystem-esxi-install

1 前言

在测试服务器上想把 tensorflow 相关代码部署一下

却发现 CentOS 6.1 带的 glibclibstdc++ 都太老了,tensorflow跑不起来。

于是想手动升级一下这两个 lib。

2 警告

如果你找到了这篇文章,并且你也想手动升级系统的libc:

“不要做这件蠢事”
“不要做这件蠢事”
“不要做这件蠢事”

太多抄来抄去的文章会教人替换 libc,却不说明任何细节和注意事项。

你需要做的,是使用LD_PRELOAD这个环境变量指定你所要使用的libc.so,而不是直接替换系统自带的 libc

3 如果你真的要这样做

如果你真的要手动升级 libc
并不在乎任何可能出现的兼容性问题,且知道其他可能出现的危害的话。

务必先切换到root账户,再进行libc软链接替换的操作。
否则在执行 sudo rm /lib64/libc.so.6 删除libc的软链接之后,
你会发现 sudo 以及一切 setuid 的程序都是不接受 LD_PRELOAD 参数的,导致你没有权限修复 libc 的软链接。

具体的步骤是:

  1. 编译一个新版的 glibc,并安装到独立的目录
  2. 切换到 root 账户
  3. 删除 /lib64/libc.so.6 这个软链接
  4. 设置 LD_PRELOAD 指定一个可用的 libc 所在目录,使 ln 恢复正常
  5. 使用 ln -s 将新版的 glibc 软链接到原处,也就是 /lib64/libc.so.6

4 如果已经出事了

唯一的方法是通过 livecd / 其他系统 挂载硬盘恢复 libc

5 我最后是如何解决这个问题的

在找虚拟化部门的同事修好了 libc 的软链接后,尝试编译新的 gcc 来获取新版的 libstdc++

手动指定两个新的 lib 后运行 tensorflow 后报错 Illegal instruction.

更换到 CentOS 7 后解决了 tensorflow 无法运行的问题。

0x00 前情提要
-
Python-EngineIO 没有实现 Socket.IO 中 JSONP-Polling 的支持,于是尝试着动态 Patch。
Python 动态 Patch 实战 (1)

0x01 起因
-
真的是没有想到,在给 Python-EngineIO 加上 JSONP-polling 支持之后,这么快就遇到了第二个需要 Patch 的情况...

这次是因为 eventlet 并没有正确处理 WSGI environ string
导致百分号编码 (Percent-encoding) 出现在 URL 中时
可能会导致 wsgi app 崩溃的 bug

0x02 相关
-
Eventlet Issue#468
Patch 代码

0x00 前言
-
其实我也不太清楚这种操作到底该叫什么
不过跟 Monkey patch 似乎是一个用途,就是在运行时修改代码
于是我就先叫他 Dynamic patch

0x01 起因
-
在使用 Flask-SocketIO 的时候,发现其并没有完全实现所有的 socket.io 中的 transport 协议
于是想手动支持一下 JSONP Polling

看着 eventlet 提供的 monkey_patch(),发现我是不是也可以动态 patch 一下他的代码
这样可以最大限度的保持项目的干净,而不用再维护一个库甚至多个库的代码分支

0x02 实战
-
当同时使用 eventlet 和 Pycharm 的 debugger 时,需要注意不能给 thread 打 monkey patch, 否则 debugger 会坏掉。

跟着代码摸了几个小时,再看了看官方 nodejs 版的 server 代码,又给官方 demo 抓了一下包,大概摸清了协议,于是把

engineio.server.Server::_ok()
engineio.payload.Payload::decode()
engineio.payload.Payload::encode()
engineio.server.Server::handle_connect()
engineio.server.Server::_handle_connect()

这五个函数替换掉了,总体思路比较简单,socket.io 协议的 payload 不变,针对请求入口和出口为 JSONP 请求做出相应修改即可。

0x03 相关
-
Patch 代码在 Github Gist
Python-EngineIO 的 Issue