Виключно прості завдання з AppSec .NET

Пропоную всім розім'яти мозок після вихідних і почати робочий тиждень з простих, на перший погляд, завдань по програмуванню на C#. Можливо ці завдання змусять вас подивитися на код своїх проектів з нової сторони, так як всі вони стосуються похмурої області – області безпеки додатків, Application Security. Про AppSec і платформу .NET пишуть не багато, кажуть, ще менше, деякі взагалі вважають, що використання будь-якого managed мови, магічним чином робить додаток захищеним. Це положення справ я намагаюся виправити, розповідаючи на конференціях про різні аспекти безпеки .NET платформи. Так на цьому тижні, в четвер, наше співтовариство SPB .NET Community проводить митап в Санкт-Петербурзі повністю присвячений питанням розробки захищених ASP .NET додатків. Кому цікаві подробиці цієї зустрічі, хто хоче дізнатися більше про співтоваристві .NET розробників Санкт-Петербурга і спробувати свої сили у вирішенні завдань AppSec .NET, запрошую під кат!

Так як на Хабре ще не писали про SPB .NET Community почну, мабуть, з нього. У червні, в Санкт-Петербурзі зібралося співтовариство програмістів, які пишуть .NET. Наша мета – це ділитися досвідом вирішення завдань, з якими ми зустрічаємося в ході роботи, збиратися в офлайні, щоб обговорити актуальні проблеми та новини світу .NET. Зараз платформа переживає бум розвитку, тут і вихід величезної кількості коду в open source, і нова web платформа, і обговорення відразу двох нових стандартів мови C#, і кросплатформеність, яка пропонує великі можливості і загрожує новим полем граблів. Як сказав Льюїс, щоб залишатися на місці, ми повинні бігти. І якщо бігти всім разом, то шанси не відстати підвищуються (бігуни зрозуміють метафору). Отже, що вже зроблено. Ми провели першу зустріч, організували острівець на IT Global Meetup, де зробили 4 доповіді, змогли познайомитися і поспілкуватися про плани на майбутнє. Судячи з відгуків, доповіді сподобалися, а ідея відродити регулярні зустрічі .NET тусовки вже у багатьох була в головах.

Зараз ми готуємо другу зустріч. Вона пройде 25 червня, о 19.30 в пітерському офісі компанії DataArt, основною темою зустрічі вибрали розробку захищених додатків. В цей четвер до нас в Санкт-Петербург приїжджає відомий експерт з інформаційної безпеки в цілому, і по платформі .NET зокрема, Володимир Кочетков VladimirKochetkov. Він погодився взяти участь у нашій зустрічі, так що хто знайомий з Володею по блогах, вебінару або його роботи в RSDN Team, у вас є шанс прийти і поспілкуватися з ним особисто. У програмі зустрічі дві доповіді і багато спілкування, це «Теорія Application Security .NET» Володимир Кочетков і «Практика Application Security .NET» Михайло Щербаков (моя доповідь). Я з матеріалом з цієї теми виступав на останніх конференціях, це .NEXT, dotnetconf.uk, SECON. Але для митапа підготував нові приклади і задачки, які ми також розберемо на зустрічі. А, та завдання… Не буду більше розповідати про митап, читайте анонс в групі спільноти spbdotnet.org, реєструйтеся посилання і приходьте. Участь звичайно безкоштовне, необхідна лише реєстрація (кількість місць на жаль, обмежена, але є вільні).

