Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

pre-istwa

Se konsa, li te rive ke sèvè a te atake pa yon viris ransomware, ki, pa yon "aksidan chans," pasyèlman kite dosye yo .ibd (fichye done anvan tout koreksyon nan tab innodb) intact, men an menm tan an konplètman ankripte dosye yo .fpm ( dosye estrikti). Nan ka sa a, .idb ka divize an:

  • sijè a restorasyon atravè zouti estanda ak gid. Pou ka sa yo, gen yon ekselan vin;
  • tab ki pasyèlman chiffres. Sitou sa yo se gwo tab, pou ki (jan mwen konprann) atakè yo pa t 'gen ase RAM pou chifreman konplè;
  • Oke, tab konplètman chiffres ki pa ka restore.

Li te posib pou detèmine ki opsyon tab yo fè pati nan tou senpleman louvri li nan nenpòt editè tèks anba kodaj la vle (nan ka mwen an se UTF8) epi tou senpleman gade fichye a pou prezans nan jaden tèks, pou egzanp:

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

Epitou, nan kòmansman an nan dosye a ou ka obsève yon gwo kantite 0 bytes, ak viris ki itilize algorithm chifreman an blòk (ki pi komen an) anjeneral afekte yo tou.
Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

Nan ka mwen an, atakè yo te kite yon fisèl 4-byte (1, 0, 0, 0) nan fen chak fichye chiffres, ki senplifye travay la. Pou chèche dosye ki pa enfekte, script la te ase:

def opened(path):
    files = os.listdir(path)
    for f in files:
        if os.path.isfile(path + f):
            yield path + f

for full_path in opened("C:somepath"):
    file = open(full_path, "rb")
    last_string = ""
    for line in file:
        last_string = line
        file.close()
    if (last_string[len(last_string) -4:len(last_string)]) != (1, 0, 0, 0):
        print(full_path)

Kidonk, li te tounen soti jwenn dosye ki fè pati premye kalite a. Dezyèm lan enplike yon anpil nan travay manyèl, men sa yo te jwenn te deja ase. Tout bagay ta byen, men ou bezwen konnen estrikti absoliman egzak ak (nan kou) yon ka leve ke mwen te gen nan travay ak yon tab souvan chanje. Pa gen moun ki sonje si yo te chanje kalite jaden an oswa si yo te ajoute yon nouvo kolòn.

Wilds City, malerezman, pa t 'kapab ede ak yon ka konsa, ki se poukisa atik sa a yo te ekri.

Ale nan pwen an

Gen yon estrikti nan yon tab ki soti nan 3 mwa de sa ki pa kowenside ak yon sèl aktyèl la (pètèt yon jaden, e pètèt plis). Estrikti tab la:

CREATE TABLE `table_1` (
    `id` INT (11),
    `date` DATETIME ,
    `description` TEXT ,
    `id_point` INT (11),
    `id_user` INT (11),
    `date_start` DATETIME ,
    `date_finish` DATETIME ,
    `photo` INT (1),
    `id_client` INT (11),
    `status` INT (1),
    `lead__time` TIME ,
    `sendstatus` TINYINT (4)
); 

nan ka sa a, ou bezwen ekstrè:

  • id_point int(11);
  • id_user int(11);
  • date_start DATETIME;
  • date_finish DATETIME.

Pou rekiperasyon, yo itilize yon analiz byte-pa-byte nan fichye a .ibd, ki te swiv pa konvèti yo nan yon fòm ki pi lizib. Depi pou jwenn sa nou bezwen, nou sèlman bezwen analize kalite done tankou int ak datatime, atik la pral dekri sèlman yo, men pafwa nou pral tou refere a lòt kalite done, ki ka ede nan lòt ensidan menm jan an.

Pwoblèm 1: jaden ak kalite DATETIME ak TEXT te gen valè NULL, epi yo tou senpleman sote nan fichye a, poutèt sa, li pa t 'posib detèmine estrikti a retabli nan ka mwen an. Nan nouvo kolòn yo, valè default la te nil, epi yon pati nan tranzaksyon an ka pèdi akòz anviwònman innodb_flush_log_at_trx_commit = 0, kidonk plis tan ta dwe pase pou detèmine estrikti a.

Pwoblèm 2: li ta dwe pran an kont ke ranje efase atravè DELETE yo pral tout nan fichye ibd la, men ak ALTER TABLE estrikti yo pa pral mete ajou. Kòm yon rezilta, estrikti done a ka varye depi nan konmansman an nan dosye a nan fen li yo. Si ou souvan itilize OPTIMIZE TABLE, lè sa a ou pa gen anpil chans pou rankontre yon pwoblèm konsa.

