squ@squ-virtual-machine:~/tools/modules-5.0.1$ pkexec --version pkexec version 0.105 squ@squ-virtual-machine:~/tools/modules-5.0.1$ uname -a Linux squ-virtual-machine 5.11.0-46-generic #51~20.04.1-Ubuntu SMP Fri Jan 7 06:51:40 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
docker:
pull 个 debian 下来,然后设置共享卷
1
docker run -it --name=de -v /home/squ/docker_volumn:/home/vol debian /bin/bash
deb http://mirrors.ustc.edu.cn/debian stable main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable main contrib non-free deb http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free
# deb http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free
checking whether the C compiler works... no configure: error: in `/home/vol/policykit-1-0.105': configure: error: C compiler cannot create executables
看 config.log
1 2 3 4 5
configure:3355: $? = 1 configure:3375: checking whether the C compiler works configure:3397: /usr/bin/gcc -g conftest.c -lposix >&5 /usr/bin/ld: cannot find -lposix collect2: error: ld returned 1exit status
安装库
1
apt-get install manpages-posix-dev
也没用,索性不加 posix 试试看
1
./configure CC=c99 CFLAGS=-g //LIBS=-lposix
继续报错
1 2 3
configure: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config.
安装
1
apt-get install -y pkg-config
继续报错
1 2 3
configure: error: Package requirements (gio-2.0 >= 2.28.0) were not met:
/* By default we don't allow running X11 apps, as it does not work in the * general case. See * * https://bugs.freedesktop.org/show_bug.cgi?id=17970#c26 * * and surrounding comments for a lot of discussion about this. * * However, it can be enabled for some selected and tested legacy programs * which previously used e. g. gksu, by setting the * org.freedesktop.policykit.exec.allow_gui annotation to a nonempty value. * See https://bugs.freedesktop.org/show_bug.cgi?id=38769 for details. */ "DISPLAY", "XAUTHORITY", NULL }; GPtrArray *saved_env; gchar *opt_user; pid_t pid_of_caller; gpointer local_agent_handle;
g_assert (argv[argc] == NULL); path = g_strdup (argv[n]); if (path == NULL) { usage (argc, argv); goto out; } if (path[0] != '/') { /* g_find_program_in_path() is not suspectible to attacks via the environment */ s = g_find_program_in_path (path); if (s == NULL) { g_printerr ("Cannot run program %s: %s\n", path, strerror (ENOENT)); goto out; } g_free (path); path = s;
/* argc<2 and pkexec runs just shell, argv is guaranteed to be null-terminated. * /-less shell shouldn't happen, but let's be defensive and don't write to null-termination */ if (argv[n] != NULL) { argv[n] = path; } }
In glib, a module named iconv support convert a charset to another. And the conversion was implemented in such dynamic library (gconv module) which implement pre-request interface, the usage of these gconv module were defined in a configuration file with name gconv-modules.
iconv 转换字符集
iconv 是在一个动态库 gconv module
动态库 gconv module 定义在配置文件夹 gconv-modules 里
会调用这个文件夹 gconv-modules 下的 so 文件中的 gconv() 和 gconv_init()
The default gconv module and gconv module configuration file was located in:
/usr/lib/gconv: Usual default gconv module path.
/usr/lib/gconv/gconv-modules: Usual system default gconv module configuration file.
/usr/lib/gconv/gconv-modules.cache: Usual system gconv module configuration cache
squ@squ-virtual-machine:~/Desktop/cve/CVE-2021-4034/poc$ iconv --help Usage: iconv [OPTION...] [FILE...] Convert encoding of given files from one encoding to another.
Input/Output format specification: -f, --from-code=NAME encoding of original text -t, --to-code=NAME encoding for output
Information: -l, --list list all known coded character sets
Output control: -c omit invalid characters from output -o, --output=FILE output file -s, --silent suppress warnings --verbose print progress information
-?, --help Give this help list --usage Give a short usage message -V, --version Print program version
The iconv support extension the charset conversion ability by user defined gconv module. When use iconv or call iconv() function, it must first allocate a conversion descriptor using iconv_open(). The operation of this function will influence by the enviroment GCONV_PATH
此处应该有源码,之后补
用 GCONV_PATH 指定自定义模块去替换系统模块
所以利用方法如下
Suppose we can control the content of enviroment GCONV_PATH, provide a gconv module configuration file and gconv module with evil code. The evil code may be execute for some case.
/* special case $SHELL */ if (g_strcmp0 (key, "SHELL") == 0) { /* check if it's in /etc/shells */ if (!is_valid_shell (value)) { log_message (LOG_CRIT, TRUE, "The value for the SHELL variable was not found the /etc/shells file"); g_printerr ("\n" "This incident has been reported.\n"); goto out; } } elseif ((g_strcmp0 (key, "XAUTHORITY") != 0 && strstr (value, "/") != NULL) || strstr (value, "%") != NULL || strstr (value, "..") != NULL) { log_message (LOG_CRIT, TRUE, "The value for environment variable %s contains suscipious content", key); g_printerr ("\n" "This incident has been reported.\n"); goto out; }
ret = TRUE;
out: return ret; }
1 2 3 4 5 6 7 8 9 10 11 12
if (g_strcmp0 (key, "SHELL") == 0) { /* check if it's in /etc/shells */ if (!is_valid_shell (value)) // SHELL值不合法 调用g_printerr { log_message (LOG_CRIT, TRUE, "The value for the SHELL variable was not found the /etc/shells file"); g_printerr ("\n" "This incident has been reported.\n"); goto out; } }
squ@squ-virtual-machine:~/Desktop/iconv$ iconv -f HACK -t UTF-8 < hack.c you be hacked alreadly! iconv: iconv.c:91: iconv: Assertion `!"Nothing like this should happen"' failed. Aborted (core dumped)
/* To qualify for the paranoia goldstar - we validate the value of each * environment variable passed through - this is to attempt to avoid * exploits in (potentially broken) programs launched via pkexec(1). */ if (!validate_environment_variable (key, value)) goto out;
然后里面又调用了--------------------------------------------------- /* special case $SHELL */ if (g_strcmp0 (key, "SHELL") == 0) { /* check if it's in /etc/shells */ if (!is_valid_shell (value)) { log_message (LOG_CRIT, TRUE, "The value for the SHELL variable was not found in the /etc/shells file"); g_printerr ("\n" "This incident has been reported.\n"); goto out; } } ----------------------------------------------------------------------- for (n = 0; shells != NULL && shells[n] != NULL; n++) { if (g_strcmp0 (shell, shells[n]) == 0) { ret = TRUE; goto out; } }