都是去年的东西了,拖啊拖,拖到今天9月份了,文章底下我留了个铺垫...本来准备跟黑哥来个SOPW的专辑的...不过还没等我发,80sec的同学已经发出来了...那就算了,直接把注入以及利用写点blog吧...

想说的几点:

1.pw虽然过滤的很BT,但注入不止这一个点;
2.利用注入获取系统关键的db_siteownerid后,拿shell可以获得很大的帮助,包括这个代码执行,以及下面我要公布的上传;
3.去年我看原始的pw7.5的时候,也就是saiy没发布那个包含漏洞的时候,都不需要db_siteownerid,也就是直接的代码执行。(于是显然...saiy牛也应该很早就发现这个漏洞了...)

好了,先说注入,很明显很白痴的一个点,其实比代码执行好看多了,估计很多人就知道了,而且在很多版本中存在,如果不是过滤的严格一点,在pw7.5的sp3版本里可以update任意表的。

看代码:

...
} elseif ($action == pcdelimg) {
    InitGP(array(fieldname,pctype));
    InitGP(array(tid,id),2);
    if (!$tid || !$id || !$fieldname || !$pctype) {
        echo fail;
    }
    $id = (int)$id;
    if ($pctype == topic) {
        $tablename = GetTopcitable($id);
    } elseif ($pctype == postcate) {
        $tablename = GetPcatetable($id);
    }

    $path = $db->get_value("SELECT $fieldname FROM $tablename WHERE tid=". pwEscape($tid));

    if (strpos($path,..) !== false) {
        return false;
    }
    $lastpos = strrpos($path,/) + 1;
    $s_path = substr($path, 0, $lastpos) . s_ . substr($path, $lastpos);

    if (!file_exists("$attachpath/$path")) {
        if (pwFtpNew($ftp,$db_ifftp)) {
            $ftp->delete($path);
            $ftp->delete($s_path);
            pwFtpClose($ftp);
        }
    } else {
        P_unlink("$attachdir/$path");
        if (file_exists("$attachdir/$s_path")) {
            P_unlink("$attachdir/$s_path");
        }
    }

    $db->update("UPDATE $tablename SET $fieldname= WHERE tid=". pwEscape($tid));

    echo success;

    ajax_footer();

...

就是直接带进来,急死人(阿里的孩子)啦...我当年也针对db_siteownerid与管理员用户密码分别写了exp,不过注入的方法跟乌云里不一样。

下面说远程代码执行,pw整体写缓存,一个函数pw_var_export打遍天下,让你几乎无可趁之机,不过uc的应用里写缓存的时候,对于key有点没当回事,于是$class[cid]被直接带进去了:

...
function threadscateGory($classdb) {//生成帖子交换分类
    
        $classcache = "<?phprn$info_class=array(rn";

        foreach ($classdb as $key => $class) {

            !$class[ifshow] && $class[ifshow] = 0;
            $flag && $info_class[$class[cid]][ifshow] && $class[ifshow] = 1;

            $class[name] = str_replace(array(",""),array("
&quot;","&#39;"),$class[name]);
            
$classcache .= "$class[cid]=>".pw_var_export($class).", ";
        }
        
$classcache .= "); ?>";
        
writeover(D_P."data/bbscache/info_class.php",$classcache);
    }
...

于是,直接写可执行脚本进缓存,生成shell在data/bbscache/info_class.php!没什么悬念了!