langyo
相信大家也看到了,论坛虽然已经恢复了正常访问,但却出现了部分内容乱码的情况,诸如评分等这类功能无法正常使用

更确切的讲,是所有动态从服务器加载的内容都不能正常使用,诸如评分、举报、异地登录提示的窗口都在此范畴

为什么会这样呢?

先不提乱码的事,在此之前必须先提起论坛另一个不太正常的地方,所有的 PHP 页面都需要额外刷新几次才展示真实内容



这是我在页面自动刷新时的某一瞬间截的图,我们可以清晰地看到,右侧的 DevTool 展示的 DOM 元素中根本没有 body 标签,只有个 head 标签

我来不及保存,也没时间专门去找工具把这个中间页面扣下来解析,不过有点常识的人应该都知道,只写个 head 还能自动刷新,只能是往 head 里写了点额外的代码使页面重新加载

等正式出来页面后,我们还能看到右下角的“乱码”



这其实是提示异地登录的信息,但没正常加载

为什么呢?其实这也和之前所说的 PHP 页面自动刷新有关系

看过 Discuz! 源码的人应该都知道,所有的动态页面加载,以及表单的提交,其实并没有使用诸如 XMLHttpRequest 或 Fetch 这类库,而是用 iframe:

  1. function _ajaxget(url, showid, waitid, loading, display, recall) {
  2.     waitid = typeof waitid == 'undefined' || waitid === null ? showid : waitid;
  3.     var x = new Ajax();
  4.     x.setLoading(loading);
  5.     x.setWaitId(waitid);
  6.     x.display = typeof display == 'undefined' || display == null ? '' : display;
  7.     x.showId = $(showid);
  8.     if (url.substr(strlen(url) - 1) == '#') {
  9.         url = url.substr(0, strlen(url) - 1);
  10.         x.autogoto = 1;
  11.     }
  12.     var url = url + '&inajax=1&ajaxtarget=' + showid;
  13.     x.get(url, function(s, x) {
  14.         var evaled = false;
  15.         if (s.indexOf('ajaxerror') != -1) {
  16.             evalscript(s);
  17.             evaled = true;
  18.         }
  19.         if (!evaled && (typeof ajaxerror == 'undefined' || !ajaxerror)) {
  20.             if (x.showId) {
  21.                 x.showId.style.display = x.display;
  22.                 ajaxinnerhtml(x.showId, s);
  23.                 ajaxupdateevents(x.showId);
  24.                 if (x.autogoto)
  25.                     scroll(0, x.showId.offsetTop);
  26.             }
  27.         }
  28.         ajaxerror = null;
  29.         if (recall && typeof recall == 'function') {
  30.             recall();
  31.         } else if (recall) {
  32.             eval(recall);
  33.         }
  34.         if (!evaled)
  35.             evalscript(s);
  36.     });
  37. }
  38. function _ajaxpost(formid, showid, waitid, showidclass, submitbtn, recall) {
  39.     var waitid = typeof waitid == 'undefined' || waitid === null ? showid : (waitid !== '' ? waitid : '');
  40.     var showidclass = !showidclass ? '' : showidclass;
  41.     var ajaxframeid = 'ajaxframe';
  42.     var ajaxframe = $(ajaxframeid);
  43.     var curform = $(formid);
  44.     var formtarget = curform.target;
  45.     var handleResult = function() {
  46.         var s = '';
  47.         var evaled = false;
  48.         showloading('none');
  49.         try {
  50.             s = $(ajaxframeid).contentWindow.document.XMLDocument.text;
  51.         } catch (e) {
  52.             try {
  53.                 s = $(ajaxframeid).contentWindow.document.documentElement.firstChild.wholeText;
  54.             } catch (e) {
  55.                 try {
  56.                     s = $(ajaxframeid).contentWindow.document.documentElement.firstChild.nodeValue;
  57.                 } catch (e) {
  58.                     s = '内部错误,无法显示此内容';
  59.                 }
  60.             }
  61.         }
  62.         if (s != '' && s.indexOf('ajaxerror') != -1) {
  63.             evalscript(s);
  64.             evaled = true;
  65.         }
  66.         if (showidclass) {
  67.             if (showidclass != 'onerror') {
  68.                 $(showid).className = showidclass;
  69.             } else {
  70.                 showError(s);
  71.                 ajaxerror = true;
  72.             }
  73.         }
  74.         if (submitbtn) {
  75.             submitbtn.disabled = false;
  76.         }
  77.         if (!evaled && (typeof ajaxerror == 'undefined' || !ajaxerror)) {
  78.             ajaxinnerhtml($(showid), s);
  79.         }
  80.         ajaxerror = null;
  81.         if (curform)
  82.             curform.target = formtarget;
  83.         if (typeof recall == 'function') {
  84.             recall();
  85.         } else {
  86.             eval(recall);
  87.         }
  88.         if (!evaled)
  89.             evalscript(s);
  90.         ajaxframe.loading = 0;
  91.         if (!BROWSER.firefox || BROWSER.safari) {
  92.             $('append_parent').removeChild(ajaxframe.parentNode);
  93.         } else {
  94.             setTimeout(function() {
  95.                 $('append_parent').removeChild(ajaxframe.parentNode);
  96.             }, 100);
  97.         }
  98.     };
  99.     if (!ajaxframe) {
  100.         var div = document.createElement('div');
  101.         div.style.display = 'none';
  102.         div.innerHTML = '<iframe name="' + ajaxframeid + '" id="' + ajaxframeid + '" loading="1"></iframe>';
  103.         $('append_parent').appendChild(div);
  104.         ajaxframe = $(ajaxframeid);
  105.     } else if (ajaxframe.loading) {
  106.         return false;
  107.     }
  108.     _attachEvent(ajaxframe, 'load', handleResult);
  109.     showloading();
  110.     curform.target = ajaxframeid;
  111.     var action = curform.getAttribute('action');
  112.     action = hostconvert(action);
  113.     curform.action = action.replace(/\&inajax\=1/g, '') + '&inajax=1';
  114.     curform.submit();
  115.     if (submitbtn) {
  116.         submitbtn.disabled = true;
  117.     }
  118.     doane();
  119.     return false;
  120. }
