php弱类型

题目:php是世界上最好的语言1

介绍:php是世界上最好的语言网址,(http://way.nuptzj.cn/php/index.php)

1,我们打开页面,说是   Can you authenticate to this website? index.txt,把index.php改成index.txt,然后我们可以看到了php代码。

2,php代码:<?php if(eregi("hackerDJ",$_GET[id])) { echo("<p>not allowed!</p>"); exit(); } $_GET[id] = urldecode($_GET[id]); if($_GET[id] == "hackerDJ") { echo "<p>Access granted!</p>"; echo "<p>flag: *****************} </p>"; } ?>   ,这道题目的问题在于urldecode(),我们可能认为传递过来的$_GET[id]没有进行url编码,但是实际上已经经过了url的编码。那么这道题目只需要将id=hackerDJ进行两次url编码即可。

题目:php是世界上最好的语言2

介绍:php是世界上最好的语言,这道题考察php弱类型,网址(http://45.63.58.62:8088/xedni.php

1,首先我们查看源代码,可恶意看到php代码:<?php if(isset($_GET["password"]) && md5($_GET["password"]) == "0") echo file_get_contents("/opt/flag.txt"); else echo file_get_contents("xedni.php"); ?> ,我们看到是两个   ==  ,(在php里面   ==   比较只比较值,不同类型会转换为同一类型比较。要比较类型用   ===   ,必须值和类型都一样才为true)

2,然后就是md5怎么得到0的问题,我们知道这个知识点下面就知道怎么做了,我们直接在百度上面找(s878926199a、240610708、QNKCDZO、aabg7XSs、aabC9RqS这几个是我找的,可以用),现在都解决了,

3,我们在原页面输入:?password=s878926199a,这样就能够得到flag了。

接着再给你们来几个这样的题

题目:天网管理系统

介绍:网址(http://ctf5.shiyanbar.com/10/web1/)

1,打开网址后,里面用户名和密码都是admin,点击“登入系统”也没用。做web的php题如果知道源代码就事半功倍,先右键查看源代码,得到先查看源代码,发现<!-- $test=$_GET['username']; $test=md5($test); if($test=='0') -->,

2,这里要求我们输入一个字符串,经过md5后等于0,这是考验php弱类型。这里我提供4个都可以通过的值:240610708、QNKCDZO、aabg7XSs、aabC9RqS

3,只要在用户名那里输入上面4个值中的任意一个,就会得到提示:/user.php?fame=hjkleffifer4,毫无疑问,我们访问一下,可以看到代码:$unserialize_str = $_POST['password']; $data_unserialize = unserialize($unserialize_str); if($data_unserialize['user'] == '???' && $data_unserialize['pass']=='???'){ print_r($flag); } #伟大的科学家php方言道:成也布尔,败也布尔。 回去吧骚年, 这代码不难懂,就是把post提交的password值经过"反序列化"(不懂的百度吧,搜一下php手册关于unserialize()函数的知识)得到一个数组,要求数组里的user和pass都满足就打印flag,这里由于我们不知道两处???到底是什么,我们只得另辟途径,从php弱类型入手,

5,bool类型的true跟任意字符串可以弱类型相等,而当代码中存在unserialize()的时候,我们可以构造bool类型,来达到欺骗。现在我们要的是一个数组,2个元素,分别是user和pass,而且值都是bool类型的true,于是我们得到  a:2:{s:4:"user";b:1;s:4:"pass";b:1;},这是反序列化,这里我详细解释一下吧,

以后就不解释了(a代表array,s代表string,b代表bool,而数字代表个数/长度),所以这里的a代表数组array,2代表有两个参数 user和pass,s代表user是字符串,4,代表user字符串长度是4,b代表是bool类型的,1代表是真。这里面不同的类型用:和;分割开。6,返回最开始的网页,输入上面写的账号密码,登入即可得到flag。

说到反序列化,我又想起来一个题

题目:PHP反序列化

介绍:网址(http://115.28.150.176/php1/index.php)(不知道这个网址现在怎么打不开了,你们知道题型就好)1,这个我们首先会看到代码,<?php class just4fun { var $enter; var $secret; } if (isset($_GET['pass'])) { $pass = $_GET['pass']; if(get_magic_quotes_gpc()){ $pass=stripslashes($pass); } $o = unserialize($pass); if ($o) { $o->secret = "*"; if ($o->secret === $o->enter) echo "Congratulation! Here is my secret: ".$o->secret; else echo "Oh no... You can't fool me"; } else echo "are you trolling?"; } ?>   

声明了一个类,这个类里面包含有$enter$secret两个成员,先把传入的$pass参数反序列化,并传参给$o。如果$o->secret === $o->enter,那么久输出所谓的秘密,也就是o->secret。

2,首先获取我们传入的参数,进行反序列化;给$o中的secret赋值;比较$o->secret和$o->enter是否相等。注意这里是 '==='。3,在 PHP 中普通的传值赋值行为有个例外就是碰到对象 object 时,在 PHP 5 中是以引用赋值的,除非明确使用了 clone 关键字来拷贝,PHP 支持引用赋值,使用“$var = &$othervar;”语法。引用赋值意味着两个变量指向了同一个数据,没有拷贝任何东西。4,知道上面所说的,我们就可以把上面的代码改一下了:<?php class just4fun { var $enter; var $secret; } $o = new just4fun(); $o->enter = &$o->secret; //这里是重点。我们使用引用传参的特点,让$o->secret的值和$o->enter的值,这样两个变量就永远相等了 echo serialize($o); ?>

5,序列化字符串为: O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;},自己在本地运行代码得到下面图

6,然后把这些复制下来提交后得到flag:nctf{serialize_and_unserialize}。

ps:详细请参考(http://115.159.210.46/archives/19.html),我也是参考的这个。

原文地址:https://www.cnblogs.com/Oran9e/p/6127812.html