欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]Pdf密码破解算法逆向

[原创]Pdf密码破解算法逆向

软件名称 PasswareKitBasic.exe
软件版本 Passware Kit 12 Demo 和 Passware Kit 11 Demo
下载地址 www.lostpassword.com
把pdf破解算法的逆向记录分享一下,有理解错误的地方还请大家指正
Pdf密码有两种user password、owner password
这里的算法是破解user password。owner password可以直接移除不用破解
该版本不能破解acrobat10.0(acrobat X)
该版本主要包含三个破解算法RC4-40  RC4-128  AES-128
用acrobat工具生成各种加密版本来做测试
让程序跑起来,在线程窗口可以有三个线程在破解,选择在CPU中打开可以断在算法里(一次断不到算法里可以多试几次)
PDF加密后的文件尾部(trailer)
trailer
<</Size 28/Encrypt 29 0 R>>
startxref
116
%%EOF
29 0 obj <</Length128
/Filter/Standard
/O(154747F335FB401F338AAA1310E11E63D6B9F7D0FCA78DD48ED834C9CB7AC976)
/P-1028
/R3
/U(02093CD04060F432EA87F6985AFFDD78676E5F66000000005900A00130C53F00)
/V 2>> endobj
从Adobe? Portable Document Format文档里可以找到:
/Length 密钥的长度
/Filter 生成密钥的方法,就是前面说的security handler
/O 是由用户口令和权限口令得到的,用来生成密钥和验证输入的权限口令
/P 访问权限的标志
/R 标准加密的(standard security handler)的版本
/U由用户口令生成,用来验证输入的用户口令或权限口令,是否要提醒用户输入密码
/V 可选,用来指明加密的算法。
/P访问权限标识详细
1-2                保留为0;
3                (版本2) 打印文档
                (版本3或者更高)打印文档(可能不是最高级别,取决于bit 12是否被设置)       
4                Modify the contents of the document by operations other than those controlled by bits 6, 9, and 11.
                通过控制bit 6、bit 9、bit11修改文档内容
5                (版本2)Copy or otherwise extract text and graphics from the document, including extracting text and graphics (in support of                         accessibility
                to users with disabilities or for other purposes).
                复制或提取文本和图形从文档,包括提取文本和图形(以支持可访问性受限用户或其他用途)。
                (版本3或者更高) Copy or otherwise extract text and graphics from the document by operations other than that controlled by bit10.
                通过控制bit 10 复制或提取文本和图形
6                Add or modify text annotations, fill in interactive form fields, and, if bit 4 is also set, create or modify interactive form fields                 (including signature fields).
                添加或修改文本注释,填写交互式表单字段;如果bit 4被设置,创建或修改交互式表单字段(包括签名字段).
7-8                保留  为1;
9                (版本3或者更高) Fill in existing interactive form fields (including
                signature fields), even if bit 6 is clear.       
                填充现有的交互表单字段(包括签名字段),即使 bit 6未设置.
10                (版本3或者更高) Extract text and graphics (in support of accessibility
                to users with disabilities or for other purposes).       
                提取文本和图形(用来支持受限用户的可访问性或其他用途)
11                (版本3或者更高) Assemble the document (insert, rotate, or delete
                pages and create bookmarks or thumbnail images), even if bit 4 is clear.
                组合文档(插入、旋转或删除页面和创建书签或缩略图)即使bit 4未设置
12                (版本3或者更高) Print the document to a representation from which a faithful digital copy of the PDF content could be                                 generated. When this bit is clear (and bit 3 is set), printing is limited to a low-level representation of the appearance, possibly of                 degraded quality. (See implementation note 25 in Appendix H.)
                打印标识。当该位未设置并且bit  3被设置,打印受限。
               
13-32                (版本3或更高)保留 必须为1;
RC4-128算法
Algorithm part1 Computing an encryption key
1.密码字符串为N字节长度,用以下字符串
  <28 BF 4E 5E 4E 75 8A 41 64 00 4E 56 FF FA 01 08 2E 2E 00 B6 D0 68 3E 80 2F 0C A9 FE 64 53 69 7A >
中的32-N个填充至32个字节。如果用户密码为空就全部填充.
2.初始化MD5,并将步骤1的结果输入到MD5函数.
3.通过加密字典中的O进入MD5哈希函数.
4.将P条目作为一个4字节无符号整数的值传递给MD5函数.
5.将文档ID的第一个元素传递给MD5.
6.如果文档metadata没有被加密传递0xFFFFFFFF到MD5函数.
7.结束MD5.
8.连续做50次:从上一个MD5函数的输出的n bytes传递到给MD5函数。其中n由加密字典条目的 length决定(length/8).
9.从最终的MD5输出的前n bytes设置为RC4加密密钥。对于版本2来说,n始终为5,但对于版本3或更高版本来说,取决于加密字典中
  length的值(length/8).
