@ruanxingzhi
2017-05-18T19:53:28.000000Z
字数 1591
阅读 1808
先不讨论文件结构了……此文用来讨论评测鸡。
……大概是基于我这两年的经验吧。可能会有不完善的地方。
评测鸡的实现,已经有了很多不考虑安全问题的版本。因此这里只讨论安全问题。
我大概把评测攻击分为两部分:编译时攻击、运行时攻击。
编译时攻击是很多评测鸡并没有防范的。例如下面几种攻击情况:
编译超时
#include </dev/random> # Linux
#include <CON> # Windows
这种攻击方式的原理是,让编译器读一个永远也读不完的文件,把评测鸡卡死在编译阶段。BZOJ已经被这段代码卡掉很多次了。
示例:http://pyoj.ml/submission/3019
解决办法:设置编译的时间限制,或者用vfk的办法,把编译器监控起来。
输出巨大文件
我们在做数论题的时候玩过这种事情:int a[10000000]={1,0}
,这样编译出来的文件会特别大。在我的机器上,它的大小是39MB。
我们想到,让编译器生成一个极大的文件。下面是一个针对gcc的编译炸弹,从wikicoding.org蒯来的。全文如下:
main[-1u]={1};
编译这段代码之后,会生成16GB的文件。
示例:http://pyoj.ml/submission/2912
解决办法:设置编译出来的可执行文件的大小限制。
include攻击
include攻击同时被vfleaking(UOJ)和李扬(QDUOJ)描述。向二位致敬。
include攻击是指:用C/C++代码include网站的配置文件,然后通过返回的编译错误信息,读取密码。
例如。对于hustoj,可以采用下面的代码:
#include "/var/www/JudgeOnline/include/db_info.inc.php"
这份代码将会include数据库的配置文件。上交这份代码,将会返回如下的编译信息:
事发后,hustoj的这个漏洞已经在一年前修复。
示例:http://pyoj.ml/submission/3020
我的解决方法:
vfk的解决办法:把编译器监视起来。
另外riteme提出了另一种鬼畜的解决办法。见https://github.com/hzxie/voj/issues/14 。
运行时攻击,已经有比较好而且通用的解决方案。解决这个问题难度并不大。
运行系统指令
system("shutdown now");
这种攻击方式很早就被解决了。
示例:http://pyoj.ml/submission/3021
解决方法:用沙箱跑评测,可以采用ptrace。但是我准备用一种更暴力的方案。直接把程序扔进docker里面跑,它爱玩成什么样就玩成什么样吧233。
fork炸弹
曾经有OJ被选手程序不停地fork()
搞炸了。
我没有拿到代码,因此这里没法分析。
故意运行超时
while(1): pass
如果评测时开了-O2
,上面的代码可以改成求斐波那契数列。反正只要确保超时就行了。
然后突然交一大堆这种程序,以达到类似DDOS的效果……
这种东西很没技术含量。这是一份针对hustoj的脚本:https://gist.github.com/Ruanxingzhi/9f0caba5e2d8a690ae1e89bcfb92abba
效果是用1000个账号,每个账号提交10次,每个账号在提交之后休息11s。
体现为:两分钟内,OJ上面多了一万份提交。
解决方法:注册的时候设置验证码,如果一个账号短时间内多次提交,在这个账号下一次提交的时候也需要验证码。
请注意,注册的时候,只用邮箱验证,不用验证码是不行的!
我玩了这么久的OJ,一共也就发现这几种攻击方式……
但是好像很多OJ对编译时攻击防范并不好。
点蜡烛。希望OJ做得越来越好吧。