MySQL資料庫遭到攻擊篡改---使用備份和binlog進行數據恢復

2020-12-17 CSDN技術社區

數據篡改即是對計算機網絡數據進行修改、增加或刪除,造成數據破壞。資料庫數據被攻擊了首先得查看是被刪除了還是被篡改了?是否有備份數據,是否能夠進行恢復並加固。本文來自資料庫技術專家張正,主要描述了MySQL遭到攻擊篡改數據,利用從庫的備份和主庫的Binlog進行不完全恢復。

以下是作者原文:

一、發現問題

今天是2014-09-26,開發大清早就說昨晚資料庫遭到了攻擊。資料庫中某文章表的文章內容欄位遭到篡改,全部改成了同一篇文章。

通過查看日制 發現 數據是在 2014-09-25 21:53:57 遭到篡改。

所有的內容全部被改成了如下:

subject: 桂林陽朔自助遊

content:

          一直都是自助遊,從不喜歡?團。去之前都是在網上做足了功課,真的是很感謝那些寫遊記寫攻略的朋友。所以,現在也想把自己的體會和經驗寫出來,和大家分享,希望對後來的朋友有幫助。

         一個月前,朋友約我去陽朔一遊,陽朔也是我一直想去的地方,特別是傳說中的西街。上網搜集資料,制定出我們的行程計劃(呵呵,可能是職業習慣吧,制定計劃和行程安排是我們的強項,計劃性和靈活性是我們的特點),目的很明確,是度假休閒,不必遊走於各個景點,其實我想朋友們也在很多地方都旅遊多了,也知道有些景點是怎麼出來的,各地都一樣。

          制定好主旋律後,我們的大致行程安排如下:

          十九號桂林集中,二十號出發去陽朔,先去陽朔安頓下來(有些人是從桂林帶著行李在楊堤路口下車,直接先去灕江漂流,然後再去陽朔,好像節約時間,不過,我們因為沒有安排那麼滿,也不想帶著行李遊玩,所以選擇先去陽朔安頓,和客棧老闆好好聊聊情況後,再決定具體細節)

         ?次度假的主要內容是:灕江漂流;遇龍河漂流(全漂),十裡畫廊;西街打望,發呆,西街酒吧,印象劉三姐,其他的根據情況和心情臨時決定。

我把文章貼出來,先譴責一下,很可能是某旅遊社的人為了打廣告 僱人幹的。

二、解決方法

這個庫我們是每天凌晨備份,保留30天的備份。主庫的Binlog保留時間為7天。

因此很容易想到的方法是將從庫2014-09-25凌晨的備份拿出來恢復,然後通過主庫的Binlog通過時間段來篩選出凌晨至2014-09-25 21:53:56的所有更改,之後的數據,經業務確認,可以捨棄掉。或者後面再通過其他方法慢慢將這部分數據找出來。但是當務之急,是立馬恢復資料庫。

三、找備份及時間點

在備份的從庫上檢查備份:

crontab -l
#0 3 * * * /data/opdir/mysqlbak/backup_mysqldump.sh 6084 >> /data/opdir/mysqlbak/6084/mysql-bakup.log 2>&1

發現備份任務讓注釋了

查看備份文件:

