<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    一種輸入回顯限制的CLI編寫思路

    VSole2022-01-20 16:32:26

     

    寫在前面

    前兩天對某廠商的路由器進行測試(已獲授權)時,發現目標設備的SSH/Telnet連入后會被強制進入一個CLI中。此CLI會對用戶的輸入進行限制,當用戶輸入的命令不是預置命令時將會無法回車提交。于是對此種CLI的實現機制產生了興趣,本文將說明一種可行的安全CLI的編寫思路。

    實現思路

    首先最直觀的想法,我們無法使用空格進行提交,說明回車符(Space)被程序忽略了。或者說,我們的輸入并沒有被預期的打印,那么按這個思路來想,可以很容易的想到Linux下的密碼輸入有同樣的特點。

    在輸入密碼時,我們的輸入能被后端捕獲,但是不會顯示在屏幕上,同時^C之類的控制指令也會同時失效。 

    庫函數實現

    那么Linux是否提供了相應的函數以供我們使用呢?答案是肯定的,那就是getpassword函數。

    在man手冊中,此函數的函數原型如下:

    #include char *getpass(const char *prompt);
    

    函數描述為:

    DESCRIPTION         top       This function is obsolete.  Do not use it.  If you want to read       input without terminal echoing enabled, see the description of       the ECHO flag in termios(3).
           The getpass() function opens /dev/tty (the controlling terminal       of the process), outputs the string prompt, turns off echoing,       reads one line (the "password"), restores the terminal state and       closes /dev/tty again.
    

    顯然,此函數是一個過時函數了,但是我們或許可以從它的實現中找到我們真正感興趣的東西。(函數定義位于glibc/misc/getpass.c)

    /* Copyright (C) 1992-2019 Free Software Foundation, Inc.   This file is part of the GNU C Library.
       The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 2.1 of the License, or (at your option) any later version.
       The GNU C Library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Lesser General Public License for more details.
       You should have received a copy of the GNU Lesser General Public   License along with the GNU C Library; if not, see   .  */
    #include #include #include         /* For string function builtin redirect.  */#include #include 
    #include #define flockfile(s) _IO_flockfile (s)#define funlockfile(s) _IO_funlockfile (s)#include 
    /* It is desirable to use this bit on systems that have it.   The only bit of terminal state we want to twiddle is echoing, which is   done in software; there is no need to change the state of the terminal   hardware.  */
    #ifndef TCSASOFT#define TCSASOFT 0#endif
    static void call_fclose (void *arg){  if (arg != NULL)    fclose (arg);}
    char * getpass (const char *prompt){  FILE *in, *out;  struct termios s, t;  int tty_changed;  static char *buf;  static size_t bufsize;  ssize_t nread;
      /* Try to write to and read from the terminal if we can.     If we can't open the terminal, use stderr and stdin.  */
      in = fopen ("/dev/tty", "w+ce");  if (in == NULL)    {      in = stdin;      out = stderr;    }  else    {      /* We do the locking ourselves.  */      __fsetlocking (in, FSETLOCKING_BYCALLER);
          out = in;    }
      /* Make sure the stream we opened is closed even if the thread is     canceled.  */  __libc_cleanup_push (call_fclose, in == out ? in : NULL);
      flockfile (out);
      /* Turn echoing off if it is on now.  */
      if (__tcgetattr (fileno (in), &t) == 0)    {      /* Save the old one. */      s = t;      /* Tricky, tricky. */      t.c_lflag &= ~(ECHO|ISIG);      tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);    }  else    tty_changed = 0;
      /* Write the prompt.  */  __fxprintf (out, "%s", prompt);  __fflush_unlocked (out);
      /* Read the password.  */  nread = __getline (&buf, &bufsize, in);  if (buf != NULL)    {      if (nread < 0)    buf[0] = '\0';      else if (buf[nread - 1] == '')    {      /* Remove the newline.  */      buf[nread - 1] = '\0';      if (tty_changed)        /* Write the newline that was not echoed.  */        __fxprintf (out, "");    }    }
      /* Restore the original setting.  */  if (tty_changed)    (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);
      funlockfile (out);
      __libc_cleanup_pop (0);
      if (in != stdin)    /* We opened the terminal; now close it.  */    fclose (in);
      return buf;}
    

    可以看到,此函數有會在入口嘗試啟動一個新的tty用于之后的操作,若沒有多余的tty,將會嘗試直接使用stdin和stderr作為輸入輸出流,隨后它調用了tcsetattr對stdin進行了設置,然后就進入了文本讀取邏輯,最后同樣調用了tcsetattr進行了設置恢復從而使stdin恢復了正常,那么看起來最核心的函數就是tcsetattr了。

    核心函數

    我們來看看tcsetattr函數的實現,在man手冊中,它的函數原型如下:

    #include 
    int tcsetattr(int fildes, int optional_actions,const struct termios *termios_p);
    

    tcsetattr()函數使用termios_p參數指向的termios結構體對fildes參數指定的文件描述符所對應的處于開啟狀態的文件流進行設置。optional_actions用于指定此配置生效的時機,定義如下:

    • TCSANOW:此配置應立即生效。
    • TCSADRAIN:在所有寫入fildes的輸出信息傳輸后生效,若更改會影響輸出的參數時應使用此配置。
    • TCSAFLUSH:在所有寫入fildes的輸出信息傳輸后生效,并且在更改之前應丟棄迄今為止接收到但未讀取的所有輸入。

    那么接下來來看看termios結構體:

    tcflag_t c_iflag;      /* input modes */tcflag_t c_oflag;      /* output modes */tcflag_t c_cflag;      /* control modes */tcflag_t c_lflag;      /* local modes */cc_t     c_cc[NCCS];   /* special characters */
    

    據man手冊所述,沒有對termios結構體的標準定義,但是一個termios結構體至少要求包含以上成員,而這恰好也是我們要用的成員變量。

    輸入模式控制c_iflag——控制終端輸入方式

    鍵值意義IGNBRK忽略BREAK鍵輸入BRKINT如果同時設置了IGNBRK,BREAK鍵的輸入將被忽略,如果設置了BRKINT但是沒有設置IGNBRK,BREAK鍵將導致輸入和輸出隊列被刷新。如果終端是前臺進程組的控制終端,這會導致此終端向前臺進程組發送SIGINT中斷信號。當 IGNBRK和BRKINT均未設置時,BREAK鍵的輸入將會被讀取為空字節 (\0),除非設置了PARMRK,此時BREAK鍵的輸入將會被讀取為序列\377 \0 \0IGNPAR忽略幀錯誤和奇偶校驗錯誤PARMRK如果設置了該位,則在輸入傳遞給程序時會標記具有奇偶校驗錯誤或幀錯誤的輸入字節。僅當INPCK置位且IGNPAR未置位時,該位才有意義。標記錯誤字節的方式是使用兩個前面的字節,\377和\0。因此,對于從終端接收到的一個錯誤字節,該程序實際上讀取了三個字節。如果有效字節的值為\377,并且未設置ISTRIP,則程序可能會將其與標記奇偶校驗錯誤的前綴混淆。因此,這種情況下有效字節\377作為兩個字節\377 \377傳遞給程序。如果IGNPAR和PARMRK均未設置,則將具有奇偶校驗錯誤或幀錯誤的字符讀取為\0INPCK對輸入內容啟用奇偶校驗ISTRIP去除字符的第8個比特INLCR將輸入的NL(換行)轉換成CR(回車)IGNCR忽略輸入的回車ICRNL將輸入的回車轉化成換行(如果IGNCR未設置的情況下)IUCLC將輸入的大寫字符轉換成小寫字符(非POSIX)IXON允許輸入時對XON/XOFF流進行控制IXANY(XSI擴展)輸入任何字符都將重新啟動停止的輸出(默認是只允許START字符重新啟動輸出)IXOFF允許輸入時對XON/XOFF流進行控制(筆者注:此處可能是手冊有誤,推測應為關閉XON/XOFF流控)IMAXBEL當輸入隊列已滿時響鈴,Linux沒有實現這個位,它會視為此標志永遠被設置(非POSIX)IUTF8將輸入視為UTF8,這將允許在cooked模式下正確執行字符擦除

    ·Break鍵是電腦鍵盤上的一個鍵。Break鍵起源于19世紀的電報。在DOS時代,Pause/Break是常用鍵之一,但是近年來該鍵的使用頻率逐年減少。在某些較舊的程序中,按這個鍵會使程序暫停,若同時按Ctrl,會使程序停止而無法執行。
    因為Break可以中斷程序,所以Break鍵也被稱為Pause鍵。

    輸出模式控制c_oflag——控制終端輸出方式

    鍵值意義OPOST啟用先處理后輸出機制OLCUC在輸出時將小寫字符映射為大寫(非POSIX)ONLCR(XSI擴展)在輸出時將NL(換行) 映射到CR-NL(回車-換行)OCRNL將輸入的CR(回車)轉換成NL(換行)ONOCR不在第0列輸出CR(回車)ONLRET不輸出CR(回車)OFILL發送填充字符以延遲終端輸出,而不是使用定時延遲OFDEL將填充字符設置為ASCII DEL(0177),如果未設置此標志,則填充字符為ASCII NUL(\0)(未在Linux上實現)NLDLY換行輸出延時,可以取NL0(不延遲)或NL1(延遲0.1s) [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]CRDLY回車輸出延時,可以取CR0、CR1、CR2或CR3[需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]TABDLY水平制表符輸出延時,可以取TAB0、TAB1、TAB2、TAB3(或XTABS,但請參閱BUGS部分)。TAB3即XTABS代表將制表符擴展為空格(每八列停止輸出一次制表符)[需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]BSDLYBackspace延遲輸出延時,可以取BS0或BS1(從未實現)[需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]VTDLY垂直制表符輸出延時,可以取VT0或VT1FFDLY換頁輸出延時,可以取FF0或FF1 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

    終端控制c_cflag——指定終端硬件控制信息

    鍵值意義CBAUD(非POSIX)設置波特率掩碼(4+1位)[需要_BSD_SOURCE或_SVID_SOURCE]CBAUDEX(非POSIX)設置額外的波特率掩碼(1位),包含在CBAUD中(POSIX定義波特率存儲在termios結構中,沒有指定精確的位置,并提供cfgetispeed()和cfsetispeed()來獲取它。一些系統使用CBAUD在c_cflag中選擇的位,其他系統使用單獨的字段,例如sg_ispeed和sg_ospeed)[需要_BSD_SOURCE或_SVID_SOURCE]CSIZE設置字符長度掩碼,取值范圍為CS5、CS6、CS7或CS8CSTOPB設置兩個停止位,而不是一個CREAD啟用接收器PARENB啟用輸出奇偶校驗生成和輸入奇偶校驗PARODD如果設置,則輸入和輸出的奇偶校驗為奇校驗,否則使用偶校驗HUPCL在最后一個進程關閉設備(掛起)后,降低調制解調器控制線CLOCAL忽略調制解調器控制線LOBLK(非POSIX)阻止來自非當前shell層的輸出。此選項供shl(shell層)使用(未在Linux上實現)CIBAUD(非POSIX)輸入速度掩碼。CIBAUD位的值與CBAUD位的值相同,向左移位IBSHIFT位 [需要_BSD_SOURCE或_SVID_SOURCE](未在Linux上實現)CMSPAR(非POSIX)啟用stick(標記/空格)奇偶校驗(某些串行設備支持):如果設置了PARODD,則奇偶校驗位始終為1,如果 PARODD未設置,則奇偶校驗位始終為0[需要_BSD_SOURCE或_SVID_SOURCE]CRTSCTS(非POSIX)啟用RTS/CTS(硬件)流控制 [需要_BSD_SOURCE或_SVID_SOURCE]

    本地模式c_lflag——控制終端編輯功能

    鍵值意義ISIG當接收到INTR、QUIT、SUSP或DSUSP中的任何字符時,生成相應的信號ICANON啟用規范編輯模式(以分割輸入)XCASE(非POSIX,未在Linux上實現)如果還設置了ICANON,則終端僅是大寫的。否則,輸入將轉換為小寫,但以\開頭的字符除外。在輸出時,大寫字符以\開頭,小寫字符轉換為大寫 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]ECHO回顯輸入的字符ECHOE如果還設置了ICANON,ERASE字符會擦除前面的輸入字符,WERASE會擦除前面的單詞ECHOK如果還設置了ICANON,KILL字符將擦除當前行ECHONL如果還設置了ICANON,即使未設置ECHO,也會回顯NL字符ECHOCTL(非POSIX)如果還設置了ECHO,除TAB、NL、START和STOP之外的終端特殊字符將作為^X回顯,其中X是特殊字符的ASCII碼值+ 0x40的字符。例如,字符0x08 (BS)回顯為^H[需要_BSD_SOURCE或_SVID_SOURCE]ECHOPRT(非POSIX)如果還設置了ICANON和ECHO,則在擦除字符時將其打印 [需要_BSD_SOURCE或_SVID_SOURCE]ECHOKE(非POSIX)如果還設置了ICANON,則按照ECHOE和ECHOPRT的規定,通過擦除行上的每個字符來回顯KILL[需要_BSD_SOURCE或_SVID_SOURCE]DEFECHO(非POSIX,未在Linux上實現)僅在進程讀取時回顯FLUSHO(非POSIX,未在Linux上實現)刷新輸出流。通過鍵入DISCARD字符來切換此標志狀態 [需要_BSD_SOURCE或_SVID_SOURCE]NOFLSH在為INT、QUIT和SUSP字符生成信號時不再刷新輸入和輸出隊列TOSTOP將SIGTTOU信號發送到嘗試寫入其控制終端的后臺進程的進程組PENDIN(非POSIX,未在Linux上實現)在讀取下一個字符時重新打印輸入隊列中的所有字符。(bash(1)以這種方式處理預輸入) [需要_BSD_SOURCE或_SVID_SOURCE]IEXTEN啟用實現定義的輸入處理。必須啟用此標志以及ICANON才能對特殊字符EOL2、LNEXT、REPRINT、WERASE進行解釋,并使 IUCLC 標志有效

    實現過程

    最初的版本

    那么,有了核心函數,接下來就可以著手編寫我們的CLI了。首先,最直接的思路,我們既然希望控制用戶輸入的字符,那么我們可以捕獲用戶鍵入的每一個字符,將其獲取至CLI,然后由CLI進行初步處理后打印。那么以上思路就要解決以下兩個問題:

    • 通常情況下,當用戶敲擊回車后所輸入的內容才會被提交至程序內的內容接收函數中。那么如何逐字符獲取呢?
    • 用戶輸入內容時,默認是回顯的,如何不回顯呢?

    那么注意到本地模式控制中的ECHO和ICANON配置項顯然可以達成我們的要求,前者可以關閉用戶輸入的回顯,后者則可以捕獲即時敲擊的內容。

    于是很容易寫出代碼如下:

    #include #include     #include #include 
    void init(){    setbuf(stdin, NULL);    setbuf(stdout, NULL);    setbuf(stderr, NULL);}
    int main(){    FILE *in;    struct termios s, t;    int tty_changed;    char command[100000];    memset(command,0,100000);    char *commandPoint = command;
        init();    in = stdin;    if(tcgetattr (fileno(in), &t) == 0)    {        s = t;        t.c_lflag &= ~(ECHO|ICANON);        tty_changed = (tcsetattr (fileno (in), TCSANOW, &t) == 0);    }    else        tty_changed = 0;    while (1)    {        printf("藍晶@汪汪系統:~$ ");        char inputChar;        read(fileno(in),&inputChar,1);        while (inputChar)        {            if(inputChar == ''){                break;            }            *(commandPoint++) = inputChar;            write(1,&inputChar,1);            read(fileno(in),&inputChar,1);        }        printf("");        printf("%s",command);        memset(command,0,100000);        commandPoint = command;    }    if (tty_changed)        (void) tcsetattr (fileno (in), TCSANOW, &s);    return 0;}
    

    這里可以看到,我們為了最大程度的防止stdin文件流被破壞,我們選擇與getpass()函數中一樣,先使用tcgetattr讀取stdin的配置,然后再進行ECHO、ICANON標志位的配置。隨后我們定義了一個命令字符串用于存放用戶輸入的指令,同時定義了一個指針指向其開頭,當獲取到用戶輸入時,依次將其存入此數組,并在讀取到回車()后將其打印,隨后將命令字符串清空,將指針置回字符串起始。當然在整個程序最后別忘了將終端的設置恢復,否則易導致終端異常的發生。

    解決退格的版本(?)

    不過我們測試其實可以發現,最初的版本中實際上是無法使用退格的,這是因為,在非標準輸入模式下,我們需要對退格進行單獨的處理,BackSpace對應的并不是\b,查閱ASCII碼表可以發現,backspace對應的是127,那么我們只要新增對127的處理即可。

    #include #include     #include #include 
    void init(){    setbuf(stdin, NULL);    setbuf(stdout, NULL);    setbuf(stderr, NULL);}
    int main(){    FILE *in;    struct termios s, t;    int tty_changed;    char command[100000];    memset(command,0,100000);    char *commandPoint = command;
        init();    in = stdin;    if(tcgetattr (fileno(in), &t) == 0)    {        s = t;        t.c_lflag &= ~(ECHO|ICANON);        tty_changed = (tcsetattr (fileno (in), TCSANOW, &t) == 0);    }    else        tty_changed = 0;    while (1)    {        printf("藍晶@汪汪系統:~$ ");        char inputChar;        read(fileno(in),&inputChar,1);        while (inputChar)        {            if(inputChar == ''){                break;            }else if(inputChar == 127){                if(strlen(command) > 0){                    *(--commandPoint) = 0;                    printf("\b \b");                }            }            *(commandPoint++) = inputChar;            write(1,&inputChar,1);            read(fileno(in),&inputChar,1);        }        printf("");        printf("%s",command);        memset(command,0,100000);        commandPoint = command;    }    if (tty_changed)        (void) tcsetattr (fileno (in), TCSANOW, &s);    return 0;}
    

    注意此處我們并不是簡單的輸出\b,而是需要輸出\b \b因為\b的意義僅僅是將光標前移一位。因此我們的處理邏輯是光標前移之后輸出一個空格覆蓋需要刪除的內容,然后再退回輸入點

    解決退格的版本

    根據上面的截圖我們其實可以看出來事實上簡單地進行退格信號處理是存在問題的,這不僅將導致指針越界,還會導致不應該被刪除的內容被刪除,因此我們需要對信號的處理加以限制。

    #include #include     #include #include 
    void init(){    setbuf(stdin, NULL);    setbuf(stdout, NULL);    setbuf(stderr, NULL);}
    int main(){    FILE *in;    struct termios s, t;    int tty_changed;    char command[100000];    memset(command,0,100000);    char *commandPoint = command;
        init();    in = stdin;    if(tcgetattr (fileno(in), &t) == 0)    {        s = t;        t.c_lflag &= ~(ECHO|ICANON);        tty_changed = (tcsetattr (fileno (in), TCSANOW, &t) == 0);    }    else        tty_changed = 0;    while (1)    {        printf("藍晶@汪汪系統:~$ ");        char inputChar;        read(fileno(in),&inputChar,1);        while (inputChar)        {            if(inputChar == ''){                break;            }else if(inputChar == 127){                if(strlen(command) > 0){                    *(--commandPoint) = 0;                    printf("\b \b");                }            }else{                *(commandPoint++) = inputChar;                write(1,&inputChar,1);            }            read(fileno(in),&inputChar,1);        }        printf("");        printf("%s",command);        memset(command,0,100000);        commandPoint = command;    }    if (tty_changed)        (void) tcsetattr (fileno (in), TCSANOW, &s);    return 0;}
    

    此時,我們退格將不會在產生超預期的行為

    加一點細節的版本

    最后~我們加億點細節,得到最終代碼:

    #include #include     #include #include #define WHITELISTCOMMANDNUM 4
    static void call_fclose (void *arg){  if (arg != NULL)    fclose(arg);}
    void init(){    setbuf(stdin, NULL);    setbuf(stdout, NULL);    setbuf(stderr, NULL);}
    int main(){    FILE *in, *out;    struct termios s, t;    int tty_changed;    char command[100000];    memset(command,0,100000);    char *commandPoint = command;    char *whitelist[WHITELISTCOMMANDNUM] = {"exit","ver","ping","pig"};
        init();    in = stdin;    if(tcgetattr (fileno(in), &t) == 0)    {        s = t;        t.c_lflag &= ~(ECHO|ICANON);        tty_changed = (tcsetattr (fileno (in), TCSANOW, &t) == 0);    }    else        tty_changed = 0;    while (1)    {        printf("藍晶@汪汪系統:~$ ");        printf("%s",command);        char inputChar;        read(fileno(in),&inputChar,1);        int commandStatus = 0;        char maybecommand[1000000];        int maybeCommandCount = 0;        memset(maybecommand,0,1000000);        while (inputChar)        {            if(inputChar == ''){                memset(maybecommand,0,1000000);                int maybecount = 0;                commandStatus = 0;                for(int whitelistidx = 0;whitelistidx < WHITELISTCOMMANDNUM;whitelistidx++){                    if(strlen(command) == strlen(whitelist[whitelistidx]) && !strncmp(command,whitelist[whitelistidx],strlen(whitelist[whitelistidx]))){                        commandStatus = 2;                        break;                    }else if(strstr(whitelist[whitelistidx],command) == whitelist[whitelistidx]){                        commandStatus = 1;                        maybeCommandCount++;                        strcat(maybecommand,whitelist[whitelistidx]);                        strcat(maybecommand,"\t");                    }                }                if(commandStatus == 1 && maybeCommandCount == 1) {                    memset(command,0,100000);                    strncpy(command,maybecommand,strlen(maybecommand)-1);                    printf("%s" , commandPoint);                    commandStatus = 2;                }                if(commandStatus != 0) break;            }else if(inputChar == 127){                if(strlen(command) > 0){                    *(--commandPoint) = 0;                    printf("\b \b");                }            }else{                *(commandPoint++) = inputChar;                write(1,&inputChar,1);            }            read(fileno(in),&inputChar,1);        }        printf("");        if(commandStatus == 1){            printf("%s",maybecommand);        }else if(commandStatus == 2){            if(!strcmp(command,"ver")){                printf("自豪的由汪汪的小藍藍開發!是安全的獸人Shell!歡迎一起成為Furry!Version:0.1beta");            }else if(!strcmp(command,"exit")){                printf("Bye!");                break;            }else{                printf("%s",command);            }            memset(command,0,100000);            commandPoint = command;        }    }    if (tty_changed)        (void) tcsetattr (fileno (in), TCSANOW, &s);    return 0;}
    

    添加的細節代碼均為基礎的C語言基礎機制代碼,此處不再解釋,請讀者自行識讀~

    后記

    后面我會出一些基于此CLI(當然不是beta版本的CLI嘿嘿嘿)的CTF題目,同時也會在CLI中加入用戶管理、Tab補全、敏感字符控制、密碼學等元素,創造一個與雙邊協議系列類似的系列題目~敬請期待~

    大家有什么有趣的想法也歡迎來與我一起討論~一起來當一個陰間題出題人吧~(不是)

    char函數控制字符
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    對于攻擊者而言,只需要在POST BODY前面添加許多無用的數據,把攻擊的payload放在最后即可繞過WAF檢測。實驗步驟首先使用BurpSuite抓取數據包,并記下數據包的Header信息編寫好我們的Python腳本進行FUZZ:#!
    開放虛擬機格式(Open Virtual Machine Format,OVF)是一種虛擬機分配格式,能夠支持不同產品與組織之間共享虛擬機。 VMware OVF Tool是由VMware免費提供的一款支持虛擬的導入導出工具,支持以命令提示符的方式運行。
    Bypass安全狗MySQL注入
    1、文檔連接釣魚 1)LINK鏈接釣魚 2)LINK快捷方式釣魚 3)CHM文檔釣魚 CHM文檔bypass waf 4)HTA釣魚 5)宏釣魚 宏釣魚 bypass waf 6)OLE(Object Linking and Embedding,對象鏈接與嵌入) 7)嵌入JS元素 8)利用模板文件注入宏指令 9)CVE 2、偽造界面釣魚 1)PPT動
    在該程序中只需要判斷x=4即可獲得系統shell。查看發現x的值為3,同時得到x的地址為0x804A02C在printf函數中的參數可控 于是可能存在格式化字符漏洞,利用字符串漏洞重寫x的值。輸入的字符串會存儲進入棧內,然后printf函數使用輸入的內容作為格式化字符串進行控制輸出。輸入多個%p打印棧上的內容判斷輸入的數據在棧上離棧頂的偏移。構造如下AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%pfrom pwn import *p=remoteadrr=p32PAYLOAD=b"AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p"p.sendline. p.interactive()可以計算該偏移量為11。
    無意中看到ch1ng師傅的文章覺得很有趣,不得不感嘆師傅太厲害了,但我一看那長篇的函數總覺得會有更騷的東西,所幸還真的有,借此機會就發出來一探究竟,同時也不得不感慨下RFC文檔的妙處,當然本文針對的技術也僅僅只是在流量層面上waf的繞過。Pre很神奇對吧,當然這不是終點,接下來我們就來一探究竟。前置這里簡單說一下師傅的思路部署與處理上傳war的servlet是?
    記一次網站滲透過程
    2022-09-13 08:37:27
    前幾天記錄某一次無意點開的一個小網站的滲透過程,幸運的是搭建平臺是phpstudy,cms是beecms,beecms有通用漏洞,然后去網上找了資料,成功getshell并獲取服務器權限。
    一、序言 記錄某一次無意點開的一個小網站的滲透過程,幸運的是搭建平臺是phpstudy,cms是beecms,beecms有通用漏洞,然后去網上找了資料,成功getshell并獲取服務器權限。 二、滲透過程 1. 無意點開一個網站,發現網站比較小,且看起來比較老,然后發現logo沒有改,于是乎去百度搜索這個cms,發現有通用漏洞,這里貼一個鏈接:Beecms 通用漏洞(https://lin
    釣魚小技巧-XLM
    2022-01-21 21:30:11
    隨后保存為啟用宏的文檔。而在實戰環境中,我們更關注的是能否執行我們的shellcode。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类