bugku 备份是个好习惯
bugku 备份是个好习惯
题目:备份是个好习惯
打开题目看到
d41d8cd98f00b204e9800998ecf8427ed41d8cd98f00b204e9800998ecf8427e
没有思路
根据题目提示:备份
联想到目录扫描看看有没有备份文件(备份文件的后缀是.bak)
在linux使用
dirb “ http://171.80.2.169:18691/ “ -X .bak
指令扫描后缀是.bak的文件
执行结果
DIRB v2.22
By The Dark Raver
START_TIME: Thu Apr 9 19:17:59 2026
URL_BASE: http://171.80.2.169:18691/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
EXTENSIONS_LIST: (.bak) | (.bak) [NUM = 1]
GENERATED WORDS: 4612
—- Scanning URL: http://171.80.2.169:18691/ —-
http://171.80.2.169:18691/index.php.bak (CODE:200|SIZE:378)
看到存在 index.php.bak
访问
http://171.80.2.169:18691/index.php.bak
自动下载文件,打开看到
开始审计代码
include_once “flag.php”;
意思是加载flag.php 将flag.php嵌入到当前脚本执行
ini_set(“display_errors”, 0);
意思是设置display_errors的值是0(display_errors时控制是否输出报错信息的,值是0时,不会在页面上输出报错信息)
$str = strstr($_SERVER[‘REQUEST_URI’], ‘?’);
意思是定义变量 str 他的值是截取当前请求的路径?之后的值包括?
比如我请求http://171.80.2.169:18691/index.php?a=1&b=2
那现在变量str值就是?a=1&b=2
$str = substr($str,1);
意思是截取变量str字符串第一位之后的值当作变量str新的值
例如原始是$str=”?a=1&b=2”
更新以后就是$str=”a=1&b=2”
$str = str_replace(‘key’,’’,$str);
意思是把变量str里面的key替换为空
例如$str=abkeyc 会变成$str=abc
parse_str($str);
是把$str的值解析成变量
例如$str=”a=1&b=2”
现在就有两个新的变量是
$a=1 $b=2
echo md5($key1);
意思是输出md5计算过后的变量key1的值
echo md5($key2);
意思是输出md5计算过后的变量key2的值
if(md5($key1) == md5($key2) && $key1 !== $key2){
意思是如果变量key1的值md5计算以后等于变量key2的值经过md5计算,并且key1的值不等于key2的值,那么执行大括号里面的代码
echo $flag."取得flag";
意思是输出变量flag的值,并输出 取得flag (这行代码就是在大括号里面的代码)
虽然这里的变量flag没有在之前的代码里面声明过是多少
但是还记得代码第一行include_once “flag.php”;
引入了一个叫flag.php的代码,所以变量flag的值应该是在这个里面被定义的
这里猜测flag.php里面的内容是 (只是猜测,无实际作用)
整理一下思路
首先:要他输出flag就必须要服务器执行 echo $flag.”取得flag”;
要服务器执行 echo $flag.”取得flag”;就必须要(md5($key1) == md5($key2) && $key1 !== $key2)成立
要(md5($key1) == md5($key2) && $key1 !== $key2)成立就必须要变量key1的值md5计算以后等于变量key2的值经过md5计算,并且key1的值不等于key2的值
这里面有三个问题要解决
1:
变量key1和key2都是在前面没有提到过的
所以只能通过 parse_str($str);
是把$str的值解析成变量
也就是在$str里面定义key1和key2
我们就要构造 ?key1=xxxxxx&key2=xxxxxx 这样的值
成功解决第一个问题
2:
前面$str = str_replace(‘key’,’’,$str);
把变量str里面的key值替换空了(可以理解成删掉了)
这个时候 ?key1=xxxxxx&key2=xxxxxx
就变成了?1=xxxxxx&2=xxxxxx 了
但是我们需要的是变量key1和key2,而不是变量1和2
那我们思考一下,如果变量str值是12key1,这里面有一个key所以会变成121
可是当他的值是kkeyey(k + key + ey),这里面其实也只有一个连起来的key,因为k ey被key隔开了,所以不会被替换
那这个时候变量str的值就会变成key,这就得到了我们想要的key
这个是侯我们构造的值就应该是 ?kkeyey1=xxxxxx&kkeyey2=xxxxxx
3:
md5计算只要是值不一样那结果就完全不一样,哪怕只是改变一点原始被计算的值
(不过这句话不够严谨,因为被计算值完全不一样,但是计算结果一样的值也是存在的,而且理论上是很多的,可是很难被找出或计算出)
要是想真的找到这种值,现在没有很好的办法
所以我们不考虑
那么我们怎么办呢,这里注意到md5($key1) == md5($key2这段代码里面使用的是==比较两边的值
搜索信息可以知道==是弱类型比较,在被比较的值可以被转译的时候自动转译,例如
key1=0e123&key2=0e456 (e是科学计数法 3e4就是3乘以10的4次方)
那么他们用==比较的时候是一样的,因为0乘以10的123次方大小和0乘以10的456次方大小是一样的(都是0)
所以我们要找两个值,md5计算以后都是0e开头并且两个值本身不一样
这里常用的有QNKCDZO和240610708
那思路就清晰了
直接传入?kkeyey1=QNKCDZO&kkeyey2=240610708
就可以符合三个要求
在
http://171.80.2.169:18691/index.php连接后面加上?kkeyey1=QNKCDZO&kkeyey2=240610708
http://171.80.2.169:18691/index.php?kkeyey1=QNKCDZO&kkeyey2=240610708
即可看到
0e8304004519934940580242199033910e462097431906509019562988736854flag{eb116ff7d0f2f40def6e9d9c6309ab65}鍙栧緱flag
其中0e830400451993494058024219903391是QNKCDZO经过md5计算后的值
0e462097431906509019562988736854是240610708经过md5计算后的值
flag{eb116ff7d0f2f40def6e9d9c6309ab65} 就是flag
鍙栧緱flag 原本是文本 取得flag 这里因为编码问题显示乱码(无需在意)
取得flag
flag{eb116ff7d0f2f40def6e9d9c6309ab65}
补充知识:为什么flag.php里面有flag,不直接访问flag.php呢,而且index.php和flag.php可以访问到,但是他不显示内容是空白界面呢
因为文件后缀是php的时候,服务器的php解析器会自动尝试解析文件里面的内容
如果是php代码格式就直接运行,不显示;如果本身php代码格式就当作普通文本文件,直接显示给客户端

浙公网安备 33010602011771号