我的一个朋友发生了一个不愉快的故事。 但是,对于米哈伊尔来说,这真是令人不快,但对我来说也很有趣。
我必须说,我的朋友是一个
UNIX用户:他可以自己安装系统,安装
mysql和
php并进行最简单的
nginx设置。
他有十二个专门从事建筑工具的网站。
这些专用于电锯的网站之一位于TOP搜索引擎中。 该网站是非营利性评论者,但有人碰到他的喉咙并袭击了他。 要么
DDoS ,然后是蛮力,然后评论将发表淫秽内容,并将滥用行为发送给托管服务器和ILV。
突然,一切都平静下来了,这种平静并不美好,该站点开始逐渐离开结果的顶端。

那是一句话,然后是管理自行车本身。
电话响了,时间快要睡觉了:“三亚,您不会看我的服务器吗? 在我看来,他们砍死了我,我无法证明这一点,但是这种感觉并没有离开第三周。 也许我只需要接受偏执狂治疗?”
接下来是一个半小时的讨论,总结如下:
- 繁殖地肥沃。
- 破解者可以获得超级用户权限;
- 攻击(如果发生)专门针对此站点;
- 问题区域是固定的,您只需要了解是否存在渗透事实;
- 黑客无法触及站点代码和数据库。
关于最后一段。

