The essence of Security Vulnerabilities
0x00 Preface
Fuzzing is a popular and efficient method for discovering vulnerabilities. Of course, it also takes some time to write the Fuzzing program. However, not all things need to write Fuzzing programs, and not all things can be Fuzzing, so we still need to continue to cultivate the internal power of our binary Security genre-"the naked eye to dig holes ".
Security Vulnerabilities have different performances at the source and assembly code levels. To perform advanced upgrades, you must have a clear understanding of the source and assembly code levels of each type of security vulnerability. Some security vulnerabilities are easy to find at the source code level, while some security vulnerabilities are easy to find at the compilation code level. At the source code level or assembly code level, even if ordinary people see the code with security vulnerabilities, they often "only see the code, no vulnerabilities ". The goal of "exploiting holes with the naked eye" is to be alert, be able to identify and quickly determine whether security vulnerabilities can be formed when you see code that is suspected to have problems.
0x01 source code 1. Link Attack
* Do you realize link attack in unix?
if(access("file",W_OK)!=0){ exit(1);}fd = open("file",O_WRONLY);write(fd,buffer,sizeof(buffer));2. Integer Overflow Example in OpenSSH 3.1
Is there a vulnerability in openssh 3.1?
u_int nresp;...nresp = packet_get_int();if(nresp){ response = xmalloc(nresp * sizeof(char*)); for(i=0; i<nresp; i++) response[i] = packet_get_string(NULL);}packet_check_eom();3. Signed Integer Vulnerability Example
Note the integer. Can it be bypassed?
int read_user_data(int sockfd) { int length, sockfd, n; char buffer[1024]; length = get_user_length(sockfd); if(length > 1024){ error("illegal input, not enough room in buffer\n"); return 1; } if(read(sockfd, buffer, length) < 0){ error("read: %m"); return 1; } return 0; }4. Truncation Vulnerability Example in NFS
Integer truncation problem?
void assume_privs(unsigned short uid) { seteuid(uid); setuid(uid);}int become_user(int uid) { if (uid == 0) die("root isnt allowed"); assume_privs(uid); }5. Details of Apple's SSL/TLS major Security Vulnerabilities
(CVE-2014-1266) Multiple goto fail causes significant security risks.
static OSStatusSSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen){ ... if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; <---- *** DANGER *** if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail; err = sslRawVerify(ctx, ctx->peerPubKey, dataToSign, /* plaintext */ dataToSignLen, /* plaintext length */ signature, signatureLen); ...fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err;}6. MS-RPC DCOM Buffer Overflow? (Shock wave)
Only one buffer zone overflows.
HRESULT GetMachineName (WCHAR * pwszPath) { The WCHAR wszMachineName [N + 1]); ... LPWSTR pwszServerName = wszMachineName; while (* pwszPath! = L '\\') * PwszServerName + + = * pwszPath + +; ...}7. Are there any vulnerabilities?
unsigned short read_length(int sockfd) { unsigned short len; if(full_read(sockfd, (void *)&len, 2) != 2) die("could not read length!\n"); return ntohs(len);}int read_packet(int sockfd) { struct header hdr; short length; char *buffer; length = read_length(sockfd); if(length > 1024){ error("read_packet: length too large: %d\n", length); return 1; } buffer = (char *)malloc(length+1); if((n = read(sockfd, buffer, length) < 0){ error("read: %m"); free(buffer); return 1; } buffer[n] = '\0'; return 0; }8. Are there any vulnerabilities?
Tip: 5rOo5oSPc216ZW9m
char *read_username(int sockfd) { char *buffer, *style, userstring[1024]; int i; buffer = (char *)malloc(1024); if(!buffer){ error("buffer allocation failed: %m"); return NULL; } if(read(sockfd, userstring, sizeof(userstring)-1) <= 0){ free(buffer); error("read failure: %m"); return NULL; } userstring[sizeof(userstring)-1] = '\0'; style = strchr(userstring, ':'); if(style) *style++ = '\0'; sprintf(buffer, "username=%.32s", userstring); if(style) snprintf(buffer, sizeof(buffer)-strlen(buffer)-1, ", style=%s\n", style); return buffer;}9. Are there any vulnerabilities?
Tip:
/* special thing for ldap.* The parts are separated by question marks. * From RFC 2255:* ldapurl = scheme "://" [hostport] ["/"* [dn ["?" [attributes] ["?" [scope] * ["?" [filter] ["?" extensions]]]]]]*/if (!strncasecmp(uri, "ldap", 4)) { char *token[5]; int c = 0; token[0] = cp = ap_pstrdup(p, cp); while (*cp && c < 5) { if (*cp == '?') { token[++c] = cp + 1; *cp = '\0'; } ++cp; }10. Are there any vulnerabilities? (Antisniff v1.1 Vulnerability)
Tips
char *indx;int count;char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset); count = (char)*indx;while (count){ if (strlen(nameStr) + count < ( MAX_LEN - 1) ){ (char *)indx++; strncat(nameStr, (char *)indx, count); indx += count; count = (char)*indx; strncat(nameStr, ".", sizeof(nameStr) strlen(nameStr)); } else { fprintf(stderr, "Alert! Someone is attempting " "to send LONG DNS packets\n"); count = 0; }}nameStr[strlen(nameStr)-1] = '\0';11. Are there any other vulnerabilities? (Antisniff v1.1.1 Vulnerability)
char *indx;int count;char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset); count = (char)*indx;while (count){/* typecast the strlen so we aren't dependent on the call to be properly setting to unsigned. */ if ((unsigned int)strlen(nameStr) + (unsigned int)count < ( MAX_LEN - 1) ){ (char *)indx++; strncat(nameStr, (char *)indx, count); indx += count; count = (char)*indx; strncat(nameStr, ".", sizeof(nameStr) strlen(nameStr)); } else { fprintf(stderr, "Alert! Someone is attempting " "to send LONG DNS packets\n"); count = 0; }}nameStr[strlen(nameStr)-1] = '\0';12. Are there any vulnerabilities? (Antisniff v1.1.2 Vulnerability)
unsigned char *indx;unsigned int count;unsigned char nameStr[MAX_LEN]; //256...memset(nameStr, '\0', sizeof(nameStr));...indx = (char *)(pkt + rr_offset); count = (char)*indx;while (count){ if (strlen(nameStr) + count < ( MAX_LEN - 1) ){ indx++; strncat(nameStr, indx, count); indx += count; count = *indx; strncat(nameStr, ".", sizeof(nameStr) strlen(nameStr)); } else { fprintf(stderr, "Alert! Someone is attempting " "to send LONG DNS packets\n"); count = 0; }}nameStr[strlen(nameStr)-1] = '\0';0x02 assembly code Layer
Next, we need to hone it in the assembly code heap. Is there a security problem with the assembly code below? What are the issues?
1. Safe or vulnerability?
text:0040106B sub_40106B proc near ; CODE XREF: _main+58p.text:0040106B.text:0040106B var_10004 = byte ptr -10004h.text:0040106B var_4 = dword ptr -4.text:0040106B arg_0 = word ptr 8.text:0040106B.text:0040106B push ebp.text:0040106C mov ebp, esp.text:0040106E mov eax, 10004h.text:00401073 call __alloca_probe.text:00401078 mov eax, dword_404020.text:0040107D xor eax, ebp.text:0040107F mov [ebp+var_4], eax.text:00401082 movsx eax, [ebp+arg_0].text:00401086 movsx eax, [ebp+eax+var_10004].text:0040108E push eax.text:0040108F push offset Format ; "t %x".text:00401094 call ds:printf.text:0040109A pop ecx.text:0040109B pop ecx.text:0040109C mov ecx, [ebp+var_4].text:0040109F xor ecx, ebp.text:004010A1 xor eax, eax.text:004010A3 call sub_401BD2.text:004010A8 leave
2. Safe or vulnerability?
text:004010AA sub_4010AA proc near ; CODE XREF: _main+60p.text:004010AA.text:004010AA var_190 = dword ptr -190h.text:004010AA arg_0 = dword ptr 8.text:004010AA.text:004010AA push ebp.text:004010AB mov ebp, esp.text:004010AD mov eax, [ebp+arg_0].text:004010B0 sub esp, 190h .text:004010B6 cmp eax, 64h .text:004010B9 jle short loc_4010BE .text:004010BB push 64h .text:004010BD pop eax .text:004010BE .text:004010BE loc_4010BE: ; CODE XREF: sub_4010AA+Fj.text:004010BE push [ebp+eax*4+var_190].text:004010C5 push offset Format ; "t %x".text:004010CA call ds:printf.text:004010D0 pop ecx
3. Safe or vulnerability?
.text:00401000 sub_401000 proc near ; CODE XREF: _main+48p.text:00401000.text:00401000 var_190 = dword ptr -190h.text:00401000 arg_0 = dword ptr 8.text:00401000.text:00401000 push ebp.text:00401001 mov ebp, esp.text:00401003 mov eax, [ebp+arg_0].text:00401006 sub esp, 190h .text:0040100C cmp eax, 64h .text:0040100F jbe short loc_401014 .text:00401011 push 64h .text:00401013 pop eax .text:00401014 .text:00401014 loc_401014: ; CODE XREF: sub_401000+Fj.text:00401014 push [ebp+eax*4+var_190].text:0040101B push offset Format ; "t %x".text:00401020 call ds:printf.text:00401026 pop ecx.text:00401027 pop ecx
4. Safe or vulnerability?
.text:004010D6 sub_4010D6 proc near ; CODE XREF: _main+68p.text:004010D6.text:004010D6 arg_0 = dword ptr 4.text:004010D6.text:004010D6 push esi.text:004010D7 push 64h ; Size.text:004010D9 call ds:malloc.text:004010DF mov esi, eax.text:004010E1 mov eax, [esp+8+arg_0].text:004010E5 cmp eax, 64h.text:004010E8 pop ecx.text:004010E9 jle short loc_4010EE.text:004010EB push 64h.text:004010ED pop eax.text:004010EE.text:004010EE loc_4010EE: ; CODE XREF: sub_4010D6+13j.text:004010EE movsx eax, byte ptr [eax+esi].text:004010F2 push eax.text:004010F3 push offset Format ; "t %x".text:004010F8 call ds:printf.text:004010FE push esi ; Memory.text:004010FF call ds:free
5. Safe or vulnerability?
. text:0040110C sub_40110C proc near ; CODE XREF: _main+70p.text:0040110C.text:0040110C var_19A0 = byte ptr -19A0h.text:0040110C var_4 = dword ptr -4.text:0040110C arg_0 = word ptr 8.text:0040110C.text:0040110C push ebp.text:0040110D mov ebp, esp.text:0040110F mov eax, 19A0h.text:00401114 call __alloca_probe.text:00401119 mov eax, dword_404020.text:0040111E xor eax, ebp.text:00401120 mov [ebp+var_4], eax.text:00401123 movsx eax, [ebp+arg_0].text:00401127 movsx eax, [ebp+eax+var_19A0].text:0040112F push eax.text:00401130 push offset Format ; "t %x".text:00401135 call ds:printf.text:0040113B pop ecx.text:0040113C pop ecx.text:0040113D mov ecx, [ebp+var_4].text:00401140 xor ecx, ebp
6. Safe or vulnerability?
.text:0040102C sub_40102C proc near ; CODE XREF: _main+50p.text:0040102C.text:0040102C var_10004 = byte ptr -10004h.text:0040102C var_4 = dword ptr -4.text:0040102C arg_0 = word ptr 8.text:0040102C.text:0040102C push ebp.text:0040102D mov ebp, esp.text:0040102F mov eax, 10004h.text:00401034 call __alloca_probe.text:00401039 mov eax, dword_404020.text:0040103E xor eax, ebp.text:00401040 mov [ebp+var_4], eax.text:00401043 movzx eax, [ebp+arg_0].text:00401047 movsx eax, [ebp+eax+var_10004].text:0040104F push eax.text:00401050 push offset Format ; "t %x".text:00401055 call ds:printf.text:0040105B pop ecx
7. Safe or vulnerability?
. .text:0040118A ; int __cdecl sub_40118A(LPCSTR lpMultiByteStr).text:0040118A sub_40118A proc near ; CODE XREF: _main+91p.text:0040118A.text:0040118A WideCharStr = word ptr -44h.text:0040118A var_4 = dword ptr -4.text:0040118A lpMultiByteStr = dword ptr 8.text:0040118A.text:0040118A push ebp.text:0040118B mov ebp, esp.text:0040118D sub esp, 44h .text:00401190 mov eax, dword_404020 .text:00401195 xor eax, ebp .text:00401197 mov [ebp+var_4], eax .text:0040119A mov ecx, [ebp+lpMultiByteStr] .text:0040119D mov eax, ecx .text:0040119F push esi .text:004011A0 lea esi, [eax+1] .text:004011A3 .text:004011A3 loc_4011A3: ; CODE XREF: sub_40118A+1Ej.text:004011A3 mov dl, [eax].text:004011A5 inc eax.text:004011A6 test dl, dl.text:004011A8 jnz short loc_4011A3.text:004011AA push 40h ; cchWideChar.text:004011AC lea edx, [ebp+WideCharStr].text:004011AF push edx ; lpWideCharStr.text:004011B0 sub eax, esi .text:004011B2 push eax ; cbMultiByte.text:004011B3 push ecx ; lpMultiByteStr.text:004011B4 push 0 ; dwFlags.text:004011B6 push 0 ; CodePage.text:004011B8 call ds:MultiByteToWideChar
8. Safe or vulnerability?
text:00401738 Size = dword ptr 4.text:00401738 Src = dword ptr 8.text:00401738.text:00401738 push esi.text:00401739 push edi.text:0040173A mov edi, [esp+8+Size].text:0040173E lea eax, [edi+1].text:00401741 push eax ; Size.text:00401742 call ds:__imp__malloc.text:00401748 mov esi, eax.text:0040174A test esi, esi.text:0040174C pop ecx.text:0040174D jz short loc_401774.text:0040174F push edi ; Size.text:00401750 push [esp+0Ch+Src] ; Src.text:00401754 push esi ; Dst.text:00401755 call _memcpy.text:0040175A push esi.text:0040175B push offset aS ; "%s\n".text:00401760 mov byte ptr [esi+edi], 0.text:00401764 call ds:__imp__printf
0x04 last
For examples at the assembly code level, you need to think about how their source code is written to compile these security vulnerability code. The source code layer and the assembly code layer can be used together. It is also necessary to understand the functions and rules of the program world from a macro perspective and its implementation details from a micro perspective.
In the above example, there are less than one hundred lines of assembly code. Are all the problems found? The battle assembly code requires us to find hidden security vulnerabilities in tens of millions of lines of assembly code in the real program world, which is much more difficult. There are defense measures against programmers, and you need to think about how to defeat it. It is a silent competition between the creators of the Program World and the time and space.
The above is actually a reference, and we need our partners to continue to study and exercise. We recommend that you learn The Art of Software Security Assessment -- Identifying andavoiding software vulnerabilities (some examples are from this book) from The book Mark Down & JohnMcDonald.