复制代码


这是取自 ajax.js 里的内容

我们可以从中看出,页面每当要发送表单或获取信息时,会动态往页面中插入个 iframe 标签,然后等 iframe 加载完成后直接获取其中的内容作为结果,稍微处理下就可以改写父页面的 DOM 显示出来了

而在目前的状态来看,此时获取到的内容真的不正常……它获取到的内容大概是这样的:

  1. var v='61b023cc1899590fa1ce2ca8171ffbd2'; document.cookie='ccdefend='+v+'; path=/'; window.location.reload();
复制代码


看到最后那句 location.reload 了么?这句其实就是重新加载页面用的

现在算是搞明白了,论坛里所有的 PHP 页面似乎都加上了某种防御机制,请求、不断刷新页面个若干次才能正常显示页面

(普通用户看到这里应该能明白如何解决不能正常评分、举报的问题了吧?其实解决方案就是多点几下,直到把它刷出来)




但这样不行诶

如果是为了防御外来 DDOS 的话,只要定位下攻击者主要攻击哪个页面,然后只对对应页面加入防御脚本就行了,不必全部都加入这种东西

而诸如 misc.php 、 home.php 这类页面,请求这些页面的一般都是 Ajax 请求,这些部分如果加入防御,就会出现所谓的乱码现象,十分影响论坛用户的正常操作

如果这个并不是管理员们主动加入的,也请尽快修复下,谢谢!

@混乱 @gamerteam

2693149792
怪不得最近站访问很慢
同感+1

2693149792
本帖最后由 2693149792 于 2018-12-19 12:20 编辑

用户体验感极差

1723624171
你们能不能签到,反正今天还是不能

gamerteam
该脚本为很多年前站长所写,经过检查确实是与dz自带的机制冲突(dz这么写主要是为了兼容IE,IE老版本没有XMLHttpRequest2是没法进行Post部分内容的)
但是暂时没有什么好的解决方案(你提到的那个方案本质上依然是一个巨大的漏洞),不开的话连网页都没法正常开启
正在联系相关的部门解决

Abraham511
现在又开始大量404了

Abraham511
现在又开始大量404了

Jager_Izlife
同感+2
签不上到难受的一批
被攻击说明论坛名声大
但是还是希望相关部门能够尽快解决,现在的状况连登录都不太现实(大号断签3天了啊!)

1139365029
  1. var v='61b023cc1899590fa1ce2ca8171ffbd2'; document.cookie='ccdefend='+v+'; path=/'; window.location.reload();
复制代码

这段代码其实是一种非常有效的防御方式,
它的主要原理就是让浏览器执行一段js,将一段指定的字符串加入cookie当中,
并在下次请求页面的时候,将这段cookie一起发送到服务器,然后重新请求当前的页面,
由于一般的攻击软件只是一味的请求页面,并不会执行页面当中的js,
所以服务器就可以根据这段cookie是否存在 来判断对方是浏览器还是攻击软件。

那么它的问题在哪里?主要是两点:
1.被滥用了。其实用户只需要首次访问的时候验证一次,之后就不需要验证了,这样反复验证,反而降低用户体验。
2.就算是浏览器,也必须放在js里面,才能执行。看到点击“签到”弹出来的不是签到界面而是一段代码了吗?浏览器请求那个界面,但服务器突然[数据删除]想要再验证几次,于是返回了一段js,让浏览器执行一下,但浏览器并不知道那是js,以为和以前的一样 是一个界面,所以就直接展示出来了。

另外这种防御不适合一直开启,会让各大搜索引擎无法正常抓取,没被攻击就最好及时关掉。

Shangyulin
这难道是上古脚本?

SumCraft
Shangyulin 发表于 2018-12-19 18:58
这难道是上古脚本?

少年我看你骨骼惊奇,这有一段祖传脚本传授于你

琉璃糖
老古董了吧........
这几天签不了到,还在为寒假正式开服没金粒而犯愁
望早日解决吧......

west.myth
Jager_Izlife 发表于 2018-12-19 14:06
同感+2
签不上到难受的一批
被攻击说明论坛名声大

被攻击和名声大没有必然联系。前几次都是某些人违规被**,心理不平衡来报复

langyo
这问题被搁置了半个月还没有得到解决么……

虽然不知道顶一下是不是违规,但我希望这个帖子能再重归反馈版帖子列表的开头,所以就再回一次……

@gamerteam 顺带问下,为什么不这么弄,连网页都无法正常开启?

混乱
在攻击停止前不能关闭这个脚本,否则服务器立刻CPU100%只能说进行部分修改,让部分固定页面不展现这个,但是Ajax这一问题,展示没有解决办法。

第一页 上一页 下一页 最后一页