Jak poprawnie deobfusacte skrypt Perla?

Próbuję deobfuscate następujący kod Perla ( źródło):

#!/usr/bin/perl
(my$d=q[AA                GTCAGTTCCT
  CGCTATGTA                 ACACACACCA
    TTTGTGAGT                ATGTAACATA
      CTCGCTGGC              TATGTCAGAC
        AGATTGATC          GATCGATAGA
          ATGATAGATC     GAACGAGTGA
            TAGATAGAGT GATAGATAGA
              GAGAGA GATAGAACGA
                TC GATAGAGAGA
                 TAGATAGACA G
               ATCGAGAGAC AGATA
             GAACGACAGA TAGATAGAT
           TGAGTGATAG    ACTGAGAGAT
         AGATAGATTG        ATAGATAGAT
       AGATAGATAG           ACTGATAGAT
     AGAGTGATAG             ATAGAATGAG
   AGATAGACAG               ACAGACAGAT
  AGATAGACAG               AGAGACAGAT
  TGATAGATAG             ATAGATAGAT
  TGATAGATAG           AATGATAGAT
   AGATTGAGTG        ACAGATCGAT
     AGAACCTTTCT   CAGTAACAGT
       CTTTCTCGC TGGCTTGCTT
         TCTAA CAACCTTACT
           G ACTGCCTTTC
           TGAGATAGAT CGA
         TAGATAGATA GACAGAC
       AGATAGATAG  ATAGAATGAC
     AGACAGAGAG      ACAGAATGAT
   CGAGAGACAG          ATAGATAGAT
  AGAATGATAG             ACAGATAGAC
  AGATAGATAG               ACAGACAGAT
  AGACAGACTG                 ATAGATAGAT
   AGATAGATAG                 AATGACAGAT
     CGATTGAATG               ACAGATAGAT
       CGACAGATAG             ATAGACAGAT
         AGAGTGATAG          ATTGATCGAC
           TGATTGATAG      ACTGATTGAT
             AGACAGATAG  AGTGACAGAT
               CGACAGA TAGATAGATA
                 GATA GATAGATAG
                    ATAGACAGA G
                  AGATAGATAG ACA
                GTCGCAAGTTC GCTCACA
])=~s/\s+//g;%a=map{chr $_=>$i++}65,84,67,
71;$p=join$;,keys%a;while($d=~/([$p]{4})/g
){next if$j++%96>=16;$c=0;for$d(0..3){$c+=
$a{substr($1,$d,1)}*(4**$d)}$perl.=chr $c}
             eval $perl;

Po uruchomieniu wyświetla Just another genome hacker.

Po uruchomieniu koryta kodu Deparse i perltidy (perl -MO=Deparse jagh.pl | perltidy) kod wygląda tak:

( my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;
(%a) = map( { chr $_, $i++; } 65, 84, 67, 71 );
$p = join( $;, keys %a );
while ( $d =~ /([$p]{4})/g ) {
    next if $j++ % 96 >= 16;
    $c = 0;
    foreach $d ( 0 .. 3 ) {
        $c += $a{ substr $1, $d, 1 } * 4**$d;
    }
    $perl .= chr $c;
}
Oto, co udało mi się rozszyfrować na własną rękę.
( my $d =
"AA...GCTCACA\n" # snipped double helix part
) =~ s/\s+//g;

Usuwa wszystkie białe spacje w $d (podwójna helisa).

(%a) = map( { chr $_, $i++; } 65, 84, 67, 71 );

Tworzy hash z kluczamiA, T, C i G oraz jako wartości 0, 1, 2 oraz 3. Zwykle koduję w Pythonie, więc to tłumaczy się na słownik {'A': 0, 'B': 1, 'C': 2, 'D': 3} w Pythonie.

$p = join( $;, keys %a );

Łączy klucze hash z $; separatorem dla wielowymiarowej emulacji tablicy . Dokumentacja mówi, że domyślną wartością jest "\034" , tak samo jak SUBSEP w awk, ale kiedy to zrobię:

my @ascii = unpack("C*", $p);
print @ascii[1];

Dostanę wartość 28? Ponadto, nie jest dla mnie jasne, w jaki sposób emuluje to wielowymiarową tablicę. Jest $p teraz coś jak [['A'], ['T'], ['C'], ['G']] W Python?

    while ( $d =~ /([$p]{4})/g ) {

Dopóki $d pasuje ([$p]{4}), wykonaj kod w bloku while. ale ponieważ nie do końca rozumiem, czym jest struktura $p, trudno mi również zrozumieć, co się tutaj dzieje.

next if $j++ % 96 >= 16;

Kontynuuj, jeśli $j modulo 96 jest większe lub równe 16. $j przyrost z każdym przejściem pętli while (?).

$c = 0;
foreach $d ( 0 .. 3 ) {
    $c += $a{ substr $1, $d, 1 } * 4**$d;
}

Dla $d w zakresie od 0 do 3 wyodrębnij jakiś podciąg, ale w tym momencie jestem całkowicie zagubiony. Na ostatnie kilka linii łączy wszystko i ocenia wynik.

Author: Braiam, 2012-02-18

1 answers

Uwaga: nie uruchamiaj ślepo zaciemnionego Perla, zwłaszcza jeśli istnieje eval, backticks, system, open, itd. zadzwoń gdzieś w nim i to może nie być zbyt oczywiste*. Usuń zaciemnienie za pomocą Deparse i ostrożnie zastąp evals instrukcjami print jest koniecznością, dopóki nie zrozumiesz o co chodzi. Należy również rozważyć uruchomienie w piaskownicy/z nieuprzywilejowanym użytkownikiem/w maszynie wirtualnej.

*s&&$_ⅇ ocenia $_ dla intance.


Pierwsza obserwacja: 034 jest ósemkowa. Jest równa 28 (dec) lub 0x1c( hex), więc nic podejrzanego.

Rzecz $; jest czysto zaciemniająca, nie mogę znaleźć powodu, aby użyć tego w szczególności. $p będzie po prostu ciągiem A.T.C.G (z . zastąpionym przez $;, cokolwiek to jest).
Tak więc w regex [$p] pasuje do dowolnego z {'A', 'T', 'C', 'G', $;}. Ponieważ $; nigdy nie pojawia się w $d, jest tam bezużyteczny. Z kolei [$p]{4} pasuje do dowolnej sekwencji czterech liter w powyższym zbiorze, jakby to było użyte (ignorując bezużyteczne $;):

while ( $d =~ /([ATCG]{4})/g ) { ... }

Gdybyś musiał to napisać sam, po usunięciu spacji, po prostu chwyciłbyś każdy kolejny podłańcuch $d o długości 4 (zakładając, że nie ma innych znaków w $d).

Teraz ta część jest fajna:

foreach $d ( 0 .. 3 ) {
    $c += $a{ substr $1, $d, 1 } * 4**$d;
}
  • $1 posiada aktualny czteroliterowy kod. substr $1, $d, 1 zwraca każdą kolejną literę z tego punktu kodowego.
  • %a maps A to 00B (binary), T to 01b, C do 10B i G do 11b.

    A   00
    T   01
    C   10
    G   11
    
  • Mnożenie przez 4**$d będzie równoważne przesunięciu w lewo 0, 2, 4 i 6.

Więc ten zabawny konstrukt pozwala zbudować dowolną wartość 8-bitową w systemie czterech baz z ATCG jako cyframi!

Tzn. wykonuje następujące przekształcenia:

         A A A A
AAAA -> 00000000

         T A A T
TAAT -> 01000001 -> capital A in ascii

         T A A C
CAAT -> 01000010 -> capital B in ascii

CAATTCCTGGCTGTATTTCTTTCTGCCT -> BioGeek

Ta część:

next if $j++ % 96 >= 16;

Sprawia, że powyższa konwersja działa tylko dla pierwszych 16 "punktów kodowych", pomija następne 80, a następnie konwertuje na następne 16, pomija następne 80 itd. Zasadniczo po prostu pomija części elipsy (system usuwania śmieci DNA).


Oto brzydki konwerter tekstu na DNA, którego możesz użyć do wytworzenia wszystkiego, co zastąpi helisę (nie obsługuje 80 skip): {]}

use strict;
use warnings;
my $in = shift;

my %conv = ( 0 => 'A', 1 => 'T', 2 => 'C', 3 => 'G');

for (my $i=0; $i<length($in); $i++) {
    my $chr = substr($in, $i, 1);
    my $chv = ord($chr);
    my $encoded ="";
    $encoded .= $conv{($chv >> 0) & 0x3};
    $encoded .= $conv{($chv >> 2) & 0x3};
    $encoded .= $conv{($chv >> 4) & 0x3};
    $encoded .= $conv{($chv >> 6) & 0x3};
    print $encoded;
}
print "\n";
$ perl q.pl 'print "BioGeek\n";'
AAGTCAGTTCCTCGCTATGTAACACACACAATTCCTGGCTGTATTTCTTTCTGCCTAGTTCGCTCACAGCGA

Włóż $d to zamiast helisy (i usuń część pomijającą w dekoderze).

 50
Author: Mat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-18 17:18:04