Unveiling the Sudo Heap Overflow Vulnerability (CVE-2021-3156): A Critical Security Flaw Reappears

本文主要是介绍Unveiling the Sudo Heap Overflow Vulnerability (CVE-2021-3156): A Critical Security Flaw Reappears,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

​​​​​​​​

Introduction

In this blog post, we dive into the intricacies of the Sudo Heap Overflow Vulnerability (CVE-2021-3156). On January 26, 2021, Qualys Research Labs discovered a flaw in sudo. When sudo parses the command line parameters, the truncation character is wrongly judged, which leads to the attacker maliciously constructing a payload, causing sudo to overflow the heap. This vulnerability can cause Local privilege escalation.

Environment

environment version

• ubuntu 20.04

• sudo-1.8.31p2

Use the following command to compile and install

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

Vulnerability

#poc./sudoedit -s  '\' 11111111111111111111111111111111111111111111111111111111111111

Executing the above POC and executing sudoedit will display the words malloc(): invalid size, which is a typical exception caused by a heap overflow.

​​​​​​​​

 Source:- https://tutorialboy24.blogspot.com/2023/07/unveiling-sudo-heap-overflow.htmlicon-default.png?t=N6B9https://tutorialboy24.blogspot.com/2023/07/unveiling-sudo-heap-overflow.html

Image description

Vulnerability Analysis

The Source code analysis

set_cmnd function 
File : plugins\sudoers\sudoers . c 
800 : static  int 
801 : set_cmnd ( void ) 
802 : { ... 819 :      if ( sudo_mode & ( MODE_RUN | MODE_EDIT | MODE_CHECK )) { //Need to meet the setting of the flag bit To enter the escape process ... 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 ++ ) //Traverse each parameter              
853 : size += strlen ( * av ) +          1 ; // Calculate the length of each parameter 
854 : if ( size == 0 || ( user_args = malloc ( size )) == NULL ) { // Dynamically allocate a section of memory through malloc to store parameter content              
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 )) { //The setting of the flag bit needs to be satisfied to enter the escape process 
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 ++               ) { //Traverse each environment variable and copy the content to the memory 
865 : while ( * from ) {            /*

The vulnerability point, when scanning the parameter content, encounter \ needs to be escaped, such as '\t' , '\n', etc., so sudo only judges whether \ is followed by a space character, that is, the isspace function is used to judge . characters included in isspace are as follows: ' ' (0x20) space (SPC) space character '\t' (0x09) horizontal tab (TAB) horizontal tab character '\n' (0x0a) newline ( LF) newline character '\v' (0x0b) vertical tab (VT ) vertical tab character '\f' (0x0c) feed (FF) form feed character '\r' (0x0d) carriage return (CR) does not include '' above carriage return . The parameters are separated by '', so when '\' is followed by '', from++ will cause the next parameter to be copied in,and finally cause the heap block to overflow.*/ 866 :

           ==  '\\'  &&  ! isspace (( unsigned  char ) from [ 1 ])) 
867 : from ++ ;                
868 : * to ++ = * from ++ ;              
869 :     }        
870 : * to ++ = ' ' ;              
871 : }        
872 : *-- to = '' ;        

Therefore, the vulnerability lies in the need to escape the escape character when entering the set_cmnd function, but the function does not judge the escape character as the end of the parameter, that is, \ + \x00

parse_args function

The parse_args function is used to reverse escaping, that is, if there are escape characters in the parameter, a \ will be added before each escape character

File : src\parse_args . c 
592 :      if ( ISSET ( mode , MODE_RUN ) &&  ISSET ( flags , MODE_SHELL )) { //The setting of the flag bit needs to be satisfied before entering the reverse escape process 
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 != '' ; 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 = '' ;          
620 : 
621 : ac += 2 ; /* -c cmnd */          
622 :    }

This is why the set_cmnd function needs to escape the parameters, so if the parse_args function is first used to reverse the parameters, and then the set_cmnd function is used to escape, then there will be no loopholes in sudo Bypass
inspection

So how to bypass the set_cmnd function and directly enter the parse_args function is the key factor for the vulnerability to be successfully triggered

The first is how to enter the set_cmnd function, sudo will go through double detection

  • sudo_mode needs to have the flag bit of MODE_RUN, MODE_EDIT or MODE_CHECK

  • sudo_mode needs to have the flag bit of MODE_SHELL or MODE_LOGIN_SHELL

