====== UTM - extract plx files ======
===== Hintergrund =====
Möchte wissen wie die UTM (eine Firewall von sophos) ein Backup erstellt/wiederherstellt.
Seitens sophos werden Perl-Scripte eingesetzt, die durch ActiveStates PerlApp als Binaries vorliegen. Ein einfaches entpacken wie bei anderen Lösungen ist nicht möglich.
===== Setup =====
VM1: Windows mit IDA Pro\\
VM2: Sophos UTM
Verbunden durch ein "internal Network" von VirtualBox
===== Bisherige Erkenntnisse =====
* Es wird zlib 1.1.4 verwendet.
* Der Quellcode ist wiederherstellbar
* Es liest sich via /proc/self/exe selber ein
=====Reversing =====
=== Ablauf (BFS) ===
0013d80: 7f3a 5baa 0200 0000 4038 0000 7000 a108 .:[.....@8..p...
0013d90: 810e 2ade 0974 65d1 f74e 2ee4 9fa8 28db ..*..te..N....(.
0013da0: 9a5e 6b26 89a6 1068 b8fb 62a1 433f f4c4 .^k&...h..b.C?..
0013db0: 4d1e a356 9208 2789 5656 6df5 fe96 d198 M..V..'.VVm.....
0013dc0: f43c be7e e2cf e69b ca48 3c0d 8730 d2d4 .<.~.....H<..0..
Der Packer durchsucht sich selbst nach einem Magic value von **0x7f 0x3a 0x5b 0xaa 0x02 0x00 0x00 0x00**. In Wirklichkeit sind dies zwei Magic values. 0x02 0x00 0x00 0x00 ist ein weitere um nicht an der falschen Stelle anzusetzen.
**0x40 0x38 0x00 0x00**, nach dem Magic, ist die Länge der Datei als auch gleichzeitig der XOR-Key
Heraus kommt eine BFS-File
00000000 ff 42 46 53 02 00 00 00 d0 37 00 00 08 00 00 00 |.BFS.....7......|
=== Ablauf (Post-BFS) ===
Das BFS-File ist ein Archive an sich. Es beinhaltet einen unbekannten Header, gefolgt von mehreren zlib-Elementen.
Entpacken kann man dies mit mittels **binwalk -e**.
Jedes dieser Elemente ist _nach_ dem entpacken jedoch erneut mit XOR bearbeitet. Der Key war durch ein Bruteforce jedoch leicht zu finden.\\
Er lautet **0xEA**.
Heraus kommen Klartext-Dateien, nebst eigenen Abhängigkeiten des Packers auch diverse andere Perl-Module.
=== BFS-Dumper ===
Krater hat einen PoC geschrieben um BFS-Daten zu finden und zu XORn
#include
#include
#include
void shift(unsigned char *buf);
void decodedata(FILE *f);
int main()
{
FILE *f=fopen("backup.plx","rb");
unsigned char buf[8]={0};
unsigned char magic[]={0x7f,0x3a,0x5b,0xaa,0x02,0x00,0x00,0x00};
while(!feof(f))
{
if(!memcmp(buf,magic,8))
{
printf("found!\n");
decodedata(f);
break;
}
shift(buf);
fread(buf+7,1,1,f);
}
fclose(f);
return 0;
}
void decodedata(FILE *f)
{
unsigned int length;
unsigned short offset;
fread(&length,4,1,f);
fread(&offset,2,1,f);
printf("found %u bytes data at offset %u\n",length,offset);
fseek(f,offset-(6+8),SEEK_CUR);
unsigned char *data=(unsigned char*)malloc(length);
fread(data,1,length,f);
unsigned int *d=(unsigned int *)data;
for(int i=0;i<(length/4);i++)
{
d[i]^=length;
}
FILE *o=fopen("output.data","wb");
fwrite(data,1,length,o);
fclose(o);
}
void shift(unsigned char *buf)
{
for(int i=0;i<7;i++)
{
buf[i]=buf[i+1];
}
}
BFS scheint das Format von flatout zu sein. Zumindest ähnelt sich das Format von BFS aus Flatout2. [[https://github.com/synopia/bfs2pack|Hier ein Repo zu einem Quelloffenen unpacker]]
===== MEMORY DUMP =====
==== Ansatz ====
Die entdeckte Perl-Datei(en) sollte(n) im Memory liegen.
==== Dump-Zeitpunkt ====
Prozesse sterben relativ schnell, wir müssen zum richtigen Zeitpunkt einen Memory Dump erstellen.
Ein Prozess **"confd.plx"** übergibt per TCP über den Port **4472** dem Prozess **"backup.plx"** auf Nachfrage Konfigurationen. Hier sollte der Perl-Code bereits entpackt sein.
''killall -r confd && nc -l 4472''
Die Kommunikation mit **"confd.plx"** lässt sich so ersetzen. Das Timeout auf eine Antwort ist hier sehr lange.