admin 发布的文章

PHP熊掌ID周级推送


<?php 
ignore_user_abort(true); //后台执行
set_time_limit(0); //无限制
@header("Content-type: text/html; charset=utf-8");
for ($i=0; $i <5000000; $i++) {  
$urls = array(
    'http://www.fxseo.net/index.php/archives/'.rand(1,318).'/', //作者本人的url规则是递增数
);
$api = 'http://data.zz.baidu.com/urls?appid=id值&token=token值&type=batch';
$ch = curl_init();
$options =  array(
    CURLOPT_URL => $api,
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POSTFIELDS => implode("n", $urls),
    CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
$json = json_decode($result,True);
if ($json['remain_batch'] != "0") {
    echo "周级推送剩余配额:".$json['remain_batch']." url:".$urls[0]."nr";
}else{
    echo "已经没有配额了兄弟."."nr";
}
}
 ?>

使用方法:php 文件名.php
这里要说一下 如果cmd输出乱码的话
chcp 65001
或者在php文件加入
system("chcp 65001");


PHP大法好—>安全的代码


0x00 首先

目前在深入的学习PHP中 自己是个学安全的 所以对于代码的安全较为敏感 网站的的漏洞源于代码的漏洞 白盒狗专注代码漏洞挖掘30年
学好代码审计的关键也是写好代码的关键:

  • 了解恶意用户要从哪些入口攻击整个框架
  • 一切输入都是有害的
  • 不要信任任何一个用户
  • 代码的逻辑

0x01 过滤输入

a.验证提交值是否为期望值或者允许值

<html>
<form action="" method="post">
    <input type="radio" name="gender" value="Male">Male<br/>
    <input type="radio" name="gender" value="Female">Female<br/>
    <input type="submit" name="submit" value="submit"><br/>
</form>
</html>
(a):
<?php
if(!empty($_POST))
{
    echo "The user's gender is ".$_POST['gender'].".<br/>";
}
?>
(b):
<?php
if(!empty($_POST))
{
    switch ($_POST['gender'])
    {
        case 'Male':
        case 'Female':
            echo "The user's gender is ".$_POST['gender'].".<br/>";
            break;

        default:
            echo "Invalid input value for gender specified.<br/>";
            break;
    }
}
?>

比较一下(a)(b)两种后台验证 (b)显然确保了正确值 对于处理数据方面显然很重要
b.确认提交类型是否为允许类型

$number_of_nights = (int)$_POST[’num_nights’];
if($num_of_nights == 0)
{
     echo “Error: Invalied number of nights for the room”;
     exit;
}

这种不仅能确认正确的输入 也可以改进系统的安全
c.输入数据库的数据

  • 输入必须使用addslashes()函数
  • stripslashes()用来返回数据的原始形式
  • php.ini文件中开启magic_quotes_gpc(格式化GET
    POST和cookie变量)和magic_quotes_runtime(格式化进入数据库的数据) 自动添加和过滤斜杠

d.其他恶意输入

  • 当用户传递数据给system()和exec()时 必须使用escapeshellcmd()避免任何恶意用户运行系统命令
<?php
        $a = escapeshellcmd($_GET['id']); //1.php?id=sixwhale;ls
        $b = $_GET['id'];
        system("echo $a");//结果(1)
        echo "<p>";
        system("echo $b");//结果(2)
    ?>

结果(1): sixwhale;ls
结果(2): sixwhale 1.php(遍历当前目录下所有文件)
;在shell里是分割命令的作用 所以可想而知 只要改变;后的值就可以导致很多命令注入

  • strip_tags()去掉HTML和PHP标记 避免恶意脚本植入
    0x02 转义输出

最常见的就是插入恶意的HTML代码 使用htmlspecialchars()或者htmlentities()函数
0x03 (//∀//)
今天看到了PHP与web安全的部分 虽然之前在网上了解过 实践中也有接触 但是感觉还是自己总结笔记印象比较深刻(毕竟还是希望在博客里写一些对自己有用的东西!!!) 只写了一部分 不定期更新中 希望不要吐槽啦(இдஇ; )


速卖通API接口签名算法[订单url生成]


<?php
    $orderid1 = $_GET['order'];
    $token1 = $_GET['token'];
    $url = 'http://gw.api.alibaba.com:80/openapi';//1688开放平台使用gw.open.1688.com域名
    $appKey = '填写appkey';
    $appSecret ='写签名串'; //签名串
    $orderid = $orderid1;// 订单号
    $token = $token1;//授权码
    $apiInfo = 'param2/1/aliexpress.open/api.findOrderById/' . $appKey;//此处请用具体api进行替换
    
        
    //配置参数,请用apiInfo对应的api参数进行替换
    $code_arr = array(
        // 'client_id'=>$appKey,
        'orderId' => $orderid,
        'access_token' => $token,
    );
    $aliParams = array();
    foreach ($code_arr as $key => $val) {
        $aliParams[] = $key . $val;
    }
    // print_r($aliParams);die;
    sort($aliParams);
    $sign_str = join('', $aliParams);
    $sign_str = $apiInfo . $sign_str; //拼接参数
    $code_sign = strtoupper(bin2hex(hash_hmac("sha1", $sign_str, $appSecret, true))); //签名算法
    $file_get_url = "{$url}/{$apiInfo}?orderId={$orderid}&access_token={$token}&_aop_signature={$code_sign}";
    if (!empty($file_get_url)) {
        $content = file_get_contents($file_get_url);
        $b = json_decode($content,TRUE);
        // print_r($b);die;
        
    }

?>

Typecho 反序列化漏洞导致前台getshell


最早知道这个漏洞是在一个微信群里,说是install.php文件里面有个后门,看到别人给的截图一看就知道是个PHP反序列化漏洞,赶紧上服务器看了看自己的博客,发现自己也中招了,相关代码如下:
2017-10-26-15090112513058.jpg

然后果断在文件第一行加上了die;
今天下午刚好空闲下来,就赶紧拿出来代码看看。

  1. 漏洞分析

先从install.php开始跟,229~235行:
要让代码执行到这里需要满足一些条件:

//判断是否已经安装
if (!isset($_GET['finish']) && file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php') && empty($_SESSION['typecho'])) {
    exit;
}

// 挡掉可能的跨站请求
if (!empty($_GET) || !empty($_POST)) {
    if (empty($_SERVER['HTTP_REFERER'])) {
        exit;
    }

    $parts = parse_url($_SERVER['HTTP_REFERER']);
    if (!empty($parts['port']) && $parts['port'] != 80 && !Typecho_Common::isAppEngine()) {
        $parts['host'] = "{$parts['host']}:{$parts['port']}";
    }

    if (empty($parts['host']) || $_SERVER['HTTP_HOST'] != $parts['host']) {
        exit;
    }
}

首先是$_GET['finish']不为空,其次是referer需要是本站,比较容易实现。
继续跟反序列化的地方:

$config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));

