Gray Hat C No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc. Other product and company names mentioned herein may be the trademarks of their respective owners. Rather than use a trademark symbol with every occurrence of a trademarked name, we are using the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The information in this book is distributed on an “As Is” basis, without warranty. While every precaution has been taken in the preparation of this work, neither the author nor No Starch Press, Inc. shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in it
Trang 3GRAY HAT C#
Trang 6GRAY HAT C# Copyright © 2017 by Brandon Perry.
All rights reserved No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher.
Publisher: William Pollock
Production Editors: Alison Law and Serena Yang
Cover Illustration: Jonny Thomas
Interior Design: Octopod Studios
Developmental Editors: William Pollock and Jan Cash
Technical Reviewer: Brian Rogers
Copyeditor: Barton D Reed
Compositor: Susan Glinert Stevens
Proofreader: Paula L Fleming
Indexer: BIM Creatives, LLC.
For information on distribution, translations, or bulk sales, please contact No Starch Press, Inc directly:
No Starch Press, Inc.
245 8th Street, San Francisco, CA 94103
phone: 1.415.863.9900; sales@nostarch.com
www.nostarch.com
Library of Congress Cataloging-in-Publication Data
Names: Perry, Brandon, author.
Title: Gray hat C# : a hacker's guide to creating and automating security tools / Brandon Perry Description: San Francisco : No Starch Press, Inc., [2017]
Identifiers: LCCN 2017002556 (print) | LCCN 2017005221 (ebook) | ISBN
9781593277598 (pbk.) | ISBN 1593277598 (pbk.) | ISBN 9781593278311 (epub)
| ISBN 1593278314 (epub) | ISBN 9781593278328 ( mobi) | ISBN 1593278322
(mobi)
Subjects: LCSH: C# (Computer program language) | Automatic control Computer
programs | Computer security.
Classification: LCC QA76.73.C154 P44 2017 (print) | LCC QA76.73.C154 (ebook)
| DDC 005.8 dc23
LC record available at https://lccn.loc.gov/2017002556
No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc Other product and company names mentioned herein may be the trademarks of their respective owners Rather than use a trademark symbol with every occurrence of a trademarked name, we are using the names only
in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark.
The information in this book is distributed on an “As Is” basis, without warranty While every precaution has been taken in the preparation of this work, neither the author nor No Starch Press, Inc shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in it
Trang 7B R I E F C O N T E N T S
Foreword by Matt Graeber xiii
Preface xvii
Chapter 1: C# Crash Course 1
Chapter 2: Fuzzing and Exploiting XSS and SQL Injection 15
Chapter 3: Fuzzing SOAP Endpoints 53
Chapter 4: Writing Connect-Back, Binding, and Metasploit Payloads 81
Chapter 5: Automating Nessus 103
Chapter 6: Automating Nexpose 115
Chapter 7: Automating OpenVAS 133
Chapter 8: Automating Cuckoo Sandbox 147
Chapter 9: Automating sqlmap 167
Chapter 10: Automating ClamAV 191
Chapter 11: Automating Metasploit 207
Chapter 12: Automating Arachni 223
Chapter 13: Decompiling and Reversing Managed Assemblies 241
Chapter 14: Reading Offline Registry Hives 249
Index 265
Trang 9C O N T E N T S I N D E T A I L
Why Should I Trust Mono? xviii
Who Is This Book For? xviii
Organization of This Book xix
Acknowledgments xxi
A Final Note xxi
1 C# CRASH COURSE 1 Choosing an IDE 1
A Simple Example 2
Introducing Classes and Interfaces 4
Creating a Class 4
Creating an Interface 4
Subclassing from an Abstract Class and Implementing an Interface 5
Tying Everything Together with the Main() Method 7
Running the Main() Method 8
Anonymous Methods 9
Assigning a Delegate to a Method 9
Updating the Firefighter Class 9
Creating Optional Arguments 10
Updating the Main() Method 11
Running the Updated Main() Method 12
Integrating with Native Libraries 12
Conclusion 13
2 FUZZING AND EXPLOITING XSS AND SQL INJECTION 15 Setting Up the Virtual Machine 16
Adding a Host-Only Virtual Network 16
Creating the Virtual Machine 17
Booting the Virtual Machine from the BadStore ISO 17
SQL Injections 19
Cross-Site Scripting 20
Fuzzing GET Requests with a Mutational Fuzzer 22
Tainting the Parameters and Testing for Vulnerabilities 23
Building the HTTP Requests 23
Testing the Fuzzing Code 25
Fuzzing POST Requests 25
Writing a POST Request Fuzzer 27
The Fuzzing Begins 28
Fuzzing Parameters 29
Trang 10Fuzzing JSON 31
Setting Up the Vulnerable Appliance 31
Capturing a Vulnerable JSON Request 31
Creating the JSON Fuzzer 33
Testing the JSON Fuzzer 37
Exploiting SQL Injections 38
Performing a UNION-Based Exploit by Hand 38
Performing a UNION-Based Exploit Programmatically 40
Exploiting Boolean-Blind SQL Vulnerabilities 43
Conclusion 51
3 FUZZING SOAP ENDPOINTS 53 Setting Up the Vulnerable Endpoint 54
Parsing the WSDL 55
Creating a Class for the WSDL Document 55
Writing the Initial Parsing Methods 56
Writing a Class for the SOAP Type and Parameters 58
Creating the SoapMessage Class to Define Sent Data 60
Implementing a Class for Message Parts 61
Defining Port Operations with the SoapPortType Class 62
Implementing a Class for Port Operations 63
Defining Protocols Used in SOAP Bindings 64
Compiling a List of Operation Child Nodes 65
Finding the SOAP Services on Ports 66
Automatically Fuzzing the SOAP Endpoint for SQL Injection Vulnerabilities 68
Fuzzing Individual SOAP Services 69
Fuzzing the HTTP POST SOAP Port 72
Fuzzing the SOAP XML Port 75
Running the Fuzzer 78
Conclusion 79
4 WRITING CONNECT-BACK, BINDING, AND METASPLOIT PAYLOADS 81 Creating a Connect-Back Payload 82
The Network Stream 82
Running the Command 84
Running the Payload 85
Binding a Payload 85
Accepting Data, Running Commands, and Returning Output 86
Executing Commands from the Stream 87
Using UDP to Attack a Network 88
The Code for the Target’s Machine 89
The Attacker’s Code 92
Running x86 and x86-64 Metasploit Payloads from C# 94
Setting Up Metasploit 94
Generating Payloads 96
Trang 11Contents in Detail ix
Executing Native Windows Payloads as Unmanaged Code 96
Executing Native Linux Payloads 98
Conclusion 102
5 AUTOMATING NESSUS 103 REST and the Nessus API 104
The NessusSession Class 105
Making the HTTP Requests 106
Logging Out and Cleaning Up 107
Testing the NessusSession Class 108
The NessusManager Class 109
Performing a Nessus Scan 110
Conclusion 113
6 AUTOMATING NEXPOSE 115 Installing Nexpose 116
Activation and Testing 117
Some Nexpose Parlance 118
The NexposeSession Class 118
The ExecuteCommand() Method 120
Logging Out and Disposing of Our Session 123
Finding the API Version 123
Driving the Nexpose API 124
The NexposeManager Class 124
Automating a Vulnerability Scan 126
Creating a Site with Assets 126
Starting a Scan 127
Creating a PDF Site Report and Deleting the Site 128
Putting It All Together 128
Starting the Scan 129
Generating a Report and Deleting the Site 129
Running the Automation 130
Conclusion 131
7 AUTOMATING OPENVAS 133 Installing OpenVAS 134
Building the Classes 134
The OpenVASSession Class 134
Authenticating with the OpenVAS Server 135
Creating a Method to Execute OpenVAS Commands 136
Reading the Server Message 137
Setting Up the TCP Stream to Send and Receive Commands 138
Certificate Validation and Garbage Collection 138
Getting the OpenVAS Version 139
Trang 12The OpenVASManager Class 140
Getting Scan Configurations and Creating Targets 141
Wrapping Up the Automation 144
Running the Automation 145
Conclusion 146
8 AUTOMATING CUCKOO SANDBOX 147 Setting Up Cuckoo Sandbox 148
Manually Running the Cuckoo Sandbox API 148
Starting the API 148
Checking Cuckoo’s Status 149
Creating the CuckooSession Class 151
Writing the ExecuteCommand() Methods to Handle HTTP Requests 151
Creating Multipart HTTP Data with the GetMultipartFormData() Method 153
Processing File Data with the FileParameter Class 155
Testing the CuckooSession and Supporting Classes 156
Writing the CuckooManager Class 157
Writing the CreateTask() Method 157
The Task Details and Reporting Methods 159
Creating the Task Abstract Class 160
Sorting and Creating Different Class Types 161
Putting It Together 163
Testing the Application 164
Conclusion 165
9 AUTOMATING SQLMAP 167 Running sqlmap 168
The sqlmap REST API 169
Testing the sqlmap API with curl 170
Creating a Session for sqlmap 173
Creating a Method to Execute a GET Request 174
Executing a POST Request 175
Testing the Session Class 176
The SqlmapManager Class 177
Listing sqlmap Options 179
Making a Method to Perform Scans 180
The New Main() Method 182
Reporting on a Scan 182
Automating a Full sqlmap Scan 183
Integrating sqlmap with the SOAP Fuzzer 185
Adding sqlmap GET Request Support to the SOAP Fuzzer 185
Adding sqlmap POST Request Support 187
Calling the New Methods 188
Conclusion 190
Trang 13Contents in Detail xi
10 AUTOMATING CLAMAV 191 Installing ClamAV 192
The ClamAV Native Library vs the clamd Network Daemon 193
Automating with ClamAV’s Native Library 193
Setting Up the Supporting Enumerations and Classes 194
Accessing ClamAV’s Native Library Functions 196
Compiling the ClamAV Engine 197
Scanning Files 198
Cleaning Up 200
Testing the Program by Scanning the EICAR File 200
Automating with clamd 201
Installing the clamd Daemon 202
Starting the clamd Daemon 202
Creating a Session Class for clamd 203
Creating a clamd Manager Class 204
Testing with clamd 205
Conclusion 206
11 AUTOMATING METASPLOIT 207 Running the RPC Server 208
Installing Metasploitable 209
Getting the MSGPACK Library 209
Installing the NuGet Package Manager for MonoDevelop 210
Installing the MSGPACK Library 211
Referencing the MSGPACK Library 211
Writing the MetasploitSession Class 212
Creating the Execute() Method for HTTP Requests and Interacting with MSGPACK 213
Transforming Response Data from MSGPACK 215
Testing the session Class 217
Writing the MetasploitManager Class 217
Putting It All Together 219
Running the Exploit 220
Interacting with the Shell 221
Popping Shells 221
Conclusion 222
12 AUTOMATING ARACHNI 223 Installing Arachni 223
The Arachni REST API 224
Creating the ArachniHTTPSession Class 225
Creating the ArachniHTTPManager Class 226
Putting the Session and Manager Classes Together 227
Trang 14The Arachni RPC 228
Manually Running the RPC 229
The ArachniRPCSession Class 230
The Supporting Methods for ExecuteCommand() 232
The ExecuteCommand() Method 234
The ArachniRPCManager Class 236
Putting It All Together 237
Conclusion 239
13 DECOMPILING AND REVERSING MANAGED ASSEMBLIES 241 Decompiling Managed Assemblies 242
Testing the Decompiler 244
Using monodis to Analyze an Assembly 245
Conclusion 247
14 READING OFFLINE REGISTRY HIVES 249 The Registry Hive Structure 250
Getting the Registry Hives 250
Reading the Registry Hive 252
Creating a Class to Parse a Registry Hive File 252
Creating a Class for Node Keys 253
Making a Class to Store Value Keys 258
Testing the Library 259
Dumping the Boot Key 259
The GetBootKey() Method 259
The GetValueKey() Method 261
The GetNodeKey() Method 261
The StringToByteArray() Method 262
Getting the Boot Key 262
Verifying the Boot Key 263
Conclusion 264
INDEX 265
Trang 15F O R E W O R D
As an attacker or defender developing software, one obviously needs to decide which language makes the most sense to use Ideally, a language won’t be chosen simply because it is what the developer is most com- fortable with Rather, a language should be chosen based on answering a series of questions such as the following:
• What are my primary target execution environments?
• What is the state of detection and logging for payloads written in this language?
• To what level does my software need to maintain stealth (for example, memory residence)?
• How well is the language supported for both the client side and the server side?
• Is there a sizable community developing in this language?
• What is the learning curve and how maintainable is the language?
Trang 16C# has some compelling answers to these questions As to the question about the target execution environment, NET should be an obvious can-didate for consideration in a Microsoft-heavy environment because it has been packaged with Windows for years However, with the open-sourcing
of NET, C# is now a language that can drive a mature runtime on every operating system Naturally, it should be considered an extremely enticing language for true cross-platform support
C# has always been the lingua franca of NET languages As you will see in this book, you will get up and running with C# in no time thanks
to its low barrier to entry and massive developer community Additionally, with NET being a managed, type-rich language, compiled assemblies lend themselves to being trivially decompiled to C# Therefore, someone writing offensive C# need not necessarily develop their capabilities in a vacuum Rather, one can pull from a wealth of NET malware samples, decompile them, read the equivalent of their source code, and “borrow” their capa-bilities They could even go so far as to employ the NET reflection API to load and execute existing NET malware samples dynamically—assuming,
of course, they’ve been reversed sufficiently to ensure they do nothing subversive
As someone who has spent years bringing offensive PowerShell into the mainstream, my efforts have brought about massive security improve-ments and logging facilities in the wake of the surge of PowerShell mal-ware The latest version of PowerShell (v5 as of this writing) implements more logging than any other scripting language in existence From a defender’s perspective, this is fantastic From a pentester, red teamer, or adversary’s perspective, this increases the noise of one’s attack significantly For a book about C#, why do I mention this? Although it has taken me years to realize it, the more PowerShell I write, the more I acknowledge that attackers stand to gain far more agility by developing their tools in C# rather than doing so strictly in PowerShell Allow me to explain:
• NET offers a rich reflection API that allows one to load and cally interact with a compiled C# assembly in memory with ease With all the additional introspection performed on PowerShell payloads now, the reflection API enables an attacker to better fly under the radar by developing a PowerShell payload that only serves as a NET assembly loader and runner
dynami-• As Casey Smith (@subTee) has demonstrated, there are many legitimate, Microsoft-signed binaries present on a default installation of Windows
that serve as a fantastic host process for C# payloads—msbuild.exe being
among the stealthiest Using MSBuild as a host process for C# malware embodies the “living off the land” methodology perfectly—the idea that attackers who can blend into a target environment and introduce
a minimal footprint will thrive for a longer period of time
• Antimalware vendors to date still remain largely unaware of NET assembly capabilities at runtime There’s still enough unmanaged code malware out there that the focus hasn’t shifted to effectively hooking the NET runtime to perform dynamic runtime introspection
Trang 17Foreword xv
• With powerful access to the massive NET class library, those able with PowerShell will find the transition to C# a relatively smooth one Conversely, those comfortable with C# will have a lower barrier
comfort-to entry in transferring their skills comfort-to other NET languages such as PowerShell and F#
• Like PowerShell, C# is a high-level language, which means developers
do not have to worry about low-level coding and memory ment paradigms Sometimes, however, one needs to go “low level” (for example, interacting with the Win32 API) Fortunately, through its reflection API and P/Invoke and marshaling interface, C# allows one to get as low level as needed
manage-Everyone has a different motivation for learning C# My motivation was the need to transition my PowerShell skills in order to become more agile with NET code across more platforms You, the reader, may have been drawn to this book as a means to acquire an attacker’s mindset to supplement your existing C# skills Conversely, you may want to apply your existing attacker’s mindset to a language embraced by many across mul-tiple platforms Whatever your motivation may be, get ready for a wild ride through Brandon’s head as he imparts his unique experience and wisdom
in developing offensive and defensive C#
Matt Graeber
Microsoft MVP
Trang 19P R E F A C E
I get asked a lot why I like C# as much as I do Being a supporter of open source software, a dedicated Linux user, and a contributor to Metasploit (which is written predominantly in Ruby), C# seems like an odd choice
as my favorite language When I began writing in C# many years ago, Miguel de Icaza (of GNOME fame)
had recently started a small project called Mono Mono, in essence, is an open source implementation of Microsoft’s NET framework C# as a lan-guage had been submitted as an ECMA standard, and the NET framework was touted by Microsoft as a replacement for Java because code could be compiled on one system or platform and run on another The only issue with this was that Microsoft had only released the NET framework for the Windows operating system Miguel and a small group of core contributors took it upon themselves to make the Mono project the bridge the NET framework needed to reach the Linux community Luckily, a friend of mine who had recommended I learn C# but knew I was also very interested in Linux, pointed me in the direction of this fledgling project to see whether
I could use both C# and Linux After that, I was hooked
Trang 20C# is a beautiful language The creator and lead architect of the guage, Anders Hejlsberg, got his start working on compilers for Pascal and later Delphi This experience gave him a keen understanding of truly pow-erful features in an assortment of programming languages After Hejlsberg joined Microsoft, C# was born around the year 2000 In its early years, C# shared a lot of language features with Java, such as Java’s syntax niceties, but over time, it grew into its own language and introduced a slew of features before Java did, such as LINQ, delegates, and anonymous methods With C#, you have many of the powerful features of C and C++ and can write full-fledged web applications using the ASP.NET stack or rich desktop appli-cations On Windows, WinForms is the UI library of choice, but for Linux, the GTK and QT libraries are easy to use More recently, Mono has intro-duced support for the Cocoa toolkit on OS X platforms Even iPhones and Androids are supported.
lan-Why Should I Trust Mono?
Detractors of the Mono project and the C# language claim that the technologies are unsafe to use on any platform that isn’t Windows Their belief that Microsoft will, at the drop of a dime, begin litigating Mono into oblivion keeps many people from even taking the project seriously I don’t find this to be a credible risk As of this writing, not only has Microsoft acquired Xamarin—the company Miguel de Icaza created to support the Mono framework—it has made large swathes of the core NET framework open source It has embraced open source software in ways many people would have thought unimaginable under the leadership of Steve Ballmer The new chief executive officer, Satya Nadella, has demonstrated that Microsoft has no problems at all with open source software, and the com-pany actively engages the Mono community to enable mobile development using Microsoft technologies
Who Is This Book For?
Many people in security-oriented jobs, such as network and application security engineers, rely on automation to one extent or another—be it for scanning for vulnerabilities or analyzing malware With many security professionals preferring to use a wide variety of operating systems, writing tools that everyone can easily run can be difficult Mono is a great choice because it is cross-platform and has an excellent core set of libraries that makes automating many aspects of a security professional’s job easy If you’re interested in learning how to write offensive exploits, automate scan-ning for infrastructure vulnerabilities, decompile other NET applications, read offline registry hives, or create custom cross-platform payloads, then many of the topics covered in this book will get you started (even if you don’t have a background in C#)
Trang 21Preface xix
Organization of This Book
In this book, we’ll cover the basics of C# and rapidly implement real-life security tools with the rich libraries available to the language Right out
of the gate, we’ll write fuzzers to find possible vulnerabilities and write full-blown exploits for any vulnerabilities found It should become very apparent how powerful the language features and core libraries are Once the basics have been covered, we’ll automate popular security tools such
as Nessus, sqlmap, and Cuckoo Sandbox Overall, once you’ve finished this book, you’ll have an excellent repertoire of small libraries to automate many of the menial jobs security professionals often perform
Chapter 1: C# Crash Course In this chapter, you learn the basics of C# object-oriented programming with simple examples, but we cover a wide variety of C# features We start with a Hello World program and then build small classes to better understand what object-oriented pro-gramming is We then move on to more advanced C# features, such as anonymous methods and P/Invoke
Chapter 2: Fuzzing and Exploiting XSS and SQL Injection In this chapter, we write small HTTP request fuzzers that look for XSS and SQL injection in a variety of data types by using the HTTP library to communicate with web servers
Chapter 3: Fuzzing SOAP Endpoints In this chapter, we take the cept of the fuzzers in the previous chapter to the next level by writing another small fuzzer that retrieves and parses a SOAP WSDL to find potential SQL injections by automatically generating HTTP requests
con-We do this while also looking at the excellent XML libraries available in the standard library
Chapter 4: Writing Connect-Back, Binding, and Metasploit Payloads
In this chapter, we break from the focus on HTTP and move on to creat ing payloads We first create a couple of simple payloads—one over TCP and one over UDP Then you learn how to generate x86/x86_64 shellcode in Metasploit to create cross-platform and cross-architecture payloads
Chapter 5: Automating Nessus In this chapter, we return to HTTP
in order to automate the first of several vulnerability scanners, Nessus
We go over how to create, watch, and report on scans of CIDR ranges programmatically
Chapter 6: Automating Nexpose In this chapter, we maintain the focus on tool automation by moving on to the Nexpose vulnerability scanner Nexpose, whose API is also HTTP based, can be automated to scan for vulnerabilities and create reports Rapid7, Nexpose’s creator, offers a free yearlong license for its community product, which is very useful for home enthusiasts
Trang 22Chapter 7: Automating OpenVAS In this chapter, we conclude the focus on vulnerability scanner automation with OpenVAS, which is open source OpenVAS has a fundamentally different kind of API than both Nessus and Nexpose, using only TCP sockets and XML for its commu-nication protocol Because it’s also free, it is useful for hobbyists look-ing to gain more experience in vulnerability scanning on a budget.
Chapter 8: Automating Cuckoo Sandbox In this chapter, we move
on to digital forensics with the Cuckoo Sandbox Working with an to-use REST JSON API, we automate submitting potential malware samples and then reporting on the results
easy-Chapter 9: Automating sqlmap In this chapter, we begin exploiting SQL injections to their fullest extent by automating sqlmap We first create small tools to submit single URLs with the easy-to-use JSON API that is shipped with sqlmap Once you are familiar with sqlmap, we integrate it into the SOAP WSDL fuzzer from Chapter 3, so any poten-tial SQL injection vulnerabilities can automatically be exploited and validated
Chapter 10: Automating ClamAV In this chapter, we begin to focus
on interacting with native, unmanaged libraries ClamAV, a popular and open source antivirus project, isn’t written in a NET language, but
we can still interface with its core libraries as well as with its TCP mon, which allows for remote use We cover how to automate ClamAV
auto-Chapter 13: Decompiling and Reversing Managed Assemblies In this chapter, we move on to reverse engineering There are easy-to-use NET decompilers for Windows, but not for Mac or Linux, so we write a small one ourselves
Chapter 14: Reading Offline Registry Hives In this chapter, we move
on to incident response and focus on registry hives by going over the binary structure of the Windows registry You learn how to parse and read offline registry hives, so you can retrieve the boot key of the sys-tem, used to encrypt password hashes stored in the registry
Trang 23Preface xxi
Acknowledgments
This book was 10 years in the making, even if it was only in a word sor for three of those years My family and friends have surely noticed that I’ve been constantly talking about C#, but have been more than lenient and understanding listeners Props to the AHA brothers and sisters who inspired many of the projects in this book Many thanks to John Eldridge, a family friend who introduced me to C# and really jump-started my interest
proces-in programmproces-ing Brian Rogers has been one of the best technical resources for bouncing ideas off of during the development of this book, as well as
an excellent technical editor with his keen eye and insights My production managers Serena Yang and Alison Law made the back and forth of the edit-ing process about as painless as it could be Of course, Bill Pollock and Jan Cash were able to sculpt my muddy words into clear sentences that anyone could read A huge thanks to the whole No Starch staff!
find source code and updates to the book at https://www.nostarch.com/
grayhatcsharp/.
Trang 25C # C R A S H C O U R S E
Unlike other languages, such as Ruby, Python, and Perl, C# programs can be run
by default on all modern Windows machines
In addition, running programs written in C#
on a Linux system such as Ubuntu, Fedora, or another
flavor couldn’t be easier, especially since Mono can quickly be installed by most Linux package managers like apt or yum This puts C# in a better posi-tion to meet cross-platform needs than most languages, with the benefit of
an easy and powerful standard library at your fingertips All in all, C# and the Mono/.NET libraries make a compelling framework for anyone wanting to write cross-platform tools quickly and easily
Choosing an IDE
Most who want to learn C# will use an integrated development ment (IDE) like Visual Studio for writing and compiling their code Visual Studio by Microsoft is the de facto standard for C# development around the
Trang 26environ-globe Free versions such as Visual Studio Community Edition are available
for personal use and can be downloaded from Microsoft’s website at https://
www.visualstudio.com/downloads/.
During the development of this book, I used MonoDevelop and Xamarin Studio depending on whether I was on Ubuntu or OS X, respec-tively On Ubuntu, you can easily install MonoDevelop using the apt pack-age manager MonoDevelop is maintained by Xamarin, the company that also maintains Mono To install it, use the following command:
$ sudo apt-get install monodevelop
Xamarin Studio is the OS X brand of the MonoDevelop IDE Xamarin Studio and MonoDevelop have the same functionality, but with slightly differ-ent user interfaces You can download the installer for the Xamarin Studio
IDE from the Xamarin website at https://www.xamarin.com/download-it/.
Any of these three IDEs will fulfill our needs in this book In fact, if you just want to use vim, you don’t even need an IDE! We’ll also soon cover how
to compile a simple example using the command line C# compiler shipped with Mono instead of an IDE
A Simple Example
To anyone who’s used C or Java, the C# syntax will seem very familiar C# is
a strongly typed language, like C and Java, which means that a variable you declare in your code can be only one type (an integer, string, or Dog class, for example) and will always be that type, no matter what Let’s start by taking a quick look at the Hello World example in Listing 1-1, which shows some basic C# types and syntax
using uSystem;
namespace vch1_hello_world
{ class wMainClass
{ public static void xMain(string[] yargs)
{
z string hello = "Hello World!";
{ DateTime now = DateTime.Now;
| Console.Write(hello);
} Console.WriteLine(" The date is " + now.ToLongDateString());
} } }
Listing 1-1: A basic Hello World application
Right off the bat, we need to import the namespaces we’ll use, and we
do this with a using statement that imports the System namespace u This
Trang 27C# Crash Course 3
enables access to libraries in a program, similar to #include in C, import in Java and Python, and require in Ruby and Perl After declaring the library
we want to use, we declare the namespace v our classes will live in
Unlike C (and older versions of Perl), C# is an object-oriented guage, similar to Ruby, Python, and Java This means that we can build complex classes to represent data structures, along with the methods for those data structures, while writing code Namespaces allow us to organize our classes and code as well as to prevent potential name collisions, such
lan-as when two programmers create two cllan-asses with the same name If two classes with the same name are in different namespaces, there won’t be a problem Every class is required to have a namespace
With the namespace out of the way, we can declare a class w that will hold our Main() method x As we stated previously, classes allow us to create complex data types as well as data structures that better fit real-world objects
In this example, the name of the class doesn’t actually matter; it’s just a container for our Main() method, which is what really matters because the
Main() method is what will execute when we run our sample application.
Every C# application requires a Main() method, just like in C and Java If your C# application accepts arguments on the command line, you can use the args variable y to access the arguments passed to the application.Simple data structures, such as strings z, exist in C#, and more com-plex ones, such as a class representing the date and time {, can also be created The DateTime class is a core C# class for dealing with dates In our example, we use it to store the current date and time (DateTime.Now) in the variable now Finally, with our variables declared, we can print a friendly message using the Console class’s Write() | and WriteLine() } methods (the latter of which includes a newline character at the end)
If you’re using an IDE, you can compile and run the code by clicking the Run button, which is in the top-left corner of the IDE and looks like a Play button, or by pressing the F5 key However, if you would like to com-pile the source code from the command line with the Mono compiler, you can easily do that as well From the directory with your C# class code, use the mcs tool shipped with Mono to compile your classes into an executable, like so:
$ mcs Main.cs -out:ch1_hello_world.exe
Running the code from Listing 1-1 should print both the string "Hello
World!" and the current date on the same line, as in Listing 1-2 On some
Unix systems, you may need to run mono ch1_hello_world.exe
$ /ch1_hello_world.exe
Hello World! The date is Wednesday, June 28, 2017
Listing 1-2: Running the Hello World application
Congratulations on your first C# application!
Trang 28Introducing Classes and Interfaces
Classes and interfaces are used to create complex data structures that would
be difficult to represent with just built-in structures Classes and interfaces
can have properties, which are variables that get or set values for a class or interface, and methods, which are like functions that execute on the class
(or subclasses) or interface and are unique to it Properties and methods are used to represent data about an object For instance, a Firefighter class might need an int property to represent the firefighter’s pension or a method that tells the firefighter to drive to a place where there’s a fire.Classes can be used as blueprints to create other classes in a technique
called subclassing When a class subclasses another class, it inherits the erties and methods from that class (known as the parent class) Interfaces
prop-are used as a blueprint for new classes as well, but unlike classes, they don’t have inheritance Thus a base class that implements an interface won’t pass down the interface’s properties and methods if it’s subclassed
Creating a Class
We’ll create the simple class shown in Listing 1-3 as an example that resents a public servant data structure for someone who works every day to make our lives easier and better
rep-public uabstract class PublicServant
{ public int vPensionAmount { get; set; }
public abstract void wDriveToPlaceOfInterest();
}
Listing 1-3: The PublicServant abstract class
The PublicServant class is a special kind of class It is an abstract class u Generally, you can just create a class like you do any other type of variable,
and it is called an instance or an object Abstract classes, though, cannot be
instantiated like other classes; they can only be inherited through ing There are many types of public servants—firefighters and police offi-cers are two that come to mind immediately It would therefore make sense
subclass-to have a base class that these two types of public servants inherit from In this case, if these two classes were subclasses of PublicServant, they would inherit a PensionAmount property v and a DriveToPlaceOfInterest delegate w that must be implemented by subclasses of PublicServant There is no gen-eral “public servant” job that someone can apply for, so there isn’t a reason
to create just a PublicServant instance
Creating an Interface
A complement to classes in C# are interfaces Interfaces allow a
program-mer to force a class to implement certain properties or methods that aren’t inherited Let’s create a simple interface to start with, as shown in Listing 1-4 This interface is called IPerson and will declare a couple of properties that people usually have
Trang 29C# Crash Course 5
public interface uIPerson
{
string vName { get; set; }
int wAge { get; set; }
}
Listing 1-4: The IPerson interface
N O T E Interfaces in C# are usually prefaced with an I to distinguish them from classes that
may implement them This I isn’t required, but it is a very common pattern used in mainstream C# development.
If a class were to implement the IPerson interface u, that class would need to implement both a Name v and an Age w property on its own Otherwise,
it wouldn’t compile I’ll show exactly what this means when we implement the Firefighter class next, which implements the IPerson interface For now, just know that interfaces are an important and useful feature of C# Programmers familiar with interfaces in Java will feel right at home with them C programmers can think of them as header files with function dec-
larations that expect a c file to implement the function Those familiar with
Perl, Ruby, or Python may find interfaces strange at first because there isn’t
a comparable feature in those languages
Subclassing from an Abstract Class and Implementing an Interface
Let’s put our PublicServant class and IPerson interface to some use and ify a bit of what we have talked about We can create a class to represent our firefighters that inherits from the PublicServant class and implements the
solid-IPerson interface, as shown in Listing 1-5.
public class uFirefighter : vPublicServant, wIPerson
//implement the IPerson interface
public string yName { get; set; }
public int zAge { get; set; }
public override void {DriveToPlaceOfInterest()
private void GetInFiretruck() {}
private void TurnOnSiren() {}
Trang 30private void FollowDirections() {}
}
Listing 1-5: The Firefighter class
The Firefighter class u is a bit more complex than anything we’ve implemented yet First, note that the Firefighter class inherits from the
PublicServant class v and implements the IPerson interface w This is done
by listing the class and interface, separated by commas, after the Firefighter
class name and a colon We then create a new constructor x that is used to set the properties of a class when a new class instance is created The new constructor will accept the name and age of the firefighter as arguments, which will set the Name y and Age z properties required by the IPerson inter-
face with the values passed We then override the DriveToPlaceOfInterest() method { inherited from the PublicServant class with one of our own,
calling a few empty methods that we declare We’re required to ment the DriveToPlaceOfInterest() method because it’s marked as abstract
imple-in the PublicServant class and abstract methods have to be overridden by subclasses
N O T E Classes come with a default constructor that has no parameters to create instances
Creating a new constructor actually overrides the default constructor.
The PublicServant class and IPerson interface can be very flexible and can be used to create classes with completely different uses We will imple-ment one more class, a PoliceOfficer class, as shown in Listing 1-6, using
PublicServant and IPerson.
public class uPoliceOfficer : PublicServant, IPerson
{ private bool _hasEmergency;
public PoliceOfficer(string name, int age) {
public bool wHasEmergency
{ get { return _hasEmergency; } set { _hasEmergency = value; } }
public override void xDriveToPlaceOfInterest()
{ GetInPoliceCar();
Trang 31private void GetInPoliceCar() {}
private void TurnOnSiren() {}
private void FollowDirections() {}
}
Listing 1-6: The PoliceOfficer class
The PoliceOfficer class u is similar to the Firefighter class, but there are
a few differences Most notably, a new property called HasEmergency w is set in the constructor v We also override the DriveToPlaceOfInterest() method x as
in the previous Firefighter class, but this time, we use the HasEmergency erty y to determine whether the officer should drive the car with the siren
prop-on We can use the same combination of parent class and interface to create classes that function completely differently
Tying Everything Together with the Main() Method
We can use our new classes to test a few more features of C# Let’s write a new Main() method to show off these new classes, as shown in Listing 1-7
Trang 32{ Console.WriteLine("Name: " + person.Name);
Listing 1-7: Tying together the PoliceOfficer and Firefighter classes with a Main() method
To use the PoliceOfficer and Firefighter classes, we must instantiate them using the constructors we defined in the respective classes We do this first with the Firefighter class u, passing a name of Joe Carrington and an age
of 35 to the class constructor and assigning the new class to the firefighter variable We also set the firefighter PensionAmount property v to 5000 After the
firefighter has been set up, we pass the object to the PrintNameAndAge() and
PrintPension() methods.
Note that the PrintNameAndAge() method takes the IPerson interface z as
an argument, not a Firefighter, PoliceOfficer, or PublicServant class When
a class implements an interface, you can create methods that accept that interface (in our case, IPerson) as an argument If you pass IPerson to a method, the method only has access to the properties or methods that the interface requires instead of to the whole class In our example, only the
Name and Age properties are available, which is all we need for the method
Similarly, the PrintPensionAmount() method accepts PublicServant { as its argument, so it only has access to the PublicServant properties and methods
We can use the C# is keyword to check whether an object is a certain type
of class, so we do this to check whether our public servant is a Firefighter |
or a PoliceOfficer }, and we print a message depending on which it is
We do the same for the PoliceOfficer class as we did for Firefighter, creating a new class with a name of Jane Hope and an age of 32; then we set her pension to 5500 and her HasEmergency property w to true After printing
the name, age, and pension x, we call the officer’s DriveToPlaceOfInterest()
method y
Running the Main() Method
Running the application should demonstrate how classes and methods interact with each other, as shown in Listing 1-8
$ /ch1_the_basics.exe
Name: Joe Carrington Age: 35
Pension of firefighter: 5000
Trang 33C# Crash Course 9
Name: Jane Hope
Age: 32
Pension of officer: 5500
Listing 1-8: Running the basics program’s Main() method
As you can see, the public servants’ names, ages, and pensions are printed to the screen, exactly as expected!
Anonymous Methods
The methods we have used so far have been class methods, but we can also
use anonymous methods This powerful feature of C# allows us to
dynami-cally pass and assign methods using delegates With a delegate, a delegate object is created that holds a reference to the method that will be called
We c reate this delegate in a parent class and then assign the delegate’s reference to anonymous methods in subclasses of the parent class This way, we can dynamically assign a block of code in a subclass to the delegate instead of overriding the parent class’s method To demonstrate how to use delegates and anonymous methods, we can build on the classes we have already created
Assigning a Delegate to a Method
Let’s update the PublicServant class to use a delegate for the method
DriveToPlaceOfInterest(), as shown in Listing 1-9.
public abstract class PublicServant
{
public int PensionAmount { get; set; }
public delegate void uDriveToPlaceOfInterestDelegate();
public DriveToPlaceOfInterestDelegate vDriveToPlaceOfInterest { get; set; }
}
Listing 1-9: The PublicServant class with a delegate
In the previous PublicServant class, we needed to override the
DriveToPlaceOfInterest() method if we wanted to change it In the new PublicServant class, DriveToPlaceOfInterest() is replaced with a delegate u and a property v that allow us to call and assign DriveToPlaceOfInterest()
Now, any classes inheriting from the PublicServant class will have a delegate they can use to set their own anonymous method for DriveToPlaceOfInterest() instead of having to override the method within each class Because they inherit from PublicServant, we’ll need to update our Firefighter and
PoliceOfficer class constructors accordingly.
Updating the Firefighter Class
We’ll update the Firefighter class first with the new delegate property The constructor, shown in Listing 1-10, is the only change we make
Trang 34public uFirefighter(string name, int age)
{ this vName = name;
this wAge = age;
this.DriveToPlaceOfInterest x+= delegate
{ Console.WriteLine("Driving the firetruck");
In the new Firefighter class constructor u, we assign the Name v and
Age w like we did before Next, we create the anonymous method and assign
it to the DriveToPlaceOfInterest delegate property using the += operator x so that calling DriveToPlaceOfInterest() will call the anonymous method This anonymous method prints "Driving the firetruck" and then runs the empty methods from the original class This way, we can add the customized code
we want to each method within a class without having to override it
Creating Optional Arguments
The PoliceOfficer class requires a similar change; we update the constructor
as shown in Listing 1-11 Because we’re already updating this class, we can
also change it to use an optional argument, which is a parameter in a
con-structor that does not have to be included when a new instance is created We’ll create two anonymous methods and use an optional argument to determine which method to assign to the delegate
public uPoliceOfficer(string name, int age, bool vhasEmergency = false)
{ this wName = name;
this xAge = age;
this yHasEmergency = hasEmergency;
if (this zHasEmergency)
{ this.DriveToPlaceOfInterest += delegate {
Console.WriteLine("Driving the police car with siren");
Trang 35Listing 1-11: The new PoliceOfficer constructor
In the new PoliceOfficer constructor u, we set the Name w and Age x properties as we did originally This time, however, we also use an optional third argument v to assign the HasEmergency property y The third argu-ment is optional because it does not need to be specified; it has a default value (false) when the constructor is provided with only the first two argu-ments We then set the DriveToPlaceOfInterest delegate property with a new anonymous method, depending on whether HasEmergency is true z
Updating the Main() Method
With the new constructors, we can run an updated Main() method that is almost identical to the first It’s detailed in Listing 1-12
public static void Main(string[] args)
Trang 36Running the Updated Main() Method
Running the new method shows how creating two PoliceOfficer classes—one with an emergency and one without—will print two different things, as demonstrated in Listing 1-13
$ /ch1_the_basics_advanced.exe
Name: Joe Carrington Age: 35
Pension of firefighter: 5000 Driving the firetruck Name: Jane Hope Age: 32
Pension of officer: 5500
u Driving the police car
Name: John Valor Age: 32
v Driving the police car with siren
Listing 1-13: Running the new Main() method with classes using delegates
As you can see, creating a PoliceOfficer class with an emergency causes the officer to drive with the siren on v Jane Hope, on the other hand, can drive without her siren on u because she has no emergency
Integrating with Native Libraries
Finally, sometimes you need to use libraries that are available only in dard operating system libraries, such as libc on Linux and user32.dll on Windows If you plan to use code in a library that was written in C, C++, or another language that gets compiled down to native assembly, C# makes
stan-working with these native libraries very easy, and we will use this technique
in Chapter 4 when making cross-platform Metasploit payloads This feature
is called Platform Invoke, or P/Invoke for short Programmers often need
to use native libraries because they are faster than a virtual machine such
as used by NET or Java Programmers such as financial or scientific sionals who use code to do heavy math might write the code that they need
profes-to be fast in C (for example, code for interfacing directly with hardware) but use C# to handle code that requires less speed
Listing 1-14 shows a simple application that uses P/Invoke to call the standard C function printf() in Linux or to pop up a message box using user32.dll on Windows
Trang 37Listing 1-14: Demonstrating P/Invoke with a simple example
This example looks more complex than it is We first declare two tions that will be looked up externally in different libraries We do this using the DllImport attribute u Attributes allow you to add extra information to methods (or classes, class properties, and so on) that is used at runtime
func-by the NET or Mono virtual machine In our case, the DllImport attribute tells the runtime to look up the method we are declaring in another DLL, instead of expecting us to write it
We also declare the exact function names and the parameters the tions expect For Windows, we can use the MessageBox() function, which expects a few parameters such as the title of the pop-up and the text to be displayed For Linux, the printf() function expects a string to print Both of these functions are looked up at runtime, which means we can compile this
func-on any system because the functifunc-on in the external library isn’t looked for until the program is running and the function is called This lets us com-pile the application on any operating system, regardless of whether that sys-tem has either or both libraries
With our native functions declared, we can write a quick Main() method v that checks the current operating system with an if statement
using os.Platform w The Platform property we use maps to the PlatformID
enumeration x, which stores the available operating systems that the gram could be running on Using the PlatformID enumeration, we can test whether we are on Windows and then call the respective method: either
pro-MessageBox() y on Windows or printf() z on Unix This application, when compiled, can be run on either a Windows machine or a Linux machine,
no matter what operating system compiled it
Conclusion
The C# language has many modern features that make it a great language for complex data and applications We have only scratched the surface of some of the more powerful features like anonymous methods and P/Invoke You’ll become intimate with the concepts of classes and interfaces, as well as
Trang 38many other advanced features, in the chapters to come In addition, you’ll learn about many more of the core classes available to you, such as HTTP and TCP clients and much more.
As we develop our own custom security tools throughout this book, you will also learn about general programming patterns, which are useful conventions for creating classes that make building on them easy and fast Good examples of programming patterns are used in Chapters 5 and 11 where we interface with APIs and RPCs of third-party tools such as Nessus and Metasploit
By the end of this book, we will have covered how C# can be used for every security practitioner’s job—from the security analyst to the engineer, and even the hobbyist researcher at home C# is a beautiful and power-ful language, and with cross-platform support from Mono bringing C# to phones and embedded devices, it is just as capable and usable as Java and other alternatives
Trang 39A fuzzer is software that attempts to find errors in other
software, such as that on servers, by sending bad or
malformed data The two general types of fuzzers are mutational and
gen-erational A mutational fuzzer attempts to taint the data in a known-good
input with bad data, without regard for the protocol or the structure of the
data In contrast, a generational fuzzer takes into account the nuances of the
server’s communication protocol and uses these nuances to generate nically valid data that is sent to the server With both types of fuzzers, the goal is to get the server to return an error to the fuzzer
tech-We’ll write a mutational fuzzer that you can use when you have a good input in the form of a URL or HTTP request (We’ll write a genera-tional fuzzer in Chapter 3.) Once you’re able to use a fuzzer to find XSS and SQL injection vulnerabilities, you’ll learn how to exploit the SQL injection vulnerabilities to retrieve usernames and password hashes from the database
Trang 40known-In order to find and exploit XSS and SQL injection vulnerabilities, we’ll use the core HTTP libraries to build HTTP requests programmatically in C# We’ll first write a simple fuzzer that parses a URL and begins fuzzing the HTTP parameters using GET and POST requests Next, we’ll develop full exploits for the SQL injection vulnerabilities that use carefully crafted HTTP requests to extract user information from the database.
We’ll test our tools in this chapter against a small Linux distribution
called BadStore (available at the VulnHub website, https://www.vulnhub
.com/) BadStore is designed with vulnerabilities like SQL injections and
XSS attacks (among many others) After downloading the BadStore ISO from VulnHub, we’ll use the free VirtualBox virtualization software to create a virtual machine in which to boot the BadStore ISO so that we can attack without risk of compromising our own host system
Setting Up the Virtual Machine
To install VirtualBox on Linux, Windows, or OS X, download the VirtualBox
software from https://www.virtualbox.org/ (Installation should be simple;
just follow the latest directions on the site when you download the software.) Virtual machines (VMs) allow us to emulate a computer system using a physi-cal computer We can use virtual machines to easily create and manage vul-nerable software systems (such as the ones we will use throughout the book)
Adding a Host-Only Virtual Network
You may need to create a host-only virtual network for the VM before ally setting it up A host-only network allows communication only between VMs and the host system Here are the steps to follow:
actu-1 Click File 4Preferences to open the VirtualBox – Preferences dialog
On OS X, select the VirtualBox 4Preferences.
2 Click the Network section on the left You should see two tabs: NAT Networks and Host-only Networks On OS X, click the Network tab at
the top of the Settings dialog
3 Click the Host-only Networks tab and then the Add host-only network
(Ins) button on the right This button is an icon of a network card laid with a plus sign This should create a network named vboxnet0
over-4 Click the Edit host-only network (Space) button on the right This
but-ton is an icon of a screwdriver
5 From the dialog that opens, click the DHCP Server tab Check the
Enable Server box In the Server Address field, enter the IP address
192.168.56.2 In the Server Mask field, enter 255.255.255.0 In the Lower
Address Bound field, enter 192.168.56.100 In the Upper Address Bound field, enter 192.168.56.199
6 Click OK to save changes to the host-only network.
7 Click OK again to close the Settings dialog.