主頁 >  其他 > Sudo堆溢位漏洞(CVE-2021-3156)復現

Sudo堆溢位漏洞(CVE-2021-3156)復現

2023-06-29 08:38:06 其他

背景介紹

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的字樣,這是典型的堆溢位后導致的例外,

image-20230628153200287

漏洞分析

原始碼分析

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的例子對漏洞進行說明

image-20230628153256097

漏洞原理圖

【----幫助網安學習,以下所有學習資料免費領!加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 = https://www.cnblogs.com/hetianlab/archive/2023/06/28/*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 = "https://www.cnblogs.com/hetianlab/archive/2023/06/28/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 = https://www.cnblogs.com/hetianlab/archive/2023/06/28/*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 = "https://www.cnblogs.com/hetianlab/archive/2023/06/28/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)) { //需要滿足標志位的設定才能進入轉義的流程

漏洞利用

漏洞利用分析

由于程式存在一個明顯的堆溢位漏洞,因此需要梳理一下堆溢位如何進行利用,

? 找到一個堆塊,該堆塊的值會影響程式執行的流程,這里稱之為可利用堆塊

? 找到可以隨意控制堆塊位置的操作,將漏洞函式申請的堆塊部署在可利用堆塊的上方,當堆溢位觸發時,可以將可利用堆塊的值被改寫成我們預期的值,

image-20230628153906962

可利用堆塊

nss是用于決議和獲取不同型別的名稱資訊,例如如何通過用名稱去獲取用戶資訊,在sudo需要獲取用戶資訊時則需要呼叫nss,

在使用nss去獲取資訊時,其實是通過不同的元件去執行相應的行為,而這些庫的檔案名則存在于/etc/nsswitch.conf的組態檔中

image-20230628153923965

例如想要查詢passwd檔案則需要用到libnss_files.so與libnss_systemed.so

image-20230628153940378

那么如何加載這些元件則需要依賴于nss_load_library函式,而且這些相關資訊都被存放在service_user結構體中,而該結構體是存放在堆記憶體中的,

標題: fig:

接著得先研究該結構體的值是否會影響程式的執行流程,代碼如下,

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,它是能夠完成修改程式執行流程的關鍵變數,

標題: fig:

舉個例子,例如我們將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 = [email protected] #若長度為0x10,則malloc(0x10) LC_MEASUREMENT = [email protected],#若長度為0X20,則malloc(0x20) LC_TELEPHONE = XXXX #不符合區域值的規范,則會呼叫free()

exp的分析

由于我們需要控制server_user的堆塊,因此需要知道該堆塊的大小為多少,通過除錯可知是0x40的堆塊,因此利用setlocate多釋放幾個0x40的堆塊,那么server_user就會使用到我們所釋放的堆塊,

標題: fig:

緊接著將漏洞堆塊分配到server_user堆塊的上方,由于server_user的堆塊是我們自己構建的,因此只需要在釋放該堆塊的同時也釋放漏洞堆塊即可,并且漏洞堆塊的申請可是根據引數的長度所設定的

標題: fig:

將設定區域值的函式設定為堆塊分配與釋放的原語,使用@后面的字符控制堆塊的大小

 

標題: fig:

使用錯誤的區域值進行堆塊的釋放

標題: fig:

最后就是如何填充到可利用堆塊,這里使用堆溢位,并且在環境變數中構造填充字串,使得漏洞堆塊可以覆寫掉可利用堆塊的內容值,但這里需要注意的是,我們需要將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'去覆寫堆的記憶體值,

標題: fig:

演示效果如下

標題: fig:

漏洞修復

漏洞的修復則是將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或者作業系統都會影響漏洞的利用,

更多網安技能的在線實操練習,請點擊這里>>

 

合天智匯:合天網路靶場、網安實戰虛擬環境

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/556245.html

標籤:其他

上一篇:鏈家廣州二手房分析 2023

下一篇:返回列表

