设计模式-模板模式

  • 理解:典型的控制反转,子类复写算法,但是最终的调用都是抽象类中定义的方式,也就是说 抽象类中定义了算法的执行顺序
  • 使用场景:例如短信系统,选择不同的短信商,但是发送短信的动作都是一样的,未来要增加不同的厂商 只需添加子类即可

下面是代码演示
汽车模型演示

<?php
/**
 * @author     :wkj
 * @createTime :2018/9/19 9:10
 * @description:设计模式-模板模式
 *
 * 理解:典型的控制反转,子类复写算法,但是最终的调用都是抽象类中定义的方式,也就是说抽象类中
 * 定义了算法的执行顺序
 * 使用场景:例如短信系统,选择不同的短信商,但是发送短信的动作都是一样的,未来要增加不同的厂商
 * 只需添加子类即可
 *   下面是一个不同汽车启动停止的演示demo
 */


abstract class Car{
    abstract protected function start();

    abstract protected function stop();

    abstract protected function music();

    abstract protected function speed();

    protected function canPlayMusic(){
        return true;
    }

    final public function run(){
        $this->start();
        $this->speed();
        $this->canPlayMusic() && $this->music();
        $this->stop();
    }
}


class SKD extends Car{

    public function start(){
        echo "斯柯达 启动\n";
    }

    public function stop(){
        echo "斯柯达 熄火\n\n";
    }

    public function music(){
        echo "斯柯达 播放音乐\n";
    }

    public function speed(){
        echo "斯柯达 踩油门\n";
    }
}

class BYD extends Car{

    public function start(){
        echo "比亚迪 启动\n";
    }

    public function stop(){
        echo "比亚迪 熄火\n\n";
    }

    public function music(){
        echo "比亚迪 播放音乐\n";
    }

    public function speed(){
        echo "比亚迪 踩油门\n";
    }
}

//(new SKD())->run();
//(new BYD())->run();

//增加新车型大众 DZ,不要播放音乐
class DZ extends Car{

    public function start(){
        echo "大众 启动\n";
    }

    public function stop(){
        echo "大众 熄火\n\n";
    }

    public function music(){
        echo "大众 播放音乐\n";
    }

    public function speed(){
        echo "大众 踩油门\n";
    }

    //父类添加canPlayMusic,子类覆写方法
    protected function canPlayMusic(){
        return false;
    }
}

(new SKD())->run();
(new BYD())->run();
(new DZ())->run();

短信发送的演示

<?php

/**
 * @author     :wkj
 * @createTime :2018/9/19 9:35
 * @description:
 */
abstract class Sms{
    /**
     * 运营商配置
     * @var string
     */
    protected $_config = [];

    /**
     * 短信文本
     * @var string
     */
    protected $_text = '[xx公司]你好,你的验证码是';

    /**
     * 构造函数
     * @param array $config 运营商配置
     */
    final function __construct($config = []){
        // 初始化配置
        $this->initialize($config);
    }

    /**
     * 初始化运营商配置
     *
     * 每个厂商的配置不一定相同,所以子类复写这个方法即可
     *
     * @param  array $config 运营商配置
     * @return void
     */
    abstract function initialize($config = []);

    /**
     * 生成短信文本
     *
     * 短信模板和厂商无关
     *
     * @return void
     */
    function makeText(){
        $this->_text .= rand(000000, 999999);
    }

    /**
     * 厂商发送短信方法
     *
     * 每个厂商复写这个方法即可
     *
     * @param  integer $mobile 手机号
     * @return void
     */
    abstract function sendSms($mobile = 0);

    /**
     * 发送短信
     *
     * 最终调用的方法,明确了算法顺序
     *
     * @param  integer $mobile 手机号
     * @return void
     */
    final function send($mobile = 0){
        // 生成文本
        $this->makeText();
        // 发送短信
        $this->sendSms($mobile);
    }

}

/**
 * 某厂商one
 */
class SmsCompanyOne extends Sms{

    /**
     * 初始化运营商配置
     * 每个厂商的配置不一定相同,所以子类复写这个方法即可
     * @param  array $config 运营商配置
     * @return void
     */
    function initialize($config = []){
        // 实现具体算法
        $this->_config = $config;
    }

