Automate MSSASI As A Shell Command
I have created an ASP.NET page to automate the Microsoft Source Code Analyzer for SQL Injection command line tool. It would be tedious to craft a command for every page in a large Classic ASP web site. I was unable to scan my entire site until I developed this ASP.NET page.
Why an ASP.NET page and not a console application? Well "I've learned to use a hammer, so I'm gonna hammer everything" as Jeff Atwood would say. LOL. But seriously, I wanted to generate a HTML report so it may as well be a single ASP.NET page. You can easily convert it to a console application or even a Windows application. I did learn how to redirect standard input, output, and error streams which is good to know.
msscasi.aspx
1: <%@ Page Language="C#" Theme="Granite" MasterPageFile="~/AppMaster.master" AutoEventWireup="true" CodeFile="msscasi.aspx.cs" Inherits="msscasi" Title="ASP Web Site Parser" %>
2: <asp:Content ID="Content1" ContentPlaceHolderID="mainCopy" Runat="Server">
3: <div class="container">
4: <h2>ASP Web Site Parser</h2>5: <p class="teaser">
6: Scans all ASP pages in a web site for SQL Injection vulnerabilities.</p>
7: <p>Enter ASP site file location: <asp:TextBox ID="txtPath" runat="server"></asp:TextBox></p>
8: <p><asp:Button ID="btnSubmit" Text="Submit" runat="server" OnClick="btnSubmit_Click" /></p>
9: <p><asp:Label ID="lblMessage" runat="server"></asp:Label></p>
10: <p><asp:Label ID="lblErrorMessage" ForeColor="red" runat="server"></asp:Label></p>
11: </div> 12: </asp:Content>13: <asp:Content ID="Content2" ContentPlaceHolderID="leftColumn" Runat="Server">
14: </asp:Content>15: <asp:Content ID="Content3" ContentPlaceHolderID="rightColumn" Runat="Server">
16: </asp:Content>msscasi.aspx.cs
1: using System;
2: using System.Data;
3: using System.Configuration;
4: using System.Collections;
5: using System.Web;
6: using System.Web.Security;
7: using System.Web.UI;
8: using System.Web.UI.WebControls;
9: using System.Web.UI.WebControls.WebParts;
10: using System.Web.UI.HtmlControls;
11: using System.IO;
12: using System.Diagnostics;
13: using System.Text;
14: 15: public partial class msscasi : System.Web.UI.Page
16: { 17: 18: StringBuilder sbStandardOutput = new StringBuilder();
19: StringBuilder sbStandardError = new StringBuilder();
20: public const string MSSCASI_PATH = "\"G:\\msscasi\\msscasi_asp.exe\"";
21: 22: /// <summary>
23: /// Handles the Click event of the btnSubmit control.
24: /// </summary>
25: /// <param name="sender">The source of the event.</param>
26: /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
27: protected void btnSubmit_Click(object sender, EventArgs e)
28: {29: if (String.IsNullOrEmpty(txtPath.Text))
30: {31: lblErrorMessage.Text = "You neglected to enter a file path to the ASP site!";
32: return;
33: }34: else
35: {36: // proceed with recursive file processing
37: try
38: {39: DirectoryInfo objDirectoryInfo = new DirectoryInfo(txtPath.Text);
40: ListDirectoryFiles(objDirectoryInfo); 41: lblMessage.Text = sbStandardOutput.ToString(); 42: lblErrorMessage.Text = sbStandardError.ToString();43: lblErrorMessage.Visible = true;
44: 45: // write a report to a file as well
46: FileInfo objFileInfo = new FileInfo(Server.MapPath("App_Data\\report.html"));
47: StreamWriter objStreamWriter = objFileInfo.CreateText(); 48: objStreamWriter.Write(sbStandardOutput.ToString()); 49: objStreamWriter.Flush(); 50: objStreamWriter.Close(); 51: objStreamWriter.Dispose(); 52: }53: catch (Exception err)
54: {55: // display error
56: lblErrorMessage.Text = err.ToString();57: lblErrorMessage.Visible = true;
58: } 59: 60: } 61: } 62: 63: /// <summary>
64: /// Lists the directory files.
65: /// </summary>
66: /// <param name="objDirectoryInfo">The obj directory info.</param>
67: /// <remarks>This is a recursive function.</remarks>
68: public void ListDirectoryFiles(DirectoryInfo objDirectoryInfo)
69: {70: string strGlobalAsa = "";
71: // loop through files
72: foreach (FileSystemInfo objFileSystemInfo in objDirectoryInfo.GetFileSystemInfos())
73: {74: if (objFileSystemInfo is FileInfo)
75: { 76: FileInfo objFileInfo = ((FileInfo)objFileSystemInfo);77: if (objFileInfo.Extension == ".asp" || objFileInfo.Extension == ".asa")
78: {79: // determine the file path to the global.asa file
80: if (objFileInfo.Name.ToLower().Trim() == "global.asa")
81: { 82: strGlobalAsa = objFileInfo.FullName; 83: }84: // shell command
85: System.Diagnostics.Process objProcess = new System.Diagnostics.Process();
86: objProcess.StartInfo.FileName = MSSCASI_PATH;87: objProcess.StartInfo.Arguments = "/GlobalAsaPath=" + strGlobalAsa;
88: objProcess.StartInfo.Arguments = "/input=" + objFileInfo.FullName;
89: // Setting this property to false enables you to redirect input, output, and error streams
90: objProcess.StartInfo.UseShellExecute = false;
91: objProcess.StartInfo.CreateNoWindow = true;
92: objProcess.StartInfo.RedirectStandardInput = true;
93: objProcess.StartInfo.RedirectStandardOutput = true;
94: objProcess.StartInfo.RedirectStandardError = true;
95: objProcess.Start(); 96: 97: StreamWriter sIn = objProcess.StandardInput; 98: StreamReader sOut = objProcess.StandardOutput; 99: StreamReader sErr = objProcess.StandardError; 100: 101: string s = sOut.ReadToEnd();
102: string e = sErr.ReadToEnd();
103: 104: if (String.IsNullOrEmpty(s) == false)
105: {106: // highlight warnings in red
107: if (s.Contains("warning"))
108: {109: sbStandardOutput.Append("<font color=#FF0000>");
110: }111: else
112: {113: sbStandardOutput.Append("<font color=#000000>");
114: }115: sbStandardOutput.Append("<br><b>");
116: sbStandardOutput.Append(objFileInfo.FullName);117: sbStandardOutput.Append("</b><br>");
118: sbStandardOutput.Append(s);119: sbStandardOutput.Append("</font><br>");
120: Debug.WriteLine(s); 121: }122: if (String.IsNullOrEmpty(e) == false)
123: {124: sbStandardError.Append("<br><b>");
125: sbStandardError.Append("<br><b>");
126: sbStandardError.Append(objFileInfo.FullName);127: sbStandardError.Append("</b><br>");
128: sbStandardError.Append(e); 129: Debug.WriteLine(e); 130: } 131: 132: sIn.Close(); 133: sOut.Close(); 134: objProcess.Close(); 135: } 136: } 137: }138: // loop through directories
139: foreach (DirectoryInfo objSubDirectoryInfo in objDirectoryInfo.GetDirectories("*.*"))
140: {141: if (objSubDirectoryInfo.Name.Substring(0,1) == "_")
142: {143: // skip FrontPage Server Extension directories
144: }145: else
146: { 147: ListDirectoryFiles(objSubDirectoryInfo); 148: } 149: } 150: 151: } 152: }