Peye atansyon, vèsyon DBMS a afekte fason done yo estoke, epi egzanp sa a ka pa travay pou lòt vèsyon pi gwo. Nan ka mwen an, yo te itilize vèsyon an Windows nan mariadb 10.1.24. Epitou, byenke nan mariadb ou travay ak tab InnoDB, an reyalite yo ye XtraDB, ki eksklizyon aplikasyon an nan metòd la ak InnoDB mysql.

Analiz dosye

Nan python, kalite done byte () montre done Unicode nan plas yon seri nimewo regilye. Malgre ke ou ka wè dosye a nan fòm sa a, pou konvenyans ou ka konvèti byte yo nan fòm nimerik lè w konvèti etalaj la byte nan yon etalaj regilye (list(example_byte_array)). Nan nenpòt ka, tou de metòd yo apwopriye pou analiz.

Apre w fin gade plizyè fichye ibd, ou ka jwenn bagay sa yo:

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

Anplis, si ou divize dosye a pa mo kle sa yo, ou pral jwenn sitou menm blòk done. Nou pral sèvi ak infimum kòm yon divizyon.

table = table.split("infimum".encode())

Yon obsèvasyon enteresan: pou tab ki gen yon ti kantite done, ant infimum ak supremum gen yon konsèy sou kantite ranje nan blòk la.

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la - tab tès ak 1ye ranje

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la - tab tès ak 2 ranje

Tablo etalaj ranje [0] yo ka sote. Apre gade nan li, mwen te toujou kapab jwenn done yo tablo anvan tout koreksyon. Gen plis chans, blòk sa a itilize pou estoke endèks ak kle yo.
Kòmanse ak tab [1] epi tradui li nan yon etalaj nimerik, ou ka deja remake kèk modèl, sètadi:

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

Sa yo se valè int ki estoke nan yon fisèl. Premye byte a endike si nimewo a pozitif oswa negatif. Nan ka mwen an, tout nimewo yo pozitif. Soti nan 3 octets ki rete yo, ou ka detèmine nimewo a lè l sèvi avèk fonksyon sa a. Script:

def find_int(val: str):  # example '128, 1, 2, 3'
    val = [int(v) for v in  val.split(", ")]
    result_int = val[1]*256**2 + val[2]*256*1 + val[3]
    return result_int

Pou egzanp, 128, 0, 0, 1 = 1Oswa 128, 0, 75, 108 = 19308.
Tablo a te gen yon kle prensipal ak oto-enkreman, epi li ka jwenn tou isit la

Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la

Lè w fin konpare done ki soti nan tab tès yo, li te revele ke objè DATETIME a konsiste de 5 byte epi li te kòmanse ak 153 (gen plis chans ki endike entèval anyèl). Depi seri DATTIME se '1000-01-01' rive '9999-12-31', mwen panse ke kantite bytes ka varye, men nan ka mwen an, done yo tonbe nan peryòd 2016 rive 2019, kidonk nou pral sipoze. sa 5 octets ase.

Pou detèmine tan an san segonn, yo te ekri fonksyon sa yo. Script:

day_ = lambda x: x % 64 // 2  # {x,x,X,x,x }

def hour_(x1, x2):  # {x,x,X1,X2,x}
    if x1 % 2 == 0:
        return x2 // 16
    elif x1 % 2 == 1:
        return x2 // 16 + 16
    else:
        raise ValueError