    /**
     * 厂商发送短信方法
     * 每个厂商复写这个方法即可
     * @param  integer $mobile 手机号
     * @return void
     */
    function sendSms($mobile = 0){
        // 实现具体的短信发送方法
        echo "厂商‘one’给手机号{$mobile}发送了短信:{$this->_text} \n";
    }

}

class SmsCompanyTwo extends Sms{

    /**
     * 初始化运营商配置
     * 每个厂商的配置不一定相同,所以子类复写这个方法即可
     * @param  array $config 运营商配置
     * @return void
     */
    function initialize($config = []){
        // 实现具体算法
        $this->_config = $config;
    }

    /**
     * 厂商发送短信方法
     * 每个厂商复写这个方法即可
     * @param  integer $mobile 手机号
     * @return void
     */
    function sendSms($mobile = 0){
        // 实现具体的短信发送方法
        echo "厂商‘two’给手机号{$mobile}发送了短信:{$this->_text} \n";
    }

}

try {
    // 用厂商one发短信
    $one = new SmsCompanyOne([
        'appkey' => 'akjlooolllnn',
    ]);
    $one->send('13666666666');

    // 用厂商two发短息
    $one = new SmsCompanyTwo([
        'pwd' => 'adadeooonn',
    ]);
    $one->send('13666666666');

} catch (\Exception $e) {
    echo 'error:' . $e->getMessage();
}

笔记分享 https://note.youdao.com/share/?id=bac70f083c249b87bcb1dd141ced4552&type=note#/

phpstorm http client 使用

phpstorm一直都可以调试接口,以前觉得很麻烦就一直使用postman来处理,大致是这样的界面

自从前面几个版本更新,发现phpstorm可以用伪代码来调试,感觉方便了点,现在记录下使用步骤

下面是简单的使用实例

使用接口调试的时候可以设置我们的环境,默认参数,postman也是有这样的设置的

创建一个http-client.env.json 配置文件,如果简单使用可以不用创建





get post都有相对应的简单模板可以使用,如下自行选择

官网的文档 https://www.jetbrains.com/help/phpstorm/http-client-in-product-code-editor.html

小程序 wepy + iview-weapp 使用

小程序相关的项目

  1. wepy 项目 https://github.com/Tencent/wepy
  2. iview-weapp https://weapp.iviewui.com/
  3. https://github.com/Tencent/weui-wxss

