© Marius Iulian Mihailescu and Stefania Loredana Nita 2021
M. I. Mihailescu, S. L. NitaPro Cryptography and Cryptanalysis https://doi.org/10.1007/978-1-4842-6367-9_22

22. Attacks

Marius Iulian Mihailescu1   and Stefania Loredana Nita1
(1)
Bucharest, Romania
 

In this chapter, we will analyze the most important attacks that can occur in a distributed environment (cloud computing [3] or big data) and how they can be exploited using the C# programming language [2] with features from version 8.0. For reference, we will use as an example an ASP.NET MVC 5 (also will work for previous versions of MVC, such as 1.0, 2.0, 3.0, and 4.0) application using C# as the back-end programming language.

The three most common attacks that occur on a daily basis on a web application are redirection attacks, SQL injections, and cross-site scripting (XSS).

The methods described here are part of the ethical hacking field and using them the wrong way can produce a major disaster for a business. The methods are very useful for the red teamers and some of them will be dedicated to post-exploitation.

Port Forwarding and How to Prevent Open Redirection Attacks

Through port forwarding a hacker cannot get access to you, but the router can be exploited in order to allow configuration on a web port.

A web application that redirects to a URL that is specified using a request based on a querystring can be easily tampered with via a redirection of the users to an external and malicious URL. This kind of attack is known as an open redirection attack .

To perform an attack and to encounter this vulnerability, it is very important to understand how login redirection works in an ASP.NET MVC web application project. In the example presented below, we can see that if we are going and access a controller action which has in its structure the [Authorize] attribute, this will redirect the unauthorized users to the /Account/LogOn view. The mentioned redirection to /Account/LogOn has in its structure a parameter known as returning_url querystring in such way that the user will be returned to the genuine URL that was requested after being logged in with success.

Attacks based on open redirection are very dangerous. The attacker knows exactly when we are proceeding to log into a certain website. This can make us vulnerable to a phishing attack. As an example, consider an attacker who sends malicious emails to users who are subscribed to a certain website in order to capture their passwords.