<p>[root@localhost 6084]# ll</p><p>total 128</p><p>drwxr-xr-x 2 root root 4096 Aug 25 03:13 20140825</p><p>drwxr-xr-x 2 root root 4096 Aug 26 03:13 20140826</p><p>drwxr-xr-x 2 root root 4096 Aug 27 03:13 20140827</p><p>drwxr-xr-x 2 root root 4096 Aug 28 03:13 20140828</p><p>drwxr-xr-x 2 root root 4096 Aug 29 03:13 20140829</p><p>drwxr-xr-x 2 root root 4096 Aug 30 03:13 20140830</p><p>drwxr-xr-x 2 root root 4096 Aug 31 03:13 20140831</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;1 03:13 20140901</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;2 03:13 20140902</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;3 03:13 20140903</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;4 03:13 20140904</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;5 03:13 20140905</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;6 03:13 20140906</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;7 03:13 20140907</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;8 03:13 20140908</p><p>drwxr-xr-x 2 root root 4096 Sep &nbsp;9 03:13 20140909</p><p>drwxr-xr-x 2 root root 4096 Sep 10 03:13 20140910</p><p>drwxr-xr-x 2 root root 4096 Sep 11 03:13 20140911</p><p>drwxr-xr-x 2 root root 4096 Sep 12 03:13 20140912</p><p>drwxr-xr-x 2 root root 4096 Sep 13 03:13 20140913</p><p>drwxr-xr-x 2 root root 4096 Sep 14 03:13 20140914</p><p>drwxr-xr-x 2 root root 4096 Sep 15 03:13 20140915</p><p>drwxr-xr-x 2 root root 4096 Sep 16 03:13 20140916</p><p>drwxr-xr-x 2 root root 4096 Sep 17 03:13 20140917</p><p>drwxr-xr-x 2 root root 4096 Sep 18 03:14 20140918</p><p>drwxr-xr-x 2 root root 4096 Sep 19 03:14 20140919</p><p>drwxr-xr-x 2 root root 4096 Sep 20 03:13 20140920</p><p>drwxr-xr-x 2 root root 4096 Sep 21 03:13 20140921</p><p>drwxr-xr-x 2 root root 4096 Sep 22 03:14 20140922</p><p><strong>drwxr-xr-x 2 root root 4096 Sep 23 18:33 20140923</strong></p><p>-rw-r--r-- 1 root root 5475 Sep 23 18:33 mysql-bakup.log</p>

備份只到20140923日,下午18:33分。

備份日誌最後一段截取:

 tail -n 5 mysql-bakup.log
deleting backup of 30 days ago -- 20140824
2014-09-23 18:19:12 begin backup ...
20140824 deleted OK
2014-09-23 18:33:43 end backup ...

因為這些表是在從庫備份的,而且表都是MyiSAM的表。查看備份腳本,是先Stop Slave之後,才開始備份,因此從備份腳本輸出的日誌中找到備份開始的時間是:

2014-09-23 18:19:12

通過:

Drwxr-xr-x 2 root root 4096 Sep 23 18:33 20140923

可看到結束時間是:2014-09-23 18:33:00

現在考慮到底是以備份開始的時間:2014-09-23 18:19:12 為Start-DateTime還是以2014-09-23 18:33:00 為Start-DateTime。

前面 提到備份腳本是從庫進行備份的,是在2014-09-23 18:19:12開始的,在這個時刻備份開始,執行了Stop Slave;因此整個備份的狀態反映的是從庫2014-09-23 18:19:12 這個時間的狀態。而且通過監控可以看到在這個時間點,從庫的延遲為0,因此可以認為這個備份就是 主庫在這個時間的備份

NOTES:
(有人可能會因為從庫上有Binlog,從庫也會接受主庫的Binlog之類的機制而造成混淆。這裡要結合我們具體的備份方式和恢復方式來看,以選出正確的時間點。)

前面提到通過日誌查到遭到篡改的時間為:2014-09-25 21:53:57,因此可以將2014-09-25 21:53:56作為Stop-DateTime

因此Binlog命令應該是這樣:

<strong>mysqlbinlog --database=[db_name] --start-datetime='2014-09-23&nbsp;</strong><strong>18:19:12</strong><strong>' --stop-datetime='2014-09-25 21:53:56'&nbsp;<br></strong><strong>[binlog_name] > binlog_name0000x.sql</strong>

四、具體的恢復操作

清楚了這些,具體的操作就簡單了:

1.從備份機拷貝備份:

SCP<備份機IP>:/data/MySQLbak/20140923/20140923.db_name.gz <恢復測試機IP>:/data/opdir/20140926

2.恢復測試機 解壓:

gunzip 20140923.db_name.gz

3.恢復測試機導入(測試恢復庫中之前沒有db_name這個庫):

MySQL -uroot -pxxxxxx -S /tmp/MySQL.sock < 20140923.db_name

4.將主庫的Binlog拷貝到恢復測試機:

查看主庫Binlog