最近一直在考虑有没有好的小程序UI 只看到官网的https://github.com/Tencent/weui-wxss,
但是觉得不太好看,今天发现iview-weapp 这个UI框架不错,尝试配合wepy应该可以比较快速的开发了
开始尝试组合使用

  1. 安装或更新wepy cli工具 npm install wepy-cli -g
  2. 生成项目 wepy init standard wepy-iview
  3. 安装项目依赖 cd wepy-iviewnpm install`
  4. clone iview-weapp项目 git clone https://weapp.iviewui.com/
  5. 新建文件目录 wepy-iview/src/iview
  6. 复制iview-weapp/src/* 到 新建的项目 wepy-iview/src/iview
  7. 此时即可使用了,比如使用modal,现在config中配置usingComponents
<view>
<i-modal title="这是标题" visible="{{ true }}" show-ok="{{true}}" ok-text="确定" show-cancel="{{false}}">
      <view>这是iview样式</view>
</i-modal>
</view>

//script  congfig中引入 
config = {
      navigationBarTitleText: 'test',
      usingComponents: {
        'i-modal': '../iview/modal/index'
      }
    }



使用 wepy build --watch 编译,使用微信开发工具即可

文件包含漏洞

php文件包含漏洞通常是下面四个函数 include,require,include_once,require_once
reuqire,require_once 如果在包含的过程中有错,比如文件不存在等,则会直接退出,不执行后续语句。

基础

当利用这四个函数来包含文件时,不管文件是什么类型(图片、txt等等),都会直接作为php文件进行解析。测试代码:

    //index.php
    $file = $_GET['file'];
    include $file;

同级目录下有phpinfo.txt 其内容为 <?php phpinfo();?>,执行如下请求
http request index.php?file=phpinfo.txt
结果如下,成功执行了phpinfo()

场景

1.具有相关的文件包含函数。
2.文件包含函数中存在动态变量,比如 include $file;。
3.攻击者能够控制该变量,比如$file = $_GET['file'];。

分类

1. LFI(Local File Inclusion)
    本地文件包含漏洞,顾名思义,指的是能打开并包含本地文件的漏洞。大部分情况下遇到的文件包含漏洞都是LFI。简单的测试用例如前所示。
2. RFI(Remote File Inclusion)
    远程文件包含漏洞。是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性会很大。
    但RFI的利用条件较为苛刻,需要php.ini中进行配置
        allow_url_fopen = On
        allow_url_include = On
    两个配置选项均需要为On,才能远程包含文件成功。在php.ini中,allow_url_fopen默认一直是On,而allow_url_include从php5.2之后就默认为Off。

php伪协议

php://input
  • 利用条件
    • allow_url_include = On。
    • 对allow_url_fopen不做要求。
  • 姿势
    http request index.php ?file=php://input POST: <? phpinfo();?>
    用burp演示一下
php://filter
  • 利用条件 (无) 对配置没有要求
  • 姿势
    http request index.php?file=php://filter/read=convert.base64-encode/resource=index.php
    通过指定末尾的文件,可以读取经base64加密后的文件源码,之后再base64解码一下就行。虽然不能直接获取到shell等,但能读取敏感文件危害也是挺大的。

    解码可以看到源代码

    http request index.php?file=php://filter/convert.base64-encode/resource=index.php //效果跟前面一样,少了read等关键字。在绕过一些waf时也许有用。
phar://
  • 利用条件
    • php版本大于等于php5.3.0
  • 姿势
    假设有个文件phpinfo.txt,其内容为 <?php phpinfo(); ?>,打包成zip压缩包,如下

    指定绝对路径
    http request index.php?file=phar://D:/code/xxx/phpinfo.zip/phpinfo.txt
    或者使用相对路径(这里test.zip就在当前目录下)
    http request index.php?file=phar://phpinfo.zip/phpinfo.txt
zip://
  • 利用条件
    • php版本大于等于php5.3.0
  • 姿势
    • 构造zip包的方法同phar。
data:URI schema
  • 利用条件
    • php版本大于等于php5.2
    • allow_url_fopen = On
    • allow_url_include = On
  • 姿势
    ```http request
    index.php?file=data:text/plain,

    ![](https://ws1.sinaimg.cn/large/0063sFGSgy1fu8zrqd7qij310p0gt75p.jpg)
    或者
     ```http request
      //<?php phpinfo();?>
      //PD9waHAgcGhwaW5mbygpOz8+
      //加号+的url编码为%2b
      index.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
    


    执行命令
    http request //<?php system('whoami');?> //PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg== /?file=data:text/plain;base64,PD9waHAgc3lzdGVtKCd3aG9hbWknKTs/Pg==

    //继续学习更新
    原文 https://chybeta.github.io/2017/10/08/php%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E/

burpsuit代理抓包,代理手机流量

以前用过burp抓包,仅仅是对http的请求,现在要求对某https的网站抓包修改返回,可以如下操作

  1. burp证书下载 设置代理的情况下,直接访问 http://burp/ 点击 CA Certificate
  2. chrome代理设置(个人比较喜欢chrome,fix可以类似设置)
    访问 chrome://settings/打开设置-高级-管理证书

    mac 安装的话 直接点击下载的文件,在钥匙串中找到PortSwigger CA 双击修改信任为始终信任即可
  3. 使用chrome拓展SwitchyOmega设置,或者可以使用chrome自己的代理,拓展比较方便
    比如添加 8089的代理 监听127.0.0.1:8089

    SwitchyOmega选择8089代理模式

现在去打开https的网站,发现可以正常拦截了

修改响应方法有两种

  1. 直接拦截修改响应

  2. 在代理的时候添加全局的修改 如下设置

burp代理手机访问
以前都是用findder来代理的,最近发现burp也是可以代理的,以后就都用burp来代理
具体设置步骤如下

  1. 比如设置代理端口8011(随便设置),当前电脑的ip是 192.168.120.45 (每个电脑可能不一样)
  2. 用手机来链接本电脑,如果是台式机可以安装无线网卡(如:360wifi之类的)
  3. 手机连接当前电脑分享的无线网,并在无线网设置代理ip为 192.168.120.45 端口为 8011
    此时即可抓取手机访问的流量了