【Writeup】Boston Key Party CTF 2015(部分题目)

假期试着做了一下这场美国的CTF比赛,无奈题目看了一遍都没什么想法,,只好等比赛结束再学习了。在这里总结一下通过此次比赛学到的姿势。

以下是六道php代码审计题目。

ial

I don‘t think that sha1 is broken. Prove me wrong.

代码如下:

<html><head><title>level1</title><link rel='stylesheet' href='style.css' type='text/css'></head><body><?phprequire 'flag.php';if (isset($_GET['name']) and isset($_GET['password'])) {if ($_GET['name'] == $_GET['password'])print 'Your password can not be your name.';else if (sha1($_GET['name']) === sha1($_GET['password']))die('Flag: '.$flag);elseprint '<p class="alert">Invalid password.</p>';}?><section class="login"><div class="title"><a href="./index.txt">Level 1</a></div><form method="get"><input type="text" required name="name" placeholder="Name"/><br/><input type="text" required name="password" placeholder="Password" /><br/><input type="submit"/></form></section></body></html>分析代码逻辑,发现GET了两个字段name和password,获得flag要求的条件是:name != password & sha1(name) == sha1(password),乍看起来这是不可能的,其实可以利用sha1()函数的漏洞来绕过。如果把这两个字段构造为数组,如:?name[]=a&password[]=b,这样在第一处判断时两数组是不同的,但在第二处判断时由于sha1()函数无法处理数组这一类型,会报错并返回false,if条件成立,获得flag。

经验证md5()函数同样存在此漏洞。

测试截图:

2.Symphony

A less than four characters number, bigger than 999? Maybe the bug is elsewhere.

代码如下:

<html><head><title>level2</title><link rel='stylesheet' href='style.css' type='text/css'></head><body><?phprequire 'flag.php';if (isset($_GET['password'])) {if (is_numeric($_GET['password'])){if (strlen($_GET['password']) < 4){if ($_GET['password'] > 999)die('Flag: '.$flag);elseprint '<p class="alert">Too little</p>';} elseprint '<p class="alert">Too long</p>';} elseprint '<p class="alert">Password is not numeric</p>';}?><section class="login"><div class="title"><a href="./index.txt">Level 2</a></div><form method="get"><input type="text" required name="password" placeholder="Password" /><br/><input type="submit"/></form></section></body></html>这个相对简单,只要脑洞够大,能想到数字还能用 1e9 这样的形式来表示。。。

3.Northeastern Univ.

Of course, a timing attack might be the answer, but I’m quite sure that you can do better than that.

代码如下:

<html><head><title>level3</title><link rel='stylesheet' href='style.css' type='text/css'></head><body><?phprequire 'flag.php';if (isset($_GET['password'])) {if (strcmp($_GET['password'], $flag) == 0)die('Flag: '.$flag);elseprint '<p class="alert">Invalid password.</p>';}?><section class="login"><div class="title"><a href="./index.txt">Level 3</a></div><form method="get"><input type="text" required name="password" placeholder="Password" /><br/><input type="submit"/></form></section></body></html>乍看也算是个比较严密的验证逻辑,但正如第一题一样,strcmp()函数也只能处理字符串参数,传个数组进去就能返回false,又由于它与0的比较用的是==而非===(允许类型转换后比较),就满足了这个 if 的条件。Payload:?password[]=a

4.Museum of Fine Arts Because cryptography is hard, we only implemented a hand-made PRNG. What could possibly go wrong?

代码如下:

<html><head><title>level4</title><link rel='stylesheet' href='style.css' type='text/css'></head><body><?phpsession_start(); require 'flag.php';if (isset ($_GET['password'])) {if ($_GET['password'] == $_SESSION['password'])die ('Flag: '.$flag);elseprint '<p class="alert">Wrong guess.</p>';}// Unpredictable seedmt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000));?><section class="login"><div class="title"><a href="./index.txt">Level 4</a></div><ul class="list"><?phpfor ($i=0; $i<3; $i++)print '<li>' . mt_rand (0, 0xffffff) . '</li>';$_SESSION['password'] = mt_rand (0, 0xffffff);?></ul><form method="get"><input type="text" required name="password" placeholder="Next number" /><br/><input type="submit"/></form></section></body></html>最初看完以后感觉不可做,莫非真要分析出rand()函数的规律?!但是那就不是CTF的难度了吧。。。后来发现如果将session手动清除掉,然后password字段也提交为空,不就可以绕过了嘛,也是蛮笨的。。。

问:一只小狗在沙漠中旅行,结果死了,问他是怎么死的?

【Writeup】Boston Key Party CTF 2015(部分题目)

相关文章:

你感兴趣的文章:

标签云: