0x00 基础快捷键

Sublime

  • 下一个词组:Ctrl+D
  • 书签:Ctrl+F2、F2
  • 展示函数:Ctrl+E
  • 选中本行:Ctrl+L
  • 匹配的括号:Ctrl+M

0x01 可重复安装

正常安装完成后,存在可重复安装的问题,因为install.lock未能生成.

freebuf有篇文章说,问题出在insall/index.php的158行,错误地使用了is_writable函数。

可是经过验证,发现并不是由这个函数导致的可重复安装问题

首先,找一下php官方手册

在代码里试着把布尔值dump出来看,是true!看来并不是158行的判断出错了

之所以没有生成install.lock, 不是因为include了两次, 也不是相同的变量define了两次

本地测试include两次,可正常运行

而是因为发生了错误, 在156行便停止运行, 所以就没有走到160行以后的写install.lock的逻辑

除此之外, 由于编码被设置成了gbk, 导致全局都存在gbk宽字节注入的问题

0x02 全局存在gbk宽字节注入

admin\include\common.inc.php:26处,对用户入参进行了统一的addslash处理.

在install/index.php,缺少过滤,直接使转义符号\被吞掉, 导致注入

0x03 安装处拿shell

利用**%df + "/" => "運"** ,吃掉’转义用的’', 直接注入了恶意内容, 需要注意的是%df里面的百分号会被url编码成%25,需要在burp里改回为% . 否则不能注入恶意代码,如图

0x04 多处xss

个人资料中MSN:QQ:办公电话:家庭电话:手机:地址的参数都是经过html实体转义的, 不存在xss问题

可是, 在"用户管理»我的个人资料"处, 存在将用户输入直接写进页面的操作,导致首页等能看到用户头像的地方都存在xss

0x05 uccode.class.php命令执行

首先介绍一下php正则匹配中的后向引用,一般用${1}, ${2}或者\\1, \\2来表示,如下面图中的两种使用方式

后向引用是在preg_replace($pattern, $replacement, $subject)中,将$pattern中的原子参数(Capturing Group)重新组合的一种实现。

例如上面35行那里,\\1代表(=((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|ed2k|thunder|synacast){1}:\/\/|www\.)([^\[\"']+?))?\\5

而这里的问题在于使用了preg_replace /e的模式, 稍加搜索就能发现, 这种模式可能导致命令执行, 即php会把$replacement当成php代码执行 , 所以这里就是我们的代码注入点.

function complie($message) {
  $message = htmlspecialchars($message);
  if(strpos($message, '[/code]') !== FALSE) {
  $message = preg_replace("/\s*\[code\](.+?)\[\/code\]\s*/ies", "\$this->codedisp('\\1')", $message);
		}
    
  if(strpos($message, '[/url]') !== FALSE) {
  $message = preg_replace("/\[url(=((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|ed2k|thunder|synacast){1}:\/\/|www\.)([^\[\"']+?))?\](.+?)\[\/url\]/ies", "\$this->parseurl('\\1', '\\5')", $message);
		}
    
  if(strpos($message, '[/email]') !== FALSE) {
  $message = preg_replace("/\[email(=([a-z0-9\-_.+]+)@([a-z0-9\-_]+[.][a-z0-9\-_.]+))?\](.+?)\[\/email\]/ies", "\$this->parseemail('\\1', '\\4')", $message);
		}

后记

还有几个地方比较有趣,但是不足以串联起来利用,此处汇总起来,供各位参考

PHP弱类型

除去不符合代码规范的部分(双目运算符左右要有1个空格的嘛),这里还错误地使用了不严格比较的==运算符,在两边取值都特殊的情况下,也能通过判断。