本文为记录个人信安小白的刷题路程,大佬勿喷,也同时希望文章能对您有所帮助

打开靶机,

F12查看,Burp抓包都没有获得什么信息,
使用dirsear扫描网站,

可以看到有flag.php文件,但是没有文件可以通过URL下载,
但是可以看到几乎全是/.git/目录下的文件,推测为git泄露,
使用GitHack工具,
我的是kali虚拟机root模式下下载的,

1
git clone https://github.com/lijiejie/GitHack 

这个支持python3环境,



获得index.php源码文件,下面进行代码审计,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
//过滤伪协议(如 data://, php:// 等)
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
//检查输入是否匹配特定模式(递归正则)
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
//过滤敏感关键词(如 et, na, info 等)
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);//若所有检查通过,则执行用户输入的代码
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>

重点理解第二层检查,这个检查会有字符串直接输入的限制,

1
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))

[a-z,_]+
匹配 1个或多个小写字母或下划线(即函数名,如 a, get_flag, readfile)。
例如:abc, my_func 都符合。
( 和 )
匹配 左括号(和右括号),表示函数调用。
(?R)?
(?R) 表示递归匹配整个正则表达式(即可以嵌套函数())。
? 表示递归部分是可选的(即允许 a()a(b())a(b(c()))等)。
实例:

1
a(b(c()))  // 匹配成功

分解:
a( → 匹配 [a-z,_]+\(
b( → 递归 (?R) 匹配 [a-z,_]+\(
c() → 递归 (?R) 匹配 [a-z,_]+\(\)
最终 a(b(c())) 被替换为空,只剩 ;(如果输入是 a(b(c()));)。

解法一:

构造payload:

1
?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

(1)localeconv()
作用:返回本地化数字和货币格式信息(关联数组)。
关键点:它的返回值是一个数组,且第一个元素是 ‘.’(当前目录)。这个函数默认返回的结果第一个数组元素就是’.’
(2)current(localeconv())
作用:获取数组的第一个元素(即 ‘.’)。
结果:返回 ‘.’(当前目录)。
(3)scandir(current(localeconv()))
作用:扫描当前目录(’.’)并返回文件列表,如:

1
[0 => ".", 1 => "..", 2 => "flag.php", 3 => "index.php"]

(4)array_reverse(scandir(…))
作用:反转数组,使flag.php更容易被next()获取:

1
[0 => "index.php", 1 => "flag.php", 2 => "..", 3 => "."]

(5)next(array_reverse(…))
作用:移动数组指针,返回第二个元素(即 “flag.php”)。
结果:返回 “flag.php”。
(6)highlight_file(next(…))
作用:高亮显示 flag.php 的源代码,直接输出 flag。

获得flag

解法二:

发现其中并没有过滤session_id函数
构造payload:

1
?exp=highlight_file(session_id(session_start()));

并且传入Cookie:PHPSESSID=flag.php(HackBar和Burp都可以)
(1)session_start()
作用:启动PHP Session,如果请求中包含PHPSESSID Cookie,则使用该值作为Session ID
返回值:始终返回 true(但这里不重要,重点是它初始化了 Session)。
(2)session_id()
无参数调用时:返回当前Session ID
session_id() 返回当前 Session ID,即 “flag.php”。
(3)highlight_file()
作用:高亮显示指定文件的源代码(这里用于读取flag.php)。

获得flag