php特性练习
php特性
WEB89
源代码如下:
1 | (?php |
题目要求我们通过GET方式传入num变量,其中,num变量不能有0~9,否则回显no no no! 。在绕过这一层判断之后,还要求我们在intval()函数中执行的结果必须是1
查找php手册,发现intval函数的判断结果如下:
1 | (?php |
那么就很好解决了,当我们给intval传入一个数组,只要数组内有值存在,必然会执行结果为1
因此我们传入?num[]=a
轻松得到结果
WEB90
源代码如下:
1 | (?php |
本题让我们首先传入num,进行强比较时不能时num等于4476,然后对num进行转化的时候又必须等于4476
我们使用弱比较绕过,传入/?num=4476a
即可获取flag
ps:如果 base 是 0,通过检测 var 的格式来决定使用的进制:
* 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,
* 如果字符串以 “0” 开始,使用 8 进制(octal);否则,
* 将使用 10 进制 (decimal)
WEB91
源代码如下:
1 | (?php |
正则匹配修饰符如下:
1 | # i 不区分(ignore)大小写; |
因此,第一次全局匹配,有换行的情况下也会进行逐行匹配,但是第二次,只进行了大小写匹配,这就造成了可以进行绕过,我们使用%0APHP
即可顺利读取(%0A时url编码后的换行符)
WEB92
源代码如下:
1 | (?php |
这不是第90题么?
仔细看还真有区别,第一步的强比较换成了弱比较,结合90的ps,我们直接传入8进制的4476:010574
按照十进制与4476比较绕过第一个if,由于开头数字为0,所以会在intval执行中自动按照八进制数据处理和4476相等,顺利解题
WEB93
源代码如下:
1 | (?php |
思路同上
WEB94
源代码如下:
1 | (?php |
查看发现第三条if语句将我们的八进制转化大法也ban了,那么我们只能另寻他法。
由于intval语句会自动取整echo intval(4.2); // 4
那么我们可以使用4476.0来绕过,又因为进入的numif语句是和4476进行强比较,因此我们浮点数和整数自然可以绕过比较,得到答案
WEB95
源代码如下:
1 | (?php |
这道题出题人汲取了上一道题的错误,将第一个if语句换为弱比较,此时我们就不能继续使用浮点数来进行绕过。
我们知道,当我们通过GET来进行传参时,+
会被视作空格处理,因此,我们可以采用八进制
来成功绕过
WEB96
源代码如下:
1 | (?php |
要求我们引入flag.php,同时,不能让文件包含flag.php,因此我们可以使用filter协议来读取php://filter/convert.base64-encode/resource=flag.php
,将读取内容解码后,即可顺利得到flag
WEB97
源代码如下:
1 | (?php |
本题需要我们进行md5的绕过,对于md5的比较,有以下几点;
1.弱比较(==):
若两个字符串的md5值都是0e开头,而且后面全是数字,那么使用这两个字符串的md5值比较的话就会得到相等的结果,例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157s878926199a
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
240610708
0e462097431906509019562988736854
314282422
0e990995504821699494520356953734
571579406
0e972379832854295224118025748221
903251147
0e174510503823932942361353209384
1110242161
0e435874558488625891324861198103
1320830526
0e912095958985483346995414060832
1586264293
0e622743671155995737639662718498
2302756269
0e250566888497473798724426794462
2427435592
0e067696952328669732475498472343
2653531602
0e877487522341544758028810610885
3293867441
0e471001201303602543921144570260
3295421201
0e703870333002232681239618856220
3465814713
0e258631645650999664521705537122
3524854780
0e507419062489887827087815735195
3908336290
0e807624498959190415881248245271
4011627063
0e485805687034439905938362701775
4775635065
0e998212089946640967599450361168
4790555361
0e643442214660994430134492464512
5432453531
0e512318699085881630861890526097
5579679820
0e877622011730221803461740184915
5585393579
0e664357355382305805992765337023
6376552501
0e165886706997482187870215578015
7124129977
0e500007361044747804682122060876
7197546197
0e915188576072469101457315675502
7656486157
0e451569119711843337267091732412
QLTHNDT
0e405967825401955372549139051580
QNKCDZO
0e830400451993494058024219903391
EEIZDOI
0e782601363539291779881938479162
TUFEPMC
0e839407194569345277863905212547
UTIPEZQ
0e382098788231234954670291303879
UYXFLOI
0e552539585246568817348686838809
IHKFRNS
0e256160682445802696926137988570
PJNPDWY
0e291529052894702774557631701704
ABJIHVY
0e755264355178451322893275696586
DQWRASX
0e742373665639232907775599582643
DYAXWCA
0e424759758842488633464374063001
GEGHBXL
0e248776895502908863709684713578
GGHMVOE
0e362766013028313274586933780773
GZECLQZ
0e537612333747236407713628225676
NWWKITQ
0e763082070976038347657360817689
NOOPCJF
0e818888003657176127862245791911
MAUXXQC
0e478478466848439040434801845361
MMHUWUV
0e7017327116301504381292098165362.强比较(===):
在 PHP5 和 PHP7 中,当两个 md5 进行比较时,若参数是不同的数组,那么 == 和 === 比较的结果均为 True3.其他情况
只能进行md5的碰撞了:
利用 fastcoll 进行 md5 碰撞,可以生成两个字面值不同但 md5 相同的文件
使用方法:将空文件拖在exe上即可
本题使用数组绕过即可
WEB98
源代码如下;
1 | (?php |
- 在这里,首先我们要介绍一下php的三元运算符: 当然,三元运算符也可以叠加运算,多个执行语句可以使用用字符串运算符号(“.”)连接起来,各执行语句用小角括号包围起来以表明它是一个独立而完整的执行语句
1
2(语句一)?(语句二):(语句三);
//这句三元语句表示,当语句一的结果为真时,执行语句二;否则,执行语句三当然,三元运算符也可以进行嵌套操作,但因为嵌套后代码可读性下降,代码后期维护成本增加,故此不做讨论1
2(语句一)?(语句二).(语句二.二):(语句三).(语句三.二);
//这句三元语句表示,当语句一的结果为真时,执行语句二、二.二;否则,执行语句三、三.三 - 其次,我们要介绍一下php的传值引用
- 变量的引用赋值: $a = &$b
- 函数调用时的引用参数传递
- 早期php是在调用时通过&符号传递引用类型的变量, 比如: func(&$arg);
- 后来, 函数的引用类型参数被规定为需要在函数声明时定义, 比如: function func(&$arg);
注: 引用声明时定义引用类型参数后, 运行时引用参数传递被废弃, 需要在php.ini中增加allow_call_time_pass_reference来开启.
- 后来, 函数的引用类型参数被规定为需要在函数声明时定义, 比如: function func(&$arg);
- 函数返回引用类型, 这种应用方式需要声明函数时, 在函数名前增加&符号, 并且, 在调用时, 要用引用赋值方式
- 带入本题进行查看,
$_GET?$_GET=&$_POST:'flag';
如果有GET存在,那么他将会引用POST的值,然后highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
最后的对比又有和flag的对比,因此我们只要在$_GET给一个flag的参数,然后再$_POST中给一个HTTP_FLAG=flag即可
WBE99
源代码如下:
1 |
|
先介绍几个函数:
array_push()
将 array 当成一个栈,并将传入的变量压入 array 的末尾。array 的长度将根据入栈变量的数目增加。
rand( int $min, int $max)
生成一个随机的[min,max]之间的整数
file_put_contents( string $filename, mixed $data[, int $flags = 0[, resource $context]] )
— 将一个字符串写入文件
- filename:要被写入数据的文件名。
- data要写入的数据。类型可以是 string,array 或者是 stream 资源(如上面所说的那样)。
- 如果 data 指定为 stream 资源,这里 stream 中所保存的缓存数据将被写入到指定文件中,这种用法就相似于使用 stream_copy_to_stream() 函数。
- 参数 data 可以是数组(但不能为多维数组),这就相当于 file_put_contents($filename, join(‘’, $array))。
本题要通过最后一句来进行flag的读取,file_put_contents()
会将GET的作为文件名,将POST的content写入n中,因此我们只需要传入n=1.php,然后再content中传入我们想执行的php代码即可,最后访问1.php即可得到flag
WBE100
源代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-21 22:10:28
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\;/", $v2)){
if(preg_match("/\;/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
}
is_numeric
— 检测变量是否为数字或数字字符串,如果是数字或者数字字符串返回TURE,否则返回FALSE- php运算符优先级:因为赋值运算的优先级比AND和OR的高,所以先赋值;比&&和||的低,所以逻辑运算符先执行,先逻辑运算,再赋值
var_dump
— 打印变量的相关信息
payload:?v1=1&v2=var_dump($ctfshow)&v3=;
成功读取$flag_is_281084bd0x2dfbc20x2d490f0x2db7d10x2d9bcfb1fdc203
注意此时flag需要将后面那一串字符串中的0x2d转为-后,包上ctfshow后提交
web101
源代码如下:
1 |
|
在本题中,可以看到v2和v3都被过滤的比较狠,所以我们需要使用反射类来进行本题的求解
- 什么是反射
反射在每个面向对象的编程语言中都存在,它的主要目的就是在运行时分析类或者对象的状态,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。 反射是操纵面向对象范型中元模型的 API,可用于构建复杂,可扩展的应用。反射在日常的 Web 开发中其实用的不多,更多的是在偏向底层一些的代码中,比如说框架的底层中依赖注入、对象池、动态代理、自动获取插件列表、自动生成文档以及一些设计模式等等,都会大量运用到反射技术。
PHP 的反射 API 很多,但是常用的一般都是 ReflectionClass 和 ReflectionMethod
- 什么是反射
- ReflectionClass
它可以用来获取类的信息:- ReflectionClass::getMethods 获取方法的数组
- ReflectionClass::getName 获取类名
- ReflectionClass::hasMethod 检查方法是否已定义
- ReflectionClass::hasProperty 检查属性是否已定义
- ReflectionClass::isAbstract 检查类是否是抽象类(abstract)
- ReflectionClass::isFinal 检查类是否声明为 final
- ReflectionClass::isInstantiable 检查类是否可实例化
- ReflectionClass::newInstance 从指定的参数创建一个新的类实例** 如果没有指定方法的话,就会像题目中默认输出很多东西:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class hacker{
public $hackername = "yn8rt";
const yn8rt='nb666';
public function show(){
echo $this->name,'<br>';
}
}
//有这么一个hacker类,假设我们不知道这个类是干什么用的,我们需要知道类里面的信息,这时候就需要用到ReflectionClass来对类进行反射
//现在我可以通过反射来获取这个类中的方法,属性,常量
//通过反射获取类的信息
$reflection = new ReflectionClass('hacker');//实例化反射对象,映射hacker类的信息
$consts = $reflection->getConstants();//获取所有常量
$props = $reflection->getProperties();//获取所有属性
$methods = $reflection->getMethods();//获取所有方法
var_dump($consts);
var_dump($props);
var_dump($methods);
返回值:
array(1) {
["yn8rt"]=>
string(5) "nb666"
}
array(1) {
[0]=>
&object(ReflectionProperty)#2 (2) {
["name"]=>
string(10) "hackername"
["class"]=>
string(6) "hacker"
}
}
array(1) {
[0]=>
&object(ReflectionMethod)#3 (2) {
["name"]=>
string(4) "show"
["class"]=>
string(6) "hacker"
}
}
* 1.常量 Contants
* 2.属性 Property Names
* 3.方法 Method Names静态
* 4.属性 Static Properties
* 5.命名空间 Namespace
* 6.Person类是否为final或者abstract
* 7.Person类是否有某个方法
- ReflectionMethod
它主要是针对方法的反射:
- ReflectionMethod::invoke 执行
- ReflectionMethod::invokeArgs 带参数执行
- ReflectionMethod::isAbstract 判断方法是否是抽象方法
- ReflectionMethod::isConstructor 判断方法是否是构造方法
- ReflectionMethod::isDestructor 判断方法是否是析构方法
- ReflectionMethod::isFinal 判断方法是否定义 final
- ReflectionMethod::isPrivate 判断方法是否是私有方法
- ReflectionMethod::isProtected 判断方法是否是保护方法 (protected)
- ReflectionMethod::isPublic 判断方法是否是公开方法
- ReflectionMethod::isStatic 判断方法是否是静态方法
- ReflectionMethod::setAccessible 设置方法是否访问
- ReflectionMethod
- ReflectionClass
因此我们可以构造payload:?v1=1&v2=echo new ReflectionClass&v3=;
,但是! 这个题目只能取出出来35位flag,最后一位需要我们使用爆破才可以得到(十六进制)
web102
源代码如下:
1 |
|
题目中含有以下几个函数:
* 1. substr — 返回字符串的子串string substr( string $string, int $start[, int $length] )
* 2. call_user_func — 把第一个参数作为回调函数调用mixed call_user_func( callable $callback[, mixed $parameter[, mixed $...]] )
* 3. file_put_contents — 将一个字符串写入文件int file_put_contents( string $filename, mixed $data[, int $flags = 0[, resource $context]] )
本题是一个特殊的构造,在php语句$v4 = is_numeric($v2) and is_numeric($v3)
中,我们要保证v2是数字才能继续运行下去(由于=的优先级高于and,因此v3任意可控),而从底下call_user_func()
中我们可以知道,v1和s都是可控的。由于题目版本是php7,因此is_numberic只能识别带e的字符串,从而引出了我们这道题目特殊的构造手段:
- 1.使用
<?=\
cat *`;作为恶意代码,使用base64加密后,得到
PD89YGNhdCAqYDs=由于等于号为补位符号,因此可以删去,使用bin2hex得到
5044383959474e6864434171594473,为一个只有字母e的数字字符串,因此这串字符可以通过
is_numeric的检测顺利传入 最终payload:
?v2=215044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.phpPOST:
v1=hex2bin`
web103
源代码如下:
1 |
|
上一问payload还可以打通
web104
源代码如下:
1 |
|
做了半天发现出不来,结果是v1 v2地址放反了
没难度,直接传俩相同的即可
某些特殊的字符加密之后以0e开,php会将其当作科学计数法处理从而判定相等
1 | 10932435112: 0e07766915004133176347055865026311692244 |
web105
源代码如下:
1 |
|