min_ = lambda x1, x2: (x1 % 16) * 4 + (x2 // 64)  # {x,x,x,X1,X2}

Li pa t 'posib ekri yon fonksyon fonksyonèl pou ane a ak mwa, kidonk mwen te oblije Hack li. Script:

ym_list = {'2016, 1': '153, 152, 64', '2016, 2': '153, 152, 128', 
           '2016, 3': '153, 152, 192', '2016, 4': '153, 153, 0',
           '2016, 5': '153, 153, 64', '2016, 6': '153, 153, 128', 
           '2016, 7': '153, 153, 192', '2016, 8': '153, 154, 0', 
           '2016, 9': '153, 154, 64', '2016, 10': '153, 154, 128', 
           '2016, 11': '153, 154, 192', '2016, 12': '153, 155, 0',
           '2017, 1': '153, 155, 128', '2017, 2': '153, 155, 192', 
           '2017, 3': '153, 156, 0', '2017, 4': '153, 156, 64',
           '2017, 5': '153, 156, 128', '2017, 6': '153, 156, 192',
           '2017, 7': '153, 157, 0', '2017, 8': '153, 157, 64',
           '2017, 9': '153, 157, 128', '2017, 10': '153, 157, 192', 
           '2017, 11': '153, 158, 0', '2017, 12': '153, 158, 64', 
           '2018, 1': '153, 158, 192', '2018, 2': '153, 159, 0',
           '2018, 3': '153, 159, 64', '2018, 4': '153, 159, 128', 
           '2018, 5': '153, 159, 192', '2018, 6': '153, 160, 0',
           '2018, 7': '153, 160, 64', '2018, 8': '153, 160, 128',
           '2018, 9': '153, 160, 192', '2018, 10': '153, 161, 0', 
           '2018, 11': '153, 161, 64', '2018, 12': '153, 161, 128',
           '2019, 1': '153, 162, 0', '2019, 2': '153, 162, 64', 
           '2019, 3': '153, 162, 128', '2019, 4': '153, 162, 192', 
           '2019, 5': '153, 163, 0', '2019, 6': '153, 163, 64',
           '2019, 7': '153, 163, 128', '2019, 8': '153, 163, 192',
           '2019, 9': '153, 164, 0', '2019, 10': '153, 164, 64', 
           '2019, 11': '153, 164, 128', '2019, 12': '153, 164, 192',
           '2020, 1': '153, 165, 64', '2020, 2': '153, 165, 128',
           '2020, 3': '153, 165, 192','2020, 4': '153, 166, 0', 
           '2020, 5': '153, 166, 64', '2020, 6': '153, 1, 128',
           '2020, 7': '153, 166, 192', '2020, 8': '153, 167, 0', 
           '2020, 9': '153, 167, 64','2020, 10': '153, 167, 128',
           '2020, 11': '153, 167, 192', '2020, 12': '153, 168, 0'}

def year_month(x1, x2):  # {x,X,X,x,x }

    for key, value in ym_list.items():
        key = [int(k) for k in key.replace("'", "").split(", ")]
        value = [int(v) for v in value.split(", ")]
        if x1 == value[1] and x2 // 64 == value[2] // 64:
            return key
    return 0, 0

Mwen sèten ke si ou pase n kantite tan, enkonpreyansyon sa a ka korije.
Apre sa, yon fonksyon ki retounen yon objè datetime soti nan yon fisèl. Script:

def find_data_time(val:str):
    val = [int(v) for v in val.split(", ")]
    day = day_(val[2])
    hour = hour_(val[2], val[3])
    minutes = min_(val[3], val[4])
    year, month = year_month(val[1], val[2])
    return datetime(year, month, day, hour, minutes)

Jere yo detekte valè ki repete souvan soti nan int, int, datetime, datetime Rekipere done ki soti nan tab XtraDB san yon dosye estrikti lè l sèvi avèk analiz byte-pa-byte nan dosye ibd la, li sanble ke sa a se sa ou bezwen. Anplis, tankou yon sekans pa repete de fwa pou chak liy.

Sèvi ak yon ekspresyon regilye, nou jwenn done ki nesesè yo:

fined = re.findall(r'128, d*, d*, d*, 128, d*, d*, d*, 153, 1[6,5,4,3]d, d*, d*, d*, 153, 1[6,5,4,3]d, d*, d*, d*', int_array)

Tanpri sonje ke lè w ap chèche lè w ap itilize ekspresyon sa a, li p ap posib pou detèmine valè NULL nan jaden obligatwa yo, men nan ka mwen an sa a pa kritik. Lè sa a, nou ale nan sa nou te jwenn nan yon bouk. Script:

result = []
for val in fined:
    pre_result = []
    bd_int  = re.findall(r"128, d*, d*, d*", val)
    bd_date= re.findall(r"(153, 1[6,5,4,3]d, d*, d*, d*)", val)
    for it in bd_int:
        pre_result.append(find_int(bd_int[it]))
    for bd in bd_date:
        pre_result.append(find_data_time(bd))
    result.append(pre_result)

Aktyèlman, sa a tout, done ki soti nan etalaj la rezilta se done nou bezwen yo. ###PS.###
Mwen konprann ke metòd sa a pa apwopriye pou tout moun, men objektif prensipal la nan atik la se ankouraje aksyon olye ke rezoud tout pwoblèm ou yo. Mwen panse ke solisyon ki pi kòrèk la ta dwe kòmanse etidye kòd sous la tèt ou mariadb, men akòz tan limite, metòd aktyèl la te sanble yo dwe pi rapid la.

Nan kèk ka, apre w fin analize dosye a, ou pral kapab detèmine estrikti apwoksimatif la epi restore li lè l sèvi avèk youn nan metòd estanda ki soti nan lyen ki anwo yo. Sa a pral pi kòrèk epi lakòz mwens pwoblèm.

Sous: www.habr.com

Add nouvo kòmantè