標籤雲
其他(161817) Python(38259) JavaScript(25515) Java(18273) C(15238) 區塊鏈(8273) C#(7972) AI(7469) 爪哇(7425) MySQL(7271) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4607) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2438) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1985) HtmlCss(1976) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • Sudo堆溢位漏洞(CVE-2021-3156)復現

    2021年1月26日,Qualys Research Labs在 sudo 發現了一個缺陷。sudo 決議命令列引數的方式時,錯誤的判斷了截斷符,從而導致攻擊者可以惡意構造載荷,使得sudo發生堆溢位,該漏洞在配合環境變數等分配堆以及釋放堆的原語下,可以致使本地提權。 ......

    uj5u.com 2023-06-29 08:38:06 more
  • 鏈家廣州二手房分析 2023

    因為詳細的資料分析在之前的文章中已經做過,而且這次重新爬取資料主要也是為了比較一下廣州二手房市場的一些新變化,所以完整且詳細的分析就不再重復了,有興趣的讀者可以翻開之前的文章。 不過我利用這些新資料確實看到了一些有趣的變化。這篇文章將會零碎的分享這些新發現。 #### 天河一騎絕塵 從影像可以看出, ......

    uj5u.com 2023-06-29 08:37:26 more
  • 11個開源專案,5位技術大咖…華為云亮相2023開放原子全球開源峰會

    摘要:華為云受邀參加了2023開放原子全球開源峰會中開源資料庫、開源安全技術與實踐等分論壇,并承辦了云原生分論壇 2023年6月13日,由2023全球數字經濟大會組委會主辦,開放原子開源基金會、北京市經濟和資訊化局、北京經濟技術開發區管理委員會承辦的2023開放原子全球開源峰會在北京圓滿落幕。本次峰 ......

    uj5u.com 2023-06-29 08:37:07 more
  • 資料恢復EaseUS(資料恢復神器)

    易我資料恢復EaseUS Data Recovery Wizard 技術員終身版為全球提供資料恢復方案,用于誤刪資料資料,電腦誤刪檔案恢復,格式化硬碟資料恢復、手機U盤資料恢復等。RAID磁盤陣列資料恢復,磁區丟失及其它未知原因丟失的資料恢復、簡單易用輕松搞定資料恢復。 EaseUS 堪稱是最好的數 ......

    uj5u.com 2023-06-29 08:36:50 more
  • 不糾結語法(田靜)

    # 第一章 簡單句的核心 ## 第一節 簡單句的核心構成 ### 簡單句的核心導圖 ![img](https://img2023.cnblogs.com/blog/2807357/202306/2807357-20230628161238883-1987928337.png) ### 注意: - 主 ......

    uj5u.com 2023-06-29 08:36:10 more
  • 分享一次性能測驗程序,5個步驟直接起飛!

    在企業中完成性能測驗專案是一個挑戰性強、技術含量高的任務。本文將分享一個公司完成高性能游戲系統的性能測驗程序,展示如何完成一次成功的性能測驗專案。 專案背景:這是一家游戲公司,推出了一款新的游戲軟體,系統要求高性能、高并發、高可用,為確保用戶體驗和游戲體驗,公司決定在正式上線前對系統進行性能測驗. ......

    uj5u.com 2023-06-29 08:35:42 more
  • 業務安全情報第十七期 | 國際航班上,小“票代”在瘋狂倒賣高價票

    頂象防御云業務安全情報中心監測發現,某航空國際航班,遭遇惡意網路爬蟲的持續攻擊。高峰時期,B2C網站惡意網路爬蟲的訪問量達84%,嚴重占用網路帶寬。此外,小“票代”還進行航班票價的倒賣,直接影響乘客正常查詢和購票。 乘坐國際航班,躲不開的“票代” 《2022年民航行業發展統計公報》顯示,國際航線完成 ......

    uj5u.com 2023-06-29 08:35:32 more
  • 解決TrueNAS中Smb共享檔案路徑不區分大小寫的問題

    # 問題 在Truenas中, 默認的smb檔案分享中, 檔案夾是不區分大小寫的. 這在一些情況下會導致無法重命名等問題, 嚴重時可能會造成拷貝檔案時的全檔案夾檔案丟失. 這是linux下的情況, 在已存在others檔案夾的情況下, 若再新建Others檔案夾, 會提示目錄已存在, 但實際上兩個目 ......

    uj5u.com 2023-06-29 08:35:20 more
  • 可觀測性是什么? 入門指南

    如果您之前對可觀測性重要性,益處,以及組成不甚了解,本文是一個合適的指南手冊。 什么是可觀測性? 可觀測性被定義為根據系統產生的輸出資料(如日志,指標和鏈路追蹤)來衡量當前系統運行狀態的能力。 可觀測性目前被廣泛的用于提升分布式 IT 系統的穩定性(系統復雜度成倍提升,在故障或者例外時很難快速定位和 ......

    uj5u.com 2023-06-29 08:34:06 more
  • 鏈家廣州二手房分析 2023

    因為詳細的資料分析在之前的文章中已經做過,而且這次重新爬取資料主要也是為了比較一下廣州二手房市場的一些新變化,所以完整且詳細的分析就不再重復了,有興趣的讀者可以翻開之前的文章。 不過我利用這些新資料確實看到了一些有趣的變化。這篇文章將會零碎的分享這些新發現。 #### 天河一騎絕塵 從影像可以看出, ......

    uj5u.com 2023-06-29 08:33:55 more