Thursday, November 14, 2019

77% of sites use at least one vulnerable jQuery library

A Snyk study reports that 77% of sites use at least one vulnerable JavaScript library and pointed out jQuery was detected in 79% of the top 5,000 URLs from Alexa.

The most popular open source JavaScript frameworks, Angular and React, and three other frontend JavaScript ecosystem projects - Vue.js, Bootstrap and jQuery all suffer from highly severity XSS vulnerabilities. 


Below is slide 36 of the Snyk  "The state of JavaScript frameworks security report 2019". report  listing jQuery libraries vulnerability severty status.



Source

Tuesday, November 12, 2019

CSharp : Convert a GUID to a Compressed Packed GUID


Here's how to compress and decompress Packed GUIDs or some people refer to them as Compressed GUIDs in C-Sharp


Input GUID         {12345678-ABCD-EFAB-1234-ABCDEFABCDEF}
Packed GUID is 87654321DCBABAFE2143BADCFEBADCFE

A Packed GUID format is loosely defined  as having a length of 32 characters, where the GUID is rearranged and the braces '{' and dashes '-' are removed.


Note: A "Compressed GUID" is a intermediate format, that rearranges the GUID and is Base85 encoded (using a restricted set) and has a length of 21 characters long and used to create Darwin Descriptors.  
A Darwin Descriptor is an encoded string and when decoded produces a combination of the ProductCode, Feature & ComponentId(s) and generally used for Windows installer, because it provides feature resilience through a mechanism called COM Advertising
Here's an example of a Darwin Descriptor, which you may have though was a virus entry in your registry!
"w_1^VX!!!!!!!!!MKKSkEXCELFiles>tW{~$4Q]c@II=l2xaTO5Z" 
decoded yields a GUID, feature name, and a GUID.
{91120000-0030-0000-0000-0000000ff1ce}EXCELFiles{0638c49d-bb8b-4cd1-b191-052e8f325736}


To decode Darwin Descriptors that are in the registry, use RegtoText tool to decode all values en masse (free demo available). 


In example code below, I use "compressed GUID" to describe Packed GUID. 


using System;
using System.Collections.Generic; 

//
public class Program
{
 public static bool IsHex(IEnumerable<char> chars)
 {
  bool isHex; 
  foreach(var c in chars)
  {
   isHex = ((c >= '0' && c <= '9') || 
      (c >= 'a' && c <= 'f') || 
      (c >= 'A' && c <= 'F'));

   if(!isHex)
    return false;
  }
  return true;
    }
 public static void Main()
 {
     //Source - http://www.hanselman.com/blog/BATCHFILEVOODOODetermineIfMultipleAndWhichVersionsOfAnMSIinstalledProductAreInstalledUsingUpgradeCode.aspx
     //like to but to bulky - https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-define-and-use-custom-numeric-format-providers
     //https://installpac.wordpress.com/2008/03/31/packed-guids-darwin-descriptors-and-windows-installer-reference-counting/
   
        //PROTO    
     //{12345678-ABCD-WXYZ-1234-ABCDEFGHIJKL}
     //should be-> 87654321DCBAZYXW2134BADCFEHGJILK
     //string inStrGUID = "{12345678-ABCD-WXYZ-1234-ABCDEFGHIJKL}"; //cannot use this contrived GUID has hex values above > (A-F) 
     
     string inStrGUID = "{12345678-ABCD-EFAB-1234-ABCDEFABCDEF}"; 
     string expectedCompressedGUID = "87654321DCBABAFE2143BADCFEBADCFE";
     //https://docs.microsoft.com/en-us/dotnet/api/system.guid.parse?view=netframework-4.7.2 - N has no dashes
     string outputFormat = "N"; //outputFormat can be N, D, B, P - N has no dashes
     string outCompressedGuid = ""; 
     string outDecompressedGuid = ""; 
     
     Guid inGuid = new Guid();
     Guid outGuid = new Guid(); 
     Guid outDCGuid = new Guid(); 
  
     bool isValidGuid = Guid.TryParse(inStrGUID, out inGuid); 
  
     Console.WriteLine("Input GUID " + inStrGUID+ " is valid? "+isValidGuid); 
        
     if (isValidGuid) {
      
      string raw = inGuid.ToString("N"); //N for no dashes
      char[] aRaw = raw.ToCharArray();
      //compressed format reverses 11 byte sequences of the original guid
      int[] revs
       = new int[]{8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2};
      int pos = 0;
      for (int i = 0; i < revs.Length; i++)
      {
       Array.Reverse(aRaw, pos, revs[i]);
       pos += revs[i];
      }
      string newstrGuid = new string(aRaw);
      
      bool isoutValidGuid = Guid.TryParse(newstrGuid, out outGuid); 
      
      if ( isoutValidGuid ) {
       
      //GUID in registry are all caps.
      outCompressedGuid = outGuid.ToString(outputFormat).ToUpper(); 
      
       Console.WriteLine("out  CGUID "+   outGuid.ToString("B").ToUpper()+" before full compression (removal of dashes) here for readability"); //for readability
      
       Console.WriteLine("\nCompressed guid is "+ outCompressedGuid );
         
       
       if (outCompressedGuid == expectedCompressedGUID) 
        Console.WriteLine("Matched expectations."); 
      else
       Console.WriteLine("Did not met expectations.");   
       
       
      } else
       Console.WriteLine("Failed to compress GUID."); 
     }
     
     Console.WriteLine("\nInput Compressed GUID " + outCompressedGuid); 
  
   
   char[] chrArrCGUID = outCompressedGuid.ToCharArray();
     
     //Here's a typical GUID Compressed in a Registry Key       
     //what if ? S-1-5-21-xxxxxxxxxx-xxxxxxxxx-xxxxxxxxx-xxx - split on new char[] {' ','-'} check any that are length 32 
  
     //Expand/Decompress/Decrypt Compressed GUID
     if (outCompressedGuid.Length == 32 && Program.IsHex(chrArrCGUID)==true){ //validate potential Compressed GUID
         
      int[] reversalidxs= new int[]{8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2};
       
      int pos = 0;
      for (int i = 0; i < reversalidxs.Length; i++)
      {
       Array.Reverse(chrArrCGUID, pos, reversalidxs[i]);
       pos += reversalidxs[i];
      }
      string newstrGuid = new string(chrArrCGUID);
      
      bool isoutValidDCGuid = Guid.TryParse(newstrGuid, out outDCGuid );
      
      if ( isoutValidDCGuid ) {
       
       //GUID in registry are all caps.
       outDecompressedGuid = outDCGuid.ToString("B").ToUpper(); 

       //Console.WriteLine("\nInput Compressed GUID "+   outDCGuid.ToString("B").ToUpper()+" this line for comparison only"); //for readability
       Console.WriteLine("Output Decomprsd GUID "+   outDCGuid.ToString("N").ToUpper()+" this line for comparison only"); //for readability

       Console.WriteLine("\nDecompressed compressed guid is "+ outDecompressedGuid );
     }
     
     }
     else 
     Console.WriteLine("Failed to decompressed CGUID.");  
  
 }
 
}