Algorithm part2  Computing the encryption dictionary’s U (user password) value (Revision 3 or greater)
1.按照Algorithm part1的方法,基于用户口令字符串生成全局加密密钥.
2.初始化MD5函数并将按照Algorithm part1步骤1生产的32位字符串输入该函数.
3.将文件ID数组中的第一个32位ID字符串传入MD5函数.
4.用第1步产生的密钥通过RC4算法来加密由步骤3输出的16位字符串.

0B272D84  49DD8B1A
0B272D88  B546154D
0B272D8C  059A4C1A
0B272D90  AB3D50CE

22 30 da 73 56 e1 48 74 e9 7f 75 49 db 8a a4 a7
5.做19次运算:用前一次的输出作为下一次的输入进行解码;密钥是由第1步产生的原始密钥的单个字节和循环数xor运算得到的.
0AFFD3B4  C7A7C82B  +颧
0AFFD3B8  1ED35085  匬?
0AFFD3BC  2F1EF1F4  赳_/
0AFFD3C0  28C6F209  .蚱(
3a fe 1a 3c 8b 61 45 b6 01 96 1b 06 c7 11 89 59
Passware Kit 11 Demo分析
填充后的数据
0AFFE084  BF289038
0AFFE088  754E5E4E
0AFFE08C  0064418A  Passware.0064418A
0AFFE090  FAFF564E
0AFFE094  2E2E0801
0AFFE098  68D0B600
0AFFE09C  0C2F803E
0AFFE0A0  5364FEA9
0AFFE0A4  2494D79E
0AFFE0A8  888F3421
0AFFE0AC  67719CB7
0AFFE0B0  9E49855C
0AFFE0B4  4B36B2F9
0AFFE0B8  9246127F
0AFFE0BC  CDAE7226
0AFFE0C0  5A206F65


0B017674  FFFFFBFC
0B017678  4E09775B
0B01767C  4CE72BD3
0B017680  4A9C5DA9
0B017684  E0B289D5
0B017688  00000080
0B01768C  00000000
0B017690  00000000
0B017694  00000000
0B017698  00000000
0B01769C  00000000
0B0176A0  00000000
0B0176A4  00000000
0B0176A8  00000000
0B0176AC  000002A0
0B0176B0  00000000

00A88CD6  |.  E8 253A0000   |call Passware.00A8C700                  ;  TTT3
00A8C73C  |.  E8 06600000   call Passware.00A92747                   ;  TTT2
00C62470  /$  55            push ebp                                 ;算法  得到加密后的16 bits
00C62471  |.  8BEC          mov ebp,esp
00C62473  |.  83EC 40       sub esp,0x40
00C62476  |.  53            push ebx
00C62477  |.  8B45 08       mov eax,[arg.1]
00C6247A  |.  8B48 0C       mov ecx,dword ptr ds:[eax+0xC]
00C6247D  |.  8B10          mov edx,dword ptr ds:[eax]
00C6247F  |.  56            push esi
00C62480  |.  8B70 04       mov esi,dword ptr ds:[eax+0x4]
00C62483  |.  57            push edi
00C62484  |.  8B78 08       mov edi,dword ptr ds:[eax+0x8]
00C62487  |.  8B45 0C       mov eax,[arg.2]
00A8D1EA  |> \8B08          mov ecx,dword ptr ds:[eax]
00A8D1EC  |.  310F          xor dword ptr ds:[edi],ecx
00A8D1EE  |.  8B50 04       mov edx,dword ptr ds:[eax+0x4]
00A8D1F1  |.  3157 04       xor dword ptr ds:[edi+0x4],edx
00A8D1F4  |.  8B48 08       mov ecx,dword ptr ds:[eax+0x8]
00A8D1F7  |.  314F 08       xor dword ptr ds:[edi+0x8],ecx
00A8D1FA  |.  8B50 0C       mov edx,dword ptr ds:[eax+0xC]
00A8D1FD  |.  3157 0C       xor dword ptr ds:[edi+0xC],edx
00A8E100  /$  89F8          mov eax,edi                               ;MD5算法
00A8E102  |.  8B0A          mov ecx,dword ptr ds:[edx]
00A8E104  |.  31F0          xor eax,esi
00A8E106  |.  81C1 78A46AD7 add ecx,0xD76AA478
00A8E10C  |.  21D8          and eax,ebx
00A8E10E  |.  01CD          add ebp,ecx
00A8E110  |.  31F8          xor eax,edi
00A8E112  |.  8B4A 04       mov ecx,dword ptr ds:[edx+0x4]
00A8E115  |.  01C5          add ebp,eax
00A8E117  |.  81C1 56B7C7E8 add ecx,0xE8C7B756
00A8E11D  |.  C1C5 07       rol ebp,0x7
00A8E120  |.  01CF          add edi,ecx
00A8E122  |.  89F0          mov eax,esi
00A8E124  |.  01DD          add ebp,ebx
00A8E126  |.  31D8          xor eax,ebx
00A8E128  |.  8B4A 08       mov ecx,dword ptr ds:[edx+0x8]
00A8E12B  |.  21E8          and eax,ebp
00A8E12D  |.  81C1 DB702024 add ecx,0x242070DB
00A8E133  |.  31F0          xor eax,esi
逆出来的算法代码(伪代码)

int JudgePdfPasswordRC4_128()
{
		int j=0;
		int rc4_count=0;
		UINT4  _State[4];
		UCHAR S[256];
		UINT state[4];
		UCHAR local_converStateEnd[16];
		memcpy(local_converStateEnd,converStateEnd,16);
		j=strlen(pdf_szZu);
		memcpy(CheckArea1,pdf_szZu,j);
		memcpy(CheckArea1+j,ConData,32-j);
		memcpy(_State,g_State,16);//取代reset();
		md5_transform_assembly(_State,CheckArea1);
		md5_transform_assembly(_State,CheckArea1 + 0x40);
		for(int md5_count = 0;md5_count != 50;++md5_count)//50次MD5算法
		{
			memcpy(CheckArea2,_State,16);
			memcpy(_State,g_State,16);//取代reset();
			CMD5::MD5Transform(_State,CheckArea2);
		}
		RC4_assemly(S, (const UCHAR*)_State, local_converStateEnd);
		for (rc4_count=0;rc4_count!=18;rc4_count++)//18次RC4算法
		{
			state[0]=_State[0]^cnt_X[rc4_count];
			state[1]=_State[1]^cnt_X[rc4_count];
			state[2]=_State[2]^cnt_X[rc4_count];
			state[3]=_State[3]^cnt_X[rc4_count];
			RC4_assemly(S, (const UCHAR*)state, local_converStateEnd);
		}
		state[0]=_State[0]^cnt_X[rc4_count];
		state[1]=_State[1]^cnt_X[rc4_count];
		state[2]=_State[2]^cnt_X[rc4_count];
		state[3]=_State[3]^cnt_X[rc4_count];
return RC4AndResult(S,m_lin,local_converStateEnd,sizeof(local_converStateEnd),(char*)state,16);
//第19次RC4算法并作判断
}

RC4-40算法分析
Passware Kit 11 Demo分析
数据处理部分
00A8D07D  |.  310F          xor dword ptr ds:[edi],ecx
00A8D07F  |.  8B50 04       mov edx,dword ptr ds:[eax+0x4]
00A8D082  |.  3157 04       xor dword ptr ds:[edi+0x4],edx
00A8D085  |.  8B48 08       mov ecx,dword ptr ds:[eax+0x8]
00A8D088  |.  314F 08       xor dword ptr ds:[edi+0x8],ecx
00A8D08B  |.  8B50 0C       mov edx,dword ptr ds:[eax+0xC]
00A8D08E  |.  3157 0C       xor dword ptr ds:[edi+0xC],edx
00A8D091  |.  8B48 10       mov ecx,dword ptr ds:[eax+0x10]
00A8D094  |.  314F 10       xor dword ptr ds:[edi+0x10],ecx
00A8D097  |.  8B50 14       mov edx,dword ptr ds:[eax+0x14]
00A8D09A  |.  3157 14       xor dword ptr ds:[edi+0x14],edx
00A8D09D  |.  8B48 18       mov ecx,dword ptr ds:[eax+0x18]
00A8D0A0  |.  314F 18       xor dword ptr ds:[edi+0x18],ecx
00A8D0A3  |.  8B50 1C       mov edx,dword ptr ds:[eax+0x1C]
00A8D0A6  |.  3157 1C       xor dword ptr ds:[edi+0x1C],edx
00A8D0A9  |.  8B4E 3C       mov ecx,dword ptr ds:[esi+0x3C]
00A91503  |.  E8 F8CBFFFF   call Passware.00A8E100                   ;  MD5算法
32字节填充数据
5E4EBF28
418A754E
564E0064        与U条目异或
0801FAFF    ----------------->生成最终数据
B6002E2E
803E68D0
FEA90C2F
7A695364

0AFFE084  BF289038
0AFFE088  754E5E4E
0AFFE08C  0064418A  Passware.0064418A
0AFFE090  FAFF564E
0AFFE094  2E2E0801
0AFFE098  68D0B600
0AFFE09C  0C2F803E
0AFFE0A0  5364FEA9
0AFFE0A4  2494D79E
0AFFE0A8  888F3421
0AFFE0AC  67719CB7
0AFFE0B0  9E49855C
0AFFE0B4  4B36B2F9
0AFFE0B8  9246127F
0AFFE0BC  CDAE7226         
0AFFE0C0  5A206F65
                经过两次MD5处理,再经过RC4处理后与最终数据比较
0B017674  FFFFFBFC     -------------------------------------------------->      判别结果
0B017678  4E09775B
0B01767C  4CE72BD3
0B017680  4A9C5DA9
0B017684  E0B289D5
0B017688  00000080
0B01768C  00000000
0B017690  00000000
0B017694  00000000
0B017698  00000000
0B01769C  00000000
0B0176A0  00000000
0B0176A4  00000000
0B0176A8  00000000
0B0176AC  000002A0
0B0176B0  00000000

逆向的代码(伪代码)
int JudgePassword_RC4_40()
{
	j=strlen(pdf_szZu);//pdf_szZu为传入的密码字符串
	memcpy(CheckArea1,pdf_szZu,j);
	memcpy(CheckArea1 + j,ConData,32-j);
	memcpy(_State,g_State,16);//取代reset();
	CMD5::MD5Transform(_State,CheckArea1);
	CMD5::MD5Transform(_State,CheckArea1 + 0x40);
	return RC4_40_AndResult(S,m_lin,converState_RC4_40,32,(char*)_State,5);
}

AES-128算法分析
Passware Kit 12 Demo分析
00B1D8C0  /$  55            push ebp           //Passware Kit 12 Demo 算法入口
00B2537B  |.  8B45 08       mov eax,[arg.1]
00B2537E  |.  8B5D 0C       mov ebx,[arg.2]
00B25381  |.  8BF1          mov esi,ecx
00B25383  |.  8B4E 04       mov ecx,dword ptr ds:[esi+0x4]
00B25386  |.  8B56 08       mov edx,dword ptr ds:[esi+0x8]
00B25389  |.  8945 A4       mov [local.23],eax
00B2538C  |.  8D040B        lea eax,dword ptr ds:[ebx+ecx]
00B2538F  |.  894D A0       mov [local.24],ecx
00B25392  |.  8946 04       mov dword ptr ds:[esi+0x4],eax    //写入1字节数据(长度)
00B24E55  |.  8B46 04       mov eax,dword ptr ds:[esi+0x4]
00B24E58  |.  03C0          add eax,eax
00B24E5A  |.  03C0          add eax,eax
00B24E5C  |.  03C0          add eax,eax
00B24E5E  |.  85FF          test edi,edi
00B24E60  |.  74 02         je short Passware.00B24E64
00B24E62  |.  0FC8          bswap eax
00B24E64  |>  8BC8          mov ecx,eax
00B24E66  |.  8B45 F8       mov eax,[local.2]
00B24E69  |.  C1E8 02       shr eax,0x2
00B24E6C  |.  8D1438        lea edx,dword ptr ds:[eax+edi]
00B24E6F  |.  894C93 F8     mov dword ptr ds:[ebx+edx*4-0x8],ecx  //填充至最后
填充口令后的数据
0A511350  BF4BF020   餕
0A511354  E748B436  6碒
0A511358  000080BD  絸..      填充方式:password + U条目最后8个字节 + 80+0 + 长度处理后的数据
0A51135C  00000000  ....
0A511360  00000000  ....
0A511364  00000000  ....
0A511368  00000000  ....
0A51136C  00000000  ....
0A511370  00000000  ....
0A511374  00000000  ....
0A511378  00000000  ....
0A51137C  00000000  ....
0A511380  00000000  ....
0A511384  00000000  ....
0A511388  00000000  ....

0A51138C  48000000  ...H
SHA256初始化(是SHA256?)
0A519D50  6A09E667  g?j
0A519D54  BB67AE85  叜g
0A519D58  3C6EF372  r髇<
0A519D5C  A54FF53A  :鮋
0A519D60  510E527F  R_Q
0A519D64  9B05688C  宧_
0A519D68  1F83D9AB  ?
0A519D6C  5BE0CD19  _袜[
循环处理
00977907  |.  E8 84160000   |call Passware.00978F90  //传入字符
00978FF2  |.  FFD0          call eax                                 ;  填充字符1
  00B2541F  |.  E8 FCD5F2FF   call Passware.00A52A20                   ;  填充字符2
0097901B  |.  FFD0          call eax                    ;  8888888888888888
00634D7B  |.  FFD2        call edx                                ;GOGO1
005F4A68  |.  FFD2          call edx                        ;  GOGO2
00B24EA1  |.  FFD0          call eax                  ;  算法处理1
00B21344  |.  E8 77C5FFFF   call Passware.00B1D8C0     ;  算法
00B24EB5  |.  E8 A6FDFFFF   call Passware.00B24C60 ;  GOGO3   bswap
00B24EC4  |.  FFD0          call eax                  ;  数据初始化1
00633857   . E8 44A04E00   call Passware.00B1D8A0    ;  数据初始化
判断比较
SHA256算法处理后的数据与U条目前32个字节比较            PDF文件的U条目

0A51E369  9CBD1FAA  ?綔                                0A507210  967D44DD  軩}
0A51E36D  CFA79CB3  硿                                0A507214  06E32AD0  ??
0A51E371  DB0322CB  ?_            比较                0A507218  011727E8  ?__   Passware.011727E8
0A51E375  52081684  ?R    ------------->                0A50721C  67D6B896  柛謌
0A51E379  2C4D47AF  疓M,                                0A507220  8FE78FAC  瑥鐝
0A51E37D  2AC42E5D  ].?                                0A507224  FDA33377  w3}
0A51E381  F53D76BF  縱=                                0A507228  46F680B4  磤鯢
0A51E385  5C809513  _晙\                                0A50722C  DC388ADF  邐8
逆向的代码()
int JudgePdfPasswordAES128()
{
	UCHAR UserPadd[64] = {0};
	UCHAR* pUserPadd = UserPadd;
	int sLen=strlen(pdf_szZu);
	::memcpy(pUserPadd,pdf_szZu,sLen);
	::memcpy(&UserPadd[sLen],pAppData_U + 32,8);
	sLen = sLen + 8;
	UserPadd[sLen] = 0x80;
	__asm
	{
		mov eax,sLen
		add eax,eax
		add eax,eax
		add eax,eax
		mov esi,pUserPadd
		add esi,0x3C
		bswap eax
		mov dword ptr [esi],eax
	}
	UINT* pSha256_r = NULL;
	pSha256_r=Sha256_r;
	UINT* pSha256_k = NULL;
	pSha256_k = Sha256_k;
	UINT importantData[8];
	UINT* pimportantData = importantData;
	__asm
	{
		pushad
		sub esp,0x64
		mov esi,pimportantData
		mov dword ptr ss:[esp],esi
		mov esi,pSha256_r
		mov ecx,0x8
		mov edi,esp
		add edi,0x4
		rep movsd
		mov esi,pSha256_k
		add esi,0xC0
		mov dword ptr ss:[esp+0x64],esi
		sub esi,0xC0
		mov edx,pUserPadd
		mov ebx,dword ptr [edx]
		bswap ebx
		mov dword ptr ss:[esp+0x60],ebx
		mov ebx,dword ptr ds:[edx+0x4]
	//内联汇编 省略……
label_1:
		add esi,0x40
		mov edx,dword ptr ss:[esp+0x18]
		xor edx,dword ptr ss:[esp+0x1C]
		and edx,edi
		xor edx,dword ptr ss:[esp+0x1C]
	//内联汇编 省略……
		add edi,dword ptr ss:[esp+0x14]
		mov dword ptr ss:[esp+0x14],edi
		ror ebp,0x16
		xor ebp,ebx
		ror ebx,0xB
		xor ebp,ebx
		add ecx,ebp
		mov dword ptr ss:[esp+0x4],ecx
		cmp esi,dword ptr ss:[esp+0x64]
		jb label_1
		lea esi,[esp+0x4]
		mov ecx,0x8
		mov edi,[esp]
		rep movsd
		add esp,0x64
		popad
	}
	for (int i=0;i != 8;++i)
	{
		importantData[i] += *(pSha256_r + i);
	}
	__asm
	{
		xor eax,eax
		mov ebx,pimportantData
label_2:
		mov edx,dword ptr [ebx+eax]
		bswap edx
		mov dword ptr [ebx+eax],edx
		add eax,4
		cmp eax,0x20
		jb label_2
	}
	UINT *pUintAppData_U = (UINT*)pAppData_U;
	for (int i = 0; i != 8;++i)
	{
		if(*(pUintAppData_U + i) != *(pimportantData + i))
			return 1;
	}
	return 0;
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功