-rw-rw---- 1 MySQL MySQL &nbsp;87669492 Sep 23 00:00 MySQL-bin.000469<br>-rw-rw---- 1 MySQL MySQL 268436559 Sep 23 04:20 MySQL-bin.000470<br>-rw-rw---- 1 MySQL MySQL 268435558 Sep 23 17:32 MySQL-bin.000471<br>-rw-rw---- 1 MySQL MySQL &nbsp;37425262 Sep 24 00:00 MySQL-bin.000472<br>-rw-rw---- 1 MySQL MySQL 137389819 Sep 25 00:00 MySQL-bin.000473<br>-rw-rw---- 1 MySQL MySQL 147386521 Sep 26 00:00 MySQL-bin.000474<br>我們需要的Binlog時間段為:2014-09-23 18:28:00 至 2014-09-25 21:53:56<br>因此只需要:<br>-rw-rw---- 1 MySQL MySQL &nbsp;37425262 Sep 24 00:00 MySQL-bin.000472<br>-rw-rw---- 1 MySQL MySQL 137389819 Sep 25 00:00 MySQL-bin.000473<br>-rw-rw---- 1 MySQL MySQL 147386521 Sep 26 00:00 MySQL-bin.000474

將這3個Binlog  Copy過去:

SCP MySQL-bin.000472 <恢復測試機IP>:/data/opdir/20140926
SCP MySQL-bin.000473 <恢復測試機IP>:/data/opdir/20140926
SCP MySQL-bin.000474 <恢復測試機IP>:/data/opdir/20140926

5.使用MySQLBinlog 生成SQL腳本:

MySQLBinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56'&nbsp;<br>MySQL-bin.000472 > 472.SQL<br>MySQLBinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56'&nbsp;<br>MySQL-bin.000473 > 473.SQL<br>MySQLBinlog --database=[db_name] --start-datetime='2014-09-23 18:19:12' --stop-datetime='2014-09-25 21:53:56'&nbsp;<br>MySQL-bin.000474 > 474SQL

6.Binlog生成的SQL腳本導入:

待20140923.db_name導入到恢復測試庫之後,將MySQLBinlog生成的SQL腳本導入到資料庫中:

MySQL -uroot -pxxxxxx -S /tmp/MySQL.sock db_name < 472.SQL
MySQL -uroot -pxxxxxx -S /tmp/MySQL.sock db_name < 473.SQL
MySQL -uroot -pxxxxxx -S /tmp/MySQL.sock db_name < 474.SQL

7.導入完成後檢查數據正確性:

大致看一下數據的情況,然後可以通過時間欄位來看一下情況:

MySQL> select max(createtime),max(updatetime) from table_name;<br>+-----------------+-----------------+<br>| max(createtime) | max(updatetime) |<br>+-----------------+-----------------+<br>| &nbsp; &nbsp; &nbsp;1411648043 | &nbsp; &nbsp; &nbsp;1411648043 |<br>+-----------------+-----------------+<br>1 row in set (0.00 sec)

時間差不多為 晚上20:27了

這個判斷,作為DBA,查看部分數據,只能起到輔助作用,具體的需要 到底是否OK,需要業務開發的人來判斷。

經過業務開發確認後,即可將該數據導出後,再導入到線上主庫中。

8、將該庫導出,並壓縮:

MySQLdump -uroot -pxxxxxx -S /tmp/MySQL.sock -q db_name table_name > table_name.SQL 

壓縮:

gzip table_name.SQL

SCP 到主庫 (複製的時候,請將網絡因素考慮進去,確認不會佔用過多帶寬而影響其他線上業務)

9.恢復測試的數據導入到線上主庫中:

線上主庫操作:

操作之前,最好讓開發把應用業務那段先暫停,否則可能會影響導入。比如這個表示MyISAM的,應用那邊如果不聽有update進來,就會阻塞數據導入。

a、主庫將原始被篡改的表改名:(不要上來就drop,先rename,後續確認沒問題了再考慮drop,因為很多問題不是一瞬間就能全部反映上來的)

rename table_name to old_table_name;

b、解壓:

gunzip table_name.SQL.gz

c、導入新表數據:

MySQL -uroot -pxxxxxx -S /tmp/MySQL.sock db_name < table_name.SQL

後面就需要開發來進一步驗證數據是否 OK 了。 驗證沒問題後,再啟動應用程式。


歡迎訂閱「CSDN雲計算」微信號獲得更多信息。(責編/劉亞瓊)

歡迎關注@CSDN雲計算微博了解最新雲計算及大數據資訊。

