Sudo堆溢出漏洞(CVE-2021-3156)复现

这篇具有很好参考价值的文章主要介绍了Sudo堆溢出漏洞(CVE-2021-3156)复现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景介绍

2021 年 1 月 26 日,Qualys Research Labs在 sudo 发现了一个缺陷。sudo 解析命令行参数的方式时,错误的判断了截断符,从而导致攻击者可以恶意构造载荷,使得sudo发生堆溢出,该漏洞在配合环境变量等分配堆以及释放堆的原语下,可以致使本地提权。

环境搭建

环境版本

• ubuntu 20.04

• sudo-1.8.31p2

采用下述命令进行编译安装

cd ./sudo-SUDO_1_8_31p2
 mkdir build
 ./configure --prefix=/home/pwn/sudo CFLAGS=”-O0 -g"
 make && make install

漏洞验证

#poc
./sudoedit -s '\' 11111111111111111111111111111111111111111111111111111111111111111111

执行上述POC执行sudoedit会出现malloc():invalid size的字样,这是典型的堆溢出后导致的异常。

漏洞分析

源码分析

set_cmnd函数
File: plugins\sudoers\sudoers.c
800: static int
801: set_cmnd(void)
802: {
            ...
819:     if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { //需要满足标志位的设置才能进入转义的流程
            ...
845: 
846:    /* set user_args */
847:    if (NewArgc > 1) {
848:        char *to, *from, **av;
849:        size_t size, n;
850: 
851:        /* Alloc and build up user_args. */
852:        for (size = 0, av = NewArgv + 1; *av; av++) //遍历每一个参数
853:        size += strlen(*av) + 1; //计算每一个参数的长度
854:        if (size == 0 || (user_args = malloc(size)) == NULL) { //通过malloc动态分配一段内存,用于存放参数内容
855:        sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
856:        debug_return_int(-1);
857:        }
858:        if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { //需要满足标志位的设置才能进入转义的流程
859:        /*
860:         * When running a command via a shell, the sudo front-end
861:         * escapes potential meta chars.  We unescape non-spaces
862:         * for sudoers matching and logging purposes.
863:         */
864:        for (to = user_args, av = NewArgv + 1; (from = *av); av++) { //遍历每个环境变量,并将内容拷贝到内存中
865:            while (*from) {
                /*
                    漏洞点,当扫描参数内容时,遇到\需要进行转义处理,例如'\t'、'\n'等,因此sudo只判断\后是否跟随着空格字符,即用isspace函数进行判                    断。                     
                    isspace包括的字符如下:
                    ' '     (0x20)    space (SPC) 空格符
                    '\t'    (0x09)    horizontal tab (TAB) 水平制表符    
                    '\n'    (0x0a)    newline (LF) 换行符
                    '\v'    (0x0b)    vertical tab (VT) 垂直制表符
                    '\f'    (0x0c)    feed (FF) 换页符
                    '\r'    (0x0d)    carriage return (CR) 回车符
                    以上不包括'\0'。
                    而参数之间是使用'\0'作为分隔符的,因此当'\\'后跟随的'\0'会使得from++从而导致将后一个参数也被拷贝进来,最后致使堆块溢出。
                */
866:            if (from[0] == '\\' && !isspace((unsigned char)from[1])) 
867:                from++;
868:            *to++ = *from++;
869:            }
870:            *to++ = ' ';
871:        }
872:        *--to = '\0';
​

使用POC的例子对漏洞进行说明

漏洞原理图

【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

因此漏洞点在于在进入set_cmnd函数时需要对转义字符进行转义,但是函数却没有判断转义字符作为参数末尾的情况,即\ + \x00

parse_args函数

parse_args函数用于反转义,即参数中若存在转义字符,会在每个转义字符之前增加一个\

File: src\parse_args.c
592:     if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) { //需要满足标志位的设置才会进入反转义流程
593:    char **av, *cmnd = NULL;
594:    int ac = 1;
595: 
596:    if (argc != 0) {
597:        /* shell -c "command" */
598:        char *src, *dst;
599:        size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) +
600:        strlen(argv[argc - 1]) + 1;
601: 
602:        cmnd = dst = reallocarray(NULL, cmnd_size, 2);
603:        if (cmnd == NULL)
604:        sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
605:        if (!gc_add(GC_PTR, cmnd))
606:        exit(1);
607: 
608:        for (av = argv; *av != NULL; av++) {
609:        for (src = *av; *src != '\0'; src++) {
610:            /* quote potential meta characters */
611:            if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')
612:            *dst++ = '\\';
613:            *dst++ = *src;
614:        }
615:        *dst++ = ' ';
616:        }
617:        if (cmnd != dst)
618:        dst--;  /* replace last space with a NUL */
619:        *dst = '\0';
620: 
621:        ac += 2; /* -c cmnd */
622:    }
​

这也是为什么set_cmnd函数需要对参数进行转义,因此若先经过parse_args函数进行反转义,后经过set_cmnd函数进行转义,那么sudo是不会出现漏洞情况的

绕过检验

那么如何绕过set_cmnd函数直接进入parse_args函数,才是漏洞能够被成功触发的关键因素

首先是如何才能过进入set_cmnd函数,sudo会经过两重检测

  1. sudo_mode需要具有MODE_RUN、MODE_EDIT或者MODE_CHECK的标志位

  2. sudo_mode需要具有MODE_SHELL或者MODE_LOGIN_SHELL的标志位

File: plugins\sudoers\sudoers.c
            ...
819:     if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { //需要满足标志位的设置才能进入转义的流程
            ...
858:        if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { //需要满足标志位的设置才能进入转义的流程
想要获得MODE_SHELL的标志位,则需要设置-s参数,此时通过 SET(flags, MODE_SHELL),将flag设置上MODE_SHELL,并且默认的mode是为NULL,因此设置-s参数可以使得flag即设置MODE_SHELL又设置MODE_RUN。
File: src\parse_args.c
479:        case 's':
480:            sudo_settings[ARG_USER_SHELL].value = "true";
481:            SET(flags, MODE_SHELL);
482:            break;
            ...
534:    if (!mode)
535:        mode = MODE_RUN;        /* running a command */
536:     }

但是若使用sudo -s,那么就会导致flag即设置MODE_SHELL又设置MODE_RUN,就会进入parse_args函数的流程,该流程会把所有非字母数字的字符前方增加一个'\',那么就会导致我们无法构造'' + '\x00'的漏洞字符,因此想要漏洞利用成功,我们不需要程序进入set_cmd函数,但是不能进入parse_args函数

File: src\parse_args.c
592:     if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) { //需要满足标志位的设置才会进入反转义流程
            ...
608:        for (av = argv; *av != NULL; av++) {
609:        for (src = *av; *src != '\0'; src++) {
610:            /* quote potential meta characters */
611:            if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')
612:            *dst++ = '\\';
613:            *dst++ = *src;
614:        }
            ...
622:    }

在parse_args函数的开头,会检测是以sudo还是以sudoedit进行调用,若使用sudoedit调用,那么会直接给mode设置上MODE_EDIT,从而绕过了mode==NULL时,需要将flag设置为MODE_RUN,因此使用sudoedit -s,可以使得flag即设置MODE_EDIT又设置MODE_SHELL

File: src\parse_args.c
        ...
265:     proglen = strlen(progname);
266:     if (proglen > 4 && strcmp(progname + proglen - 4, "edit") == 0) {
267:    progname = "sudoedit";
268:    mode = MODE_EDIT;
269:    sudo_settings[ARG_SUDOEDIT].value = "true";
270:     }

想要进入set_cmnd第二条路径就是flag设置为MODE_EDIT | MODE_SHELL,这样的输入就能够绕过parse_args函数而禁止进入set_cmd函数,这也是为什么sudo的堆溢出,需要使用sudoedit -s触发,而不是sudo -s

File: plugins\sudoers\sudoers.c
            ...
819:     if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { //需要满足标志位的设置才能进入转义的流程
            ...
858:        if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { //需要满足标志位的设置才能进入转义的流程

漏洞利用

漏洞利用分析

由于程序存在一个明显的堆溢出漏洞,因此需要梳理一下堆溢出如何进行利用。

• 找到一个堆块,该堆块的值会影响程序执行的流程,这里称之为可利用堆块

• 找到可以随意控制堆块位置的操作,将漏洞函数申请的堆块部署在可利用堆块的上方,当堆溢出触发时,可以将可利用堆块的值被改写成我们预期的值。

可利用堆块

nss是用于解析和获取不同类型的名称信息,例如如何通过用名称去获取用户信息,在sudo需要获取用户信息时则需要调用nss。

在使用nss去获取信息时,其实是通过不同的动态链接库去执行相应的行为,而这些库的文件名则存在于/etc/nsswitch.conf的配置文件中

例如想要查询passwd文件则需要用到libnss_files.so与libnss_systemed.so

那么如何加载这些动态链接库则需要依赖于nss_load_library函数,而且这些相关信息都被存放在service_user结构体中,而该结构体是存放在堆内存中的。

接着得先研究该结构体的值是否会影响程序的执行流程,代码如下。

File: nsswitch.c
327: static int
328: nss_load_library (service_user *ni)
329: {
330:   if (ni->library == NULL) 
331:     {
332:       /* This service has not yet been used.  Fetch the service
333:     library for it, creating a new one if need be.  If there
334:     is no service table from the file, this static variable
335:     holds the head of the service_library list made from the
336:     default configuration.  */
337:       static name_database default_table;
338:       ni->library = nss_new_service (service_table ?: &default_table,
339:                     ni->name); //若ni->library的值为NULL,那么就会新建一个ni->library并将成员都进行初始化
340:       if (ni->library == NULL)
341:    return -1;
342:     }
343: 
344:   if (ni->library->lib_handle == NULL) //由于ni->library刚新建,因此ni->library->lib_handle必定为NULL
345:     {
346:       /* Load the shared library.  */
347:       size_t shlen = (7 + strlen (ni->name) + 3
348:              + strlen (__nss_shlib_revision) + 1);
349:       int saved_errno = errno;
350:       char shlib_name[shlen];
351: 
352:       /* Construct shared object name.  */
353:       __stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
354:                          "libnss_"),
355:                    ni->name),
356:              ".so"), //shalib_name是根据拼接得到
357:        __nss_shlib_revision);
358: 
359:       ni->library->lib_handle = __libc_dlopen (shlib_name); //加载动态链接库
​

上述代码有个非常关键的点在于,程序会使用__libc_dlopen打开shalib_name指定的动态链接库,而shalib_name是通过ni->name进行一系列的拼接得到,而ni->name则是存放在结构体service_user *ni中的,该结构体又是存放在堆内存中的。那么我们就找到了关键的值ni->name,它是能够完成修改程序执行流程的关键变量。

举个例子,例如我们将ni->name修改为X/test,那么最后拼接的结果会得到libnss_X/test.so,那么如果我们在当前目录下新建一个libnss_X并且在该目录中创建一个test.so的动态链接库,那么sudo就会加载并执行我们动态链接库中的代码。至此我们找到利用的第一个关键因素,可利用堆块。

布置堆块的操作

由于我们已经找到了可利用的堆块,如果能够将堆溢出的堆块部署在可利用堆块的上方,在利用堆溢出修改ni->name,即可完成任意代码执行的效果。

在sudo的main函数中,会执行setlocate函数。setlocale 是一个用于设置程序的区域设置(locale)的函数,在许多编程语言和操作系统中都有对应的实现。

区域设置是指程序在运行时所采用的语言、地区、日期格式、货币符号等相关信息的集合。通过设置区域设置,程序可以根据不同的地区和语言环境来适应本地化需求。

export LC_ALL=en_US.UTF-8@XXXX

而在setlocal函数中涉及十分多的堆块分配与释放的操作,当调用setlocal(LC_ALL,"")时,程序会通过环境变量设置的值去搜索区域设置的值,而环境变量的搜索则依靠_nl_find_locale函数。

_nl_find_locale函数
File: locale\findlocale.c
101: struct __locale_data *
102: _nl_find_locale (const char *locale_path, size_t locale_path_len,
103:         int category, const char **name)
104: {
        ... 
184:   /* LOCALE can consist of up to four recognized parts for the XPG syntax:
185: 
186:        language[_territory[.codeset]][@modifier]
187: 
188:      Beside the first all of them are allowed to be missing.  If the
189:      full specified locale is not found, the less specific one are
190:      looked for.  The various part will be stripped off according to
191:      the following order:
192:        (1) codeset
193:        (2) normalized codeset
194:        (3) territory
195:        (4) modifier
196:    */
       /*
            区域的格式为C_en_US.UTF-8@XXXXXX
            _nl_explode_name用于判断(1)(2)(3)(4)哪部分存在,哪部分缺失
       */
197:   mask = _nl_explode_name (loc_name, &language, &modifier, &territory,
198:               &codeset, &normalized_codeset);
199:   if (mask == -1)
200:     /* Memory allocate problem.  */
201:     return NULL;
202: 
        //locale_file则给区域设置进行动态内存的分配
205:   locale_file = _nl_make_l10nflist (&_nl_locale_file_list[category],
206:                    locale_path, locale_path_len, mask,
207:                    language, territory, codeset,
208:                    normalized_codeset, modifier,
209:                    _nl_category_names_get (category), 0); //返回NULL
210: 
211:   if (locale_file == NULL)
212:     {
213:       /* Find status record for addressed locale file.  We have to search
214:     through all directories in the locale path.  */
215:       locale_file = _nl_make_l10nflist (&_nl_locale_file_list[category],
216:                    locale_path, locale_path_len, mask,
217:                    language, territory, codeset,
218:                    normalized_codeset, modifier,
219:                    _nl_category_names_get (category), 1);
220:       if (locale_file == NULL)
221:    /* This means we are out of core.  */
222:    return NULL;
223:     }
}

_nl_make_l10nflist**函数**

_nl_make_l10nflist会根据我们传入的值进行堆块的分配。

File: intl\l10nflist.c
150: struct loaded_l10nfile *
151: _nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list,
152:            const char *dirlist, size_t dirlist_len,
153:            int mask, const char *language, const char *territory,
154:            const char *codeset, const char *normalized_codeset,
155:            const char *modifier,
156:            const char *filename, int do_allocate)
157: {
        ...
165:   //根据我们传入的区域值的长度进行动态分配
166:   abs_filename = (char *) malloc (dirlist_len
167:                  + strlen (language)
168:                  + ((mask & XPG_TERRITORY) != 0
169:                     ? strlen (territory) + 1 : 0)
170:                  + ((mask & XPG_CODESET) != 0
171:                     ? strlen (codeset) + 1 : 0)
172:                  + ((mask & XPG_NORM_CODESET) != 0
173:                     ? strlen (normalized_codeset) + 1 : 0)
174:                  + ((mask & XPG_MODIFIER) != 0
175:                     ? strlen (modifier) + 1 : 0)
176:                  + 1 + strlen (filename) + 1);
177: 
        ...
292: }
​

setlocale**函数**

setlocale函数总体操作则是读取环境变量的值获取区域设置的值,根据区域设置的值分配堆块大小,若其中存在不符合区域值的规范,则会将所有先前申请的堆块都释放掉。

File: locale\setlocale.c
334:       while (category-- > 0)
335:    if (category != LC_ALL)
336:      {
            //通过_nl_find_locale函数去获取环境变量的值,存放在newdata[category]中
337:        newdata[category] = _nl_find_locale (locale_path, locale_path_len,
338:                         category,
339:                         &newnames[category]);
340: 
            ...
364:        else
365:          {
                //使用__strdup函数在堆内存中分配空间,并将newdata[category]拷贝进去
366:            newnames[category] = __strdup (newnames[category]);
367:            if (newnames[category] == NULL)
368:              break;
369:          }
            ...
393:      if (category != LC_ALL && newnames[category] != _nl_C_name
394:          && newnames[category] != _nl_global_locale.__names[category])
395:        free ((char *) newnames[category]); //这里就是堆块释放的原语了,只要有一个区域设置的值不符合规范,则将之前所有申请的堆块都释放掉
​

因此可以通过区域值去控制堆块的大小,接着在最后设置一个错误的区域值去控制堆块的位置,至此我们找到可控制堆块的操作。

LC_IDENTIFICATION = C.UTF-8@XX..XX #若长度为0x10,则malloc(0x10) LC_MEASUREMENT = C.UTF-8@XX..XXX,#若长度为0X20,则malloc(0x20) LC_TELEPHONE = XXXX #不符合区域值的规范,则会调用free()

exp的分析

由于我们需要控制server_user的堆块,因此需要知道该堆块的大小为多少,通过调试可知是0x40的堆块,因此利用setlocate多释放几个0x40的堆块,那么server_user就会使用到我们所释放的堆块。

紧接着将漏洞堆块分配到server_user堆块的上方,由于server_user的堆块是我们自己构建的,因此只需要在释放该堆块的同时也释放漏洞堆块即可,并且漏洞堆块的申请可是根据参数的长度所设置的

将设置区域值的函数设置为堆块分配与释放的原语,使用@后面的字符控制堆块的大小

 文章来源地址https://www.toymoban.com/news/detail-505206.html

使用错误的区域值进行堆块的释放

最后就是如何填充到可利用堆块,这里使用堆溢出,并且在环境变量中构造填充字符串,使得漏洞堆块可以覆盖掉可利用堆块的内容值,但这里需要注意的是,我们需要将ni->library中用\x00填充,而\x00是无法直接输入到环境变量中的,因此需要再次观察漏洞函数是如何拷贝字符的。根据代码分析可知,只要''后紧跟着'\x00',那么我们就能将\x00的值直接拷贝的堆内存中。紧接着将ni->name修改为我们认为构造的动态链接库即可。

File: plugins\sudoers\sudoers.c
866:            if (from[0] == '\\' && !isspace((unsigned char)from[1])) //若 '\' 后跟着'\x00'
867:                from++; //此时from会指向\x00
868:            *to++ = *from++; //使用\x00进行值的拷贝
869:            }

设置多个环境变量使得内存存在多个'' + '\x00',从而使用'\x00'去覆盖堆的内存值。

演示效果如下

漏洞修复

漏洞的修复则是将MODE_EDIT的标志位进行了额外的判断,并且在''后面增加了对'\0'的校验

​
--- a/plugins/sudoers/sudoers.c Sat Jan 23 08:43:59 2021 -0700
+++ b/plugins/sudoers/sudoers.c Sat Jan 23 08:43:59 2021 -0700
@@ -547,7 +547,7 @@
 
     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
     /* XXX - causes confusion when root is not listed in sudoers */
-    if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) {
+    if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) {
    if (user_uid == 0 && strcmp(prev_user, "root") != 0) {
        struct passwd *pw;
 
@@ -932,8 +932,8 @@
     if (user_cmnd == NULL)
    user_cmnd = NewArgv[0];
 
-    if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) {
-   if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
+    if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) {
+   if (!ISSET(sudo_mode, MODE_EDIT)) { //对MODE_EDIT进行了额外的判断
        const char *runchroot = user_runchroot;
        if (runchroot == NULL && def_runchroot != NULL &&
            strcmp(def_runchroot, "*") != 0)
@@ -961,7 +961,8 @@
        sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
        debug_return_int(NOT_FOUND_ERROR);
        }
-       if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
+       if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL) &&
+           ISSET(sudo_mode, MODE_RUN)) { //需要sudo -s才能进行转义
        /*
         * When running a command via a shell, the sudo front-end
         * escapes potential meta chars.  We unescape non-spaces
@@ -969,10 +970,22 @@
         */
        for (to = user_args, av = NewArgv + 1; (from = *av); av++) {
            while (*from) {
-           if (from[0] == '\\' && !isspace((unsigned char)from[1]))
+           if (from[0] == '\\' && from[1] != '\0' &&  //增加了'\0'的判断
+               !isspace((unsigned char)from[1])) {
                from++;
+           }
+           if (size - (to - user_args) < 1) {
+               sudo_warnx(U_("internal error, %s overflow"),
+               __func__);
+               debug_return_int(NOT_FOUND_ERROR);
+           }
            *to++ = *from++;
            }
+           if (size - (to - user_args) < 1) {
+           sudo_warnx(U_("internal error, %s overflow"),
+               __func__);
+           debug_return_int(NOT_FOUND_ERROR);
+           }
            *to++ = ' ';
        }
        *--to = '\0';

总结

Sudo堆溢出攻击流程

首先利用setlocate作为堆块分配与释放的原语,构造出适合的堆布局确保server_user堆块尽可能贴近漏洞代码开辟出来的堆块。

其次利用堆溢出将server_user堆块的ni->name值覆盖,覆盖的值为恶意构造的动态链接库名。

最后等待动态链接库被加载执行。

Sudo堆溢出利用的限制

由于sudo堆溢出依赖堆的布局,因此不同版本的sudo或者操作系统都会影响漏洞的利用。

更多网安技能的在线实操练习,请点击这里>>

 

到了这里,关于Sudo堆溢出漏洞(CVE-2021-3156)复现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VMware ESXi OpenSLP 堆溢出漏洞(CVE-2021–21974)勒索事件

    据BleepingComputer 2月3日消息,法国计算机紧急响应小组(CERT-FR) 近日发出警告,攻击者正通过一个远程代码执行漏洞,对全球多地未打补丁的 VMware ESXi 服务器部署新型ESXiArgs 勒索软件。 据悉,该漏洞编号为CVE-2021-21974,由 OpenSLP 服务中的堆溢出问题引起,未经身份验证的攻击者

    2024年02月04日
    浏览(45)
  • CVE-2021-22205 GitLab 远程命令执行漏洞复现

    目录 一、漏洞信息 二、环境搭建 三、复现过程 1.测试漏洞 2.漏洞利用,反弹shell 四、修复建议 一、漏洞信息 漏洞名称 GITLAB 远程命令执行漏洞 漏洞编号 CVE-2021-22205 危害等级 高危 CVSS评分 6.5 漏洞厂商 Ruby 受影响版本 11.9 = Gitlab CE/EE 13.8.8;13.9 = Gitlab CE/EE 13.9.6;13.10 = Gitlab

    2024年02月05日
    浏览(44)
  • HIKVISION海康威视代码执行漏洞复现(CVE-2021-36260)

    2023年将会持续于B站、CSDN等各大平台更新,可加入粉丝群与博主交流:838681355,为了老板大G共同努力。 GET访问/x.asp

    2024年02月12日
    浏览(45)
  • Django系列所有漏洞复现vulhubCVE-2018-14574,CVE-2022-34265,CVE-2021-35042

    Django默认配置下,如果匹配上的URL路由中最后一位是/,而用户访问的时候没加/,Django默认会跳转到带/的请求中。(由配置项中的django.middleware.common.CommonMiddleware、APPEND_SLASH来决定)。 在path开头为//example.com的情况下,Django没做处理,导致浏览器认为目的地址是绝对路径,最

    2024年02月07日
    浏览(40)
  • CVE-2021-1675 Windows Print Spooler权限提升漏洞复现

    Microsoft Windows Print Spooler 服务未能限制对RpcAddPrinterDriverEx()函数的访问,该函数可能允许远程身份验证的攻击者以系统权限在易受攻击的系统上执行任意代码。该RpcAddPrinterDriverEx()函数用于在系统上安装打印机驱动程序。此函数的参数之一是DRIVER_CONTAINER对象,它包含有关添加的

    2024年02月06日
    浏览(44)
  • Apache Http Server 路径穿越漏洞复现(CVE-2021-41773)

    Apache HTTP Server(简称 Apache)是 Apache 软件基金会的一个开放源码的网页服务器软件,可以在大多数电脑操作系统中运行。由于其跨平台和安全性,被广泛使用,是最流行的 Web 服务器软件之一。它快速、可靠并且可通过简单的 API 扩展,将 Perl/Python 等解释器编译到服务器中。

    2024年02月08日
    浏览(77)
  • WebLogic反序列化漏洞复现+利用工具(CVE-2021-2394)

    Oracle官方发布了2021年7月份安全更新通告,通告中披露了WebLogic组件存在高危漏洞,攻击者可以在未授权的情况下通过IIOP、T3协议对存在漏洞的WebLogic Server组件进行攻击。成功利用该漏洞的攻击者可以接管WebLogic Server。 这是一个二次反序列化漏洞,是CVE-2020-14756和CVE-2020-14825的

    2024年02月06日
    浏览(96)
  • 【漏洞复现】Apache_HTTP_2.4.50_路径穿越漏洞(CVE-2021-42013)

    感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 说明 内容 漏洞编号 CVE-2021-42013 漏洞名称 Apache HTTP_2.4.50_路径穿越漏洞 漏洞评级 高危 影响范围 2.4.49 2.4.50 漏洞描述 CVE-2021-42013是由CVE-2021-41773的不完整修复导致的漏洞,攻击者可以使用路径遍历攻击将

    2024年02月05日
    浏览(34)
  • MS08-067远程代码执行漏洞(CVE-2008-4250) | Windows Server服务RPC请求缓冲区溢出漏洞复现

    What is SMB? SMB(Server Message Block)是一个协议服务器信息块,它是一种客户机/服务器、请求/响应协议,通过SMB协议可以在计算机间共享文件、打印机、命名管道等资源,电脑上的网上邻居就是靠SMB实现的;SMB协议工作在应用层和会话层,可以用在TCP/IP协议之上,SMB使用TCP139端口和

    2024年02月08日
    浏览(39)
  • Log4j2 - JNDI 注入漏洞复现(CVE-2021-44228)

    Apache log4j 是 Apache 的一个开源项目, Apache log4j2 是一个 Java 的日志记录工具。该工具重写了 log4j 框架,并且引入了大量丰富的特性。我们可以控制日志信息输送的目的地为控制台、文件、GUI组件等,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。 l

    2024年02月07日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包