====== 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.