相關焦點

  • 【用binlog日誌】恢復 MySQL 資料庫刪除數據
    在數據丟失的緊急情況下,可以嘗試用binlog日誌功能進行數據恢復操作。正是由於binlog日誌以上的特性,在實際的案件取證中也可以通過binlog日誌來恢復刪除數據。要通過binlog日誌恢復mysql資料庫刪除數據的前提:binlog日誌確定是開啟的。
  • MySQL 備份數據那點事
    mysqldump什麼是 mysqldump ?mysqldump 是 MySQL 用於執行邏輯備份的一款工具,可以根據原始資料庫對象以及表的定義和數據來生成一系列可以被執行的 SQL 語句。通常我們用它作為備份或者遷移數據。
  • MySQL - binlog日誌簡介及設置
    前言mysql-binlog是MySQL資料庫的二進位日誌,用於記錄用戶對資料庫操作的SQL語句((除了數據查詢語句)信息。可以使用mysqlbin命令查看二進位日誌的內容。優點:不會出現某些特定情況下的存儲過程、或function、或trigger的調用和觸發無法被正確複製的問題。缺點:會產生大量的日誌,尤其是alter table的時候會讓日誌暴漲。
  • Facebook如何實現PB級資料庫自動化備份
    措施1:二進位日誌和mysqldump  第一道防線稱為「措施1」,或「機架」備份(rack backup),簡稱RBU。在每個資料庫機架上,不論其類型為何,都有兩個RBU存儲伺服器。以RBU作為資料庫伺服器放在同一個機架中,這可以保證最大的帶寬和最小的延遲,它們同時可以作為緩存,在備份的下個措施使用。
  • 必須了解的mysql三大日誌-binlog、redo log和undo log
    日誌是 mysql 資料庫的重要組成部分,記錄著資料庫運行期間各種狀態信息。mysql日誌主要包括錯誤日誌、查詢日誌、慢查詢日誌、事務日誌、二進位日誌幾大類。作為開發,我們重點需要關注的是二進位日誌( binlog )和事務日誌(包括redo log 和 undo log ),本文接下來會詳細介紹這三種日誌。
  • 必須了解的MySQL三大日誌:binlog、redo log和undo log
    日誌是mysql資料庫的重要組成部分,記錄著資料庫運行期間各種狀態信息。mysql日誌主要包括錯誤日誌、查詢日誌、慢查詢日誌、事務日誌、二進位日誌幾大類。作為開發,我們重點需要關注的是二進位日誌(binlog)和事務日誌(包括redo log和undo log),本文接下來會詳細介紹這三種日誌。
  • Mysql數據誤刪除快速回滾
    作者 | Video++極鏈科技OPSTeam整理 | 包包在資料庫操作中,難免會因為各種各樣的原因對數據造成損壞,這個時候就需要對資料庫快速恢復。傳統的方法會先恢復mysql備份,再去用mysqlbinlog抽取指定時間點的日誌,再恢復,這樣的操作比較耗時,容易出錯,那有沒有一種工具可以快速把誤刪除的操作SQL逆過來,然後重新插入誤刪除的數據呢?
  • 解析XtraBackup備份MySQL的原理和過程
    XtraBackup對Innodb的備份之所以是熱備,無需鎖表,是基於Innodb自身的崩潰恢復機制,它首先複製所有的Innodb數據文件,這樣複製出來的文件肯定是不一致的,然後對每個文件進行崩潰恢復處理,最終達到一致。
  • MySQL教程之MySQL定時備份資料庫
    一、MySQL數據備份1.1、 mysqldump命令備份數據在MySQL中提供了命令行導出資料庫數據以及文件的一種方便的工具mysqldump,我們可以通過命令行直接實現資料庫內容的導出dump,首先我們簡單了解一下mysqldump命令用法:
  • 【贈書 - 數據恢復】無備份情況下恢復MySQL誤刪的表
    今天分享的內容,是他在MySQL數據恢復上所做的嘗試。本文主要分享在沒有備份的情況下,MySQL資料庫如何恢復被刪除的表。用的最多的就是Myisam和innodb存儲引擎。目前基本上都是5.5+版本了,我想幾乎沒有人再去使用Myisam了吧。我這裡所測試都5.6,5.7版本中默認都存儲引擎已經是Innodb了。因此這裡我以Innodb引擎為例子進行說明。這裡我們首先來測試innodb_file_per_table為off的情況,即表結構和數據存在同一個文件中。
  • MySQL恢復delete的數據
    MySQL數據表InnoDB引擎表誤刪恢復(共享表空間ibdata1)和獨立表空間MySQL數據表InnoDB引擎表誤刪恢復(獨立表空間innodb_file_per_table=1)的情況下如何恢復數據、如果不幸誤刪了資料庫MySQL資料庫誤刪恢復。
  • MySql 高頻企業面試題
    MySQL中的binlog日誌記錄了數據中的數據變動,便於對數據的基於時間點和基於位置的恢復,但日誌文件的大小會越來越大,點用大量的磁碟空間,因此需要定時清理一部分日誌信息手工刪除:首先查看主從庫正在使用的binlog文件名稱
  • MySQL 中的 binlog 和 relay-log 結構完全詳解
    今天我們來深挖一下mysql的複製機制到底有哪一些,以及binlog和relay-log的結構到底是什麼樣子的。binlog作用binlog的主要作用是記錄資料庫中表的更改,它只記錄改變數據的sql,不改變數據的sql不會寫入,比如select語句一般不會被記錄,因為他們不會對數據產生任何改動。
  • Mysql的binlog和relay-log到底長啥樣?
    上一篇mysql面試的文章之後收到不少朋友的意見,希望深入講講複製、日誌的格式這些,今天,我們就來深挖一下mysql的複製機制到底有哪一些,以及binlog和relay-log的結構到底是什麼樣子的。binlog作用binlog的主要作用是記錄資料庫中表的更改,它只記錄改變數據的sql,不改變數據的sql不會寫入,比如select語句一般不會被記錄,因為他們不會對數據產生任何改動。
  • MySQL update的數據恢復
    電商類的平臺,想必價格管控複查等規範和流程都是健全的,依然避免不了意外(誰也不知道明天和意外哪個先來)。雖然囉嗦,依然想再提醒下:後悔藥數據恢復再次提醒:1,首先需要說明的是,生產環境下慎重執行刪除操作,除非你確實明白自己在做什麼,否則不執行危險動作。2,有條件的情況下,依靠系統來管理數據和資料庫,儘可能降低潛在的管理的風險。
  • canal 1.1.2 發布,阿里 MySQL Binlog 增量訂閱&消費組件
    的binlog解析 【BinlogChange(MySQL8)】canal提供內置的客戶端能力【ClientAdapter】RocketMQ消息支持直接投遞至aliyun ons(RocketMQ雲服務) #1169功能重構MQ消息發送的配置相關從
  • MySQL mysqldump 數據導出詳解
    tmp/user.sql3.導出db1中的a1、a2表注意導出指定表只能針對一個資料庫進行導出,且導出的內容中和導出資料庫也不一樣,導出指定表的導出文本中沒有創建資料庫的判斷語句,只有刪除表-創建表-導入數據mysqldump -uroot -proot --databases db1 --tables a1
  • Mysql資料庫備份和還原常用的命令
    備份MySQL資料庫的命令mysqldump -hhostname -uusername -ppassword databasename > backupfile.sql備份MySQL資料庫為帶刪除表的格式備份MySQL資料庫為帶刪除表的格式,能夠讓該備份覆蓋已有資料庫而不需要手動刪除原有資料庫
  • 面試被問MySQL 主從複製,怎麼破?
    此時,我們可以將資料庫擴展成主從複製模式,將讀操作和寫操作分離開來,多臺資料庫分攤請求,從而減少單庫的訪問壓力,進而應用得到優化。# 3.3 備份主資料庫數據若主從資料庫都是剛剛裝好且數據都是一致的,直接執行 show master status 查看日誌坐標。若主庫可以停機,則直接拷貝所有資料庫文件。若主庫是在線生產庫,可採用 mysqldump 備份數據,因為它對所有存儲引擎均可使用。
  • 新來的妹紙 rm -rf 把公司整個資料庫刪沒了!!!
    打電話到機房,將盤掛到另一臺伺服器上,ssh上去查看文件全部被清,這臺伺服器運行的可是一個客戶的生產系統啊,已經運行大半年了,得儘快恢復啊。於是找來脫機備份的資料庫,發現備份文件只有1kb,裡面只有幾行熟悉的mysqldump注釋(難道是crontab執行的備份腳本有問題),最接盡的備份也是2013年12月份的了,真是屋漏偏逢連夜雨啊。