我们来讨论包含文件漏洞,首先要问的是,什么才是"远程文件包含漏洞"?回答是:服务器通过php的特性(函数)去包含任意文件时,由于要包 含的这个文件来源过滤不严,从而可去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。几乎所有的 cgi程序都有这样的 bug,只是具体的表现方式不一样罢了。
» 阅读全文
Submitted by gouki on 2010, February 28, 10:03 PM
我们来讨论包含文件漏洞,首先要问的是,什么才是"远程文件包含漏洞"?回答是:服务器通过php的特性(函数)去包含任意文件时,由于要包 含的这个文件来源过滤不严,从而可去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。几乎所有的 cgi程序都有这样的 bug,只是具体的表现方式不一样罢了。
» 阅读全文
Submitted by gouki on 2010, February 25, 11:01 AM
我在写sbConfigure类的时候,还是采用了以前的Configure的解析方法,即get方法可以以字符串的形式来读取数组变量,就象这样
但事实上,我为了这个返回,写了五六次代码了,但最终还是采用了foreach的方法
第一次我这么处理(采用了Eval),
后来,yhustc说这样不太安全,所以我改成了foeach的方式
$_err这个变量是为了防止变量在没有设定的时候仍然返回值。。。
昨天我又想用eval,但还是失败了。。。
不知道有没有更好的转换方式,查看了parse_ini_file,因为我想,ini文件中有
有这样的返回数组。所以我在想着参考。然而仍然失望 ,又想着pack?serialize?json_decode?之类的解决方式,但还是失败了。。郁闷啊。
先记录一下,如果有更好的方法,就再次更新
Submitted by gouki on 2010, February 24, 9:26 AM
乔大姐的文章,几年前的了。。不过,还是值得一观,这也是我一朋友在问过,为什么存到文件里的内容不是UTF-8的时候引申出来的事了。
以下内容是乔大姐的转载,主要内容如下【我把C的那部分做了高亮,其余不变】,关于乔大姐是谁,可以从我转载的页面中获知,http://bbs.chinaunix.net/viewthread.php?tid=807393,本人不作介绍,以防被劈。
更广义的字符集转换:iconv
在先前的章节中,我们已见到了两组 mbs 与 wcs 互转的函式,第一组对于有「状态改变」的编码系统 mbs 无法做到字符串的状态控制,故不适合做该 mbs 的转换工作;而第二组则可以直接做字符串的状态控制,故使用范围就更广了。然而,这两组字符串转换函式在某些使用场合下都有很大的限制,广义而言,它们都 属于「字符集转换函式」,然而它们都直接与 I18N、locale 机制绑在一起,也就是说在使用它们之前,程序都必须设好正确的 locale 才行。故在以下的情况使用它们就会很不方便,甚至根本行不通:
• 如果程序中需要做 A 字集编码与 B 字集编码的转换时,不幸的是这两种字集 编码都不是目前程序所处的 locale 所采用的。若使用前述的 wcs 与 mbs 转换函式,唯一的办法只有先呼叫 setlocale(),将程序的 LC_CTYPE locale 先切换到使用字集编码 A 的 locale,把字符串 A 转成 wcs 字符串后,再呼叫一次 setlocale(),将程序的 locale 切换到使用字集编码 B 的 locale,最后才把 wcs 字符串转成字符串 B。万一 都找不到任何 locale 采用字集 A 或字集 B 时,则这一招就没有用了。
• 如果程序中需要同时做多种字集编码的转换时,则这些 wcs 与 mbs 的转换 函式就无法办到了。原因是一旦 setlocale() 设定好程序的 locale 之后,其影响是遍及整个程序每个部分,我们不可能做到在转换字集编码 A 时设好 locale A,又 ``同时'' 设好 locale B 来转字集编码 B。
因此,我们需要更广义的字集转换系统,一个可以与 locale 完全无关的转换系统,才能方便地达到上述的要求。故在 XPG2 标准中另外定义了一组全新的函式接口: iconv。事实上,在 glibc 中,表面上看来那些 wcs 与 mbs 转换函式与 iconv 不太一样,但它们底层的 wcs 与 mbs 转换工作却是由 iconv 来达成的。故 iconv 可以说是字集转换系统中最基底的函式接口。
iconv 字集转换系统只有三个函式,在很多系统中是宣告在 iconv.h 里头,使用上与一般在做档案读写的概念一样,先 ``开启''、之后 ``操作''、完毕后要 ``关闭'',这些函式包括:
• iconv_t iconv_open(const char *TOENC, const char *FROMENC)
• size_t iconv (iconv_t CD, const char **INBUF,
size_t *INBYTESLEFT, char **OUTBUF, size_t *OUTBYTESLEFT)
• int iconv_close(iconv_t CD)
首先 iconv_open() 函式就是做 ``开启'' 动作,也就是当我们要将编码系统 A 转换到编码系统 B 时,必须先呼叫此函式,将 FROMENC 设成编码系统 A 的名字,同时将 TOENC 设成编码系统 B 的名字,这时此函式就会做类似档案开启的动作,传回一个代表此转换管道的数据结构 iconv_t 供后续使用。事实上,在系统的实作中真的是将 iconv_open() 当作 ``开启档案'' 来处理,故它会受到目前系统或同一行程中可开启档案数所限,如果系统或程序的其它部分已开启了太多的档案以至于逼近系统上限,则有可能这边的 iconv_open() 会失败。
如果 iconv_open() 开启失败时,它会传回 (iconv_t)-1 的值,同时设定 errno 全域变量,用以指出开启失败的原因。而开启失败的原因,不外乎就是已开启的档案数已超过上限、或系统内存不足、或系统本身无法做到编码系统 A 与 B 之间的转换。有兴趣的读者可以直接去阅读 info libc, * Character Set Handling:: 一节了解各 errno 的值与其所代表的意义。
第二个 iconv() 函式就是用来做实际编码系统转换工作的,它必须先呼叫过 iconv_open() 并取得 iconv_t 结构后才能工作。只要 iconv_open() 可以开启成功,则理论上它就可以进行转换工作,而且不论其来源编码与目标编码是 mbs 字符串或 wcs 字符串、或二者的混合互转,都没有关系。但要注意的是,如果其中有 wcs 字符串时,就算用来存放 wcs 字符串是使用 wchar_t * 形别,在传入此函式时仍然统一用 char * 来处理。
若要做字符串 A 转换成字符串 B 时,字符串 A 是经由 *INBUF 传入,而 *INBYTESLEFT 则传入数组 A 的长度,一律以字节数来计算。而转换的结果则由 *OUTBUF 传回,同样的 *OUTBYTESLEFT 则为 *OUTBUF 的长度。如果转换成功了,则 *INBUF 最后会设在存放字符串 A 的数组末尾,而 *INBYTESLEFT 会设为目前此数组还剩多少字节可以用。而 *OUTBUF 与 *OUTBYTESLEFT 也是一样。因此我们可以在相同的 A、B 数组中重复呼叫此函式。举个例子来说,如果转换过程中在 A 数组里头遇到了不合法的字符而无法进行转换时,则 *INBUF 与 *OUTBUF 就会停在无法转换的位置上,并将已转换成功的结果传回,则我们可以自行决定看是要跳过那个不合法的字符,继续转换剩余的部分,或做其它的特殊处理 ...等等。
在很多情况下有可能造成 iconv() 的转换失败,例如前面提到的在 A 数组中遇到不合法的字符,或者 A 中某个字符在 B 中找不到可对应的字。其中第二个情况是最有可能发生的,而目前 glibc-2.1.x 系统中遇到这种情况时就当做是转换失败,而不做进一步的处理。当然这并不是最好的处理方式,故未来可能会有所改变。而根据 info libc 的说明,如果转换失败了, iconv() 最后的传回值是 (size_t)-1,并设定 errno 的值说明失败的原因;如果转换成功,则传回值会是已成功转换的字符个数。但我们实际的测试结果,在 glibc-2.1.3 的系统下,如果转换成功后其传回值却永远是 0,与 info libc 上的描述不一样,这点有点奇怪,不晓得是不是目前 glibc 的 bug?
若遇到含「状态改变」的编码系统时,iconv() 也能正确工作,它能在转换的过程中随时记录、更新字符串目前的状态 (应该就是记录在 iconv_t CD 结构中),故就算是采「分期付款」方式将同一字符串切成数分一段段来转换,也不会出问题。但要注意的是,在第一次使用 iconv() 之前,必须先初始化一下 A、B 两字符串的状态,就好像我们在先前所提的 mbsrtowcs() 等函式一样,在使用前也必须先做好状能初始化,如此才能让后续可以正常工作。而对于 iconv() 而言,初始化的方式就是呼叫它时,*INBUF 与 *OUTBUF 都设为 NULL 即可。
最后一个 iconv_close() 函式,就是当整个转换结束后,用来做「关闭档案」用的。
底下我们就写了一个范例程序,用来说明 iconv 函式界面的使用方式:
Submitted by gouki on 2010, February 23, 9:01 AM
以下内容均来自老王。说实话,simplexml的这些问题我以前遇到过,而且还是非常强烈的遇到了。
那时候是08年的事了,项目中与SOAP在交互,返回的都是XML,所以就直接采用了simplexml_load_string了。这时候就会遇到这种问题,比如我拉一个列表,但会有三种情况:1、没数据,2、1条数据,3、正常数据
1、没数据的时候,返回一个空的simplexml Object,
2、一条数据的时候,返回的也是一个simplexml Object,结果集成了这个object的元素
3、数据列表,这时候返回的却是一个Array,每一个元素是simplexml Object,等同于2。
后来我是没办法,就多写了一个函数判断,如果是object,并且不为空,直接把object强制转为array,因为,如果是空的simplexml Object,强制转的话,还是Object,转不了。。。
当时还有一个可恨的事情,我以前可能介绍过,xml在返回的时候,他的形式可能是这样的<test-name>gouki</test-name>,在返回这样的形式时,生成object时,却是test_name,在没有print_r出来时,我死活搞不定。。。后来才发现这个问题,郁闷啊
好了,说了半天,该说说老王的内容了:
这个问题遇到好几次了,今天翻看以前代码的时候看到,便记下来,先用一段代码重现一下问题:
乍一看,结果很让人费解:
XML/HTML代码
- SimpleXMLElement Object
- (
- [foo] => Array
- (
- [0] => SimpleXMLElement Object
- (
- [bar] => hello
- )
- [1] => SimpleXMLElement Object
- (
- [bar] => world
- )
- )
- )
- SimpleXMLElement Object
- (
- [bar] => hello
- )
明明print_r显示foo是一个有两个bar元素的数组,但是最后却仅仅显示了一个bar元素!
原因其实很简单,在如上所示simplexml_load_string的结果里,foo并不是数组,而是一个迭代对象!
可以这样确认:看来,print_r或者var_dump之类的表象并不完全可信,自己多留心吧。PHP代码
- foreach ($data->foo as $v) print_r($v);
- foreach ($data->children() as $v) print_r($v);
原文来自:http://hi.baidu.com/thinkinginlamp/blog/item/9dbb15ce7a621632b700c86a.html
Submitted by gouki on 2010, February 21, 2:15 PM
前段时间有人问,如何统计自己的项目一共写了多少行代码,当时我说的是,遍历目录,然后用files函数读取每个要统计的文件【根据后缀名过滤】,并去掉空行,最后就把数字累加起来就可以了。
后来,他是google到一个专门统计代码的程序后搞定了。
刚才,看到cnitblog,有人这样写道:
linux下面的方法来自:http://www.cnblogs.com/maczpc/archive/2010/01/28/1658371.html