首页
关于
时光机
Github
更多
文章归档
友情链接
Search
1
live/msn等微软绝版邮箱详细的注册教程
4,661 阅读
2
欢迎使用 Typecho
3,141 阅读
3
一个功能强大又好用的RSS订阅器:FreshRSS安装教程
2,486 阅读
4
使用Aria2下载BT磁力的时候,速度慢或者没速度的解决方法
2,164 阅读
5
VPS使用BaiduPCS-Go高速下载百度网盘的文件,支持上传/离线下载等操作
1,985 阅读
默认分类
主机教程
登录
Search
标签搜索
no tag
暂无标签
短篇文学
OI 成都外国语学校 日记
短篇文学 封面
干货教程
typecho
python
eve
程序源码源码星泽V社 封面
星泽V社 封面
linux
OI
PHP
mysql
实用软件
kali
OI 题解 成都外国语学校
漏洞利用
Java
Typecho
累计撰写
2,547
篇文章
累计收到
3
条评论
首页
栏目
默认分类
主机教程
页面
关于
时光机
Github
文章归档
友情链接
搜索到
6
篇与
的结果
2023-08-27
PHP获取用户的真实ip地址
本文介绍如何使用PHP获取用户的真实ip,并且写入到txt文档首先创建一个php文件,将下面代码放到PHP文件中 然后在连接起来就可以了本文作者:小小孩子们,转载请注明本文链接https://www.xxhzm.cn/index.php/archives/14/转载请注明原文地址
2023年08月27日
265 阅读
0 评论
0 点赞
2018-11-23
php生成excel文件的简单方法
前言什么叫简单,把数据库的数据导入到excel就行了, 这个就是简单了代码如下: 版权属于:逍遥子大表哥本文链接:https://blog.bbskali.cn/523.html按照知识共享署名-非商业性使用 4.0 国际协议进行许可,转载引用文章应遵循相同协议。
2018年11月23日
222 阅读
0 评论
0 点赞
2018-05-25
记一次对PHP代码加密的破解
题记 fJK9auN9auN9aucvAFf3bgQ1+lh0TGzVCcKlGnohCc8VHrIVI/qBPDK9aJ81Pvm1H/IVI/1WfJK9Pvm1auN9arzBPD81PD81aJ81Zrt9PvN9Pvm1aJ8WfJ81auN9aJ81ar1BPD81aJ81aum1ZG1V+npjAndW+JTfTsdIYMBc5MQDtcNSnncuMQtpZ4fNAviEMr81eViVQsABi0A9asiQaMK6ABt0ihfobJQa5J2qyvDVHrANeBiJtnTFGJsZGDoiPBKenQfPQhQMQcXTMgh/Y4tsTgAWyMd7+lcS+RNobViDACTRwFsEauJjaveci0bq5GOUfjBdZGBLTgiO+RisZrt9aum1PvN9aumd54Q4YM1WfJK9auN9auN9arBLuedjTChcyCfsIrbSH/K2YMsOC4iU+gTdTjp1yFmV51DZbgQoAMsjTGmVYCX1yFN3TMcXyM1SblX1fvOir/tDyCtOTPDBCcN9nct+fRtdAlosfcDLueWBY4KSAlQSAuDBCcN9nct+f4iU+Vts+VeVCPOir/tvTMpBTlKs+Mhd+0DBCcN9nct+fRis+gtB+4Q2YMsSfcDLueWBb4cDbFisbVTsb/mKIrtXwFNWbhOVb4QjAgQjfcDLueWBb4cDbFisbVTsbVNUbVez9GtXwFNWbhOVblKjArAA51DZfFi2AFNcb4Qj+Mhd+rmKIrtXwFNWbhOVTMcXyM1VCPOir/tv+Ct1ACisb/mKIrtXwFNWbhOV+Mhd+FQvTCIVCPOir/tv+Ct1blhvbjmKIrtXwFNWbhOV+Mhd+FNXbRaVCPOir/t2YMsObRQ/ygQ0ArmKIrtDyCtOTPOir/t2YMsOYgKBwGmKIrt0+4pDTMpD51DZflcXyMoDwCNsIuDzIBXnPn1/51DZfFi/9PmLueWBb4QSTlhjbghp9MQqbloUTlnWI/1/HrtvTMpBTlKs+Mhd+/BLueWBTMcXyMoSAMDKY4Kc+VeWfFis+gtXbVfXwGBLuedg+RfsYMiWZrtvTMpBYCfjYCBzYCazflQ2YMsOTlKB+4tUZeDZw1DZfFi2AFNs+Mhd+FtUIuDzflQ2YMsOTlKB+4tU51DZfFi2AFmz9GNSTCbzb4cDbrzBb4cDbFisbVTsb/1Bb4cDbFisbVTsbVNUbVeOAFfcTG1Bb4cDbFQvTCIOfFi2AFN1YCivZPOir/tv+Ct1HPpBTMfcTjmKIlTX+Fis51DZfFi2AFm29Vis+gt2YMsOZrtv+Ct1TMcXyMoD+j1Bb4cDbFQvTCf2YMsOHrt2YMsObRQ/ygQ0Ar1B+Mhd+lfUTFBOflcXyMoDwCNsZPOirVDir02sY4XUIrbir0ovYRfdbFezAFs1TPD/AlQqArK6YCTXb4ijyCNDI0qirghOTCfDZh1Vo97aq+4LD868kO7KS+Izfv2sY4XUIrts+Mhd+lpc+POLTMiW+jmVIH04HH9fSyyRWOUiIrbLTMiW+jmBTMcXyMoSAMDL54Q0yl8zfjrqK/jRWOUij6w1RrmV54Q0yl8zfFi/5v2sY4XUIrbzS9TbClpbClERWOUiO8gpdOHZ5/moaumsChoSChoSSiueS86pD851WOLRci79RK9ZU9LIS7w/vLCiOE5XCrbd54oUY4hDyMKSHgXjTMYKCrAXTlcd+/p1yFNbfvO8HRi0bgs1AuqV51==恩恩,这是什么鬼!查了下$OOO0O0O00=__FILE__;$OOO000000是用来加密的,那么我们该如何处理这个问题呢?借助伟大的google粑粑。我找到了一个解密网站。微盾解密:https://yoursunny.com/p/PHP-decode/我们打开网站,复制上面的代码,然后点解解密即可。版权属于:逍遥子大表哥本文链接:https://blog.bbskali.cn/212.html按照知识共享署名-非商业性使用 4.0 国际协议进行许可,转载引用文章应遵循相同协议。
2018年05月25日
251 阅读
0 评论
0 点赞
2018-05-21
认识局部变量 全局变量 静态变量
局部变量对于局部变量,只能在引用的函数中使用。而结束函数后,该变量也失去了意义。全局变量顾名思义,全局变量就是在整个项目中都可以进行调用。但需要注意的是,在函数中是不能直接进行调用的,我们需要关键词globla进行声明就就可以了。静态变量静态变量,其值是不会发生变化。通常用关键词static定义静态变量。实例代码 版权属于:逍遥子大表哥本文链接:https://blog.bbskali.cn/195.html按照知识共享署名-非商业性使用 4.0 国际协议进行许可,转载引用文章应遵循相同协议。
2018年05月21日
214 阅读
0 评论
0 点赞
2018-05-10
ThinkPHP 框架SQL注入技术分析
简要描述ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企 业应用开发而诞生的。ThinkPHP从诞生的12年间一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码 的同时,也注重易用性。目前ThinkPHP框架是国内使用量最大的框架之一,国内用户量众多。近日,360企业安全 集团代码卫士团队安全研究人员发现该框架V5.1.7-V5.1.8 版本在底层数据处理驱动解析数据的时候存在缺陷,一 定场景下,攻击者可以通过构造恶意数据包利用SQL注入的方式获取用户数据库内容。360企业安全集团代码卫士 团队已第一时间和ThinkPHP团队进行沟通修复,建议相关用户及时更新官方发布的新版本。漏洞分析:注:改漏洞ThinkPHP官方团队在报送当天(2018-04-06)紧急进行了修复处理,详细请参考:https://github.com/top-think/framework/commit/39bb0fe6d50ee77e0779f646b10bce08c442a5e3以下漏洞分析基于ThinkPHP V5.1.8(2018-04-05未更新版)这里我们主要跟进分析执行update操作的过程。为了方便理解,先直接放出函数的调用栈。Mysql.php:200, think\db\builder\Mysql->parseArrayData() Builder.php:147, think\db\Builder->parseData() Builder.php:1139, think\db\Builder->update() Connection.php:1149, think\db\Connection->update() Query.php:2571, think\db\Query->update() Index.php:18, app\index\controller\Index->testsql() Container.php:285, ReflectionMethod->invokeArgs() Container.php:285, think\Container->invokeReflectMethod() Module.php:139, think\route\dispatch\Module->run() Url.php:31, think\route\dispatch\Url->run() App.php:378, think\App->think\{closure}() Middleware.php:119, call_user_func_array: {C:\wamp64\www\think518\thinkphp\library\think\Middleware.php:119}() Middleware.php:119, think\Middleware->think\{closure}() Middleware.php:74, call_user_func: {C:\wamp64\www\think518\thinkphp\library\think\Middleware.php:74}() Middleware.php:74, think\Middleware->dispatch() App.php:399, think\App->run() index.php:21, {main}()缺陷关键点为thinkphp解析用户传递过来的Data可控,且可以绕过安全检查。根据文件 Connection.php:1149, think\db\Connection->update() 第1102行update函数分析,这个函数的主要功 能是用于执行update SQL语句。 //Connection.php:1149, think\db\Connection->update() public function update(Query $query) { $options = $query->getOptions(); if (isset($options['cache']) && is_string($options['cache']['key'])) { $key = $options['cache']['key']; } $pk = $query->getPk($options); $data = $options['data']; if (empty($options['where'])) { // 如果存在主键数据 则自动作为更新条件 if (is_string($pk) && isset($data[$pk])) { $where[$pk] = [$pk, '=', $data[$pk]]; if (!isset($key)) { $key = $this->getCacheKey($query, $data[$pk]); } unset($data[$pk]); } elseif (is_array($pk)) { // 增加复合主键支持 foreach ($pk as $field) { if (isset($data[$field])) { $where[$field] = [$field, '=', $data[$field]]; } else { // 如果缺少复合主键数据则不执行 throw new Exception('miss complex primary data'); } unset($data[$field]); } } if (!isset($where)) { // 如果没有任何更新条件则不执行 throw new Exception('miss update condition'); } else { $options['where']['AND'] = $where; $query->setOption('where', ['AND' => $where]); } } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { $key = $this->getCacheKey($query, $options['where']['AND'][$pk]); } // 更新数据 $query->setOption('data', $data); // 生成UPDATE SQL语句 $sql = $this->builder->update($query); $bind = $query->getBind(); if (!empty($options['fetch_sql'])) { // 获取实际执行的SQL语句 return $this->getRealSql($sql, $bind); } // 检测缓存 $cache = Container::get('cache'); if (isset($key) && $cache->get($key)) { // 删除缓存 $cache->rm($key); } elseif (!empty($options['cache']['tag'])) { $cache->clear($options['cache']['tag']); } // 执行操作 $result = '' == $sql ? 0 : $this->execute($sql, $bind); if ($result) { if (is_string($pk) && isset($where[$pk])) { $data[$pk] = $where[$pk]; } elseif (is_string($pk) && isset($key) && strpos($key, '|')) { list($a, $val) = explode('|', $key); $data[$pk] = $val; } $query->setOption('data', $data); $query->trigger('after_update'); }return $result; 刚刚我们将用户可控的 $data set到 $query['options'] 中,这里我们先获取 $query['options'] 内容到 $options 中,然后对Data进行解析 $data = $this->parseData($query, $options['data']);第1146行, $query->setOption(‘data’, $data); 这里将用户传递的 $data set到 $query 变量中,为下一步的生 成 UPDATE SQL语句做准备,执行 $sql = $this->builder->update($query); 语句,重点马上要来了,跟进Builder.php:1139, think\db\Builder->update() 函数 //Builder.php:1139, think\db\Builder->update() public function update(Query $query) { $options = $query->getOptions(); $table = $this->parseTable($query, $options['table']); $data = $this->parseData($query, $options['data']); if (empty($data)) { return ''; } foreach ($data as $key => $val) { $set[] = $key . ' = ' . $val; } return str_replace( ['%TABLE%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'], } [ $this->parseTable($query, $options['table']), implode(' , ', $set), $this->parseJoin($query, $options['join']), $this->parseWhere($query, $options['where']), $this->parseOrder($query, $options['order']), $this->parseLimit($query, $options['limit']), $this->parseLock($query, $options['lock']), $this->parseComment($query, $options['comment']), ], $this->updateSql);刚刚我们将用户可控的 $data set到 $query['options'] 中,这里我们先获取 $query['options'] 内容到 $options 中,然后对Data进行解析 $data = $this->parseData($query, $options['data']);//Builder.php:147, think\db\Builder->parseData() protected function parseData(Query $query, $data = [], $fields = [], $bind = [], $suffix = '') { if (empty($data)) { return []; } $options = $query->getOptions(); // 获取绑定信息 if (empty($bind)) { $bind = $this->connection->getFieldsBind($options['table']); } if (empty($fields)) { if ('*' == $options['field']) { $fields = array_keys($bind); } else { $fields = $options['field']; } } $result = []; foreach ($data as $key => $val) { $item = $this->parseKey($query, $key); if ($val instanceof Expression) { $result[$item] = $val->getValue(); continue; } elseif (!is_scalar($val) && (in_array($key, (array) $query->getOptions('json')) || 'json' == $this->connection->getFieldsType($options['table'], $key))) { $val = json_encode($val); } elseif (is_object($val) && method_exists($val, '__toString')) { // 对象数据写入 $val = $val->__toString(); } if (false !== strpos($key, '->')) { list($key, $name) = explode('->', $key); $item = $this->parseKey($query, $key); $result[$item] = 'json_set(' . $item . ', \'$.' . $name . '\', ' . $this- >parseDataBind($query, $key, $val, $bind, $suffix) . ')'; } elseif (false === strpos($key, '.') && !in_array($key, $fields, true)) { if ($options['strict']) { throw new Exception('fields not exists:[' . $key . ']'); } } elseif (is_null($val)) { $result[$item] = 'NULL'; } elseif (is_array($val) && !empty($val)) { switch ($val[0]) { case 'INC': $result[$item] = $item . ' + ' . floatval($val[1]); break; case 'DEC': $result[$item] = $item . ' - ' . floatval($val[1]); break; default: $value = $this->parseArrayData($query, $val); if ($value) { $result[$item] = $value; } } } elseif (is_scalar($val)) { // 过滤非标量数据 $result[$item] = $this->parseDataBind($query, $key, $val, $bind, $suffix); } } return $result; } //Mysql.php:200, think\db\builder\Mysql->parseArrayData() protected function parseArrayData(Query $query, $data) { list($type, $value) = $data; switch (strtolower($type)) { case 'point': $fun = isset($data[2]) ? $data[2] : 'GeomFromText'; $point = isset($data[3]) ? $data[3] : 'POINT'; //在第115行,通过 foreach ($data as $key => $val) 处理 $data ,然后解析 $key 保存到 $item 变量中去,之后 执行下面的判断逻辑,想要合理地进入各个判断分支,就要巧妙的构造 $key 和 $value 也就是 $data 的值。紧接 着我们进入漏洞触发点 $value = $this->parseArrayData($query, $val); ,跟进函数 $value = $this- >parseArrayData($query, $val); //Mysql.php:200, think\db\builder\Mysql->parseArrayData() protected function parseArrayData(Query $query, $data) { list($type, $value) = $data; switch (strtolower($type)) { case 'point': $fun = isset($data[2]) ? $data[2] : 'GeomFromText'; $point = isset($data[3]) ? $data[3] : 'POINT'; if (is_array($value)) { $value = implode(' ', $value); } $result = $fun . '(\'' . $point . '(' . $value . ')\')';//需要简单的构造一下sql语 break; default: }这里 $type 、 $value 和 $data 均为可控值,那么函数返回的 $result 也就是可控的。回到上一个 Builder.php 文件中,将返回的结果赋值到 $result[$item] = $value; 中,之后的生成SQL语句和常见的流程没有任何差别不在 展开具体分析。版权属于:逍遥子大表哥本文链接:https://blog.bbskali.cn/129.html按照知识共享署名-非商业性使用 4.0 国际协议进行许可,转载引用文章应遵循相同协议。
2018年05月10日
213 阅读
0 评论
0 点赞
1
2