File : plugins\sudoers\sudoers . c ... 819 :      if ( sudo_mode & ( MODE_RUN | MODE_EDIT | MODE_CHECK )) { //The setting of the flag bit needs to be satisfied to enter the escape process ... 858 : if ( ISSET ( sudo_mode , MODE_SHELL | MODE_LOGIN_SHELL )) { // Need to meet the setting of the flag bit to enter the escape process If you want to get the flag bit of MODE_SHELL, you need to set the -s parameter, at this time through SET ( flags , MODE_SHELL ), set the flag to MODE_SHELL, and the default mode is NULL, so setting the -s parameter can make the flag set both MODE_SHELL and 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 : }

But if you use sudo -s, it will cause the flag to set MODE_SHELL and MODE_RUN, and you will enter the process of the parse_args function, which will add a '\' in front of all non-alphanumeric characters, which will cause us to fail. Construct the vulnerability character of '' + '\x00', so if we want to exploit the vulnerability successfully, we don't need the program to enter the set_cmd function, but we cannot enter the parse_args function

File : src\parse_args . c 
592 :      if ( ISSET ( mode , MODE_RUN ) &&  ISSET ( flags , MODE_SHELL )) { //The setting of the flag bit needs to be satisfied before entering the anti-escaping process ... 608 : for ( av = argv ; * av != NULL ; av ++ ) { 609 : for ( src = * av ; * src !='' ; src ++ ) { 
610 : /* quote potential meta characters */            
611 : if ( ! isalnum (( unsigned char ) * src ) && * src != '_' && * src != '-' && * src != '$' )                        
612 : * dst ++ = '\\' ;              
613 : * dst ++ = * src             ; 
614 : }        ... 622 : }

At the beginning of the parse_args function, it will detect whether it is called by sudo or sudoedit. If it is called by sudoedit, it will directly set MODE_EDIT to the mode, thus bypassing the mode==NULL. When the flag needs to be set to MODE_RUN , so use sudoedit -s, you can set the flag to set MODE_EDIT and set 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 : }

The second path to enter set_cmnd is to set the flag to MODE_EDIT | MODE_SHELL. Such input can bypass the parse_args function and prohibit entry to the set_cmd function. This is why the heap overflow of sudo needs to be triggered by sudoedit -s instead of sudo - the s

File : plugins\sudoers\sudoers . c ... 819 :      if ( sudo_mode & ( MODE_RUN | MODE_EDIT | MODE_CHECK )) { //The setting of the flag bit needs to be satisfied to enter the escape process ... 858 : if ( ISSET ( sudo_mode , MODE_SHELL | MODE_LOGIN_SHELL )) { // Need to meet the setting of the flag bit to enter the escape process

exploit

Vulnerability Exploitation Analysis

Since the program has an obvious heap overflow vulnerability, it is necessary to sort out how the heap overflow is exploited.

• Find a heap block whose value will affect the flow of program execution, which is called an available heap block.

• Find an operation that can freely control the location of the heap block, and deploy the heap block applied by the vulnerable function above the exploitable heap block. When the heap overflow is triggered, the value of the exploitable heap block can be rewritten to our expected value.

Available Heaps

NSS is used to parse and obtain different types of name information, such as how to obtain user information by name, and NSS needs to be called when sudo needs to obtain user information.

When using NSS to obtain information, it actually performs corresponding behaviors through different dynamic link libraries, and the file names of these libraries exist in the configuration file of /etc/nsswitch.conf

Image description

For example, if you want to query the passwd file, you need to use libnss_files.so and libnss_systemed.so

Image description

So how to load these dynamic link libraries needs to depend on the nss_load_library function, and this related information is stored in the service_user structure, which is stored in the heap memory.

Image description

Then it is necessary to study whether the value of the structure will affect the execution flow of the program. The code is as follows.

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 ); //if ni If the value of ->library is NULL, a new ni->library will be created and all members will be initialized                     
340 :        if ( ni -> library  ==  NULL ) 
341 :   return  - 1 ; 
342 : } 
343 : 
344 :    if ( ni -> library -> lib_handle  ==  NULL ) //Since ni->library is newly created, ni->library->lib_handle must be 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 :        __st***y ( __st***y ( __st* **y ( __st***y ( shlib_name , 
354 : "libnss_" ),                          
355 : ni -> name ),                    
356: ".so" ), //shalib_name is obtained according to splicing              
357 : __nss_shlib_revision );        
358 : 
359 :        ni -> library -> lib_handle  =  __libc_dlopen ( shlib_name ); //load dynamic link library

