前言

学到后面发现自己看代码能力还是很菜,于是接下来的学习都会拿一些框架cms来学习,顺便复现一下古老的漏洞。

目录结构

├─admin
│  ├─css
│  ├─img
│  └─js
├─install
├─usr
│  ├─plugins
│  │  └─HelloWorld
│  ├─themes
│  │  └─default
│  │      └─img
│  └─uploads
└─var
    ├─IXR
    ├─Typecho
    │  ├─Db
    │  │  ├─Adapter
    │  │  │  └─Pdo
    │  │  └─Query
    │  ├─Http
    │  │  └─Client
    │  │      └─Adapter
    │  ├─I18n
    │  ├─Plugin
    │  ├─Router
    │  └─Widget
    │      └─Helper
    │          ├─Form
    │          │  └─Element
    │          └─PageNavigator
    └─Widget
        ├─Abstract
        ├─Comments
        ├─Contents
        │  ├─Attachment
        │  ├─Page
        │  ├─Post
        │  └─Related
        ├─Interface
        ├─Metas
        │  ├─Category
        │  └─Tag
        ├─Options
        ├─Plugins
        ├─Themes
        └─Users

install.php解析

首先设置了根目录等,也设置了包含路径,包含的内容都在/var目录下

/** 设置包含路径 */
@set_include_path(get_include_path() . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . '/var' . PATH_SEPARATOR .
__TYPECHO_ROOT_DIR__ . __TYPECHO_PLUGIN_DIR__);

随后调用Typecho_Common::init()初始化,方法里面定义了__autoLoad方法,用_作为分割符,对输入的GET、POST 、COOKIE进行了过滤。

    public static function init()
    {
        /** 设置自动载入函数 */
        spl_autoload_register(array('Typecho_Common', '__autoLoad'));

        /** 兼容php6 */
        if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
            $_GET = self::stripslashesDeep($_GET);
            $_POST = self::stripslashesDeep($_POST);
            $_COOKIE = self::stripslashesDeep($_COOKIE);

            reset($_GET);
            reset($_POST);
            reset($_COOKIE);
        }

        /** 设置异常截获函数 */
        set_exception_handler(array('Typecho_Common', 'exceptionHandle'));
    }

public static function __autoLoad($className)
    {
        @include_once str_replace(array('\\\\', '_'), '/', $className) . '.php';
    }

接着定义了几个有关参数操作的函数,接着一顿操作选语言。

/**
 * 获取传递参数
 *
 * @param string $name 参数名称
 * @param string $default 默认值
 * @return string
 */
function _r($name, $default = NULL) {
    return isset($_REQUEST[$name]) ?
        (is_array($_REQUEST[$name]) ? $default : $_REQUEST[$name]) : $default;
}

/**
 * 获取多个传递参数
 *
 * @return array
 */
function _rFrom() {
    $result = array();
    $params = func_get_args();

    foreach ($params as $param) {
        $result[$param] = isset($_REQUEST[$param]) ?
            (is_array($_REQUEST[$param]) ? NULL : $_REQUEST[$param]) : NULL;
    }

    return $result;
}

/**
 * 输出传递参数
 *
 * @param string $name 参数名称
 * @param string $default 默认值
 * @return string
 */
function _v($name, $default = '') {
    echo _r($name, $default);
}

建立数据库对象

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fbf46092-70b9-456e-9a67-a54a8567c9e9/rId23.png

接下来是建库啥的一些初始化操作。其中跟数据库有关的就三个php

var\\Typecho\\Db.php
var\\Typecho\\Db\\Query.php
var\\Typecho\\Db\\Adapter\\Mysql.php

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/34a351ed-e3a0-4b0e-a2fe-007610a7ca8c/rId24.png

最常见的一句数据库插入语句,先通过insert找表(这里做了表名的过滤),返回的是Typecho_Db_Query对象,然后通过调用Typecho_Db_Query的rows方法(这里做了列名的过滤)一顿操作之后还是返回Typecho_Db_Query对象,最后把Typecho_Db_Query对象当作参数执行query方法。

$installDb->query($installDb->insert('table.options')->rows(array('name' => 'theme', 'user' => 0, 'value' => 'default')));

其中Db.php中的sql()函数