А тепер увага завдання.

  1. Містить проблеми безпеки код наступній aspx сторінки? Якщо містять, то які і в яких рядках коду? Питання із зірочкою: які дані потрібно відправити на сервер, щоб продемонструвати атаки? Умови виконання коду стандартні: на сервері IIS 8.5 з налаштуваннями за замовчуванням, aspx сторінка входить в web-проект з налаштуваннями за замовчуванням, збирається під Framework 4.5.1.

    <%@ Page Language="C#" AutoEventWireup="true"%>
    <script language="C#" runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
    var text = TextBox1.Text + TextBox2.Text;
    if (text != String.Empty)
    {
    Label1.Text = "Input: " + text;
    }
    else
    {
    TextBox1.Text = Request["first"] + Request["second"];
    }
    
    int count;
    if (Int32.TryParse(Request["count"], out count))
    {
    for (int i = 0; i < count; i++)
    {
    var name = String.Format("base64_item{0}", i);
    var value = Request[name];
    if (value != null)
    {
    RadioButtonList1.Items.Add(new ListItem(Encoding.UTF8.GetString(Convert.FromBase64String(value)), value));
    }
    }
    }
    }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    </head>
    <body>
    <!--
    <asp:Label runat="server">
    <%= Request["first"] + Request["second"] %>
    </asp:Label>
    -->
    Preview:
    <img src="<%= ResolveUrl("~/Content/Images/" + Request["page"] + ".png")%>"/>
    
    <form id="form1" runat="server">
    <asp:Label ID="Label1" runat="server"></asp:Label><br/>
    <asp:RadioButtonList ID="RadioButtonList1" runat="server"/><br/>
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox><br/>
    <asp:Button ID="Button1" runat="server" Text="Save"/>
    </form>
    </body>
    </html>
    

  2. Містить проблеми безпеки наступний C# код? Якими способами атакуючий може проексплуатувати уразливості, якщо вони є? Як би ви виправили цей код? Доступ до БД здійснюється через класи Entity Framework'а, CoinsDB – клас контексту нашої БД, спадкоємець DbContext. CustomerLogin — клас нашої сутності з БД, його код є нижче. Умови виконання коду стандартні, як і в прикладі вище, БД – MS SQL.

    protected void Page_Load(object sender, EventArgs e)
    {
    using (var db = new CoinsDB())
    {
    var where = String.Empty;
    var parameters = new List<object>();
    
    var email = Request["email"];
    if (email != null)
    {
    where += String.Format(" email LIKE '{0}%'", email);
    }
    
    var field = Request["field"];
    var min = Request["min"];
    var max = Request["max"];
    if (field != null && min != null && max != null)
    {
    if (!String.IsNullOrEmpty(where))
    {
    where += " AND";
    }
    
    where += String.Format(" {0} >= @min AND {0} <= @max", EncodeSqlField(field));
    parameters.Add(new SqlParameter("@min", min));
    parameters.Add(new SqlParameter("@max", max));
    }
    
    var query = "SELECT * FROM CustomerLogin";
    if (!String.IsNullOrEmpty(where))
    {
    query += " WHERE";
    query += where;
    }
    
    var output = db.Database.SqlQuery<CustomerLogin>(query, parameters.ToArray()).ToArray();
    
    lblOutput.Text = output.Length == 0
    ? "Not found"
    : String.Join("<br/>", output.Select(customer => customer.login + " - " + customer.rating));
    }
    }
    
    private string EncodeSqlField(string field)
    {
    return field.Replace("'", String.Empty)
    .Replace(" ", String.Empty)
    .Replace("\\", String.Empty)
    .Replace(",", String.Empty)
    .Replace("(", String.Empty)
    .Replace(")", String.Empty);
    }
    
    [Table("CustomerLogin")]
    public partial class CustomerLogin
    {
    [Key]
    [StringLength(100)]
    public string login { get; set; }
    
    [StringLength(100)]
    public string email { get; set; }
    
    public long raiting { get; set; }
    public long customerNumber { get; set; }
    
    [Required]
    [StringLength(40)]
    public string password { get; set; }
    
    public short? question_id { get; set; }
    
    [StringLength(50)]
    public string answer { get; set; }
    }
    

Відповіді, будь ласка, пишіть у коментарях під спойлером. Всі цікаві випадки ми розберемо 25 червня на митапе.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.