The key point of the above code is that the program will use __libc_dlopen to open the dynamic link library specified by shalib_name, and shalib_name is obtained by a series of splicing through ni->name, and ni->name is stored in the structure service_user In *ni, the structure is stored in the heap memory. Then we found the key value ni->name, which is a key variable that can modify the execution flow of the program.

Image description

For example, if we change ni->name to X/test, then the final splicing result will get libnss_X/test.so, then if we create a new libnss_X in the current directory and create a test.so in the directory The dynamic link library, then sudo will load and execute the code in our dynamic link library. So far we have found the first key factor of utilization, which is the use of heap blocks.

The operation of arranging blocks

Since we have found the available heap blocks, if we can deploy the heap overflowed heap blocks above the available heap blocks, and use the heap overflow to modify ni->name, the effect of arbitrary code execution can be completed.

In the main function of sudo, the setlocate function will be executed. setlocale is a function used to set the locale of the program, and there are corresponding implementations in many programming languages​​and operating systems.

Regional settings refer to the collection of related information such as the language, region, date format, currency symbol, etc. used by the program at runtime. By setting the locale, the program can adapt to localization needs according to different regions and language environment s.

export LC_ALL=en_US.UTF-8@XXXX

In the setlocal function, a lot of heap block allocation and release operations are involved. When calling setlocal(LC_ALL,""), the program will search for the value of the locale through the value set by the environment variable, and the search for the environment variable depends on _nl_find_locale function.

_nl_find_locale function 
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: Besides 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: */ /* The format of the area is C_en_US.UTF-8@XXXXXX _nl_explode_name is used for judgment (1 )(2)(3)(4)Which part exists and which part is missing */ 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 is dynamic for regional settings Memory allocation 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 ); // return 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 , code set ,                    
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* *function**

_nl_make_l10nflist will allocate heap blocks according to the value we pass in.

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 :    //Dynamic allocation according to the length of the area value we pass in 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* *function**

The overall operation of the setlocale function is to read the value of the environment variable to obtain the value of the regional setting, and allocate the heap block size according to the value of the regional setting. If there is any specification that does not meet the regional value, all previously applied heap blocks will be released. .

