世安杯 型別 writeup
阿新 • • 發佈:2018-12-15
開啟題目頁面後先出現的程式碼
// An highlighted block
<?php
show_source(__FILE__);
$a=0;
$b=0;
$c=0;
$d=0;
if (isset($_GET['x1']))
{
$x1 = $_GET['x1'];
$x1=="1"?die("ha?"):NULL;
switch ($x1)
{
case 0:
case 1:
$a=1;
break;
}
}
$x2=(array)json_decode(@$_GET['x2']);
if(is_array($x2)){
is_numeric(@$x2["x21"])?die("ha?"):NULL;
if(@$x2["x21"]){
($x2["x21"]>2017)?$b=1:NULL;
}
if(is_array(@$x2["x22"])){
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?");
$p = array_search ("XIPU", $x2["x22"]);
$p===false?die("ha?"):NULL;
foreach($x2["x22"] as $key=>$val){
$val==="XIPU"?die("ha?"):NULL;
}
$c=1;
}
}
$x3 = $_GET['x3'];
if ($x3 != '15562') {
if (strstr($x3, 'XIPU')) {
if (substr(md5($x3),8,16) == substr (md5('15562'),8,16)) {
$d=1;
}
}
}
if($a && $b && $c && $d){
include "flag.php";
echo $flag;
}
?>
---------------------
依據程式碼可得需要a,b,c,d都要為1的時候,才可以得到flag。
先來看第一段程式碼
// A code block
var foo = 'bar';
// An highlighted block
if (isset($_GET['x1']))
{
$x1 = $_GET['x1'];
$x1=="1"?die("ha?"):NULL;
switch ($x1)
{
case 0:
case 1:
$a=1;
break;
}
}
die是php的一個函式,相當於exit()就是是輸出的作用,但是輸出完 會退出本指令碼,所以我們要避免輸出die。 就可得x1需要等於0.
// A code block
var foo = 'bar';
// An highlighted block
$x2=(array)json_decode(@$_GET['x2']);
if(is_array($x2)){
is_numeric(@$x2["x21"])?die("ha?"):NULL;
if(@$x2["x21"]){
($x2["x21"]>2017)?$b=1:NULL;
}
if(is_array(@$x2["x22"])){
if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?");
$p = array_search("XIPU", $x2["x22"]);
$p===false?die("ha?"):NULL;
foreach($x2["x22"] as $key=>$val){
$val==="XIPU"?die("ha?"):NULL;
}
$c=1;
}
}
首先是json_decode解碼,詳情請看 http://php.net/manual/en/function.json-decode.php 鍵x21的值不可為純數字,但是需要大於2017,所以只要讓鍵x21的值為2018a就可以。因為php中大於小於是不會判斷型別是否相同,所以前面是數字就可以通過前面並且大於2017.
x22裡面需要是一個數組,且有兩個元素,第一個元素也需要是陣列,利用array_search有如下特性:
// A code block
var foo = 'bar';
// An highlighted block
$x3 = $_GET['x3'];
if ($x3 != '15562') {
if (strstr($x3, 'XIPU')) {
if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) {
$d=1;
}
}
}
最後的x3是因為15562的MD5是0e開頭,在弱比較的時候會判斷為0。然後php的MD5是32位的,所以只需要找到前面XIPU加上後面是的數字經過MD5後也為0e開頭即可。附上大神指令碼。
// A code block
var foo = 'bar';
// An highlighted block
import hashlib
for i in xrange(1000000):
s = 'XIPU' + str(i)
mymd5 = hashlib.md5()
mymd5.update(s)
mymd5 = mymd5.hexdigest()
flag = 1
if mymd5[8:10] == '0e':
for j in mymd5[10:24]:
if j.isalpha():
flag = 0
break
if flag == 1:
print s
break