Sunday, November 10, 2019

Why are malware viruses so widespread?

This is the perennial question, that will not die. Here's one major reason why.

Microsoft security engineer Matt Miller from Microsoft Security Response Center
 gave a recent presentation at a security conference tracking malware attacks across Microsoft software for the last 12 years. In slide 10 of the presentation, he states around 70 percent of all Microsoft patches were fixes for memory safety bugs

The reason for this high percentage is because Windows operating system has been written mostly in C and C++. These "memory-unsafe" programming languages that allow developers fine-grained control of the memory addresses where their code can be executed, but also can leave gaping holes. 

Like Windows, Apple Macintosh operating system and Iphone OS (which is a variant of Unix, a Linux predecessor) and Linux variants are all written in "memory-unsafe" C or C++, primarily for speed. Kernels have been traditionally written in C. C's philosophy was to trust the programmer.

It would require a tremendous effort to re-write, the OS into a memory safe language.

Specifically, as of 26 September 2018, using then-current 20,088,609 LOC (lines of code) for the Linux kernel version 4.14.14  and the current US National average programmer salary of $75,506 show it would cost approximately $14 Billion dollars to rewrite the existing GPL-2.0 code that existing contributors still have claimed to if they decided to rescind the grant of license to the kernel source.  Source: https://en.wikipedia.org/wiki/Linux_kernel

What is a Memory-unsafe bug?

Memory-unsafe bugs happen when software, accidentally or intentionally, accesses system memory in a way that exceeds its allocated size and memory addresses, accessing other parts of the system to gain elevated privileges or impregnate custom malware code into that adjacent memory space.

Memory-unsafe bugs have similar terms such as buffer overflow, race condition, page fault, null pointer, stack exhaustion, heap exhaustion/corruption, use after free, or double free --all describe memory safety vulnerabilities. 










































There is a tension for whom the responsibility resides with, the language/compiler or the operating system. 

The C philosophy is always trust the programmer. And also not checking bounds allows a C program to run faster. The problem is that C/C++ doesn't actually do any boundary checking with regards to arrays. It depends on the OS to ensure that you are accessing valid memory.

There is only one solution and that is to re-write the entire Windows Operating system in a memory-safe language like Rust. That is starting to be addressed

Here's a brief review of one unsafe memory bug, stack overflow.




































Source Slides : https://github.com/Microsoft/MSRC-Security-Research/blob/master/presentations/2019_02_BlueHatIL/2019_01%20-%20BlueHatIL%20-%20Trends%2C%20challenge%2C%20and%20shifts%20in%20software%20vulnerability%20mitigation.pdf

Stack Overflow Attack Source Slides
https://www.slideshare.net/gumption/buffer-overflow-attacks-7024353