File : locale\setlocale . c 
334 :        while ( category --  >  0 ) 
335 : if ( category != LC_ALL )      
336 :      { //Use the _nl_find_locale function to obtain the value of the environment variable and store it in newdata[category] 337 : newdata [ category ] = _nl_find_locale ( locale_path , locale_path_len , 338 : category , 339 : & newnames[ category ]); 
340 : ... 364 : else 365 :   { //Use the __strdup function to allocate space in the heap memory and copy newdata[category] into it 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 ]) ; The primitive, as long as there is a regional setting value that does not conform to the specification, all previously applied heap blocks will be released     

Therefore, the size of the heap can be controlled by the area value, and then a wrong area value is set at the end to control the position of the heap. So far we have found an operation that can control the heap.

​​​​​​​​

 Source:- https://tutorialboy24.blogspot.com/2023/07/unveiling-sudo-heap-overflow.htmlicon-default.png?t=N6B9https://tutorialboy24.blogspot.com/2023/07/unveiling-sudo-heap-overflow.html

LC_IDENTIFICATION =  C.UTF-8@XX..XX  #If the length is 0x10, then malloc(0x10) LC_MEASUREMENT =  C.UTF-8@XX..XXX , #If the length is 0X20, then malloc(0x20) LC_TELEPHONE = XXXX #If it does not conform to the specification of the area value, free() will be called analysis of exp

Since we need to control the heap block of server_user, we need to know the size of the heap block. Through debugging, we can see that it is a heap block of 0x40, so use setlocate to release a few more heap blocks of 0x40, then server_user will use what we released pile of blocks.

Image description

Immediately after that, allocate the vulnerability heap block above the server_user heap block. Since the server_user heap block is constructed by ourselves, we only need to release the vulnerability heap block while releasing the heap block, and the application for the vulnerability heap ap ap block can be set according to the length of the parameter

Image description

Set the function of setting the area value as the primitive of heap block allocation and release, and use the character after @ to control the size of the heap block

Image description

Freeing heap blocks with wrong region values

Image description

Finally, how to fill in the exploitable heap block. Here, heap overflow is used, and the filling string is constructed in the environment variable, so that the exploitable heap block can overwrite the content value of the exploitable heap block. However, it should be noted here that we need to Ni->library is filled with \x00, and \x00 cannot be directly input into the environment variable, so it is necessary to observe how the vulnerable function copies characters again. According to the code analysis, as long as '' is followed by '\x0 0', then we can directly copy the value of \x00 to the heap memory. Then modify ni->name to the dynamic link library we think is constructed.

File : plugins\sudoers\sudoers . c 
866 : if ( from [ 0 ] == '\\' && ! isspace (( unsigned char ) from [ 1 ])) //if '\' is followed by '\x00'                
867 : from ++ ; //At this point from will point to \x00                
868 : * to ++ = * from ++ ; //Use \x00 to copy the value              
869 :     }       

Set multiple environment variables so that there are multiple '' + '\x00' in the memory, so use '\x00' to cover the memory value of the heap.

Image description

The demonstration effect is as follows

Image description

Bug Fixes

The repair of the vulnerability is to make an additional judgment on the flag bit of MODE_EDIT, and add a check of '' after ''

---  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 )) { // extra judgment on 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 is required to escape            /* * 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 ] != '' && / / Added the judgment of ''                   
+ ! 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 = '' ;

Summarize

sudo heap overflow attack process

First, use setlocate as the primitive for heap block allocation and release, and construct a suitable heap layout to ensure that the server_user heap block is as close as possible to the heap block created by the vulnerable code.

Secondly, the heap overflow is used to overwrite the ni->name value of the server_user heap block, and the overwritten value is a maliciously constructed dynamic link library name.

Finally, wait for the dynamic link library to be loaded and executed.

Limitations of Sudo Heap Overflow Exploitation

Since the sudo heap overflow depends on the layout of the heap, different versions of sudo or the operating system will affect the exploitation of the vulnerability.

​​​​​​​​Source :- https://tutorialboy24.blogspot.com/2023/07/unveiling-sudo-heap-overflow.htmlicon-default.png?t=N6B9https://tutorialboy24.blogspot.com/2023/07/unveiling-sudo-heap-overflow.html

这篇关于Unveiling the Sudo Heap Overflow Vulnerability (CVE-2021-3156): A Critical Security Flaw Reappears的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/236356

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

GPU 计算 CMPS224 2021 学习笔记 02

并行类型 (1)任务并行 (2)数据并行 CPU & GPU CPU和GPU拥有相互独立的内存空间,需要在两者之间相互传输数据。 (1)分配GPU内存 (2)将CPU上的数据复制到GPU上 (3)在GPU上对数据进行计算操作 (4)将计算结果从GPU复制到CPU上 (5)释放GPU内存 CUDA内存管理API (1)分配内存 cudaErro

2021-8-14 react笔记-2 创建组件 基本用法

1、目录解析 public中的index.html为入口文件 src目录中文件很乱,先整理文件夹。 新建components 放组件 新建assets放资源   ->/images      ->/css 把乱的文件放进去  修改App.js 根组件和index.js入口文件中的引入路径 2、新建组件 在components文件夹中新建[Name].js文件 //组件名首字母大写

2021-08-14 react笔记-1 安装、环境搭建、创建项目

1、环境 1、安装nodejs 2.安装react脚手架工具 //  cnpm install -g create-react-app 全局安装 2、创建项目 create-react-app [项目名称] 3、运行项目 npm strat  //cd到项目文件夹    进入这个页面  代表运行成功  4、打包 npm run build

spring security 中的授权使用

一、认证     身份认证,就是判断一个用户是否为合法用户的处理过程。Spring Security 中支持多种不同方式的认证,但是无论开发者使用那种方式认证,都不会影响授权功能使用。因为 SpringSecurity 很好做到了认证和授权解耦。   二、授权     授权,即访问控制,控制谁能访问哪些资源。简单的理解授权就是根据系统提前设置好的规则,给用户分配可以访问某一个资源的