sistema sintaxis programacion guia ejemplos ejecutar desde completo comando cero aprender perl deobfuscation

sintaxis - perl guia completo pdf



¿Cómo deobfusacte correctamente una secuencia de comandos de Perl? (1)

Estoy tratando de desofuscar el siguiente código de Perl ( source ):

#!/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;

Cuando se ejecuta, imprime Just another genome hacker.

Después de ejecutar el código a través de Deparse y perltidy ( perl -MO=Deparse jagh.pl | perltidy ) el código se ve así:

( 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; }

Esto es lo que he podido descifrar por mi cuenta.

( my $d = "AA...GCTCACA/n" # snipped double helix part ) =~ s//s+//g;

elimina todos los espacios en blanco en $d (la doble hélice).

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

hace un hash con las teclas A , T , C y G y como valores 0 , 1 , 2 y 3 . Normalmente código en Python, por lo que esto se traduce en un diccionario {''A'': 0, ''B'': 1, ''C'': 2, ''D'': 3} en Python.

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

une las teclas del hash con $; el separador de subíndices para la emulación de matriz multidimensional . La documentación dice que el valor predeterminado es "/ 034", lo mismo que SUBSEP en awk, pero cuando lo hago:

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

Me sale el valor 28 ? Además, no me queda claro cómo emula esto una matriz multidimensional. ¿Es $p algo así como [[''A''], [''T''], [''C''], [''G'']] en Python?

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

Siempre que $d coincida ([$p]{4}) , ejecute el código en el bloque while. pero como no entiendo completamente qué estructura es $p , también me cuesta entender qué sucede aquí.

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

Continúe si el $j módulo 96 es mayor o igual a 16. Incrementos de $j con cada pasada del ciclo while (?).

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

Para $d en el rango de 0 a 3 extrae alguna subcadena, pero en este punto estoy completamente perdido. Las últimas líneas concatenan todo y evalúan el resultado.


Precaución : no ejecute ciegamente perl ofuscado, especialmente si hay un eval , backticks, system , open , etc. llame a algún lugar y eso puede no ser demasiado obvio * . Deparse con Deparse y reemplazar cuidadosamente las eval con declaraciones impresas es una obligación hasta que comprenda lo que está sucediendo. También se debe considerar ejecutar en una zona de pruebas / con un usuario sin privilegios / en una máquina virtual.

* s&&$_ⅇ evalúa $_ por intance.

Primera observación: 034 es octal. Es igual a 28 (dec) o 0x1c (hex), por lo que no hay nada sospechoso allí.

El $; la cosa es pura ofuscación, no puedo encontrar una razón para usar eso en particular. $p solo será una cadena ATCG (con . reemplazado por $; lo que sea).
Por lo tanto, en la expresión regular [$p] coincide cualquiera de {''A'', ''T'', ''C'', ''G'', $;} . Desde $; nunca aparece en $d , es inútil allí. A su vez [$p]{4} coincide con cualquier secuencia de cuatro letras en el conjunto anterior, como si se hubiera usado (ignorando el inútil $; ):

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

Si tuviera que escribir esto usted mismo, después de haber eliminado el espacio en blanco, simplemente tomaría cada subcadena sucesiva de $d de longitud cuatro (suponiendo que no haya otros caracteres en $d ).

Ahora esta parte es divertida:

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

  • $1 contiene el punto de código actual de cuatro letras. substr $1, $d, 1 devuelve cada letra sucesiva de ese punto de código.
  • %a asigna A a 00b (binario), T a 01b, C a 10b y G a 11b.

    A 00 T 01 C 10 G 11

  • multiplicar por 4**$d será equivalente a un desplazamiento a la izquierda en el bit de 0, 2, 4 y 6.

¡Así que esta divertida construcción te permite construir cualquier valor de 8 bits en el sistema de base cuatro con ATCG como dígitos!

es decir, hace las siguientes conversiones:

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

Esta parte:

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

hace que la conversión anterior se ejecute solo para los primeros 16 "puntos de código", se salta los siguientes 80, luego se convierte para los siguientes 16, salta los siguientes 80, etc. Básicamente se saltea partes de la elipse (sistema de eliminación de ADN basura).

Aquí hay un feo convertidor de texto a ADN que puede usar para producir cualquier cosa que reemplace la hélice (no maneja el tema de omisión de 80):

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

Adhiere $d que en lugar de la hélice (y elimina la parte de saltar en el decodificador).