首先使用Typecho_Cookie的get方法获取__typecho_config,get方法如下:

public static function get($key, $default = NULL)
{
    $key = self::$_prefix . $key;
    $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : (isset($_POST[$key]) ? $_POST[$key] : $default);
    return is_array($value) ? $default : $value;
}

可以看到给$value赋值这一行,如果$_COOKIE里面没有就从$_POST里面获取,所以我们测试漏洞的时候直接POST也是可以的,不用每次设置Cookie了。
反序列化漏洞要利用势必离不开魔术方法,我之前收集了一些和PHP反序列化有关的PHP函数:

__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发

install.php中有一行

$db = new Typecho_Db($config['adapter'], $config['prefix']);

其中Typecho_Db的构造函数如下,如果我们反序列化构造一个数组,其中adapter设置为一个类,那么就可以触发这个类的__toString()方法。

/**
 * 数据库类构造函数
 *
 * @param mixed $adapterName 适配器名称
 * @param string $prefix 前缀
 * @throws Typecho_Db_Exception
 */
public function __construct($adapterName, $prefix = 'typecho_')
{
    /* 获取适配器名称 /
    $this->_adapterName = $adapterName;
    /* 数据库适配器 /
    $adapterName = 'Typecho_Db_Adapter_' . $adapterName;

然后我们全局搜索__toString()方法,发现两个有搞头的文件:

/var/Typecho/Feed.php
/var/Typecho/Db/Query.php

我这里跟一下Feed.php,查看Feed.php的__toString()方法,其中第290行:

foreach ($this->_items as $item) {
    $content .= '' . self::EOL;
    $content .= '' . htmlspecialchars($item['title']) . '' . self::EOL;
    $content .= '' . $item['link'] . '' . self::EOL;
    $content .= '' . $item['link'] . '' . self::EOL;
    $content .= '' . $this->dateFormat($item['date']) . '' . self::EOL;
    $content .= '' . htmlspecialchars($item['author']->screenName) . '' . self::EOL;
    //省略........
}

其中调用了$item['author']->screenName,$item是$this->_items的foreach循环出来的,并且$this->_items是Typecho_Feed类的一个private属性。

我们可以利用这个$item来调用某个类的__get()方法,上面说过__get()方法是用于从不可访问的属性读取数据,实际执行中这里会获取该类的screenName属性,如果我们给$item['author']设置的类中没有screenName就会执行该类的__get()方法,我们继续来全局搜索一下__get()方法。

发现/var/Typecho/Request.php中的__get()方法如下:

public function __get($key)
{
    return $this->get($key);
}

跟进$this->get()方法如下:

public function get($key, $default = NULL)
{
    switch (true) {
        case isset($this->_params[$key]):
            $value = $this->_params[$key];
            break;
        case isset(self::$_httpParams[$key]):
            $value = self::$_httpParams[$key];
            break;
        default:
            $value = $default;
            break;
    }

    $value = !is_array($value) && strlen($value) > 0 ? $value : $default;
    return $this->_applyFilter($value);
}

这里没什么问题,但最后一行:

return $this->_applyFilter($value);

跟进一下发现:

private function _applyFilter($value)
{
    if ($this->_filter) {
        foreach ($this->_filter as $filter) {
            $value = is_array($value) ? array_map($filter, $value) :
            call_user_func($filter, $value);
        }

        $this->_filter = array();
    }

    return $value;
}

这个foreach里面判断如果$value是数组就执行array_map否则调用call_user_func,这俩函数都是执行代码的关键方法。而这里$filter和$value我们几乎都是可以间接控制的,所以就可以利用call_user_func或者array_map来执行代码,比如我们设置$filter为数组,第一个数组键值是assert,$value设置php代码,即可执行。


Ubuntu16.04.4本地提权漏洞


漏洞简介

Twitter上Nikolenko发推表示ubuntu最新版本存在一个本地提权漏洞,并且提供了EXP下载地址,该漏洞在老版本中已经完成修复,但是在ubuntu16.04版本依旧可以被利用。
2018-03-16-15211958549029.jpg

影响范围

目前已知范围
ubuntu 16.04.4

漏洞复现

使用本人在日本云平台服务商conoha.jp上的主机测试,亲测可用。
2018-03-16-QQ20180316-181627@2x.png

POC下载地址:upstream44.c.zip

修复方案

目前暂未有明确的补丁升级方案。 建议用户在评估风险后,通过修改内核参数限制普通用户使用bpf(2)系统调用:

echo 1 > /proc/sys/kernel/unprivileged_bpf_disabled

ubuntu官网暂时没有提供修复方案,补丁更新请关注ubuntu官方漏洞公告:https://usn.ubuntu.com/