只有白色IP前端正在向世界展示。 后端和前端之间没有交换,除了http(s)之外,用户/密码不同,密钥不交换。 在灰色地址上,除80/443以外的所有端口都已关闭。 只有迈克尔完全信任的两个用户才知道白色IP后端。
Debian 9安装在前端,在通话时,系统已通过外部防火墙与外界隔离并停止了运行。
“好吧,请允许我进入。”我决定将睡眠时间推迟一个小时。 “我会亲眼看到。”
以下:
$ grep -F PRETTY_NAME /etc/*releas* PRETTY_NAME="Debian GNU/Linux 9 (stretch)" $ `echo $SHELL` --version GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu) $ nginx -v nginx version: nginx/1.10.3 $ gdb --version GNU gdb (Debian 8.2.1-2) 8.2.1
寻找可能的骇客
我首先以
救援模式启动服务器。 我安装磁盘,翻阅身份验证,
历史记录 ,系统日志等,如果可能,请检查文件创建日期,尽管我知道正常的破解者会在他身后“冒汗”,而Misha在搜寻自己时已经“踩踏”了。
我从普通模式开始,尤其是在不知道要寻找什么的同时,我正在研究配置。 他主要对
nginx感兴趣,因为一般而言,前端没有其他东西。
这些配置很小,结构合理,可以打包成十几个文件;我只是通过
cat'依次浏览它们。 一切似乎都很干净,但是您永远不会错过其中的
include ,我将进行完整列出:
$ nginx -T nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
我不明白:“商家信息在哪里?”
$ nginx -V nginx version: nginx/1.10.3 TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_sub_module --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module
第二个添加到列表问题中:“为什么要使用这么古老的nginx版本?”
此外,系统认为该版本是全新安装的:
$ dpkg -l nginx | grep "[n]ginx" ii nginx 1.14.2-2+deb10u1 all small, powerful, scalable web/proxy server
我在打电话:
-Misha,您为什么要重建
nginx ?
-好的,我什至不知道该怎么做!
-好吧,睡吧...
Nginx进行了明确的重组,并且出于某种原因隐藏了“ -T”的列表。 毫无疑问,黑客攻击是可以接受的,并且(因为Misha始终用新服务器替换了服务器),请考虑已解决的问题。
确实,由于某人获得了
root特权 ,因此仅
重新安装系统并查找在那里消耗很少的东西是有意义的,但是这次好奇心击败了梦想。 如何找出他们想对我们隐藏的东西?
让我们尝试跟踪:
$ strace nginx -T
我们看穿的痕迹显然是行数不够啦
write(1, "/etc/nginx/nginx.conf", 21/etc/nginx/nginx.conf) = 21 write(1, "... write(1, "\n", 1
为了好玩,比较结论
$ strace nginx -T 2>&1 | wc -l 264 $ strace nginx -t 2>&1 | wc -l 264
我认为代码的一部分
/src/core/nginx.c case 't': ngx_test_config = 1; break; case 'T': ngx_test_config = 1; ngx_dump_config = 1; break;
简化为以下形式:
case 't': ngx_test_config = 1; break; case 'T': ngx_test_config = 1;
或
case 't': ngx_test_config = 1; break; case 'T': ngx_test_config = 1; ngx_dump_config = 0; break;
因此,不会显示按-T列出。
但是如何查看我们的配置?
如果我的想法是正确的,并且问题仅存在于变量
ngx_dump_config中,我们将尝试使用
gdb进行安装,因为存在密钥
--with-cc-opt -g ,并且我们希望优化
-O2不会对我们造成伤害。 同时,由于我不知道在
'T':情况下如何处理
ngx_dump_config ,因此我们不会调用此块,而是使用
案例't'进行安装
:为什么我可以同时使用“ -t”和“ -T”在
if(ngx_test_config)内部处理
if(ngx_dump_config)块:
if (ngx_test_config) { if (!ngx_quiet_mode) { ngx_log_stderr(0, "configuration file %s test is successful", cycle->conf_file.data); } if (ngx_dump_config) { cd = cycle->config_dump.elts; for (i = 0; i < cycle->config_dump.nelts; i++) { ngx_write_stdout("# configuration file "); (void) ngx_write_fd(ngx_stdout, cd[i].name.data, cd[i].name.len); ngx_write_stdout(":" NGX_LINEFEED); b = cd[i].buffer; (void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos); ngx_write_stdout(NGX_LINEFEED); } } return 0; }
当然,如果在此部分中更改了代码,而不是
大小写“ T” :,那么我的方法将不起作用。
测试nginx.conf已经凭经验解决了这个问题,发现对于恶意软件的操作,需要使用以下形式的最小
nginx配置:
events { } http { include /etc/nginx/sites-enabled/*; }
为了简洁起见,我们将使用它。
运行调试器 $ gdb --silent --args nginx -t Reading symbols from nginx...done. (gdb) break main Breakpoint 1 at 0x1f390: file src/core/nginx.c, line 188. (gdb) run Starting program: nginx -t [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, main (argc=2, argv=0x7fffffffebc8) at src/core/nginx.c:188 188 src/core/nginx.c: No such file or directory. (gdb) print ngx_dump_config=1 $1 = 1 (gdb) continue Continuing. nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # configuration file /etc/nginx/nginx.conf: events { } http { map $http_user_agent $sign_user_agent { "~*yandex.com/bots" 1; "~*www.google.com/bot.html" 1; default 0; } map $uri $sign_uri { "~*/wp-" 1; default 0; } map :$sign_user_agent:$sign_uri $sign_o { :1:0 o; default ; } map :$sign_user_agent:$sign_uri $sign_a { :1:0 a; default ; } sub_filter_once off; sub_filter '' $sign_o; sub_filter '' $sign_a; include /etc/nginx/sites-enabled/*; } # configuration file /etc/nginx/sites-enabled/default: [Inferior 1 (process 32581) exited normally] (gdb) quit
步骤如下:
- 在main()函数中设置一个断点
- 运行程序
- 更改定义config的输出的变量的值ngx_dump_config = 1
- 继续/结束程序
如您所见,实际配置与我们的不同,我们从中选择一个虚假的部分:
map $http_user_agent $sign_user_agent { "~*yandex.com/bots" 1; "~*www.google.com/bot.html" 1; default 0; } map $uri $sign_uri { "~*/wp-" 1; default 0; } map :$sign_user_agent:$sign_uri $sign_o { :1:0 o; default ; } map :$sign_user_agent:$sign_uri $sign_a { :1:0 a; default ; } sub_filter_once off; sub_filter '' $sign_o; sub_filter '' $sign_a;
让我们按顺序考虑这里发生了什么。
由
User-Agent的yandex / google定义:
map $http_user_agent $sign_user_agent { "~*yandex.com/bots" 1; "~*www.google.com/bot.html" 1; default 0; }
WordPress服务页面不
包括在内 :
map $uri $sign_uri { "~*/wp-" 1; default 0; }
对于同时属于上述两种情况的人
map :$sign_user_agent:$sign_uri $sign_o { :1:0 o; default ; } map :$sign_user_agent:$sign_uri $sign_a { :1:0 a; default ; }
在
html页面的文本中,将
'o'更改为
'o' ,将
'a'更改为
'a' :
sub_filter_once off; sub_filter '' $sign_o; sub_filter '' $sign_a;
确实如此,微妙之处在于
'a'!='A'与
'o'!='O'相同 :

因此,搜索引擎机器人会收到用拉丁语
'a'和
'o'稀释的修改后的垃圾,而不是正常的100%西里尔文字。 我不打算讨论这如何影响SEO,但这样的文字散列不太可能对SERP中的位置产生积极影响。
有幻想的家伙怎么说。
参考文献
使用GDB进行调试gdb(1)-Linux手册页strace(1)-Linux手册页Nginx-模块ngx_http_sub_module关于电锯,链锯和电锯