Let’s consider the following example in which an attacker sends a link to users which contains a login page on a specific webpage (e.g. http://apressprocryptoexample.com) which has in its component a redirection to the forged page,

http://apressprocryptoexample.com/Account/LogOn?returnUrl=http://apresprocryptoexample.com/Account/LogOn. Pay attention to the returning URL, which points to apresprocryptoexample.com. Note that an "s" is missing from the word “apress.” This means that the domain apresprocryptoexample.com is being controlled by hackers.

If the login is performed correctly, the AccountController LogOn action from ASP.NET MVC will redirect us to the URL mentioned in the querystring parameter, returning_url. In this situation, the URL is the one used by the attacker, which is http://apresprocryptoexample.com. If we are not paying attention, we will not notice the difference in the browser. The attacker is a very well versed person and is careful to make sure that the fake page looks exactly like the original one. The fake login page includes an error message that says that we need to log in with our credentials again. Once we retype our credentials, the fake login page will save the data and send us back to the original page, ApressProCryptoExample.com. At this point, ApressProCryptoExample.com will have already logged us in with success, and the fake authentication page is able to redirect us to that specific page. The final result is based on the fact that the attacker is aware of our credentials (user name and password) and we, the real users, are not aware that we have provided our credentials so easily [4].

Let’s continue by looking at the code (Listing 22-1) for the LoginAuthentication action from our application. Our defined controller will return a redirection to returning_url. The validation is missing completely for the returning_url parameter.
[HttpPost]
public ActionResult LoginAuthentication(
                                    LogOnModel model,
                                    string returning_url)
{
    if (ModelState.IsValid)
    {
        if (MembershipService.ValidateUser(model.UserName,
        model.Password))
        {
            FormsService.SignIn(model.UserName,
                                model.RememberMe);
            if (!String.IsNullOrEmpty(returning_url)) {
                return Redirect(returning_url);
            }
            else {
                return RedirectToAction("Index", "Home");
            }
        }
        else {
            ModelState.AddModelError("", "The credentials are
                                      wrong. Please, try again.");
        }
    }
    //** if we reach here it means that
    //** something went wrong
    //** we will show again the form
    return View(model);
}
Listing 22-1

Login Controller

Table 22-1

Other Examples of SQL Injections

Example of SQL injection

Description

' or ''

String characters as indicators

-- or #

Single-line comments

/*..*/

Multiple-line comments

+

Addition, concatenation (also for URLs)

||

Double concatenation

%

Wildcard attribute indicator

?Param1=foo&Param2=bar

URL parameters

PRINT

Non-transactional command

@variable

Local variable

@@variable

Global variable

waitfor delay '0:0:10'

Time delay

Listing 22-2 shows how to perform the validation with returning_url. This is done using a new method, IsLocalUrl(), which is part of the helper class System.Web.Mvc.Url.
[HttpPost]
public ActionResult LoginAuthentication(LogOnModel model, string returning_url)
{
    if (ModelState.IsValid)
    {
        if (MembershipService.ValidateUser(model.UserName,
                                           model.Password))
        {
            FormsService.SignIn(model.UserName,
                                            model.RememberMe);
            if (Url.IsLocalUrl(returning_url)){
                return Redirect(returning_url);
            }
            else {
                return RedirectToAction("Index", "Home");
            }
        }
        else {
            ModelState.AddModelError("",
                      "The credentials are wrong.
                       Please, try again.");
        }
    }
    //** if we reach here it means that
    //** something went wrong
    //** we will show again the form
    return View(model);
}
Listing 22-2

Validation for returning_url

SQL Injection

For many companies, their business occurs online and in environments [5] such as cloud computing and big data, so their web sites are becoming more and more exposed to the possibility of data theft. Hackers can get important information from their data and pass it to other players on the market.

SQL injection is one of the most common methods through which malicious users can inject different SQL commands into a SQL statement using web page input. By doing so, the malicious users can break the security of the web application.

In this section, we will consider the following web application, which is built from scratch for this purpose. The reason of creating such an application from scratch is to illustrate the common mistakes developers make during the development process.

The first step is to build a database with a table that holds the login data for users. The database is created in Microsoft SQL Server v.17.9. Figure 22-1 shows the structure of the table and Listing 22-3 shows the SQL script code for generating the table. One of the common mistakes is that many web applications store passwords in plaintext. It is recommended to avoid this practice. The best practice is to use hashes of the password (such as MD5, SHA128, SHA256 etc.). For our example, we will use plaintext passwords.
../images/493660_1_En_22_Chapter/493660_1_En_22_Fig1_HTML.jpg
Figure 22-1

Table structure

USE [Apress_ProCrypto_SQLInjectionDB]
GO
/****** Object:  Table [dbo].[LoginUserData]
Script Date: 6/23/2020 2:51:06 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[LoginUserData](
     [ID] [int] IDENTITY(1,1) NOT NULL,
     [FirstName] [varchar](50) NULL,
     [LastName] [varchar](50) NULL,
     [Email] [varchar](50) NULL,
     [Password] [varchar](50) NULL,
     [LastDateLogged] [datetime] NULL,
 CONSTRAINT [PK_LoginUserData] PRIMARY KEY CLUSTERED
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Listing 22-3

Login User Data Table SQL Script

The second step is to populate the table with some data, as in Figure 22-2. And then we execute the script against the table from Listing 22-4.
../images/493660_1_En_22_Chapter/493660_1_En_22_Fig2_HTML.jpg
Figure 22-2

Data for users

SET NOCOUNT ON
INSERT INTO dbo.LoginUserData
              ([FirstName],[LastName],
              [Email],[Password],[LastDateLogged])
VALUES
      ('Jefferson','Nicholas','[email protected]','password1',CONVERT(datetime,NULL,121))
      ,('Thomas','Claudio','[email protected]','password2',CONVERT(datetime,NULL,121))
      ,('Steven','Paolo','[email protected]','password3',CONVERT(datetime,NULL,121))
      ,('Billy','Walsh','[email protected]','password4',CONVERT(datetime,NULL,121))
Listing 22-4

Data Content

The third step consists of building the web application. For this, we will not use an extra fancy web application architecture. It’s just a simple web application with two web pages. The connection to the database is done using ADO.NET. With other object relational mapping (ORMs) such as NHibernate, LINQ-to-SQL, or Entity Framework, the results are the same. The single difference is the long time for processing the SQL injection.

The first page that we build is Login.aspx. As you can see in Figure 22-3, the page contains a simple form. The code is shown in Listing 22-5.
../images/493660_1_En_22_Chapter/493660_1_En_22_Fig3_HTML.jpg
Figure 22-3

Login.aspx page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<!DOCTYPE html>
<html xmlns:="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <center>
        <form id="form1" runat="server">
        <div>
            <asp:Login ID="MyLogin" runat="server"
                   OnAuthenticate="MyLogin_Authenticate"
                   Width="331px" BackColor="#F7F6F3" BorderColor="#E6E2D8" BorderPadding="4" BorderStyle="Solid" BorderWidth="1px"
                   Font-Names="Verdana" Font-Size="0.8em" ForeColor="#333333" Height="139px">
            <InstructionTextStyle Font-Italic="True"
                                                    ForeColor="Blue" />
            <LoginButtonStyle BackColor="green"
                   BorderColor="black" BorderStyle="Solid" BorderWidth="1px" Font-Names="Verdana"
                   Font-Size="0.8em" ForeColor="#284775" />
                <TextBoxStyle Font-Size="0.8em" />
                <TitleTextStyle BackColor="green" Font-Bold="True" Font-Size="0.9em"
                   ForeColor="White" />
            </asp:Login>
        </div>
        </form>
    </center>
    <br />
    <br />
    <center>
             This example is build for illustrating SQL
             Injection. Authors: Marius Iulian MIHAILESCU and Stefania Loredana NITA
    </center>
</body>
</html>
Listing 22-5

The HTML Source Code of Login.aspx

Listing 22-6 shows the server side code for Login.aspx. What you can note from here is that there’s no kind of validation for the integrity of the password or avoiding SQL injection attacks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
public partial class Login : System.Web.UI.Page
{
    DataTable data_table;
    SqlDataAdapter adapter;
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void MyLogin_Authenticate(object sender,
                                        AuthenticateEventArgs e)
    {
        SqlConnection connection = new SqlConnection(@"Data
                         Source=SERVER_NAME;Initial Catalog=Apress_ProCrypto_SQLInjectionDB;Integrated Security=True");
        string query="select * from LoginUserData where
                   Email='"+ MyLogin.UserName+"'and Password='"+
                   MyLogin.Password+"' ";
        adapter = new SqlDataAdapter(query, connection);
        data_table = new DataTable();
        adapter.Fill(data_table);
        if (data_table.Rows.Count >= 1)
        {
            Response.Redirect("index.aspx");
        }
    }
}
Listing 22-6

Server Side Source Code for Login.aspx

The second page is called Index.aspx, which is a confirmation page for a successful login (see Listings 22-7 and 22-8). There is nothing special about the page.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Index.aspx.cs" Inherits="Index" %>
<!DOCTYPE html>
<html xmlns:="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>APRESS-Example of SQL Injection</title>
</head>
<body>
    <form id="form1" runat="server">
    <div><center>
    <h1>Hello, Apress! <br/>
        Example for SQL Injection
    </h1></center>
    </div>
    </form>
</body>
</html>
Listing 22-7

Source Code for Index.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Index : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}
Listing 22-8

Server Side Source Code for Index.aspx

Now that we have the entire project set, let’s proceed with the SQL injection analysis and attack. The query is as follows:
                 select * from LoginUserData where
             Email='"+ MyLogin.UserName+"'and Password='"+
                 MyLogin.Password+"';
Let’s consider the case when in the TextBox of the login control we have entered ‘ or 1=1. Once the Log In button is pressed, the query will look like the following:
select  * from LoginUserData where Email=" or 1=1--'and Password="
If the attacker knows the username or rule 1=1, it will not be applied anymore. He will simply write the username + ‘ in the TextBox and comment everything that follows, like so:
               select  * from LoginUserData where
          Email='[email protected]'--and Password="
Another dangerous example is deleting records or dropping tables from the database. The following example shows this situation:
select * from LoginUserData where Email=" Delete from LoginUserData
       –'and Password="

Other types of SQL injections can be seen in Table 23-1. Some of them are quite dangerous and are not recommended to be used against live production databases.

In case of an ASP.NET MVC web application, the procedure is similar with the one described above.

Cross-Site Scripting (XSS)

Cross-site scripting (XSS) is a security vulnerability where an attacker inserts client-side scripts, mostly JavaScript, into web pages. When a user accesses a web application, the browser will load the affected pages, and the scripts found within those pages will run, providing attackers a way to get possession of cookies and session tokens. Most of the time, XSS vulnerabilities occur when the web application takes the user input and outputs it to another page without validating, encoding, or escaping it.

From experience, we recommend that you follow these rules to protect your web application against XSS:
  • Never enter sensitive data in HTML pages, such as HTML form inputs, queries, HTTP headers, etc.

  • Everything that is found within a HTML element should be encoded.

  • Everything that is found within a HTML attribute should be encoded.

  • Any untrusted data that are, let’s say, necessary (I don’t like this term but let’s keep it in this way) to be added in JavaScript should be first entered in an HTML element whose contents should be retrieved during the runtime process.

  • Before adding any data to a URL query string, make sure that the URL is encoded.

As an example, we will consider how HTML encoding behaves with the Razor engine used in MVC, which encodes the entire output from variables. For this not to happen we need to have a workaround to prevent this situation. An HTML attribute related to encoding represents a superset of the HTML encoding type, which means we don’t need to worry if we should use HTML encoding or HTML attribute encoding. We just need to be sure to use ‘@’ in the HTML context and not when we are trying to add untrusted data as input directly with JavaScript.

Let’s consider the following Razor [1] view from Listing 22-9. The output of the view will be an untrustedInput variable. This type of variable has in its component some characters that can be exploited and used with success in XSS attacks. These characters are <, “, and >. In the rendered output, the encode looks like:<&quot;testing123&quot;>
@{
       var untrustedInput = "<"testing123">";
   }
   @untrustedInput
Listing 22-9

Example of a Razor View

There are some cases when we want to add values to JavaScript to be processed within our view. To achieve this, we can proceed down two paths. The safest way to achieve this is by placing the value within the data attribute of a specific tag and to take it in our JavaScript, as shown in Listing 22-10.
@{
       var untrustedInput = "<"testing123">";
   }
   <div
       id="theDataToBeInjected"
       data-untrustedinput="@untrustedInput" />
   <script>
     var theDataToBeInjected =
            document.getElementById("theDataToBeInjected");
     //** for all the clients
     var clientWithUntrustedInput =
         theDataToBeInjected.getAttribute("data-untrustedinput");
     //** for clients that support HTML 5
     var clientWithUntrustedInputHtml5 =
         theDataToBeInjected.dataset.untrustedinput;
     document.write(clientWithUntrustedInput);
     document.write("<br />")
     document.write(clientWithUntrustedInputHtml5);
   </script>
Listing 22-10

Using Razor and JavaScript Encoding

The code from Listing 22-10 will produce the output shown in Listing 22-11.
<div
     id="theDataToBeInjected"
     data-untrustedinput="<&quot;testing123&quot;>" />
   <script>
     var theDataToBeInjected =
                   document.getElementById("theDataToBeInjected");
     var clientWithUntrustedInput =
         theDataToBeInjected.getAttribute("data-untrustedinput");;
     var clientWithUntrustedInputHtml5 =
         theDataToBeInjected.dataset.untrustedinput;
     document.write(clientSideUntrustedInputOldStyle);
     document.write("<br />")
     document.write(clientWithUntrustedInputHtml5);
   </script>
Listing 22-11

The Output

Once the script is run, the rendering result will be
<"testing123">
   <"testing123">
Also, we can call the JavaScript encoder as shown in Listing 22-12.
@using System.Text.Encodings.Web;
   @inject JavaScriptEncoder encoder;
   @{
       var someUntrustedInput = "<"testing123">";
   }
   <script>
       document.write("@encoder.Encode(someUntrustedInput)");
   </script>
Listing 22-12

JavaScript Encoder

Once this is rendered by the browser, we will have the following:
<script>
    document.write("u003Cu0022testing123u0022u003E");
</script>

This being said, in practice it is difficult to pay attention to the encoding process. The encoding takes place on the output and the encoded values should not be stored in the database or on servers, especially in cloud computing in a big data environment.

Conclusion

This chapter presented three common attacks that occur in a web application: port forwarding with redirection attacks, SQL injections, and cross-site scripting attacks.

By the end of this chapter, you can now
  • Identify three common attacks within web applications.

  • Deal with the vulnerabilities in a professional way by providing latest support from the features of the programming language.

  • Understand how a SQL injection behaves and how it can be encountered.

  • Understand the danger of exposing applications through port forwarding with redirection attacks by understanding the disaster that could occur.

  • Understand what cross-site scripts are and how they behave.

Bibliography

  1. [1]

    Introduction to ASP.NET Web Programming using the Razor Syntax (C#). Available online: https://docs.microsoft.com/en-us/aspnet/web-pages/overview/getting-started/introducing-razor-syntax-c.

     
  2. [2]

    Brandon Perry. Gray Hat C# - A Hacker’s Guide to Creating and Automating Security Tools. No Starch Press, 2017.

     
  3. [3]

    Adam Freeman. Pro ASP.NET Core 3 – Develop Cloud-Ready Web Applications using MVC Blazor, and Razor Pages. Apress, 2020.

     
  4. [4]

    Stephen Haunts. Applied Cryptography in .NET and Azure Key Vault. Apress, 2019.

     
  5. [5]

    Robert Ciesla. Encryption for Organizations and Individuals – Basics of Contemporary and Quantum Cryptography. Apress, 2020.

     
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.9.179