is119 / checksec.py

2019_KUCIS_Project_checksec.py
2 stars 7 forks source link

PE - GS를 제대로 검사하지 못하는 문제 #46

Open koyokr opened 4 years ago

koyokr commented 4 years ago
PS E:\project\checksec-pe-sample\sample> python ..\..\2019_KUCIS_Project_checksec.py\version_elf+pe\ver.1\checksec.py .\x64-no-gs.exe
        Filename   .NET    NX Dynamic Base  ASLR    CFG Force Integrity    GS High Entropy VA Isolation    RFG   SEH Safe SEH
 .\x64-no-gs.exe  False  True         True  True  False           False  True            True      True  False  True    False
PS E:\project\checksec-pe-sample\sample> ..\..\winchecksec\build\Release\winchecksec.exe .\x64-no-gs.exe
Dynamic Base    : true
ASLR            : true
High Entropy VA : true
Force Integrity : false
Isolation       : true
NX              : true
SEH             : true
CFG             : false
RFG             : false
SafeSEH         : false
GS              : true
Authenticode    : false
.NET            : false

winchecksec과 프로젝트 코드 모두 GS가 설정되지 않으면 load config의 security cookie의 값이 0일 것이라는 가정 하에 판단한다.

https://github.com/InformationSecurity119/2019_KUCIS_Project_checksec.py/blob/1e055090f101aa94b1da93b2a7d4d53f1e01a9df/version_elf%2Bpe/ver.1/Analyze_PE.py#L68-L72

그러나 GS를 설정하지 않고 빌드한 프로그램도 load config의 security cookie 값이 0이 아닐 수 있다.

https://stackoverflow.com/questions/7829929/how-to-say-if-a-binary-is-gs-compiled-or-not-and-without-symbols

koyokr commented 4 years ago

x86의 경우

void vulnerable(const char *str) {
00381700 55                   push        ebp  
00381701 8B EC                mov         ebp,esp  
00381703 81 EC D8 00 00 00    sub         esp,0D8h  
00381709 53                   push        ebx  
0038170A 56                   push        esi  
0038170B 57                   push        edi  
0038170C 8D BD 28 FF FF FF    lea         edi,[ebp-0D8h]  
00381712 B9 36 00 00 00       mov         ecx,36h  
00381717 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0038171C F3 AB                rep stos    dword ptr es:[edi]  
--> 0038171E A1 24 A0 38 00       mov         eax,dword ptr [__security_cookie (038A024h)]  
--> 00381723 33 C5                xor         eax,ebp  
--> 00381725 89 45 FC             mov         dword ptr [ebp-4],eax  
00381728 B9 08 C0 38 00       mov         ecx,offset _FD037FC4_main@cpp (038C008h)  
0038172D E8 DB FA FF FF       call        @__CheckForDebuggerJustMyCode@4 (038120Dh)  
    char buffer[10];
    strcpy(buffer, str);
00381732 8B 45 08             mov         eax,dword ptr [str]  
00381735 50                   push        eax  
00381736 8D 4D EC             lea         ecx,[buffer]  
00381739 51                   push        ecx  
0038173A E8 0A FB FF FF       call        _strcpy (0381249h)  
0038173F 83 C4 08             add         esp,8  
}
00381742 52                   push        edx  
00381743 8B CD                mov         ecx,ebp  
00381745 50                   push        eax  
00381746 8D 15 74 17 38 00    lea         edx,ds:[381774h]  
0038174C E8 E9 FA FF FF       call        @_RTC_CheckStackVars@8 (038123Ah)  
00381751 58                   pop         eax  
00381752 5A                   pop         edx  
00381753 5F                   pop         edi  
00381754 5E                   pop         esi  
00381755 5B                   pop         ebx  
--> 00381756 8B 4D FC             mov         ecx,dword ptr [ebp-4]  
--> 00381759 33 CD                xor         ecx,ebp  
--> 0038175B E8 80 FA FF FF       call        @__security_check_cookie@4 (03811E0h)  
00381760 81 C4 D8 00 00 00    add         esp,0D8h  
00381766 3B EC                cmp         ebp,esp  
00381768 E8 AA FA FF FF       call        __RTC_CheckEsp (0381217h)  
0038176D 8B E5                mov         esp,ebp  
0038176F 5D                   pop         ebp  
00381770 C3                   ret  

x64의 경우

void vulnerable(const char *str) {
00007FF69ABC1710 48 89 4C 24 08       mov         qword ptr [rsp+8],rcx  
00007FF69ABC1715 55                   push        rbp  
00007FF69ABC1716 57                   push        rdi  
00007FF69ABC1717 48 81 EC 18 01 00 00 sub         rsp,118h  
00007FF69ABC171E 48 8D 6C 24 20       lea         rbp,[rsp+20h]  
00007FF69ABC1723 48 8B FC             mov         rdi,rsp  
00007FF69ABC1726 B9 46 00 00 00       mov         ecx,46h  
00007FF69ABC172B B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00007FF69ABC1730 F3 AB                rep stos    dword ptr [rdi]  
00007FF69ABC1732 48 8B 8C 24 38 01 00 00 mov         rcx,qword ptr [rsp+138h]  
--> 00007FF69ABC173A 48 8B 05 C7 A8 00 00 mov         rax,qword ptr [__security_cookie (07FF69ABCC008h)]  
--> 00007FF69ABC1741 48 33 C5             xor         rax,rbp  
--> 00007FF69ABC1744 48 89 85 E8 00 00 00 mov         qword ptr [rbp+0E8h],rax  
00007FF69ABC174B 48 8D 0D B6 F8 00 00 lea         rcx,[__FD037FC4_main@cpp (07FF69ABD1008h)]  
00007FF69ABC1752 E8 2B F9 FF FF       call        __CheckForDebuggerJustMyCode (07FF69ABC1082h)  
    char buffer[10];
    strcpy(buffer, str);
00007FF69ABC1757 48 8B 95 10 01 00 00 mov         rdx,qword ptr [str]  
00007FF69ABC175E 48 8D 4D 08          lea         rcx,[buffer]  
00007FF69ABC1762 E8 CE FA FF FF       call        strcpy (07FF69ABC1235h)  
}
00007FF69ABC1767 48 8D 4D E0          lea         rcx,[rbp-20h]  
00007FF69ABC176B 48 8D 15 8E 84 00 00 lea         rdx,[__xt_z+160h (07FF69ABC9C00h)]  
00007FF69ABC1772 E8 BD FB FF FF       call        _RTC_CheckStackVars (07FF69ABC1334h)  
--> 00007FF69ABC1777 48 8B 8D E8 00 00 00 mov         rcx,qword ptr [rbp+0E8h]  
--> 00007FF69ABC177E 48 33 CD             xor         rcx,rbp  
--> 00007FF69ABC1781 E8 4C F9 FF FF       call        __security_check_cookie (07FF69ABC10D2h)  
00007FF69ABC1786 48 8D A5 F8 00 00 00 lea         rsp,[rbp+0F8h]  
00007FF69ABC178D 5F                   pop         rdi  
00007FF69ABC178E 5D                   pop         rbp  
00007FF69ABC178F C3                   ret  
koyokr commented 4 years ago

https://github.com/olliencc/WinBinaryAudit/blob/master/WinBinAudit/WinBinAuditv1Checks.cs