CTF实验吧10-20

天网

第一步看源码

发现一条:


我们可以知道php弱类型中以0e开头的可以满足==0,$test是通过md5加密的,百度一下0e开头的md5哈希字符串,如下:(这一部分可看php审计中的漏洞解析)

QNKCDZO(0e830400451993494058024219903391)

s878926199a(0e545993274517709034328855841020)

s155964671a(0e342768416822451524974117254469)

s214587387a(0e848240448830537924465865611904)

随便挑一个填在用户名中。

得到一条信息:

/user.php?fame=hjkleffifer

内容很明确,这是url一部分

我们把它拼接好:http://ctf5.shiyanbar.com/10//user.php?fame=hjkleffifer

进入后发现信息:

$unserialize_str = $_POST['password'];

$data_unserialize = unserialize($unserialize_str);

if($data_unserialize['user'] == '???' && $data_unserialize['pass']=='???')

{

print_r($flag);

}

伟大的科学家php方言道:成也布尔,败也布尔。

回去吧骚年

这段代码不难懂,就是把post提交的password值经过"反序列化"得到一个数组,要求数组里的user和pass都满足,就打印flag,但是我们无法得知'???'是什么,但是我们可以注意到信息中判断条件使用的为==,也是php弱类型,


bool类型的true跟任意字符串可以弱类型相等的,当代码中存在unserialize或者json_decode的时候,我们可以构造bool类型,来达到欺骗。现在我们构造一个数组,内瀚2个元素,分别是user和pass,都是bool类型的true,于是我们得到

a:2:{s:4:"user";b:1;s:4:"pass";b:1;}

(a代表array,s代表string,b代表bool,而数字代表个数/长度)

讲这些输入登录系统的密码一栏,使用post提交也可以,就可以得到flag了


忘记密码了

点开链接之后,任意输入什么,都会弹框出来

你邮箱收到的重置密码链接为 ./[email protected]&check=???????

于是我们访问以下看一看http://ctf5.shiyanbar.com/10/upload/[email protected]&check=???????

出现了step2的界面,但是马上又回到了原来的界面。可以抓包来看一下

找回密码step2

email:

token:

在包中发现了submit.php,查看一下看看

但是不能访问,不是admin

但是我们可以知道这是vim,会有临时文件,应该没有禁用

一、vim备份文件

默认情况下使用Vim编程,在修改文件后系统会自动生成一个带~的备份文件,某些情况下可以对其下载进行查看;

eg:index.php普遍意义上的首页,输入域名不一定会显示。   它的备份文件则为index.php~

二、vim临时文件

vim中的swp即swap文件,在编辑文件时产生,它是隐藏文件,如果原文件名是submit,则它的临时文件

.submit.swp。如果文件正常退出,则此文件自动删除。

所以我们查看临时文件

访问http://ctf5.shiyanbar.com/10/upload/.submit.php.swp

里面有很多乱码,但还是有两段可读的代码

CREATE TABLE IF NOT EXISTS `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`username` varchar(255) NOT NULL,

`email` varchar(255) NOT NULL,

`token` int(255) NOT NULL DEFAULT '0',

PRIMARY KEY (`id`)

) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

if(!empty($token)&&!empty($emailAddress)){

if(strlen($token)!=10) die('fail');

if($token!='0') die('fail');

$sql = "SELECT count(*) as num from `user` where token='$token' AND email='$emailAddress'";

$r = mysql_query($sql) or die('db error');

$r = mysql_fetch_assoc($r);

$r = $r['num'];

if($r>0){

echo $flag;

}else{

echo "澶辫触浜嗗憖";

}

}

从代码里可以知道,

token初始化为0,但if语句中要让他长度为10,可以置为0000000000

$emailAddress我们可以从刚才的源代码中知道admin的邮箱

所以

http://ctf5.shiyanbar.com/10/upload/[email protected]&token=0000000000


OnceMore

关键码

else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)

{

if (strpos ($_GET['password'], '*-*') !== FALSE)

分析:

要获得一个长度小于8,值大于999999的数

所以要用到科学计数法

并且该数中要包含“-”

单纯在数中加“-”会无意义,使用%00截断后,加上*-*

即:

原url后加入“1e8%00*-*”

有个小问题 你要是在输入框中输入%00是会被转码的变成%2500所以要直接在url中加


Guess Session


session_start();

if (isset ($_GET['password'])) {

if ($_GET['password'] == $_SESSION['password'])

die ('Flag: '.$flag);

else

print '

Wrong guess.

';

}

mt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000));

?>

其实最主要的就在那个判断条件上:if ($_GET['password'] == $_SESSION['password'])

我们只需要在密码什么都不填,并且抓包,把Cookie中的Session删掉不就好了吗,这样等号两端就都是空了

FALSE


if (isset($_GET['name']) and isset($_GET['password'])) {

if ($_GET['name'] == $_GET['password'])

echo '

Your password can not be your name!

';

else if (sha1($_GET['name']) === sha1($_GET['password']))

die('Flag: '.$flag);

else

echo '

Invalid password.

';

}

else{

echo '

Login first!

';

?>

在源代码中,获得flag的核心条件是使$_GET['name'] != $_GET['password']且sha1($_GET['name']) === sha1($_GET['password'])。

把name,password字段构造为数组。 即可使第一个条件成立。 如:?name[]=1&password[]=2

通过查阅得知,sha1函数对参数为数组的情况会反回false 即可使第二个条件成立。

即可得出flag.

你可能感兴趣的:(CTF实验吧10-20)