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: }