新的一年想把0day漏洞安全这本书读完,会一步一步踏踏实实的学完,和大家共享笔记。
环境我想用vs2019运行,老的编译器很多人不用了,渐渐的会被淘汰。用新的编译器可以锻炼下编译选项的功底。
我的笔记是配合书写的,理论部分会少用笔墨,着重在实验上。
这一部分书上讲解的足够了,如果暂时看不懂,多看看就好。功夫不负有心人,迟早学会的事情。
这一部分书上讲解的足够了,如果暂时看不懂,多看看就好。功夫不负有心人,迟早学会的事情。
VS2019 X86 Debug
属性->c/c++->常规->sdl检查关闭
属性->c/c++->代码运行->基本运行时检查->关闭【堆栈帧 (/RTCs)】
然后运行代码,输入qqqqqqqq即,可完成简单的溢出覆盖。
###
SDL关闭和头文件的增加为了让程序代码跑起来。
堆栈帧 (/RTCs)的关闭,则是为了让程序不在运行时检查程序。
如果不关闭堆栈帧 (/RTCs),原本buffer[8]会因为检查多出8字节。然后程序报错,我原本以为时字符对齐的问题,检查后发现不是。是运行时检查的问题。
关闭堆栈帧 (/RTCs)的汇编代码:
开启堆栈帧 (/RTCs)的汇编代码:
通过代码的比较,我们可以发现,函数使用@_RTC_CheckStackVars@8进行检测,跟进去发现该函数容纳了两个_RTC_CheckStackVars,当检测不是0CCCCCCCCh的时候,会报错,并进入_RTC_StackFailure函数。
属性->c/c++->常规->sdl检查关闭
属性->c/c++->代码运行->基本运行时检查->关闭【堆栈帧 (/RTCs)】
修改上述配置后,发现无法正常运行,单步调试发现fopen断点出现问题。搜索查询后发现有些编译器不支持rw+的格式。这里我们将rw+修改为r+即可正确运行。r和r+的区别是r+拥有写权限。我大胆猜测,rw+不支持的原因是功能设计上的重复。
在这里我们运行还会遇到一个问题
我们需要把栈保护天使GS关闭。
属性->c/c++->代码运行->安全检查->关闭【禁用安全检查 (/GS-)】
这个时候代码就会报书上期望我们出现的错误,返回值出现错误。理论方面书上说的已经很全面,这里就简单画个图。
最终结果如下图,符合书上预期:
属性->c/c++->常规->sdl检查关闭
属性->c/c++->代码运行->基本运行时检查->关闭【堆栈帧 (/RTCs)】
属性->c/c++->代码运行->安全检查->关闭【禁用安全检查 (/GS-)】
创建一个文件,password.txt,构造shellcode。这里按照书上就好,然后看下面的步骤。
配置需要进行修改,因为要静态获取buffer地址,aslr随机基址要关闭,因为要在数据区执行代码,数据执行保护(DEP)也要关闭。
属性->链接器->高级->随机基址->否
属性->链接器->高级->数据执行保护(DEP)->否
password.txt,有两个地方需要修改,根据书中描述。
一个是Messagebox的地址,在下图中会讲解如何寻找。
一个是buffer的地址,下文中也会详细介绍细节。
我们在程序中添加messagebox,这样我们的代码就会调用User32.dll,我们使用dependency可以获取该模块函数地址。
根据书中方法,计算正确值
但是可以看到,程序并不能正确运行,这问题常出在现在的windows操作系统里,优先基址常常不是实际加载地址,在PE格式中DLL会给出一个优先加载地址,当程序并未占用该地址时,优先按照该基址进行计算。占用的话,会重新申请空间。
问题发生了,如何解决,这里使用Ollydbg查看模块地址。
下面是Ollydbg的正确解决方案
步骤1:点击E字母
步骤2:找到User32,此时使用该模块地址计算,可以获得正确地址,成功弹出messagebox
如果不想算,就按一下User32,快捷键ctrl+n,找到messageboxA一样可以。
注:
不知不觉三阶段快毕业了,非常感谢科锐的指导,科锐的耐心指导,才能够让我的基础越加雄厚。
非常感谢钱老师、张老师、王老师、田老师、唐老师、江老师。
尤其王老师,陪伴我们走了最长的路,还记得科锐学习的时候经常学崩溃,因为任务量多,对新手难。
有一次哭着和王老师聊天,王老师帮我排解压力、还把笔记借给我学习,非常感谢。
这是估计是我在科锐期间最后一次发帖了,在此纪念一年的学习时光。
祝科锐越来越好,也祝自己越来越好。
int
verify_password(char
*
password)
{
int
authenticated;
char
buffer
[
8
];
/
/
add local buffto be overflowed
authenticated
=
strcmp(password, PASSWORD);
strcpy(
buffer
, password);
/
/
over flowed here!
return
authenticated;
}
void main()
{
int
valid_flag
=
0
;
char password[
1024
];
while
(
1
)
{
printf(
"please input password: "
);
scanf(
"%s"
, password);
valid_flag
=
verify_password(password);
if
(valid_flag)
{
printf(
"incorrect password!\n\n"
);
}
else
{
printf(
"Congratulation! You have passed the verification!\n"
);
break
;
}
}
}
int
verify_password(char
*
password)
{
int
authenticated;
char
buffer
[
8
];
/
/
add local buffto be overflowed
authenticated
=
strcmp(password, PASSWORD);
strcpy(
buffer
, password);
/
/
over flowed here!
return
authenticated;
}
void main()
{
int
valid_flag
=
0
;
char password[
1024
];
while
(
1
)
{
printf(
"please input password: "
);
scanf(
"%s"
, password);
valid_flag
=
verify_password(password);
if
(valid_flag)
{
printf(
"incorrect password!\n\n"
);
}
else
{
printf(
"Congratulation! You have passed the verification!\n"
);
break
;
}
}
}
int
verify_password(char
*
password)
{
004015F0
push ebp
004015F1
mov ebp,esp
004015F3
sub esp,
50h
004015F6
mov eax,dword ptr [__security_cookie (
0407004h
)]
004015FB
xor eax,ebp
004015FD
mov dword ptr [ebp
-
4
],eax
00401600
push ebx
00401601
push esi
00401602
push edi
00401603
mov ecx,offset _06E17EB3_Test@cpp (
0409008h
)
00401608
call @__CheckForDebuggerJustMyCode@
4
(
0401285h
)
int
authenticated;
char
buffer
[
8
];
/
/
add local buffto be overflowed
authenticated
=
strcmp(password, PASSWORD);
0040160D
push offset string
"1234567"
(
0405B30h
)
00401612
mov eax,dword ptr [password]
00401615
push eax
00401616
call _strcmp (
040103Ch
)
0040161B
add esp,
8
0040161E
mov dword ptr [authenticated],eax
strcpy(
buffer
, password);
/
/
over flowed here!
00401621
mov eax,dword ptr [password]
00401624
push eax
00401625
lea ecx,[
buffer
]
00401628
push ecx
00401629
call _strcpy (
040119Ah
)
0040162E
add esp,
8
return
authenticated;
00401631
mov eax,dword ptr [authenticated]
}
00401634
pop edi
00401635
pop esi
00401636
pop ebx
00401637
mov ecx,dword ptr [ebp
-
4
]
0040163A
xor ecx,ebp
0040163C
call @__security_check_cookie@
4
(
040111Dh
)
00401641
mov esp,ebp
00401643
pop ebp
00401644
ret
int
verify_password(char
*
password)
{
004015F0
push ebp
004015F1
mov ebp,esp
004015F3
sub esp,
50h
004015F6
mov eax,dword ptr [__security_cookie (
0407004h
)]
004015FB
xor eax,ebp
004015FD
mov dword ptr [ebp
-
4
],eax
00401600
push ebx
00401601
push esi
00401602
push edi
00401603
mov ecx,offset _06E17EB3_Test@cpp (
0409008h
)
00401608
call @__CheckForDebuggerJustMyCode@
4
(
0401285h
)
int
authenticated;
char
buffer
[
8
];
/
/
add local buffto be overflowed
authenticated
=
strcmp(password, PASSWORD);
0040160D
push offset string
"1234567"
(
0405B30h
)
00401612
mov eax,dword ptr [password]
00401615
push eax
00401616
call _strcmp (
040103Ch
)
0040161B
add esp,
8
0040161E
mov dword ptr [authenticated],eax
strcpy(
buffer
, password);
/
/
over flowed here!
00401621
mov eax,dword ptr [password]
00401624
push eax
00401625
lea ecx,[
buffer
]
00401628
push ecx
00401629
call _strcpy (
040119Ah
)
0040162E
add esp,
8
return
authenticated;
00401631
mov eax,dword ptr [authenticated]
}
00401634
pop edi
00401635
pop esi
00401636
pop ebx
00401637
mov ecx,dword ptr [ebp
-
4
]
0040163A
xor ecx,ebp
0040163C
call @__security_check_cookie@
4
(
040111Dh
)
00401641
mov esp,ebp
00401643
pop ebp
00401644
ret
int
verify_password(char
*
password)
{
00E317A0
push ebp
00E317A1
mov ebp,esp
00E317A3
sub esp,
0E0h
00E317A9
push ebx
00E317AA
push esi
00E317AB
push edi
00E317AC
lea edi,[ebp
-
20h
]
00E317AF
mov ecx,
8
00E317B4
mov eax,
0CCCCCCCCh
00E317B9
rep stos dword ptr es:[edi]
00E317BB
mov eax,dword ptr [__security_cookie (
0E3A004h
)]
00E317C0
xor eax,ebp
00E317C2
mov dword ptr [ebp
-
4
],eax
00E317C5
mov ecx,offset _06E17EB3_Test@cpp (
0E3C008h
)
00E317CA
call @__CheckForDebuggerJustMyCode@
4
(
0E3132Fh
)
int
authenticated;
char
buffer
[
8
];
/
/
add local buffto be overflowed
authenticated
=
strcmp(password, PASSWORD);
00E317CF
push offset string
"1234567"
(
0E37B30h
)
00E317D4
mov eax,dword ptr [password]
00E317D7
push eax
00E317D8
call _strcmp (
0E31046h
)
00E317DD
add esp,
8
00E317E0
mov dword ptr [authenticated],eax
strcpy(
buffer
, password);
/
/
over flowed here!
00E317E3
mov eax,dword ptr [password]
00E317E6
push eax
00E317E7
lea ecx,[
buffer
]
00E317EA
push ecx
00E317EB
call _strcpy (
0E31212h
)
00E317F0
add esp,
8
return
authenticated;
00E317F3
mov eax,dword ptr [authenticated]
}
00E317F6
push edx
00E317F7
mov ecx,ebp
00E317F9
push eax
00E317FA
lea edx,ds:[
0E31828h
]
00E31800
call @_RTC_CheckStackVars@
8
(
0E311EFh
)
00E31805
pop eax
00E31806
pop edx
00E31807
pop edi
00E31808
pop esi
00E31809
pop ebx
00E3180A
mov ecx,dword ptr [ebp
-
4
]
00E3180D
xor ecx,ebp
00E3180F
call @__security_check_cookie@
4
(
0E31154h
)
00E31814
add esp,
0E0h
00E3181A
cmp
ebp,esp
00E3181C
call __RTC_CheckEsp (
0E31253h
)
00E31821
mov esp,ebp
00E31823
pop ebp
00E31824
ret
00E31825
nop dword ptr [eax]
00E31828
add dword ptr [eax],eax
00E3182A
add byte ptr [eax],al
00E3182C
xor byte ptr [eax],bl
00E3182E
jecxz __$EncStackInitStart
+
84h
(
0E31830h
)
00E31830
in
al,
0FFh
00E31832
?? ??????
}
00E31833
dec dword ptr [eax]
00E31835
add byte ptr [eax],al
00E31837
add byte ptr [eax
+
ebx],bh
00E3183A
jecxz __$EncStackInitStart
+
90h
(
0E3183Ch
)
00E3183C
bound esi,qword ptr [ebp
+
66h
]
00E3183F
jb
00001843
int
verify_password(char
*
password)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-3-7 11:56
被瑞皇编辑
,原因: