Sie sind auf Seite 1von 231

NEXT GENERATION AUTHENTICATION

INFRASTRUCTURES WITH ROLE-BASED SECURITY


FOR CLOUD COMPUTING

GRZEGORZ K. SPYRA
MSC ADVANCED SECURITY AND DIGITAL FORENSICS
SCHOOL OF COMPUTING
AUGUST 2012
SUBMITTED IN PARTIAL FULFILMENT OF THE REQUIREMENTS
OF EDINBURGH NAPIER UNIVERSITY FOR THE DEGREE OF MASTER OF SCIENCE
IN ADVANCED SECURITY AND DIGITAL FORENSICS

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

AUTHORSHIP DECLARATION
I, Grzegorz K. Spyra, confirm that this dissertation and the work presented in it are my
own achievements.
1. Where I have consulted the published work of others this is always clearly attributed;
2. Where I have quoted from the work of others the source is always given. With the
exception of such quotations this dissertation is entirely my own work;
3. I have acknowledged all main sources of help;
4. If my research follows on from previous work or is part of a larger collaborative
research project I have made clear exactly what was done by others and what I have
contributed myself;
5. I have read and understand the penalties associated with plagiarism;
6. I confirm that I have obtained informed consent from all people I have involved in the
work in this dissertation following the School's ethical guidelines;
Signed:
Grzegorz K. Spyra Zrich, 20 August 2012
Matriculation no: 06012419

ii

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

DATA PROTECTION DECLARATION


Under the 1998 Data Protection Act we cannot disclose your grade to an unauthorized
person. However, other students benefit from studying dissertations that have their grades
attached.
Please sign your name against one of the options below to state your preference:

The University may make this dissertation, with indicative grade, available to others

The University may make this dissertation available to others, but the grade may not be disclosed

The University may not make this dissertation available to others

iii

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

ABSTRACT
Currently one of the most popular IT trends is to migrate into the cloud computing, and a
security engineer who integrates enterprise infrastructure with the cloud needs to provide the
best possible security level to protect the digital identity against unauthorized use. The task of
cloud-based authentication can be very simple as there are several products on the market that
are ready to take responsibility for all processes around authentication. However enterprise
identity management it is not only an authentication to one simple web page, where in more or
less secure manner system authenticates who you are? and not only what you know? The
enterprise identity management models comprise of multiple components including enterprise
directory, provisioning component, workflow components and the privilege management
components. To effectively control enterprise identity authentication the implementation
requires efficient access control model like Role-based Security Access Control (RBAC) and
very scalable framework, which align with business and not only with IT systems.
This thesis aims is to evaluate the implementation of Role-based security for Oath
authentication model exposed as Identity as a Service (IDaaS) using Infrastructure as a Service
cloud-based server instance. It focuses on different aspects of digital identity, authentication,
RBAC and cloud computing, that are delivered in large enterprise. This thesis presents an
OAuth 1.0 authentication enabled system, and is compared with the commonly used in
enterprise Microsoft Integrated Windows Authentication model.
The Proof of Concept implementation is a framework that consists of SQL database, .Net
services and ASP.Net components. To deliver the model that will quickly adapt to new findings
made during writing this thesis and the model that will self-evaluate all the interconnected
components and technologies used, the dedicated authentication and authorization front-end is
implemented on top of the framework. The tests performed return either grant or deny access at
different stages of authorization flow. Scenarios created for model evaluation show how
different technologies with various configurations can adapt into the cloud across several
security boundaries with federated identity and RBAC.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

TABLE OF CONTENTS
ABSTRACT

ACKNOWLEDGMENTS

1. INTRODUCTION

1.1. CONTEXT
1.2. AIMS AND OBJECTIVES
THESIS LAYOUT
1.2.1. LITERATURE REVIEW
1.2.2. HIGH LEVEL DESIGN
1.2.3. CLOUD-BASED IMPLEMENTATION AND LOW LEVEL DESIGN
1.2.4. EVALUATION
1.2.5. CONCLUSIONS

8
9
10
10
10
10
11
11

2. RESEARCH & LITERATURE REVIEW

12

2.1. INTRODUCTION
2.2. DIGITAL IDENTITY AND IDENTITY MANAGEMENT
2.2.1. IDENTITY PROVISIONING
2.2.2. IDENTITY AS A SERVICE (IDAAS)
2.2.3. FEDERATED IDENTITY
2.2.4. CLAIMS-BASED IDENTITY
2.3. AAA IN CLOUD
2.3.1. INTEGRATED WINDOWS AUTHENTICATION
2.3.2. OAUTH
2.3.3. CLAIMS-BASED AUTHENTICATION
2.3.4. WHY DIRECTORY?
2.4. ROLE-BASED SECURITY
2.4.1. CONCEPT
2.4.2. RBAC VIA ABAC
2.5. XAAS
2.6. SECURITY CONCERNS
2.6.1. DATA PROTECTION ACT
2.6.2. PATRIOT ACT
2.6.3. SAFE HARBOR
2.6.4. PERSONAL DATA IN THE CLOUD
2.6.5. INTEGRATED WINDOWS AUTHENTICATION
2.6.6. OAUTH
2.6.7. OAUTH 1.0 VS 2.0
2.6.8. SOAP PROTOCOL VULNERABILITIES
2.6.9. RBAC MODEL STRENGTHS & VULNERABILITIES
2.7. CONCLUSIONS

12
13
14
17
19
20
22
22
24
28
30
32
32
33
34
35
35
36
37
37
37
38
38
38
39
39

3. HIGH LEVEL DESIGN

41

3.1. INTRODUCTION
3.1.1. BACKGROUND
3.1.2. DESIGN GOALS
3.3. ARCHITECTURE
3.3.1. INTRODUCTION

41
41
43
44
44

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3.4. DATA
3.4.1. INTRODUCTION
3.4.2. SCHEMA
3.5. CODE
3.5.1. INTRODUCTION
3.5.2. MODULES
3.5.4. INTERFACES
3.5.5. IDENTITY TYPES
3.6. DAILY OPERATIONS
3.7. INSTALLATION
3.7.1. IAAS
3.7.2. IIDMANAGEMENT
3.7.4. IPORTAL AND ENTERPRISE PORTAL
3.7.5. IADCONNECTOR
3.7.6. DEDICATED DATABASE
3.8. INTEROPERABILITY WITH OTHER SYSTEMS
3.9. SECURITY
3.10. OPEN ISSUES AND RECOMMENDATIONS
3.10.1. IADCONNECTOR
3.10.2. RBAC & ABAC TRANSACTIONS SECURITY
3.11. CONCLUSIONS

45
45
46
50
50
50
53
53
54
54
54
54
55
55
56
56
56
57
57
58
58

4. CLOUD-BASED IMPLEMENTATION

60

4.1. INTRODUCTION
4.2. SYSTEM CONFIGURATION
4.2.1. AMAZON EC2 CLOUD INSTANCE (IAAS)
4.2.3. MICROSOFT ACTIVE DIRECTORY DOMAIN SERVICES
4.2.4. OAUTH 1.0
4.2.6. INTEGRATED WINDOWS AUTHENTICATION
4.3. CLIENT SIDE
4.3.1. CLOUD INSTANCE ACCESS
4.4. ACTIVE DIRECTORY PROVISIONING
4.4.1. AD FOREST
4.4.2. DOMAIN STRUCTURE AND UNDERLYING OBJECTS
4.5. META-DIRECTORY
4.5.1. IIDMANAGEMENT
4.5.2. IADCONNECTOR
4.6. CONCLUSIONS

60
60
60
61
61
65
66
66
67
67
67
68
68
69
72

5. EVALUATION

73

5.1. INTRODUCTION
5.2. METHODOLOGY
5.3. NEXT GENERATION VS TRADITIONAL AUTHENTICATION APPROACHES
5.3.1. WINDOWS INTEGRATED AUTHENTICATION
5.3.2. OAUTH
5.3.3. BRIEF SUMMARY
5.4. RBAC & ABAC
5.4.1. ROLE-BASED ACCESS CONTROL SCALABILITY
5.4.2. BRIEF SUMMARY
5.5. CONCLUSIONS

73
73
74
74
77
80
80
80
84
84

7. CONCLUSIONS

86

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

7.1. OVERALL CONCLUSIONS


7.2. FUTURE WORK
7.3. ISSUES
7.1. SELF APPRAISAL

86
87
87
88

APPENDIXES
APPENDIX A
APPENDIX B
APPENDIX C
APPENDIX D
APPENDIX E
APPENDIX F
APPENDIX G
APPENDIX H
APPENDIX I
APPENDIX J
APPENDIX K

A
SUPERVISION

DIARY
PROFESSIONAL RESEARCH
GANTT CHART
EC2 AMAZON CLOUD SERVER INSTANCE SPECIFICATION
IIDMANAGEMENT DATABASE SCHEMA DESCRIPTION
IADCONNECTOR DATABASE SCHEMA DESCRIPTION
IPORTAL DATABASE SCHEMA DESCRIPTION
STORED PROCEDURES
PROVISIONING.CMD
IADCONNECTOR

A
B
E
R
U
V
W
X
Y
EE
GG

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

LIST OF FIGURES
FIGURE 1 IDENTITY PROVISIONING TRADITIONAL MANUAL APPROACH
15
FIGURE 2 IDENTITY PROVISIONING AUTOMATED APPROACH
15
FIGURE 3 CLOUD-BASED IDENTITY PROVIDER SERVICE
18
FIGURE 4 CONFIDENTIALITY, INTEGRITY AND AVAILABILITY IN IDAAS
18
FIGURE 5 INFRASTRUCTURE WITHOUT FEDERATED IDENTITY (BLACKBRIDGE).
19
FIGURE 6 FEDERATED IDENTITY INFRASTRUCTURE WITH CENTRAL FIM HUB (BLACKBRIDGE)
20
FIGURE 7 CLAIMS BASED IDENTITY ENTITIES (BERTOCCI, 2011)
21
FIGURE 8 CLAIMS-BASED IDENTITY AUTHENTICATION FLOW
22
FIGURE 9 INITIAL TOKEN ISSUE PROCESS IN IWA
22
FIGURE 10 AUTHENTICATION USING CACHED ACCESS TOKEN
24
FIGURE 11 AUTHENTICATION USING CACHED CREDENTIALS WITH TWO DOMAINS IN TWO-WAY TRUST
24
FIGURE 12 RESOURCE OWNER GRANTS RESOURCE ACCESS TO THE CLIENT (HAMMER, RECORDON, & HARDT, 2012)
26
FIGURE 13 CLIENT REQUESTS ACCESS TOKEN FROM AUTHORIZATION SERVER (HAMMER, RECORDON, & HARDT, 2012) 27
FIGURE 14 CLIENT CLAIMS RESOURCE ACCESS FROM RESOURCE SERVER WITH VALID ACCESS TOKEN (HAMMER, RECORDON, &
HARDT, 2012)
27
FIGURE 15 CLAIMS-BASED AUTHENTICATION (BERTOCCI, 2011)
29
FIGURE 16 CLAIMS-BASED AUTHENTICATION WITH SSO (BERTOCCI, 2011)
30
FIGURE 17 OBJECT LOCATION WITHIN DIRECTORY INFORMATION TREE (DIT) (ANDERSEN, 2008)
31
FIGURE 18 ABAC RULES SET FILTERING ASSETS ACCESS BASED ON ACCOUNTS ATTRIBUTES
34
FIGURE 19 CLOUD ABSTRACTION LAYERS; THE BEST-KNOWN SERVICE MODELS (BUCHANAN, 2010)
35
FIGURE 20 MIND THE GAP PHRASE FROM LONDON UNDERGROUND WITH LOGO USED BY DEUBY AT AL (DEUBY, 2011) 37
FIGURE 21 IDAAS IMPLEMENTATION WITH IIDMANAGEMENT AND IADCONNECTOR (FIM, IAM AND LDAP CONNECTOR) 41
FIGURE 22 IIDMANAGEMENT - ABAC ENGINE THAT ENFORCES RBAC RULES
42
FIGURE 23 OAUTH FLOW BETWEEN IPORTAL AND ENTERPRISE PORTAL
43
FIGURE 24 IIDMANAGEMENT TABLES REQUIRED TO FEDERATE IDENTITY
47
FIGURE 25 IIDMANAGEMENT ABAC ENGINE TABLES
48
FIGURE 26 IADCONNECTOR INVENTORY SCHEMA
49
FIGURE 27 IADCONNECTOR SYNC META-DATA AND CONFIGURATION TABLES
50
FIGURE 28 BLOCK DIAGRAM OF IADCONNECTOR SERVICE MODULES ACTIVITY FLOW
52
FIGURE 29 DEVDEFINED.OAUTH LIBRARIES (VISUAL STUDIO 2010 SOLUTION EXPLORER)
61
FIGURE 30 DEVDEFINED.OAUTH-EXAMPLES (VISUAL STUDIO 2010 SOLUTION EXPLORER)
62
FIGURE 31 IPORTAL AND ENTERPRISEPORTAL POOLS
64
FIGURE 32 ACTIVE DIRECTORY USERS AND COMPUTERS CONSOLE PROVISIONED DOMAIN STRUCTURE
68
FIGURE 33 ENTERPRISE PORTAL WELCOME PAGE
74
FIGURE 34 IWA LOCAL TEST ACCESS GRANTED
75
FIGURE 35 IWA CLOUD TEST ACCESS DENIED
75
FIGURE 36 IWA LOCAL TEST WITH KERBEROS SECURITY TOKEN; USER IS A MEMBER OF SECURITY GROUP ACCESS GRANTED
76
FIGURE 37 IWA LOCAL TEST RESOURCE OWNER SPYRA REMOVED FROM THE SECURITY GROUP
77
FIGURE 38 IWA LOCAL TEST KERBEROS TICKET ENTITLEMENTS BASED ON SECURITY GROUPS MEMBERSHIPS ACCESS
GRANTED
77
FIGURE 39 OAUTH CLOUD-BASED AND LOCAL TESTS; STEP1 - SUCCESSFULLY REDIRECTED TO IP FOR AUTHENTICATION
78
FIGURE 40 OAUTH CLOUD-BASED AND LOCAL TESTS; STEP2 ACCESS CONTROL PAGE RO SUCCESSFULLY AUTHENTICATED 79
FIGURE 41 OAUTH CLOUD-BASED AND LOCAL TESTS; STEP3 ACCESS GRANTED
79
FIGURE 42 OAUTH CLOUD-BASED AND LOCAL TESTS; TOKEN EXPIRED ACCESS DENIED
80
FIGURE 43 ABAC ENFORCES RBAC RULES AND BILL ACCOUNT CANNOT CONTROL THE RESOURCE
83
FIGURE 44 ABAC ENFORCES RBAC RULES; OAUTH ACCESS GRANTED
84
FIGURE 45 IAAS CLOUD SERVER INSTANCE SPECIFICATION
U

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

LIST OF TABLES
TABLE 1 ESTIMATE NUMBER OF INSTANCES OF EACH PART
TABLE 2 IIDMANAGEMENT DATABASE TABLES
TABLE 3 IADCONNECTOR DATABASE TABLES
TABLE 4 XML CONFIGURATIONS
TABLE 5 ADVANCED SERVICE CONFIGURATION
TABLE 6 AUTHENTICATION TESTS SUMMARY
TABLE 7 CURRENT FEDERATED IDENTITY INFORMATION
TABLE 8 CURRENT ABAC RULE SET
TABLE 9 UPDATED ABAC RULE; ADDED LEGAL & RISK DEPARTMENT
TABLE 10 ABAC ENGINE ENFORCED RBAC RULE BASED ON NEW DEPARTMENT IN THE RULE SCOPE
TABLE 11 FEDERATED IDENTITY FRAMEWORK TEST RESULTS
TABLE 12 IIDMANAGEMENT DATABASE DESIGN DETAILS
TABLE 13 IADCONNECTOR DATABASE DESIGN DETAILS
TABLE 14 IPORTAL IADCONNECTOR DATABASE DESIGN DETAILS

44
69
70
71
71
80
82
83
83
83
84
W
X
X

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

ACKNOWLEDGMENTS
I want to start by thanking my wife and daughter for their patience while I work on this
thesis. Thank you Olivia for being patient and compassionate. I know these are very first
moments for us, you as my 6 months old daughter and me your father. Hope one day we will be
able to discuss the latest information security trends.
I would like to thank my supervisor Prof. William Buchanan for all the ideas he shared with
me. Without him this thesis would not have the current shape and I would miss many important
contexts so crucial for deliverables.
Professionally, I want to thank my manager John M. for all the support I got from him. All
the meetings with third parties you invited me to related to FIM and Claims-based
authentication helped me to see federated identity in reach enterprise context.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

1. INTRODUCTION
1.1. CONTEXT
The Internet evolved from era where it was mostly used as a medium that gives access to
unrestricted data to an era of cloud computing, where the Internet is more adapted for enterprise
use. Cloud implementations of authentication infrastructures are currently widely discussed due
to their nature (Deuby, 2011). Business processes that previously were integrated internally into
enterprise are now exposed in cloud computing via the Internet. The Confidentiality,
Availability and Integrity (CIA) triad, which is a base of any security measure, can be
evaluated against number of new threats related to authentication for cloud computing. Rolebased security (also called Role-based access control RBAC) implementations for
authentication and authorization delivered with cloud computing need to offer some
equivalence, and give even more enhanced functionality than internally integrated enterprise
implementations. RBAC, one of the non-discretionary access control types, is the most
innovative identity and access management (IAM) model since Discretionary Access Control
(DAC) and Mandatory Access Control (MAC) access control types were released (Sandhu,
Coyne, Feinstein, & Youman, 1996).
OAuth next to RBAC is another important, next generation technology that allows secure
access to user data across different sites without need for username and password exchange.
This authentication model empowers enterprises to securely access external resources like
Facebook, Tweeter, Google, Flickr etc. and also other enterprises (Hammer E. , 2010). OAuth
protocol was created to securely delegate rights to different clients across different platforms
independently from location, organization and business role. Its current implementation solves
many identity related issues that main market players who deal with customer identity were
facing for the last few years (Hammer E. , 2010). OAuth is also becoming more popular in
large enterprise implementations, and unlike Role-based security, OAuth is enterprise
independent.
RBAC implementations are often complex, as they require underlying meta-directory that
supports identity recognition and security entitlements control (Pohlman, 2003). These
implementations can be simple to adjust into Small Office Home Office (SOHO) also in
Small and Medium-Sized Enterprises (SMEs), however they are becoming complex and are

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

often not efficient when it comes to Large Enterprises (LEs) implementations, where security,
RBAC authentication and operations performance constraints play role.
All three elements: authentication, Role-based security and cloud computing, are separate
terms in Next Generation Authentication Infrastructures with Role-based Security for Cloud
Computing subject however implemented together into the cloud instance will act as Identity
as a Service (IDaaS) cloud-based service. Each of these terms comprise distinct technology
therefore scalability, efficiency and security level of a model where all three were integrated
together need to be evaluated and the model adjusted to ensure the highest possible efficiency
and security level in enterprise.

1.2. AIMS AND OBJECTIVES


This thesis aims to present a prototype of a next generation Cloud-based identity architecture,
and evaluate it against traditional methods. The main objectives are thus:

Perform a literature review around the key areas of IDaaS for large enterprise and data
protection.

Create a high-level design for the testing and evaluation system that will be used. This will be
supported with critical analysis of different implementation models that are available on the
market and delivered as ready out-of-the-box products.

Implement and evaluate the practical aspects of possible RBAC system and compare, and
evaluate directory with database model as a complete meta-directory system. This will
evaluate two authentication models: OAuth and Integrated Window authentication separately,
with and without RBAC. Along with the identity management framework it aims to create
heterogeneous implementation for federated identity where different authentication models are
used. This will show how next generation authentication infrastructures like OAuth meet IT
market requirements, and also how RBAC aligns with business and how both OAuth and RBAC
can efficiently integrate into complex system environment like we have in large enterprise.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

THESIS LAYOUT
1.2.1. LITERATURE REVIEW
This chapter is dedicated to critical evaluation of existing Identity Management models
showing possible implementations of authentication infrastructures that can be delivered in
cloud computing. It shows aspects of identity provisioning with Role-based security as a way
of secure, effective and business oriented access control. It also compares Identity Management
and RBAC operations carried out in Microsoft Active Directory and Microsoft SQL database.
In conclusion is outlines the operations are more suitable for directory application, and which
perform best with database applications. Additionally this chapter shows how the next
authentication infrastructures can align with both enterprise and external services like Windows
Live ID, Google, Yahoo, Facebook, and so on, especially when we consider not only technical
aspects of implementation, but also Information Security with its CIA triad.
1.2.2. HIGH LEVEL DESIGN
The High Level Design chapter specifies the design goals, and outlines the model design
details from high-level perspective. It provides a solid background for the implementation, and
includes the directory structure and provisioned identities details, such as organization structure
and identity object counts. It also outlines self-developed cloud-based implementation of
Identity as a Service with RBAC and ABAC systems based on Microsoft Active Directory
(AD). To test the authentication infrastructure for both implementations used OAuth 1.0
protocol and a basic client application.
This chapter thus presents the complete system architecture with all components. It describes
the system interfaces, communication between components, data operations, and code modules
with internal functions, also cloud instance hardware and software details.
1.2.3. CLOUD-BASED IMPLEMENTATION AND LOW LEVEL DESIGN
The Cloud-based Implementation chapter consists of system implementation details such as:
directory provisioning steps; database structure scripts; MS Server Roles installation and
configuration details; MS SQL DB stored procedures and functions scripts; supporting custom
Windows Services; and scripts that are used for meta-directory and Identity Management. All
settings specific for the Proof of Concept (PoC) implementation are in this chapter, and all the
design aspects that are not covered in HLD section are thoroughly described in LLD thesis
chapter.

10

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Complete .Net source code, MS SQL stored procedures and functions, supporting scripts can
be found in Appendixes. In LLD section only selected code parts are used that are required to
justify the design decisions.
1.2.4. EVALUATION
The Evaluation chapter covers testing methods used to validate data and data operations from
created system prototype. This chapter is crucial as this is where two different RBAC
implementations are evaluated. The prototype system provisioned is SME size rather than LE
size, although operations used to control security entitlements of digital identities can show
issues that need to be addressed when delivering product mature for the destination market.
1.2.5. CONCLUSIONS
The Conclusions chapter summarizes all previous sections and shows whether and how
the aims and objectives were met. All possible enhancements to the prototype and
implementation suggestions are covered here, as they are not required for the PoC of this
thesis.

11

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

2. RESEARCH & LITERATURE REVIEW


2.1. INTRODUCTION
This chapter reviews different aspects of Digital Identity and control of its activities in
modern cloud-based infrastructures. At first this thesis presents Digital Identity and all concepts
behind Identity Management, including provisioning with a basic exposure to RBAC and
ABAC models. From this point-of-view, the thesis shows two modern views on identity:
Identity as a Service (IDaaS) cloud-based model; and Federated Identity, which shares
some concepts with IDaaS, however defines different approach to digital identity.
The second section is dedicated to OAuth protocol, which compares new concepts of
authentication and authorization with more classic enterprise approach, and which is specific to
Microsoft systems called Integrated Windows Authentication. In this section there is a focused
on concept of storing identity meta-data in directory and on several aspects related to data
auditing.
The third section reviews Role-based security model and all aspects related to RBAC
technology, including its popularity because of various economic factors. It is also a new
approach that overcomes the most common access control issues related to information
security. Next to RBAC, the thesis presents another new access control approach called ABAC
and show the differences between RBAC and ABAC security, and also present model where
both access control models were used.
The fourth XaaS section reviews different concepts related to cloud computing and service
types that can be delivered with cloud. Here the thesis briefly reviews different possible system
architectures that aim to be implemented into the cloud. The last section is dedicated to
information security. It evaluates the technologies reviewed in this thesis with several terms
related to data protection. Next it evaluates the next generation technologies with common
systems security vulnerabilities and shows how these technologies defend against traditional
types of cyber-attacks.

12

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

2.2. DIGITAL IDENTITY AND IDENTITY MANAGEMENT


Many times in our life we deal with different types of identity. In most of the cases different
organizations or institutions provide systems for identification, where in the context of these
systems we are identified. Often it depends on level of privileges that your identity has in a
specific system context and the sensitivity of the data that this identity gives access to, that the
system should correctly identify who you are rather than what you know. An important part that
should be to considered the risk related to granularity of the identification system, and
privileges that are granted to system identities.
To give an example, we can look at the bus ticketing system in Edinburgh. If someone
obtained in an illegal way someone elses 1Ridacard, lets say it is valid for all Edinburgh buses
for four weeks, as per ticket price table from the 4th of March 2012, Lothian Buses will lose
40 if they give the legal owner the new Ridacard replacement. If we take the same
identification model, where we use Smartcard, however the privileges related to the identity
that this card grants are on the security operations manager level from any respectable bank,
lets say hypothetically Royal Bank of Scotland.
In this scenario the single identity misuse could lead to a billion pounds loss for the RBS and
what is the most important part is the loss of the trust that is crucial in a financial sector. When
we take another simple example, also with a Ridacard and a Smartcard, as per Lothian Buses
Terms & Conditions: student Ridacard will not be valid for travel beyond the expiry date of
the matriculation card (Lothian Buses, 2012). This means if someone left university before the
date on the matriculation card, and the matriculation card had not been returned for a month,
the student who uses this card could travel as a valid passenger with a student discount. The
monthly Lothian Buses loss would be then 11. If again we take the RBS Smartcard system
and an internship student who is granted sensitive systems access where the condition is that
the student can work only under RBS senior employee supervision we then have a similar
scenario. After the internship in one department, the student then starts the second internship in
a different department, however the rights granted initially to the student remain unchanged.
Student still can access sensitive systems, however in this department the student is not
required to have any supervision, as the new role does not require any. The risk related to

Lothian Buses company from Edinburgh released Smartcard type bus ticket that stores information
about your bus travel entitlements. It uses a card owner photo at the top of the card to validate if the
cardholder legally uses the card.
1

13

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

operations that the student could perform on bank systems due to owned privileges is very high
and the bank loss could be estimated then in billion pounds.
The problem highlighted here is a very common in Identity and Access Management
systems. In IAM we do not have students, but privileged identities that hold permissions over
resources and as per our example with the student these permissions remain even if security
entitlements were taken away. We also have scenarios where access control system does not
enforce separation of duties on controlled identities (see Section 2.6.9). Having the separation
of duties enforced in our example with a student, we can be sure that student would not be able
to cause any harm as would not be able to initiate and complete any transaction by himself.
With right identity authorization and authentication technique and proper identity provisioning
procedures in place, implemented beside with identity Role-based security operations, any of
the scenarios with student breaching the system rules would not have place.
2.2.1. IDENTITY PROVISIONING
2.2.1.1. Enterprise Processes

Identity provisioning is an important process in every enterprise. It is not only specific to the
enterprise, as also in popular social media portals, accounts are provisioned with some default
settings. In enterprises, identities can be provisioned differently depending on the employee
location, department, role in this department or customer contract terms and conditions, while
in social media portals during provisioning identities may be differentiated by customer
country, interests, or language. Provisioning automates many processes that before were
manual processes of creating accounts and granting access to these accounts over resources
across the enterprise (see Figure 1, Figure 2).
Figure 1 outlines the traditional provisioning, where the process with several different actors
that are involved in identity provisioning. We can start with HR Officer who registered newlyhired employee in HR System. The HR Officer sends email to Help Desk Analyst and requests
specific accounts to be created for the new employee and specifies what is the organizational
role of the new employee. Based on HR instructions, the new system accounts (identities) are
created, however there are several access rights related to this organizational role that
Help Desk Analyst could not grant. This is where System Administrator role is required in
provisioning process. Help Desk Analyst sends email to System Administrator to permission
the newly created accounts over several resources and systems.

14

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 1 Identity Provisioning traditional manual approach

Figure 2 Identity Provisioning automated approach

15

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The automated provisioning process is fairly simple and actually the HR Officer is the only
actor that has to perform some manual actions in this system. The New Employee record is
picked up by provisioning engine and automatically based on the organizational role that was
assigned to the employee record the relevant set of new accounts is created in all required
systems and are automatically permissioned over systems assigned to the default departmental
role.
Both models are close to Role-based security, although these examples show how it works in
many organizations. Currently provisioning systems try to reduce the amount of systems where
the account is provisioned, and rather than this, provision one corporate identity into the
directory or the database and via either Identity Provider, or using direct identity meta-data
access perform operations of Authentication and Authorization.
Provisioning helps business to quickly adapt to new requirements like Internet and cloud
computing. It also helps the enterprise to reduce the time it takes to implement a new physical
IT infrastructure changes and align to various changes of interconnected systems. It is not only
a process that takes responsibility for simple operation of new account creation as its
functionality spreads beyond account creation process. We can define provisioning as a
functional extension of Authorization. Both consist a natural combination as provisioning
process enforces user account and rules creation while authorization enforces these rules
(Pohlman, 2003).
Provisioning systems are critical infrastructure components because this is where all the
processes like account creation, enablement, disablement and deletion lie (Pohlman, 2003).
With proper identity provisioning system that has relevant underlying access control model
(like RBAC) the student from our example (see Section 2.2) would not breach the bank access
control rules because provisioning would take care of student department change and reflect it
in correct access rights amendment. By automating the timely provisioning and de-provisioning
of user accounts and security entitlements, organizations can meet privacy and compliance
requirements and also reduce the risk of unauthorized access (Mather, Kumaraswamy, & Latif,
2009).
2.2.1.2. Enterprise Directory

Identities provisioning requires a strong back-bone not only to suit the basic indexing rules to
access identity, store properties of the identity or to perform identity operations in transactional

16

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

manner but also, what is the most important, to locate the newly provisioned identity in the
right place of the organizational structure, grant generic permissions based on the identity
purpose and define the identitys role within the structure. This is where directory
implementations are becoming the most powerful and efficient (Arkills, 2003).
Directory is hierarchical and structured as a tree. This is a place where all identity
information about employees, suppliers, customers and assets. Identity provisioning into LDAP
makes the provisioning process straightforward in terms of self-defining identity security role
within the enterprise that is represented with structured directory.
2.2.2. IDENTITY AS A SERVICE (IDAAS)
IDaaS is one of the services that are delivered with cloud computing. This architecture
exposes organizational IAM systems and processes with the cloud. In other words all processes
that were internally implemented into the enterprise can now be outsourced into third party
IDaaS providers (Mather, Kumaraswamy, & Latif, 2009). By implementing ready IDaaS
models the enterprise can save time and money required to delivered own federated identity
management infrastructure. The federated identity enablement it is not only related to
implementation of the system that supports FIM but also complex and secure network
infrastructure that consists of dedicated perimeter networks designed to provide FIM services.
From technical perspective IDaaS is nothing else than Software as a Service (SaaS) cloudbased service dedicated for Identity Management that acts as Identity Provider (IdP). IDaaS
acts as a proxy for the organization handling cloud services access requested by identities (see
Figure 3). IDaaS stores identities in a trusted identity store that can be synchronized with
organizational directory (Mather, Kumaraswamy, & Latif, 2009).
When the enterprise implements Cloud-based Identity Service Provider all Cloud-based
Service Providers (CSP) should delegate authentication to the newly established IdP. This
model delivers Single sign-on (SSO) functionality as every authentication is done once prior to
any further cloud services access.
For the enterprise the migration into IDaaS model might be relatively simple, although in
large sized enterprise there are always requirements to support extensive auditing and reporting
functionality (Mather, Kumaraswamy, & Latif, 2009). When it comes to IdP evaluation with
Confidentiality, Integrity and Availability (CIA) triad (see Figure 4) there is much more to
mitigate than simple Identity Management systems migration into the IDaaS.
17

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 3 Cloud-based Identity Provider Service

Figure 4 Confidentiality, Integrity and Availability in IDaaS

Such infrastructure change where organizations decide to migrate Identity Management


and Authentication internal processes into the cloud-based IDaaS should be preceded with
thorough risk analysis and new Business Continuity Plan proposal.
IDaaS is a popular solution that is more and more adapted for large enterprise environments.
There are several out-of-the-box products like Microsoft Windows Azure Active Directory
18

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

(WAAD), which integrate with enterprise MS Active Directory infrastructures and provide
cloud-based authentication services. IdP can be also placed into the cloud under IaaS cloud
server instance and actually act as the IDaaS enabled system. This custom approach is a part of
this dissertation and will be explained in High Level Design and Cloud-based Implementation
sections.
2.2.3. FEDERATED IDENTITY
Federated Identity is a term that responds to demand for digital identity to step beyond the
enterprise boundary. Federated identity is a key IAM component that links digital identities
across domain boundaries (Mather, Kumaraswamy, & Latif, 2009). Separate secure domain
boundaries (see Figure 5) can store digital identity information separately in directories or other
identity repositories, also can implement various meta-directories to store the identity metadata, however as long as there is no concept of federated identity these security boundaries will
not go beyond the organization that implemented the identity management system (Windley,
2005).

Figure 5 infrastructure without federated identity (BlackBridge).

Concept of federated identity rose in opposition to centralized identity concept. Problems


that both concepts meant to address are related to de-centralized digital identity directories or
other repositories that are within the same or across different organizations. Each identity
repository stores information that is relevant to specific identity within its domain, however

19

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

different repositories may store information about one the same identity that is not consistent,
while other identity information might be just redundant. Centrally managed repository did not
solve the problem as could not handle cross-organizational authentication and authorization
(Windley, 2005). The federated identity solves the identity problem, as it does not restrict the
view on the identity infrastructure to one central homogeneous repository (Windley, 2005).
Federation provides processes and supporting technologies to enable cooperation among
different digital identity stores so the identity is linked regardless of its repository location.
These identity linkages are controlled with FIM systems (Windley, 2005) and they can be
enforced by pre-defined system rules or also can be amended manually in exceptional cases.
Because the identity is linked federated identity can flexible authenticate users from partner
organizations (see Figure 6) and authorize them to access protected resources (Windley, 2005).
For this thesis used the FIM concept in developed IDaaS model where implemented
federated identity model with linked digital identities from MS Active Directory through SQL
based meta-directory.

Figure 6 Federated identity infrastructure with central FIM hub (BlackBridge)

2.2.4. CLAIMS-BASED IDENTITY


Claims-based identity is a natural way of dealing with identity and access control.
(Bertocci, 2011)

20

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

This statement simplifies, however summarizes the idea behind the claims-based identity.
When look at the conceptual model (see Figure 7) can see four entities: Subject,
Identity Provider, Relying party and a claim. The natural way corresponds to live examples
where e.g. student (Subject) receives student ID (Claim) from the university (Identity Provider)
so student can now get into the club (Relying Party) with the new ID as a claim that stores
information about the student age (the claim property). The club does not have to verify if the
student actually meets the age criteria because the club as a Relying Party it is relying on
somebody else that done the verification in the first place (Identity Provider) and issued the
student ID.

Figure 7 Claims based Identity entities (Bertocci, 2011)

Claims-based identity and claims-based authentication is the core of the federated


identity (see Section 2.2.3). It was invented to solve problem of authentication where various
systems at different layers of implementation from different domain boundaries can
successfully authenticate the digital identity. The claims-based identity concept delivers an
abstraction layer that is independent from the implementation platform (see Figure 8). For the
developer who decides to enable the product for claims-based identity the implementation
model that comes with this concept will provide sufficient security level required for secure
authentication without having problems specific for implementation itself (Bertocci, 2011).
The main advantage of claims-based authentication over traditional authentication is that
Service Provider (SP) regardless whether it is inside or outside the organization can get relevant

21

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

identity information required to authenticate the identity (Deuby, 2011). The complete
authentication flow is described in the Claims-based Authentication section.

Figure 8 Claims-based Identity authentication flow

2.3. AAA IN CLOUD


2.3.1. INTEGRATED WINDOWS AUTHENTICATION
The Integrated Windows authentication is a term and a concept used to describe
authentication model that consists of several different authentication protocols used in
Microsoft Windows systems. The concept behind IWA is that user credentials are hashed on
the client side before are sent through the network.

Figure 9 initial token issue process in IWA

The hashed credentials are provided to the web server using cryptographic exchange and the
user is not prompt to provide the username and password as long as the stored credentials can

22

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

pass the authentication (see Figure 9). In case if authentication exchange fails the user is
prompted to provide Windows credentials for IWA flow (De Clercq, 2004).
The Integrated Windows authentication really consists of two authentication protocols:
NTLM and Kerberos. These protocols are used to call Security Support Providers. The specific
to the IWA is that it uses HTTP protocol to transport messages (De Clercq, 2004). The reason
why the transmission with SSP is not secured is that in IWA model the secure credentials are
not actually exchanged but only the hash is a subject of the authentication. Both NTLM and
Kerberos are widely used in most of the enterprise authentication implementations, however
both are either not secure or not scalable.
The NTLM v1 protocol does not provide any cryptography for authentication messages
transmission. Its successor NTLM v2 is much more secure (Boeynaems, 2010), however
Kerberos is faster and deliver several other features that are missing in both NTLM
implementations (De Clercq, 2004). The major advantage of NTLM over Kerberos is that the
NTLM can successfully authenticate in heterogeneous infrastructures while Kerberos must be
registered in a domain that is in a trust-relationship with a domain that web server is a member
of (Boeynaems, 2010).
The new authentications techniques (see Section 2.3.3) try to solve problems of their
predecessors but are still not well established and in most of the cases are not delivered as outof-the-box product.
Integrated Windows authentication is best suited for authentication within the enterprise with
intranet Web sites, although this technology is not scalable for the Internet and cloud services
(De Clercq, 2004).

23

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 10 Authentication using cached access token

Figure 11 Authentication using cached credentials with two domains in two-way trust

2.3.2. OAUTH
As per the example with the student (see Section 2.2) a very common problem with
authentication and authorization protocols is that they do not provide the most secure service in

24

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

order to protect resources. The Kerberos, one of the most popular authentication methods that
are currently widely used behaves exactly like the Ridacard system and does not validate the
token itself since it is issued. Security Access Token (SAT) that is created when user login into
Microsoft Windows system machine stores security information what can do about the
identity (user account). From the moment that the user logged into the machine the user
receives list of security groups that are stored in SAT, which exists as long as the user remains
logged in. The SAT is secured and not easily accessible, however the problem appears when
we grant user new security entitlement via Security Group. The security change will not reflect
the SAT till the user does not logoff from the system. This might not be a problem as we can
inform the user that in order to have the security entitlements refreshed has to logoff and log
back on again, although what if we remove the user from the security group. If the user should
not have access to some network resource anymore and the security entitlement removal was
done as an emergency change because there is a suspicion that the identity performs some
malicious operations that might be harmful for the organization, the access level of the identity
remain unchanged. The SAT will not reflect the security change on time and it will remain
valid for the user as long as the user session exists.
This problem might not be that serious as long as we have a control over what happens in our
organization. What if we start federating with other organization where many internal processes
might be very different and may not have the same information security culture as we managed
to maintain?
The Kerberos authentication reached its limits (see Section 2.3.1) and it does not respond to
latest IT market demands anymore. In era of cloud computing and distributed services, where
different web-based applications needs to exchange information in identity context (Google,
Flickr, Twitter, Facebook, Linkedin) and where third-party applications interconnect with
multiple services via APIs there is a demand for a new set of protocols that will address the
issues that older protocols can not address anymore (Hammer E. , 2010).
The OAuth was designed to solve many security and scalability problems of authentication
and authorization infrastructures. The most significant change to the authentication model that
came with OAuth protocol is completely different approach to credentials exchange. Using
OAuth users can grant third-party access to secure resources without need of username and
password exchanged. OAuth delivers not only the framework to build authentication and
authorization system but also a secure standard, which defines various access control features
25

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

(Hammer, Recordon, & Hardt, 2012). The OAuth was created to work over HTTP protocol
what makes it easily adaptable for any Internet and cloud-based web-services, which need to
interconnect to securely share protected resources.
2.3.2.1. Beyond Client-Server

OAuth unlike other traditional client-server authentication models adds concept from
Discretionary Access Control model where the object owner controls the access to the object
(Hammer E. , 2010). The innovation introduced with OAuth is that resource owner is one of the
authorization entities that can act either as only resource owner or as both resource owner and
the client. The client is the one that needs to access the protected resource.
The resource owner is the subject that grants the resource access without sharing credentials
with client. This is processed using token and shared-secret match (Hammer E. , 2010). The
token is the alternative to credentials exchange and it is representing authorization issued to the
client. In order to access the resource, the client requests authorization grant from the resource
owner (see Figure 12).
The access grant unlike in scenario where resource owner shares credentials with the client,
represents specific scopes and access duration (Hammer, Recordon, & Hardt, 2012). These are
properties that are controlled by both the resource server and authorization server and are
represented as access token properties.
When the client receives the access token from Authorization Server it contacts the Resource
Server to claim the resource access with the valid access token (see Figure 14).

Figure 12 Resource owner grants resource access to the Client (Hammer, Recordon, & Hardt, 2012)

26

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 13 Client requests access token from Authorization Server (Hammer, Recordon, & Hardt, 2012)

Figure 14 Client claims resource access from Resource Server with valid access token (Hammer, Recordon, &
Hardt, 2012)

2.3.2.2. Beyond old conventions

In the most bookish implementation of the OAuth protocol the three actors are defined that
are part of the authorization flow. This model is described as 3-legged model, where leg in
other words is the party involved in OAuth flow. Other implementations consist of two and
more actors and are called respectively 2-legged, 3-legged, n-legged implementations.

27

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The OAuth as a framework gives developer the wide range of authorization system design
choices (Hammer E. , 2010).
It is not an easy task to adjust OAuth authentication model to traditional RBAC
implementations around authentication. The reason behind it is that Role-based security bases
access control decisions on the functions an identity is allowed to perform within an
organization (Ferraiolo & Kuhn, 1992). The enterprise implementation of OAuth authentication
with RBAC can be very simple (what will be proved in the Chapter 4) although to benefit from
all OAuth features we need to go beyond the enterprise.
This OAuth protocol implementations variations, same as Cloud-based authorization models,
opens new possibilities of doing things that were not possible within traditional authorization
and authentication infrastructures. This important specific of these next generation
authentication infrastructures make them suitable for various types of Role-based security
systems (Bertocci, 2011). E.g. the access can be controlled with RBAC for the group of clients
and enforced on the authorization server by refusing access token issue before the access is
explicitly granted based on other rules that have higher priority than simple resource owner
approval.
2.3.3. CLAIMS-BASED AUTHENTICATION
Claims-based identity model is a key of FIM implementations. It consists of a subject that in
most cases is a user who wants to access an application. The application can be a standalone
application, a Web site or any Web-based service. This part of the model in identity jargon is
called Relying Party or Service Provider (SP). The last element of the model is an Identity
Provider (IP) that knows about the subject and knows how to authenticate the subject. There
can be more than one IP introduced to the system, however in most cases at least one needs to
be always available. In spite of that IP is an abstract role it has strictly defined functions, which
require system components such as: directories, identity repositories and authentication systems
(Bertocci, 2011). Security Token Provider (STS) is also one of the IP components. It is nothing
else than a specialized Web service, which has only one dedicated function to issue security
tokens.
The claims-based authentication in the simplest scenario (see Figure 15) starts with a subject,
a user who tries to access web-based application (Relying Party A at Figure 15). The user sends
HTTP GET command to the web-based application (RP A). Application redirects the user to

28

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Security Token Service for authentication. When STS authenticates the user it issues
Security Token (ST) and send it back to the user. Having ST the user can go back to the webbased application with the valid ST and access the service (Bertocci, 2011).

Figure 15 Claims-based authentication (Bertocci, 2011)

Federated identity can exchange identity related data across security boundaries using claims,
assertions and access tokens. In a traditional approach directory (LDAP, and so on) defines
security domain for the enterprise and acts as an identity provider for this enterprise. In
federated identity scenario the entire enterprise that provides identity information acts as an IP
(Deuby, 2011).
Claims-based

authentication

introduces

another

important

functionality

for

FIM

infrastructures that is called Circle of Trust. CoT is a name used to describe scenario where two
or more SPs trust the same IP in order to share Digital Identity information. This is a part of
Single sign-on implementation where different parties can share the digital identity information
so the end-user does not have to authenticate itself again with IP.
In claims-based authentication model SSO is nothing else than use of traditional browser
cookies with a bit of trust management (Bertocci, 2011).

29

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 16 Claims-based authentication with SSO (Bertocci, 2011)

In SSO scenario (see Figure 16) the user when reach the STS is already authenticated with it
(see Figure 15) because the authentication has been already completed when the user was
accessing Relying Party A in previous example. STS does not have to initiate the authentication
flow again it only releases new sequence number and sends the Security Token back to the user
so the user can successfully access the Relying Party B (Bertocci, 2011). This authentication
flow is completely transparent for the end-user and the process works even better in practice as
there are session cookies involved. This is very short presentation how claims-based
authentication works in practice and how it delivers SSO functionality.
2.3.4. WHY DIRECTORY?
Directories deliver functionality that is not available in transactional databases what includes
hierarchical structure with objects access management that perfectly integrates with this
hierarchy. This specific security mechanism, where access can be controlled with extreme
granularity, which scales to object attribute level, comprises integrated part of any directory.
One of the most popular directory roles is being as a source of an authentication (Pohlman,
2003). IAM and FIM systems make use of directories to authorize resource or web-based
applications access. Because the directory is a security boundary for contained objects and
interconnected systems and due to its internal design and auditing functionality it is the most
common element of every large enterprise infrastructure and any organization that protects
resources and control access of registered identities.

30

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The most basic directory functions are thus:

Authentication and authorization

Store network resources naming and location

Network resources administrating and managing

Applications enablement

(Pohlman, 2003)
Currently the X.500 standard is the most commonly used directory data structure standard
used in directories implementation. This standard defines several protocols although these are
not

in

scope

of

this

thesis.

The

one

that

is

important

to

mention

is

Lightweight Directory Access Protocols (LDAP). This standard provides an open directory
access protocol, which inherits X.500 data model, however is much more efficient than its
predecessor Directory Access Protocol (DAP). LDAP is highly scalable to a global size with
millions of entries that are organized in secured and self-defining structures (see Figure 17).
Successfully deployed directories are scalable enough to be used in Small and Medium
Enterprise (SME) and in Large Enterprise (LE) (Pohlman, 2003).

Figure 17 Object location within Directory Information Tree (DIT) (Andersen, 2008)

The most popular implementation of LDAP is Microsoft Active Directory (Andersen, 2008).
MS AD provides wide range of services that use LDAP concept and delivers products that use
MS AD to control data access. MS AD has underlying flat database Extensible Storage Engine,
which is based on Jet databases that were used in other Microsoft products in early 90s
(Maples, 2008).
31

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Objects stored in MS AD are having unique GUIDs, however these identifiers are relatively
large in MS implementations because GUID takes 16 bytes of memory that is why MS AD uses
distinguished name tags (DNT), which are unique within MS AD forest security boundary and
take only 4 bytes of memory (Maples, 2008). This internal MS AD structure is important to
understand, as this is crucial to deliver efficient meta-directory framework for IAM and FIM
that can scale to LE sized organizations (see Section 3.4.2.2).
Currently one of the most challenging tasks related to MS AD is to successfully place it in
the cloud. Organizations that use MS AD integrate it with many organization systems and
processes such as Business Continuity Plan. Internal implementations are designed to deliver
highly available system that enables fail-over functionality across different locations. This
functionality is a part of MS AD and is always considered when planning and deploying
MS AD infrastructures. Microsoft recently delivered a new cloud-based IDaaS service called
Windows Azure Active Directory to address demand for MS AD as IDaaS service (Sean,
2012).

2.4. ROLE-BASED SECURITY


2.4.1. CONCEPT
While DAC and MAC access control types align with IT systems operations and
administration, RBAC aligns to job functions to enforce access control entirely through roles
(OConnor & Loomis, 2010). RBAC shortens the distance between Access Control,
Information Security and Business requirements, although its implementation in cloud brings
new challenges due to character of RBAC systems, which are closely tight up with enterprise
within its boundary (Sandhu, Coyne, Feinstein, & Youman, 1996). Implementation of RBAC
systems is more and more top one priority in most of the companies that are enterprise size.
Access control system requires intensive supervision over existing resource access control
infrastructure. Relatively small system with 1,000 users and 100,000 resources will require:
1,000 x 100,000 = 109 possible authorization triples (Bertino, Martino, Paci, & Squicciarini,
2010). Role-based security is an attempt to reduce costs related to administration of access
control system. Once RBAC structure is established it remains relatively constant (Ferraiolo &
Kuhn, 1992).
The basic logic behind RBAC model can be represented in a simple formal description
proposed by Ferraiolo et al:

32

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

For each subject, we define active role as the one that is currently being used by the subject

AR(s:subject) = {the active role for s:subject}

One or more roles can be performed by each authorized subject

RA(s:subject) = {authorized roles for s:subject}

One or more 2transactions may be performed by each authorized role

TA(r:role) = {transactions authorized for role r}

Subject may be entitled to execute transactions and the following predicate is true when subject s
can execute transaction t

exec(s:subject, t:tran) = true if s:subject allowed to execute t:transaction

Using above formal description it can be deducted that role can be compound of set of
transactions that identity can perform in organizational context.
Authentication infrastructures with Role-based security are not new in IT, although cloud
implementation requires authentication to meet cloud client needs as well as RBAC model
specific requirements (Pohlman, 2003).
2.4.2. RBAC VIA ABAC
Every account or asset has attributes that tell something about it. These attributes of account
or asset objects are specific for the context of these objects. Such properties through
comparative processing of organizational knowledge about the object such as location or
description, or situational data such as date and time when account accessed the asset (e.g. user
logged into the system), the Identity & Access Management system can take access control
action and decide whether object is authorized to perform specific activity in the secured
Attributes-Based Access Control (ABAC) infrastructure (OConnor & Loomis, 2010).
ABAC can be used to leverage account information and contextual information to securely
control access. This approach relies on other systems that control identity and resource access
that is why consistence of processed data will impact the quality of Attributes-based security
system. Having reliable identity provisioning system, which can rapidly replicate changes
related to identity within organizational context can make ABAC a powerful access control
model, which unlike RBAC can be easily exposed outside organization. RBAC cannot provide
sufficient level of access control security, as the identity from outside the enterprise cannot be
term used by Ferraiolo et al refers to bindings of transformation procedure and data access. In this
convention when we take savings deposit transaction that updates a savings database and transaction
file Read savings file is a valid transaction while Read is not.
2

33

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

matched with any specific internal role what would give granularity of transactions which can
be performed by digital identity. With authorization engine created as a hybrid of the RBAC
and ABAC models, the delivered system leverages the best of each (see Section 3).

Figure 18 ABAC rules set filtering assets access based on accounts attributes

2.5. XAAS
XaaS is an acronym that refers to Anything-as-a-(Cloud)Service. Cloud computing is a term
used to describe all different types of applications and XaaS services that are accessed with
Internet protocols and networking standards. Cloud computing is using virtualized resources
that are located on a distributed networks (Sosinsky, 2011). XaaS services are one of the cloud
concepts that aimed to deliver pay-as-you-go customer experience (Sosinsky, 2011). The three
early cloud computing models are Infrastructure as a Service (IaaS), Software as a Service
(SaaS) and Platform as a Service (PaaS) (see Figure 19), however as cloud computing matures
several other models were introduced like Hardware as a Service, Identity as a Service (IDaaS),
Complianc as a Service (CaaS), provisioning, storage, monitoring, communications and many
others (Sosinsky, 2011) are currently available as ready to use service delivered by cloud
computing providers.
IaaS model delivers ready infrastructure for application such as servers, networks, storage
and other components that are provided as manageable components. Another widely
implemented cloud service model is SaaS, which delivers ready to use applications such as
GoogleMail, Hotmail and many others. PaaS layer is mainly a part of Service Oriented

34

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Architecture (SOA) service delivery model, which helps to develop applications (Buchanan,
2010).
The service models that are currently being delivered by different cloud providers are either
more generic and are compound of different cloud services sub-types or are specialized and
describe distinguish function of the service.

Figure 19 Cloud abstraction layers; the best-known service models (Buchanan, 2010)

2.6. SECURITY CONCERNS


2.6.1. DATA PROTECTION ACT
The DPA regulates all data subject rights also normalizes the consent that organization signs
with data subject in terms of data protection. This means that organization must follow all DPA
principles and also that all operations where personal data is a subject matter the DPA must
apply. What does it brig to the organization? It guarantees that valid consent, which complies
with the UK DPA 1998 regulates also personal data transfer across borders within EU and
EEA, also to other countries that are considered as having adequate level of protection
(Information Commissioner's Office, 2010).

35

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Switzerland is one of the countries outside of the EEA, which has adequate level of data
protection (Information Commissioner's Office, 2010) required to transfer data from the EEA
or EU. Since Switzerland ratified the Convention for the Protection of Individuals with regard
to Automatic Processing of Personal Data in October 1997 it covers all basic principles of data
protection, which are mandatory to have adequate to UK DPA 1998 principals applied
(Information Commissioner's Office, 2010) (Information Commissioner's Office, 2010).
This act guaranties that personal data hold by any organization that comply with DPA is safe
and will not be send to somebody else, any individual or government without consent of data
subject. This also regulates cloud data flow as data stored under one jurisdiction where DPA
applies cannot be transferred outside this jurisdiction without Information Commissioner
consent (Desai & Johnson, 2012).
2.6.2. PATRIOT ACT
Uniting and Strengthening America by Providing Appropriate Tools Required to Intercept
and Obstruct Terrorism Act of 2001 (USAPA) also called USA Patriot Act of 2001 was signed
into law in October 26, 2001. One of the most controversial privacy-related legislation that has
several implications for cloud computing (Deuby, 2011). The act regulates private data access
under jurisdiction of USA. This law grants powers to law enforcements and intelligence
agencies to control electronic communication (Pohlman, 2003). These changes in U.S. law
caused many concerns among foreign governments, organizations and financial institutions
related to data flows. The Canada, that used to store data with providers located in USA
prohibited any government related data to be stored under U.S. jurisdiction (Deuby, 2011).
Many financial institutions located in European Union and Switzerland tightened rules
regarding secure data access and data replication by enforcing reviewed information security
policies or by introducing separation of duties (Ferraiolo & Kuhn, 1992) for all transactions
related to data access.
This problem of data protection in the cloud across different jurisdictions is very often
discussed and is the main concern, which stops enterprises from migrating into the cloud
computing. Leading cloud providers try to convince data commissioners to put trust in security
that comes with cloud computing, although USA Patriot Act of 2001 is the main argument
against the cloud computing (Desai & Johnson, 2012).

36

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

2.6.3. SAFE HARBOR


The U.S. Safe Harbor Program is the attempt to convince European organizations that data
can be stored securely under USA jurisdiction. This is a try of compliance with EU data
protection requirements. This program covers only several organizations what is regulated with
Federal Trade Commission, which does not apply to organization such as financial institutions
(Deuby, 2011).
Because in cloud computing data can be stored outside both EU and USA this makes U.S.
Safe Harbor Program ineffective (Deuby, 2011). Cloud providers offer customers several
options including selection of preferred data location, however these offers break the cloud
concept where cloud ought to adapt to service demands by delivering flexible and efficient
distributed model.
2.6.4. PERSONAL DATA IN THE CLOUD
The flexibility that comes with the cloud computing have many disadvantages which have its
source in data security. The USA Patriot Act of 2001 (see Section 2.6.1) causes many concerns
mostly related to next generation infrastructures deployment, which benefit from being location
independent.

From data protection perspective all the federated identity models

implementations, including Identity Providers location and security boundaries definitions still
constitute milestone for cloud computing to be a safe platform for everyone everywhere.
Cloud deployment might look attractive for Small and Medium Enterprise (SME), although
move into the cloud for Large Enterprises (LE) is followed by many information security
challenges related to data protection and jurisdictional, and organizational internal legal
compliance (Deuby, 2011).

Figure 20 Mind the Gap phrase from London Underground with logo used by Deuby at al (Deuby, 2011)

2.6.5. INTEGRATED WINDOWS AUTHENTICATION


The Integrated Windows Authentication is not as vulnerable to phishing attack as other
authentication techniques. Because client does not need username and password to access
resources there is no risk related to spoofed resource URL where user ends up providing secure

37

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

credentials on the page which is looking exactly the same as the one that user expects to log
onto. This problem was solved with Windows security token, which is obtained during client
logon process on a Windows system. Using IWA any resource can be accessed by the client
without providing additional credentials if it is joined to the MS domain where the client is
logged into or if it trusts the clients domain.
2.6.6. OAUTH
The OAuth protocol is same as most of the other authentication protocols vulnerable to
phishing attack. If the consumer sends user (resource owner) a site that looks like
authentication page of the users service provider then the attacker can intercept user
credentials. It is not the protocol problem but it is a general problem with all authentication
methods.
The OAuth protocol was designed to overcome eavesdropping and main-in-the-middle attack
and support non-secure HTTP protocol at the same time. OAuth can support secured HTTPS
channel where client-server can exchange plaintext messages, however HTTPS is not always
available. In order to ensure that the message can be send via HTTP in a secure manner OAuth
transmits secure data using RSA-SHA1 and HMAC-SHA1 (Hammer E. , 2010).
The same protocol implements basic technique to mark requests with 3nonce and timestamp.
This security approach protects requests against replay attack. Nonces are stored by the
Service Provider to protect the resource by making sure that requests are send only once and
they are received in a right order derived from the request timestamp (Hammer E. , 2010).
2.6.7. OAUTH 1.0 VS 2.0
There are major differences between OAuth 1.0 and 2.0 versions. Version 2.0 does not
support cryptography at the protocol level instead it uses TLS what makes version 2.0 more
vulnerable to all types of attack that TLS is vulnerable to. Another major difference is lack of
secure credentials set on each protected resource request in version 2.0. In version 1.0 both
token and client credentials are in use while in version 2.0 client credentials are no longer used
(Hammer E. , 2010).
2.6.8. SOAP PROTOCOL VULNERABILITIES
unique number that is used only once. OAuth includes nonce when generating a request signature in
order to ensure that only party that owns the shared secret can generate a valid hash and validate the
signature.
3

38

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

When we look at the backend of the Web service we find that SOAP as the compound
communication model protocol is highly vulnerable to many types of attack. This part of the
model must be extremely protected and security model should be revised against threats related
to integrity and confidentiality of the communication.
SOAP is vulnerable to several types of attack and these with the highest likelihood are:

the message can be read or modified by a potential attacker

the message can be spoofed with a Web service well-formed message that lacks valid security
claims to warrant communication

the message sent to Web service can be spoofed by an attacker in the way that the message does
not lose the consistency what causes that the service processes the request as valid and responds to
the client.

We see that SOAP implementations are highly vulnerable to major security threats and in
order to deliver secure point-to-point communication we need to ensure that confidentiality and
integrity are well secured.
Some of the security issues related to SOAP protocol can be resolved with XML encryption
and XML signatures and some can be resolved with different standardizations created to
securely represent security information inside the SOAP message (Bertino, Martino, Paci, &
Squicciarini, 2010).
2.6.9. RBAC MODEL STRENGTHS & VULNERABILITIES
Very common information security challenge is enforcement of security policies that tend to
protect organization against fraud. With Role-based security mechanisms it is possible to
enforce separation of duties (Ferraiolo & Kuhn, 1992). This means that not a single individual
is allowed to execute all transactions. As an example we can look at the bank payment system,
where payment transaction has to be initiated by a different individual than the one that
approves the transaction (Ferraiolo & Kuhn, 1992).

2.7. CONCLUSIONS
This chapter reviewed currently the most promising Identity and Access Management
models that federate identities and are scalable in the way that makes them suitable for large
cloud-based implementations. Next generation authentication models are not like their
predecessors a ready out-of-the-box products but are rather evolving frameworks that try to

39

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

follow the latest identity management trends, with federated identity and IDaaS models settled
as the core concepts.
The most important finding of this chapter is that the most of the federated identity
management, access control and authentication concepts are frameworks that try to align with
heterogeneous organizational infrastructures which slowly migrate into cloud computing.
RBAC and ABAC not only define distinguished access control models but like other
frameworks can be customized and be deployed together as one consistent access control
system.
Despite of new ways of authentication and identity management the traditional identity
repositories like directory do not change and they only expand domains which constitute
security boundaries for directories into the cloud services.
The major concerns are related to the cloud and its global scalability abilities that actually do
not guarantee sufficient data protection under different jurisdictions. Despite of cloud providers
warrants ensuring that data in the cloud they deliver will be safe many governments and major
market players do not trust the cloud computing and keep the data within their internal security
boundaries.

40

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3. HIGH LEVEL DESIGN


3.1. INTRODUCTION
3.1.1. BACKGROUND
The selected model for IDaaS delivers a solid framework under federated identity
management that supports different access management models like RBAC and ABAC
(see Figure 21). It is using meta-directory to control and link the digital identities across
different security boundaries.
The iIdManagement database was designed to deliver federated identity functionality with
RBAC and ABAC access control models (see Figure 22). It simply processes the data that is
stored in meta-directory build in a cloud instance. With different data sources the best data
processing performance and efficiency can be achieved with similar data repositories that use
similar data structures and with efficient data bandwidth between these sources. Building metadirectory helps to interconnect the repositories and expose the required data for processing
(Pohlman, 2003).
iPortal and Enterprise Portal are simple pages created to evaluate the federated identity
model using OAuth protocol to authorize between each other (see Figure 23). Both pages are
customized examples delivered for OAuth by Eran Hammer.

Figure 21 IDaaS implementation with iIdManagement and iADConnector (FIM, IAM and LDAP connector)

41

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 22 iIdManagement - ABAC engine that enforces RBAC rules

The iADConnector Service has been developed to simplify queries and reports on data that is
stored in the Active Directory and other LDAP repositories that are spread across the
organization and trusted parties. Using LDAP based queries for certain types of reports do not
efficiently perform as it is not optimal. Object filtering scenarios are limited and performance is
significantly impacted with increasing filter complexity. LDAP was designed to well-perform
for authentication and authorization therefore LDAP used for reporting and auditing can be
used but have an impact on the performance of directory based environment.
The iADConnector Service inventories objects from Active Directory and LDAP directories
into dedicated SQL database. Because iADConnector service acts as a Read-Only Domain
Controller for MS AD only change deltas of AD objects are being updated into the DB.

42

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 23 OAuth flow between iPortal and Enterprise Portal

3.1.2. DESIGN GOALS


The Active Directory and LDAP data in the SQL database can be queried and matched with
other SQL databases data in a more effective way. The following list contains some examples
of reports that are created using data from iADConnector inventories:

Memberships of several groups across forests and domains for review purposes.

Memberships of several groups across forests and domains combined with user attributes
for membership rules.

Active Directory group data for ownership and general maintenance purposes.

Active Directory group and user data for RBAC and ABAC mass transactions.

Active Directory computer data for maintenance purposes.

Custom federated identity views joining all accounts belonged to identity

LDAP data queries that need a complex custom data view.

Transactional identity processing based on different access management models

43

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3.3. ARCHITECTURE
3.3.1. INTRODUCTION
The iIdManagement is using MS SQL server and its functionality benefits from MS SQL
query language and management tools that are delivered with the MS SQL product. This is
more development framework rather than implementation that will work in all IAM and FIM
scenarios. There is only one MS SQL server instance, which is hosting iIdManagement
database. It delivers meta-directory for the custom FIM implementation.
In iIdManagment digital identities are constructed based on automated or manual process
using Stored Procedures. Constructed digital identities are compound of other linked identities
(accounts) across various security boundaries via meta-directory.
The iIdManagement joins two account sources under one federated identity. The one
accounts store for iPortal is based on SQL database and the other for Enterprise Portal is a
meta-data from Enterprise Active Directory (SpyraConsulting.net AD forest).
iPortal and Enterprise Portal are two pages hosted on one MS IIS server in the cloud. Are
build using ASP.NET with DevDefined.OAuth .Net libraries. They authenticate user using
iPortal database, which is created for federated identity and Role-based security purposes.
The iADConnector is a Windows service built on top of the .Net Framework. The service
was designed to work in distributed, client-server or cloud-based environments; however the
service can run only on the MS Windows based machine.
The iADConnector synchronizes data from LDAP directories into dedicated SQL database.
ELEMENT

NUMBER

COMMENTS

Instances

Threads initialized

.Net framework default

LDAP Connections

NO_CPU_CORE_PER_GC *
MAX_DC_POOL_THREADS

2 1 for Hedani and Auredi/1 for Omni


1 old iADConnector instance for GLDAP
Number of threads is determined based on .Net
framework version
iADConnector connects to one GC at time and the
number of initiated LDAP connections is determined
based on formula.

Table 1 Estimate number of instances of each part

Several instances of the server can run simultaneously against one database to split data
processing per different security boundaries and to ensure that issues from one security
boundary will not affect inventorying performance of the other security boundary.

44

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The iADConnector does not retrieve LDAP data changes deltas using multi-threading,
however it uses the multi-threading technique to retrieve and process the object attributes that
were changed in LDAP and parse them to the correct type and format required for DB. Objects
that were changed are just retrieved without any other information that the object
distinguishedName so the multi-threading can find the changed object and collect all the
attributes required for inventory.
The iADConnector establishes several LDAP connections per server to go around the LDAP
connection limitations that restrict number of simultaneous LDAP queries per LDAP
connection. The number of LDAP connections is calculated based number of open connections
using MS AD domain controller specific formula.
The iADConnector as a simple service does not use any external components except
.Net Framework. All internal components can be logically represented as inventory cycle steps
(see Figure 26 iADConnector inventory schema). This representation does match the service
flow, if we would use a different and more detailed granularity (e.g. using functions that
perform specific operations) because of the LDAP structure and LDAP objects relationship that
does not match the data structure of SQL databases. Interconnections between different LDAP
objects to be simplified for the DB require very specialized approach that transforms
hierarchical directory objects relationship into transactional database structure.

3.4. DATA
3.4.1. INTRODUCTION
The iIdManagement database is MS SQL database with couple dedicated Stored Procedures.
Because the existing system design before iIdManagement was based on MS technologies the
preferred solution had to suit the existing system. The iIdManagment is a framework that
benefits from identity stores that are located on the same MS SQL server instance. It joins
different identities from different identity stores under one federated identity and using ABAC
based operations against different identity stores enables or disables access to iPortal page.
The iPortal database is a simple account store for iPortal page. Registered iPortal accounts
with passwords hashes are stored in iPortal database. Because these accounts belong to a real
person that has more than one account in several systems, they are subjects for federated
identity management.

45

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

iADConnector service is completely based on MS SQL database. Inventory data, advanced


configuration and synchronization metadata are all stored in database. .Net Framework
provides complete set of interfaces that are necessary to access both LDAP directories and SQL
databases.
Because the service connects to different directories across different security boundaries it
cannot use the default service credentials that the service is running under. The
Windows Authentication does not scale across different directories. The iADConnector is using
impersonation with encrypted credentials to authenticate with directories.
The iADConnector inventory can be used to build complete meta-directory solution that can
cope with different LDAP repositories. The underlying SQL database can easily be integrated
with other Identity & Access Management solutions like iIdManagement that are controlling
identity inside one or across many security boundaries. The iADConnector because is not
tighten up to one security boundary can act as an identity source for federated identity
infrastructure.
3.4.2. SCHEMA
3.4.2.1. iIdManagement

The iIdManagement is a heart of all identity related operations (complete tables and columns
description can be found in Appendix F).. Using Stored Procedures it provisions new digital
identities, which are then joined with accounts from iPortal and iADconnector. The identity
linking is performed in two steps. First we need to provision the global identity and then
dedicated Stored Procedures link different accounts. The iPortal account linking is very
simplified and cannot be automated, as the accounts store (iPortal.dbo.Accounts table see
Figure 24) does not provide enough information to match account information with identity
meta-data.

46

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The iADConnector inventory provides broad account information sufficient to completely


automate identity provisioning and identity linking process. This part of identity linking is
automated and identities are matched with stored procedure using surname and first name of
the person who is represented with the federated identity.

Figure 24 iIdManagement tables required to federate identity

The iIdManagement delivers also access control functionality. The set of two tables
(see Figure 25) controls access to iPortal page with RBAC rules enforced through ABAC
(complete tables and columns description can be found in Appendix H). This part of
iIdManagement is also a development framework that can control access across different
interconnected systems.
The iPortal account store defines whether stored account can access the iPortal or not with
dedicated status attribute. iIdManagement manipulates with iPortal access using federated
identity and different properties of the digital identity that are stored across account stores.

47

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 25 iIdManagement ABAC engine tables

3.4.2.2. iADConnector

The iADConnector maps two schemas the one from LDAP with custom SQL DB schema.
Because of the directory (mostly MS AD) specific representation of object properties the
service transposes LDAP native schema into data schema that can match transactional
database. E.g. MS AD uses additional dedicated attribute to store group memberships. This
attribute is part of the schema and this transformation is transparent for the end-user who sees
group members as a list of objects in user-friendly format. This exposition is using the
dedicated linking attribute, which actually keeps pairs of unique object indexes from directory
database. Transformations in such scenarios are very complex because the actual changes
(directory location, properties change) of the objects that are linked are not represented as a
membership link update but only an update specific to object itself. This might not be a
problem in small and medium enterprise (SME) as the member attribute of the group can be
parsed into delimited format or XML format and stored as any other attribute in the DB and be
overwritten with a new value. The problem arises when we deal with thousands of
memberships and in order to efficiently control and audit the security across different security
boundaries we need to keep membership data is a separate table. Because we do not know if
any of the group members on the list were changed we need to maintain event driven
functionality, which is implement for every object type and sends specific object update
information to the membership repository. Specific to directory objects interconnections
require inventory to store all objects from one security boundary in separate tables
differentiated only by object class. In MS AD the forest establish the security boundary for
interconnected domains.

48

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 26 iADConnector inventory schema

Because we deal with different directories iADConnector implements several directory


distribution specific schema transformation components. The shared part of the schema
transformation across various directory distributions are objects with their attributes that are not
constructed and stored as a single or multi-valued attribute on the object (complete tables and
columns description can be found in Appendix G).

49

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 27 iADConnector sync meta-data and configuration tables

The iADConnector advanced configuration and synchronization metadata are stored in two
tables under iADConnector database (see Figure 27). More details are provided in Appendix G.

3.5. CODE
3.5.1. INTRODUCTION
The code used to deliver working model is mostly C#, ASP.Net and MS SQL based. .Net
code is a mixture of ASP.Net with C# and C# with MS SQL snippets embedded for SQL
database inventory data control. MS SQL is used also on the database level through several
Stored Procedures that are delivered with the framework.
3.5.2. MODULES
3.5.2.1. iIdManagement

The iIdManagement is a MS SQL framework that is interconnecting MS SQL based account


stores using Stored Procedures with provisioned federated identity. This framework is also
enforcing access rights based on accounts filtering from different stores. The iIdManagement
registers account stores with unique identifiers that can be called when need to access the
account store for federated identity. This approach faces redundant data problem as only
minimal information about the identity is stored in iIdManagment.dbo.iIdentity table required
to uniquely distinguish the identity and recognize interconnected identities (other accounts
from account stores).
50

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The Role-based security can be enforced only via Attribute-based security; this approach is
the most suitable for Meta-Directories where only identity properties are exposed outside the
security boundary. The iIdManagement is using two dedicated tables (see Figure 25) and
Stored Procedure to create a federated identity view with all interconnected accounts to create a
subset of identities that have or do not have access to resources based on attributes based ruleset. This approach requires automated accounts provisioning engine, which is not part of this
implementation.
3.5.2.2. iPortal with Enterprise Portal

The iPortal and Enterprise Portal are separate sub-projects from one ASP.Net based solution
that is delivered by DevDefined as OAuth implementation example. This example was
completely customized for evaluation purposes of this thesis.
The authorization and authentication flow are performed on one server across different
running web page instances. While Enterprise Portal is relying on MS Active Directory to
control access with Integarated Windows Authentication, the iPortal uses dedicated iPortal
database to store credentials. The iPortal database replaced account store delivered with OAuth
example. iPortal pages use set of OAuth 1.0 libraries also delivered by DevDefined. These
.Net Framework based libraries were also customized and precompiled to work with the model
developed for this thesis purposes. The examples are using latest OAuth 1.0 libraries
precompiled with .Net Framework 4.0.
3.5.2.3. iADConnector

The iADConnector service it is built of several different dedicated classes and uses all
benefits of .Net Framework 3.5. The inputs and outputs are always the same as iADConnector
consumes LDAP data as an input and through various transformations derives SQL DB data as
an output. Additionally the service uses XML configuration file, which stores the basic
information required to start the service and point it to the database instance. The major
configuration input, which includes encrypted credentials, comes from the database
(see Appendix G in Appendixes).
The engine connects to the directories and enumerates all objects and next stores them in a
dedicated database. The system that was built before iADConnector is based on
MS technologies and to make the service more consistent with existing meta-directory
solutions that were created before iADConnector. Service is using .Net Framework 3.5. The

51

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

.Net Framework version is especially important for the threads control so it is not
recommended to increment or decrement it without complete understanding of the code and all
internal components dependences.

Figure 28 Block diagram of iADConnector service modules activity flow

52

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3.5.4. INTERFACES
The iIdManagement platform does not expose any interfaces other than default interfaces
that are delivered with MS SQL server. Then the OAuth implementation communicates via
HTTP and there is no other communication between pages than through HTTP protocol. The
iADConnector code does not expose any interfaces. The set of custom libraries used in the
service are dedicated for the iADConnector and there are no plans to reuse them with other
code.
3.5.5. IDENTITY TYPES
3.5.5.1. iIdManagement

The database with dedicated Stored Procedures does not require any dedicated service
account. All identity related operations, which are automated are executed from database level
and do not require additional credentials. Because delivered iIdManagement database based
framework is going to be used only as a PoC dedicated security access control design is not
required.
3.5.5.2. iPortal with Enterprise Portal

The iPortal page has its own dedicated account store that keeps basic credentials information
required to authenticate and status of user account, whether account is active or inactive, what
determines access to iPortal.
Enterprise Portal is using MS Active Directory accounts and allows access to all
authenticated domain users using Integrated Windows authentication.
3.5.5.3. iADConnector

The service uses dedicated service account, which mainly needs access to the database
instance and service files. This account can be also used to access directory if no alternative
credentials are provided. The alternative directory credentials for service impersonation are
stored in a dedicated configuration database table. These are stored in an encrypted form and
are decrypted ad hoc when the service attempts to access the directory.
With default service credentials Windows Authentication is used to access directory,
however if there are alternative credentials provided for the directory the service performs the
LDAP bind operation using the alternative credentials.

53

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3.6. DAILY OPERATIONS


The iIdManagement framework delivers Stored Procedure that filters identities based on
RBAC rules using ABAC technique. This SP can be scheduled perform identity and access
operations on daily basis or can also run on some short interval. The recommended way to
schedule this SP is to create separate MS SQL server job that executes the SP on the server.
In the normal service operation the iADConnector reads synchronization meta-data to select
the latest server used for given domain (if there is more than one server for a domain; specific
for MS AD synchronization scenarios). The service updates DB accordingly to LDAP directory
changes. This process takes place based on the service run cycle configuration, which is
defined in the XML configuration file.

3.7. INSTALLATION
3.7.1. IAAS
The IDaaS implementation requires IaaS platform with Microsoft Windows Server installed.
It requires pre-installed .Net Framework in version 3.5 and 4.0. To run fronted the
MS Visual Studio 2010 and MS IIS are required. The back-end will require MS SQL Server in
version 2005 and newer.
3.7.2. IIDMANAGEMENT
iIdManagement database framework does not require any specific installation. For this thesis
purposes the default database that can be created with Microsoft SQL Server Management
Studio wizard is sufficient. The only requirement is to recreate the default database schema
using script provided.
Installation steps:

create dedicated databases with all tables provided in the schema

*create dedicated SQL jobs to automate RBAC and ABAC data processing using stored
procedures

54

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3.7.4. IPORTAL AND ENTERPRISE PORTAL


Both pages do not require any specific installation and can be published via IIS, however for
this thesis debugging mode under MS Visual Studio 2010 is sufficient.
3.7.5. IADCONNECTOR
The iADConnector installation requires only couple simple steps:

create dedicated databases with all tables provided in the schema

install the iADConnector service on the machine that has access (no blocked with firewalls) to the
DB instance

configure the iADConnector XML configuration file and specify the connection string for the DB

specify the advanced iADConnector configuration using DB configuration table


3.7.5.1. iADConnector service installation

The NT Shell script can be used to install the service. This script is a part of the
iADConnector package.
There are two scenarios for post-installation service configuration adjustments:

service is running with credentials that are used to access directory; in this case default service
credentials have to be changed

service will use alternative credentials to access directories; in this case the only consideration is
whether default system credentials set by default for the service can access the service database
and if cannot the service required dedicated service account to run under it
3.7.5.2. iADConnector service configuration

Service is configured in two locations:

service XML configuration file, which is located under service program file folder

dedicated database table that is selected based on the XML configuration file

When all tables are in place including configuration table, synchronization meta-data table
and inventory tables, the service needs some additional adjustments. The DB schema defined
for the inventory has to reflect the LDAP object classes and inventory types. This is done with
the service configuration table. The configuration example is delivered with the iADConnector
package (see Table 5 Advanced service configuration).
Alternative credentials for service impersonation are also stored in the configuration table.

55

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

*it is important from security reasons to provide alternative credentials as the last step of the
configuration, just before the service is started; credentials before are encrypted are stored in
plain-text format.
3.7.6. DEDICATED DATABASE
When the database is created without any specific schema defined the complete
iIdManagement and iADConnector databases structure can be created from the SQL scripts
provided. It is very important to create one set of inventory tables per either directory or forest
(only MS AD scenarios).
*any additional columns iADConnector for new LDAP attributes can be defined at this stage,
also columns that are not part of the LDAP schema can be added here if are required for
various administration or identity management purposes

3.8. INTEROPERABILITY WITH OTHER SYSTEMS


Because the iIdManagment and iADConnector meta-directories are MS SQL based it will
integrate with all other types of meta-directory systems that are also based on MS SQL. Placing
both DBs aside with other meta-directory databases under one SQL server instance can
simplify all custom inter-database queries, although it is important to thoroughly assess the DB
server if it can handle additional database and all DB operations required to maintain it.
The interoperability is optional and is not required for the framework to run. While the
iIdManagement can be integrated with other database based identity repositories the
iADConnector can be integrated with:

Identity and asset provisioning systems

Identity and Access Management systems

ABAC and RBAC security systems

All types of custom meta-directory solutions

3.9. SECURITY
The iPortal database does not stores password but only MD5 hashes for user passwords. This
will not provide sufficient security required for enterprise size implementations, however
hashed password allows users to authenticate against iPortal and does not expose passwords to
anyone who can view credentials stored in the database.
56

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Security delivered with Enterprise Portal is based on traditional Integrated Windows


authentication and this Microsoft model is reviewed in details in Section 2.3.1.
The iADConnector delivers secure model of data access because of the impersonation with
specially tailored credentials that give only the minimal access rights required to list LDAP
objects. This is empowered with dedicated credentials encryption, which is done automatically
by the service when are found in a plain-text format. Additionally these credentials are not hold
by the service during the inventorying cycle. These are retrieved from DB and used ad hoc only
when required binding the LDAP directory and afterwards are disposed. Credentials are also
kept as a SecureString type what makes them even more secure in the service context.
Encryption is done with the dedicated library that was created especially for this thesis and
evaluation of delivered model. Credentials are converted to byte array format and each bit is
negated. The result of the bitwise operation is then represented in Base-64 format. This is
symmetric encryption that does not provide sufficient security, however is a part of a service
framework that can be easily replace with more advanced encryption libraries.

3.10. OPEN ISSUES AND RECOMMENDATIONS


3.10.1. IADCONNECTOR
The iADConnector service is a tool that can successfully inventory very complex large
enterprise size LDAP infrastructures, with a set of special extensions created only for
MS Active Directory. Because the iADConnector was initially created to inventory MS AD all
additional functionality to enumerate other LDAP directories are just extensions and have no
dedicated design section that would support all LDAP schemas and data structures. Despite of
that iADConnector is using low level LDAP libraries delivered with .Net Framework the
complete model needs to be redesign to handle all types of LDAP directories in the most
efficient way.
Membership reporting functionality represents distinguished names of interconnected
objects, what makes it easy to read; however there are scenarios where membership reports that
require recursive approach using MS SQL CTE queries can consume whole system memory
and storage space. These scenarios are very common where multiple membership nesting levels
were used what caused overall membership count around 100mln group memberships. This
issue requires complete service redesign to represent memberships in a way that is similar to
MS AD representation where additional linking attribute is used, which links objects indexes.

57

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

3.10.2. RBAC & ABAC TRANSACTIONS SECURITY


If iIdManagement framework should support transactional access control operations each
token assignment transaction based on RBAC & ABAC assignment should be secured with
MD5 hash that is derived from transaction record. This should be performed on the DB
transactions level using SQL trigger that utilizes built-in MS SQL function called
HASHBYTES('MD5','concatenated_columns'). Transactions then should be accessed with
Stored Procedures, which verify MD5 hash of each read transaction before it is returned to the
client.
It is recommended to add either DB instance name or table primary key unique name as a
salt to generate MD5 hash. It will guarantee security transactions integrity.

3.11. CONCLUSIONS
This HLD delivers a model with all major components that are required to build an enterprise
sized federated identity infrastructure with Role-based security. This chapter of the thesis
presented how the IDaaS cloud service can be implemented and how all integral components
are interconnected do deliver federated identity authentication functionality with Role-based
security. These components consist of FIM development framework named iIdManagement,
that is created using MS SQL server, which benefits from wide MS SQL database server builtin functionality. This component manages digital identities from two account repositories. One
account repository is created to control iPortal access and is logically located in a separate
cloud instance. The second account repository is a database inventory of directory data that is
located in a different logical cloud instance. Both database repositories are located on the same
MS SQL server instance what allows iIdManagement framework to control federated identity
what satisfies findings from Section 2.2.3. The directory connectors that are delivered with
iADConnector service give the possibility to retrieve subsets of identities across organizations.
This complex implementation gives a very powerful platform for RBAC via ABAC access
control what satisfies finding in Section 2.4.2. The front-end that is created in ASP.Net with
underlying OAuth 1.0 libraries simulates two separate portals that are located on two separate
cloud instances. Because this model is only created as a PoC for this thesis there are many
possible enhancements and security considerations if this framework meant to be rolled-out
into enterprise. Last two sections of this chapter are dedicated to these concerns related to
delivered PoC design.

58

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

59

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

4. CLOUD-BASED IMPLEMENTATION
4.1. INTRODUCTION
This chapter describes all details of cloud-based implementation, which was designed in
previous chapter of this thesis. The complete code including .Net libraries, NT Shell and SQL
scripts, and stored procedures created for this Proof of Concept are not presented here, although
all are listed here and referenced either to Appendixes or files from installation package. The
following sections cover all the implementation details that are important for the next,
Evaluation chapter.
Almost all parts of the implementation were scripted either using NT Shell or SQL. This
makes this prototype transferable to any other cloud instance. Because the back-end engine is a
development framework rather than a ready product it can be rebuilt on any other server and
used for testing and evaluation purposes. The front-end component is a .Net solution delivered
by DevDefined and is also very movable as does not require dedicated installation. The frontend iPortal and Enterprise Portal are published with MS IIS.

4.2. SYSTEM CONFIGURATION


4.2.1. AMAZON EC2 CLOUD INSTANCE (IAAS)
The complete EC2 cloud server instance with preinstalled MS Windows Server 2008
(see specification in Appendix E) and required server services for this thesis such as MS SQL
Server 2008 and MS Internet Information Services, was delivered by Edinburgh Napier
University. This is instance has a public IP address and is registered with a public DNS
namespace:
IP: 23.21.161.237
DNS: ec2-23-21-161-237.compute-1.amazonaws.com

All further server adjustments and prototype specific configuration are described in the next
sections of this chapter.

60

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

4.2.3. MICROSOFT ACTIVE DIRECTORY DOMAIN SERVICES


The MS AD DS installation is a default server role installation without any additional
customization. Role was installed on the server using provisioning scripts created for this
prototype. To install AD DS role on the server from Command Line Interface simply used:
ServerManagerCmd.exe -query
ServerManagerCmd.exe -install ADDS-Domain-Controller -allSubFeatures

4.2.4. OAUTH 1.0


To test the OAuth 1.0 protocol implementation used set of DevDefined.OAuth libraries and
DevDefined.OAuth-Examples solution. The libraries source code is available separately and
the examples come with pre-compiled libraries. Examples required several adjustments and
customization for the prototype purposes. The libraries are amended and recompiled therefore
examples are not using the OAuth 1.0 libraries that they were delivered with it.
The main OAuth 1.0 libraries change was related to the token validation section
modification.

Figure 29 DevDefined.OAuth libraries (Visual Studio 2010 Solution Explorer)

61

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Because the constructor declares token expiration date with DateTime object that not
necessarily has to be initiated with any date/time there is a small change implemented in
DevDefined.OAuth library, InMemoryTokenRepository.cs class:
public void ConsumeAccessToken(IOAuthContext accessContext)
{
AccessToken accessToken = GetAccessToken(accessContext);
if (accessToken.ExpiryDate != DateTime.MinValue && accessToken.ExpiryDate < Clock.Now)
{
throw new OAuthException(accessContext, OAuthProblems.TokenExpired, "Token has
expired");
}
}

The recompiled libraries allows more comprehensive DevDefined.OAuth-Examples code


debugging and it is another benefit for prototype evaluation because not only examples but also
underlying libraries can be attached for analysis to MS Visual Studio while solution is running.
The main DevDefined.OAuth-Examples solution amendment was related to authentication
and account store. Only two parts had to be changed to redirect the authenticating and
authorizing portal to database to retrieve the credentials.

Figure 30 DevDefined.OAuth-Examples (Visual Studio 2010 Solution Explorer)

62

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The first part are two changes to the the Web.Config (see Table 4), one to change the
authentication method and the second to add the new database connection string:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" cookieless="UseUri">
<!--<credentials passwordFormat="Clear">
<user name="john" password="password"/>
<user name="jane" password="password"/>
</credentials>-->
</forms>
</authentication>
<connectionStrings>
<add
name="iPortal"
connectionString="Persist
Security
Info=False;Integrated
Security=SSPI;database=iPortal;server=IP-0A74C61D\SQLEXPRESS;Connect Timeout=120" />
</connectionStrings>

The second part is to change the code that validates the credentials and this is done in
login.aspx.cs ASP.Net page code by adding new Authenticate method:
private bool Authenticate(string sUserName, string sPassword)
{
string sQuery = @"
SELECT COUNT(*)
FROM
Accounts
WHERE
userName = '{0}'
AND
passwordHASH = '{1}'
AND
isActive = 1
";
using(
SqlConnection
sqlConnection
=
new
SqlConnection(ConfigurationManager.ConnectionStrings["iPortal"].ConnectionString) )
{
sqlConnection.Open();
using (MD5 md5hash = MD5.Create())
{
using(SqlCommand sqlCommand = new SqlCommand(
String.Format(sQuery,
sUserName,
String.Join(String.Empty,
md5hash.ComputeHash(Encoding.UTF8.GetBytes(sPassword)).Select(cByte
=>
cByte.ToString("x2").ToUpper())) ),
sqlConnection) )
{
using ( SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
{
sqlDataReader.Read();
if (Convert.ToInt16(sqlDataReader.GetValue(0)) == 1)
{
return true;
}
}
}
}
}
return false;
}

63

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

protected void LoginButton_Click(object sender, EventArgs e)


{
if( Authenticate(UserName.Text, Password.Text) )
//FormsAuthentication.Authenticate(UserName.Text, Password.Text))
FormsAuthentication.RedirectFromLoginPage(UserName.Text, true);
else
FailureText.Text = "Invalid Login";
}

To publish the pages on a cloud instance to make them available in Internet there is couple
code

changes

required.

When

both

DevDefined.ExampleConsumerSite

and

DevDefined.ExampleProviderSite projects are published with MS IIS there are two additional
changes required.

Figure 31 iPortal and EnterprisePortal pools

One is trivial and is related to DevDefined.ExamplesConsumerSite Web.Config file


modification:
<ExampleConsumerSite.Properties.Settings>
<setting name="RequestTokenUrl" serializeAs="String">
<value>http://ec2-23-21-161-237.compute1.amazonaws.com/iPortal/GetRequestToken.aspx</value>
</setting>
<setting name="UserAuthorizationUrl" serializeAs="String">
<value>http://ec2-23-21-161-237.compute1.amazonaws.com/iPortal/UserAuthorize.aspx</value> </setting>
<setting name="AccessTokenUrl" serializeAs="String">
<value>http://ec2-23-21-161-237.compute1.amazonaws.com/iPortal/GetAccessToken.aspx</value>
</setting>
<setting name="DataUrl" serializeAs="String">
<value>http://ec2-23-21-161-237.compute-1.amazonaws.com/iPortal/Data.aspx</value>
</setting>
</ExampleConsumerSite.Properties.Settings>

The second one is also simple, however requires the project rebuilt. This change need to be
done in DevDefined.ExampleConsumerSite solution to OAuthPage.cs code file:
//string callBackUrl = "http://localhost:" + HttpContext.Current.Request.Url.Port + "/Callback.aspx";
string sCurrentPage = HttpContext.Current.Request.Url.AbsoluteUri;
string callBackUrl = sCurrentPage.Substring(0, sCurrentPage.LastIndexOf('/')) + "/Callback.aspx";

64

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

4.2.6. INTEGRATED WINDOWS AUTHENTICATION


The IWA settings can be easily enabled in ASP.Net using Web.Config files, however this
authentication should be only enforced on the client site. To see how the model can be scaled
we add additional line to the DevDefined.ExamplesConsumerSite Web.Config:
<configuration>
<system.web>
<identity impersonate="true" />
</system.web>
</configuration>

To extend the model to control access on the Resource Owner side with IWA the code has to
be

extended

on

both

sides,

iPortal

and

Enterprise

Portal

side.

On

the

DevDefined.ExamplesProviderSite the new page DataIWA.aspx.cs was created. The most


important part of the code validates Resource Owner Kerberos token security groups
membership.
protected void Page_Load(object sender, EventArgs e)
{
WindowsPrincipal oPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
if (oPrincipal.IsInRole("SecretDataAccess"))
{
Response.Clear();
Response.Write(GetContactsForUser("john"));
Response.End();
}
Response.StatusCode = 403;
Response.Write("Access Denied");
Response.End();
}

The part of the code that is on the client site is from DevDefined.ExamplesConsumerSite in
ViewData.aspx.cs. The example came with a small code error, which can be fixed with the
following code that properly handles OAuthException. Also the communication channel from
OAuth 1.0 needs to be replaced with IWA authentication:

65

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

try
{
if (((IToken)Session[accessTokenString]) != null)
{
session.AccessToken = ((IToken)Session[accessTokenString])
ConsumerKey = "fake", Token = "fake" };

??

new

TokenBase

try
{
string response = session.Request()
.Get()
.ForUrl(Settings.Default.DataUrl)
.SignWithToken()
.ReadBody();
xmlFeed.DocumentContent = response;
}
catch (OAuthException oauthEx)
{
ErrorInfo.Text
=
String.Format("Access
was
denied
to
resource:<br/>{0}<br/><br/>", oauthEx.Message);
}
}
else
{
string
sIWAuthentication
=
String.Format("{0}/DataIWA.aspx",
Settings.Default.DataUrl.Substring(0, Settings.Default.DataUrl.LastIndexOf('/')));
using
(HttpWebResponse
webResponse
(HttpWebResponse)WebRequest.Create(sIWAuthentication).GetResponse())
{
xmlFeed.DocumentContent = webResponse.ReadToEnd();
}
}
}
catch (WebException webEx)
{
var response = (HttpWebResponse)webEx.Response;

if (response.StatusCode == HttpStatusCode.Forbidden)
{
ShowOAuthProblemDetails(response);
}
else
{
ShowStatusCodeDetails(response);
}
}

4.3. CLIENT SIDE


4.3.1. CLOUD INSTANCE ACCESS
Because the iPortal and Enterprise Portal pages are published on the cloud server the client
can either access the portal from the Internet using http://ec2-23-21-161-237.compute1.amazonaws.com/EnterprisePortal/ address or access the portal locally from the cloud instance

66

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

server. To access the pages from the server more beneficial is using MS Visual Studio 2010 so
the authentication flow can be tracked using VS Debugger.

4.4. ACTIVE DIRECTORY PROVISIONING


The provisioning of the forest and all underlying objects was planned at the early stage of the
thesis and because the aims slightly evolved the provisioned structure is more advanced than it
is required to meet the current aims, however is very useful for all meta-directory specific tests.
4.4.1. AD FOREST
The Active Directory forest was provisioned from CLI using DCPROMO.EXE program
running in unattended mode with Provisioning_unattended.txt forest configuration file. The
provisioning file was preconfigured for this PoC, however does not introduce any specific
forest settings required for this prototype.
DCPROMO.exe /unattend:Provisioning_unattended.txt
; Usage:
;DCPROMO.exe /unattend:Provisioning_unattended.txt
;
[DCInstall]
ReplicaOrNewDomain=Domain
NewDomain=Forest
NewDomainDNSName=SpyraConsulting.net
ForestLevel=3
DomainNetbiosName=SPYRACONSULTING
DomainLevel=3
InstallDNS=Yes
ConfirmGc=Yes
CreateDNSDelegation=No
DatabasePath="C:\Windows\NTDS"
LogPath="C:\Windows\NTDS"
SYSVOLPath="C:\Windows\SYSVOL"
SafeModeAdminPassword=

4.4.2. DOMAIN STRUCTURE AND UNDERLYING OBJECTS


Complete domain structure with Organizational Units and security principal such as user
objects, group objects were provisioned using NT Shell script. Because this thesis had couple
major modifications regarding aims and objectives the provisioned AD structure is much more
complex than required. The complete NT Shell Provisioning.cmd script can be found in
Appendix J.

67

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 32 Active Directory Users and Computers console provisioned domain structure

4.5. META-DIRECTORY
4.5.1. IIDMANAGEMENT
4.5.1.1. Database installation

iIdManagement database should be created on the same MS SQL server instance as other
meta-directory components. The default database configuration that is pre-defined when using
Microsoft SQL Server Management Studio wizard is sufficient to build a working framework.
Scripts folder iIdManagement\sql_scripts contains SQL scripts required to create default
tables definition. The tables were provisioned using NT Shell command on the SQL server:
FOR /R %i In (tbl_*.sql) DO SQLCMD -S IP-0A74C61D\SQLEXPRESS -d iADConnector -i %i

68

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The successfully provisioned database should contain the following tables and columns:
Table Name
Identity

iLinking

iSource

iRule

iRuleDef

Column Name
pk_id
Surname
FirstName
MiddleName
Country
City
Description
fk_identityID
fk_iSourceID
fk_AccountID
fk_Account
pk_id
name
tableContext
description
ruleName
isActive
dtCreated
pk_id
fk_iRuleID
isExclusion
country
division
department
distingusishedName
dtCreated

Table 2 iIdManagement database tables

All stored procedures required by the prototype can be found in Appendix I or in the package
folders with SQL scripts required for DB provisioning.
4.5.2. IADCONNECTOR
The service is a milestone for this thesis and successful FIM implementation with Role-based
access control relies on the properly build model with meta-directory framework.
4.5.2.1. Database installation

Scripts folder iADConnector\sql_scripts contains database tables definitions. All scripts


prefixed with tbl_ are required to create DB schema for iADConnector. The successfully
provisioned database should contain tables and columns listed in Table 3. The tables were
provisioned

using

NT Shell

command

on

the

FOR /R %i In (tbl_*.sql) DO SQLCMD -S IP-0A74C61D\SQLEXPRESS -d iADConnector -i %i

69

SQL

server:

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics
Table Name
configuration

sync_control

user

contact

group

computer

membership

Zrich, 20 August. 2012

Column Name
DNSDomain
KeyName
KeyValue
Description
dcDNS
invocationID
highestCommittedUSN
domainName
tableContext
dtSynced
pk_id
objectGuid
sAMAccountName
distinguishedName
objectSid
cn
department
c
UAC_ACCOUNTDISABLE
pk_id
objectGuid
sAMAccountName
distinguishedName
objectSid
cn
department
c
UAC_ACCOUNTDISABLE
objectGuid
sAMAccountName
distinguishedName
objectSid
cn
description
objectGuid
sAMAccountName
distinguishedName
objectSid
cn
department
location
description
operatingSystem
group_dn
member_dn
group_cn
member_cn

Table 3 iADConnector database tables

4.5.2.2. XML configuration

The xml file is using default format for .Net ConfigurationManager namespace. It uses
AppSettings and ConnectionStrings sections utilizing simple key/value configuration
convention.
appSettings
Key
configuration
interval
schedule
firstrun

Value
Configuration
1
22:00
0

Mandatory/Optional
Mandatory
Mandatory
Optional
Optional

70

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics
connectionStrings
Key
iADConnector

Zrich, 20 August. 2012

Value
Persist Security Info=False;Integrated
Security=SSPI;database=iADConnector;server=IP0A74C61D\SQLEXPRESS;Connect Timeout=120

Mandatory/Optional
Mandatory

Table 4 XML configurations

*Configuration file iADConnector.exe.config is delivered as a package component.


4.5.2.3. iADConnector Database advanced configuration
DESCRIPTION
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default
Default

DNSDOMAIN

domain.net
domain.net
domain.net
domain.net
domain.net
domain.net
domain.net
domain.net

KEYNAME
ComputerEnumeration
ContactEnumeration
FspEnumeration
GroupEnumeration
MemberEnumeration
SecurityEnumeration
UserEnumeration
SyncControl
ComputerTable
ContactTable
FspTable
GroupTable
MembershipTable
SecurityTable
UserTable
NearSite

Default

domain.net

Password

Default

domain.net

User

KEYVALUE
1
1
1
1
1
-1
1
sync_control
computer
contact
fsp
group
membership
security
user
SITE_NAME
PW=nCSoT/ya8etDMKf1vDpXU
PaGdAtKBhX6uSec30T1mrb5RS
DIbwH9ooM
ID=aN4KEzh1yPxu8qL9UjP5cuv
zz/

MANDATORY/OPTIONAL
Optional
Optional
Optional
Optional
Optional
Optional
Optional
Mandatory
Optional
Optional
Optional
Optional
Optional
Optional
Optional
Optional
Optional

Table 5 Advanced service configuration

section where KeyName ends with *Enumeration enables/disables different types of enumeration;
value 1 states for enabled and works in intervals; value 0 states for enabled and works on
schedule; value -1 states for disabled enumeration

SyncControl KeyName column value specifies the location for synchronization meta-data

section where KeyName ends with *Table specifies the name of the table for specific enumeration
type

KeyName NearSite is MS AD enumeration specific parameter that specifies recommended site to


connect to for given domain

KeyName User and Password stores encrypted credentials for given domain

*Example configuration can be created using configuration.sql SQL script thats part of the
iADConnector package.
The service accounts should be properly permissioned over directory. There are MS AD
forest specific permissions which enable service to process deltas of changes and act as ReadOnly domain controller. These permissions can be set from CLI using following commands:

71

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

DSACLS "CN=Deleted Objects,DC=SpyraConsulting,DC=NET" /TakeOwnership


DSACLS "CN=Deleted Objects,DC=SpyraConsulting,DC=NET " /G SpyraConsulting\ADConnector:LCRP
DSACLS "CN=ForeignSecurityPrincipals,DC=SpyraConsulting,DC=NET " /G SpyraConsulting\ADConnector:LCRP

1.1.1.1. Service installation

Two service files iADConnector.exe and iADConnector.exe.config are delivered as a part of


the package. InstallService.cmd script under Scripts folder can be used to install iADConnector
as a Windows Service on the server. Please edit the script before use to adjust the paths to make
sure that service will be installed under correct location.

4.6. CONCLUSIONS
This chapter of the thesis covered the cloud-based implementation of all prototype
components. This implementation proves that the identity can be federated and controlled with
Role-based security via ABAC model (Section 2.4.2). Because it delivers very scalable FIM
framework that works across security boundaries it satisfies federated identity model described
in Section 2.2.3.
The delivered system authenticates the client and authorizes the resource access between
portals using OAuth 1.0 protocol (Section 2.3.2) or IWA (Section 2.3.1). The underlying
federated identity engine called iIdManagement recognizes identity for the account and based
on an ABAC match with the other account of this identity it decides, whether access can be
granted or should be denied. This is possible due to the underlying meta-directory that
normalize cross-account stores communication because of the SQL platform and framework
that is controlled with stored procedures. The iADConnector is responsible for account store
maintenance, which is inventoried from external directory source. It successfully handles
approximately 10k provisioned accounts what makes it suitable for enterprise implementations
what meets one of the thesis objectives. All of the above also show that the PoC
implementation meets all the functional requirements from High Level Design chapter.

72

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

5. EVALUATION
5.1. INTRODUCTION
The aim of this chapter is to test the model delivered with this thesis and to evaluate
technologies that this model use. Because the PoC covers wide scope of concepts related to
federated identity and IAM with Role-based security it actually addresses the most important
concerns related to security and authentication infrastructures. OAuth protocol is evaluated
together with IWA authentication. Tests will be carried out directly on the cloud instance and
also from the Internet to assess the two technologies and show how they scale across security
boundaries. Locally accessed portals represent access within single security boundary while
portals exposed as a cloud service belong to two different security boundaries. An evaluation
uses simple technical methods to clearly prove, which authentication and authorization methods
meet requirements related to security and federated identity concept.

5.2. METHODOLOGY
The PoC implementation and delivered framework give possibility to test different scenarios
where request it either approved and access granted to the resource or is not approved and
access is denied. Evaluation methods are grouped into simple categories that address the main
issues related to different technologies that are discussed in previous chapters:

Scalability across security boundaries

Reliable and consistent access control

Scalability across different platforms

The testing environment consists of two logical components front-end and back-end. The
front-end provides two links for two different authentication and authorization techniques
(see Figure 33). The object that is protected are Johns contacts. Clicking Click here button
for each of two selected technologies initializes authentication flows. Based on different initial
conditions access to the resource will be granted or denied. The only exception regarding initial
conditions is related to token expiration test, where access is withdrawn from the subjects
security entitlements.

73

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 33 Enterprise Portal welcome page

5.3. NEXT GENERATION VS TRADITIONAL AUTHENTICATION APPROACHES


5.3.1. WINDOWS INTEGRATED AUTHENTICATION
5.3.1.1. Scalability across security boundaries

Windows Integrated Authentication has its advantageous over other authentication methods
it actually gives access to resources that are in the same security boundary as the security
principal that claims access to these resources. Only successfully authenticated client, whether
it is a user or a computer can perform operations against the resource within Windows
Integrated Authentication environment. There are methods to enable security principal to claim
resource access from other than its own security boundary (here other Active Directory forest),
although this specific configuration of external trusts is normally made after enterprises legal
agreements so there is no risk that individual grants access over internal resources outside of
enterprises security boundary, which remains under Windows Integrated Authentication
infrastructure control.
The IWA test performed from within the development environment where only one security
boundary is available to authorize against the resource was successful (see Figure 34). The
same resource access attempt using IWA via portal opened from the cloud-based instance fails
(see Figure 35). In the first test Resource Owner and Identity Provider (iPortal) are sharing one
security boundary: SpyraConsulting.net forest. In the second test access to the resource is

74

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

denied because the Identity Provider is still in the AD forest boundary, while Resource Owner
is accessing IP from Internet.

Figure 34 IWA local test access granted

Figure 35 IWA cloud test access denied

5.3.1.2. Access control response to security entitlement changes

75

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

MS Active Directory security access token - shorter SAT, is created when user logs in into
the system and the token is valid for the time that the user is logged (Price, Price, &
Fenstermacher, 2008). If the user loses security permissions this is not automatically reflected
on

the

security

token.

MS AD

account

can

then

perform

actions

on

Windows Integrated Authentication enabled infrastructure and it also keeps access to resources
as the security identifier (objectSid) of the group that gives access to the resource is present in
the SAT which is tightly dependent on the users Windows session.
The object - protected resource access is secured with dedicated MS AD SecureDataAccess
security group. The Windows account that is used to access the resource is a member of this
group. Using IWA authentication the Kerberos token is checked for this security entitlement
and if the group is on the security token groups list user is granted the resource access (see
Figure 34).

Figure 36 IWA local test with Kerberos security token; user is a member of security group access granted

When we remove the user from the security group the access should be withdrawn, however
the default Kerberos ticket lifetime in MS AD is 10 hours (Walla, 2000), so the ticket remains
unchanged unless the lifetime elapsed or user logged off from the system (Price, Price, &
Fenstermacher, 2008).

76

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 37 IWA local test Resource Owner spyra removed from the security group

Even when the user was removed from the group the Kerberos ticket based authorization still
grants access to the resource and receives the same data set as in the previous local test
(see Figure 34). While debugging the code during Kerberos authorization (see Figure 38) it
shows that the group was not removed from the ticket and access is still valid.

Figure 38 IWA local test Kerberos ticket entitlements based on security groups memberships access granted

The access to the resource was withdrawn when the user was logged of from the Windows
session and when to SAT was deleted from memory (Price, Price, & Fenstermacher, 2008).
5.3.2. OAUTH
5.3.2.1. Scalability across security boundaries

OAuth protocol was created to control access to resources across different security
boundaries (Hammer E. , 2010). Its advantage over Integrated Windows authentication is its
77

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

scalability. Because the token can be securely send using HTTP the authentication system will
be able to control resource access even if the ticket need to be issued outside the domain of
Identity Provider (in our model MS AD forest). In our example the OAuth protocol to
authenticate Resource Owner uses username and password set. Because these credentials are
only provided on the IP side (iPortal API) the further actions required to obtain resource access
are secured.
The both tests, using local development environment and cloud-based service, resulted in
granted access to the resource. To access the object the Resource Owner is redirected to iPortal
to provide credentials: username john, password napier123 (see Figure 39).

Figure 39 OAuth cloud-based and local tests; Step1 - successfully redirected to IP for authentication

When RO is successfully authenticated with IP iPortal displays access control page so the
RO can decide whether issue the access token for the resource or decline the request
(see Figure 40).

78

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 40 OAuth cloud-based and local tests; Step2 access control page RO successfully authenticated

When access is granted by RO the security access token is released and client
(Enterprise Portal) receives protected resource data (see Figure 41).

Figure 41 OAuth cloud-based and local tests; Step3 access granted

5.3.2.2. Access control response to security entitlement changes

The OAuth protocol issues security access token per access request. This token has its
security context relevant to resource and RO. Unlike with IWA the security token has lifetime
property specific to this security context. This value can vary and because OAuth is not related

79

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

to any particular product the developer who implements OAuth infrastructure can decide how
to handle tokens lifetime. When IP issues the access token the resource can be access as long as
the ticket is valid.
Both resource access token leases timed out in one minute and when resource access was
claimed the access was denied.

Figure 42 OAuth cloud-based and local tests; token expired access denied

5.3.3. BRIEF SUMMARY


Test
Authentication within one
security boundary
Cross-security boundaries
authentication without
domains trust
Temporary access
enforcement

OAuth
passed

IWA
passed

Comments
none

passed

failed

none

passed

failed

OAuth delivers advanced access


control on access token level.
IWA uses access token properties
specific for the domain policies.
Access control model specific for
IWA implementations does not pass
the test.

Table 6 Authentication tests summary

5.4. RBAC & ABAC


5.4.1. ROLE-BASED ACCESS CONTROL SCALABILITY
Role-based security is independent from authentication system while access control model
based on specific technology like MS Active Directory can be used only within its security
80

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

boundary. Having identity independent from one authentication system we can control what the
identity is entitled to do across different platforms. Because Role-based security corresponds to
organization structure it does not easy scale outside the organization with internal
organizational rules. RBAC systems need a communication path to exchange identity role
information. This is where ABAC implementation can be used. Exposed part of internal
structure via ABAC from other organization can be used to enforce RBAC rules. Enough that
properly provisioned identity property corresponds to the organizational rule and the ABAC
engine can use this property to control access of the foreign identity.
To test this part of the model used OAuth and enforce RBAC control on Resource Owner.
The internal iPortal account store keeps RO credentials. iPortal accounts are linked using
iIdManagement (see Section 3.4.2.1) view of federated identity. This view was created using
stored procedures. Because iPortal accounts cannot provide sufficient information to uniquely
link identities with other account stores this process needs to be performed manually using
following commands:
--Register identites
EXEC iIdManagement.dbo.RegisterIDentity @Surname = 'Napier', @FirstName = 'John', @description='Scientist'
--Register iPortal accounts
EXEC dbo.LinkIdentityFromiPortal @Surname='Napier', @FirstName='John', @userName='john'

Because newly created identity view for John Napier has enough properties to match the
linking rule (see stored procedure in Appendix I) for iADConnector account store join the
existing identity view can be automatically joined with respective account from different
security boundary under one federated identity. The current view of the identity can be created
with custom SQL query:

81

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

SELECT

FROM

ID.FirstName as FI_FirstName,
ID.Surname as FI_Surname,
ID.[Description] as FI_Details,
ACC.userName as LO_userName,
ACC.[status] as LO_accountStatus,
USR.sAMAccountName as DS_userName,
ISNULL(USR.department,'') as DS_department,
CONVERT(varchar(20), GETDATE(), 120) as view_date
iIdManagement.dbo.iIdentity ID

JOIN
iIdManagement.dbo.iLinking LNK
ON
ID.pk_id = LNK.fk_iIdentityID
JOIN
iIdManagement.dbo.iLinking BLNK
ON
LNK.fk_iIdentityID = BLNK.fk_iIdentityID
JOIN
iPortal.dbo.Accounts ACC
ON

ACC.userName = LNK.fk_Account

JOIN
iADConnector.dbo.[user] USR
ON
USR.pk_id = BLNK.fk_AccountID

The return information about the federated identity will be compound of different properties
from inter-connected accounts that belong to different security boundaries.

Table 7 Current federated identity information

We see that only John Napier has active iPortal account, what is indicated with
LO_accountStatus column. This status is controlled with stored procedure (see Appendix I) and
iRule sets:
SELECT
RBAC.ruleName,
ISNULL(RBAC_DEF.country,'') as country,
ISNULL(RBAC_DEF.division, '') as division,
ISNULL(RBAC_DEF.department, '') as department,
CONVERT(varchar(20), RBAC_DEF.dtCreated, 120) as whenCreated
FROM
iIdManagement.dbo.iRule RBAC
JOIN
iIdManagement.dbo.iRuleDef RBAC_DEF
ON
RBAC.pk_id = RBAC_DEF.fk_iRuleID

82

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Table 8 Current ABAC rule set

The only entitled department over Resource is HR, and logon attempts with any other
accounts from other than HR departments return access denied message.

Figure 43 ABAC enforces RBAC rules and bill account cannot control the resource

When we add another department (see Table 9) to the rule we will see that ABAC engine
based on exposed attributes from one account repository activates iPortal accounts (see Table
10).

Table 9 Updated ABAC rule; added Legal & Risk department

Table 10 ABAC engine enforced RBAC rule based on new department in the rule scope

83

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Figure 44 ABAC enforces RBAC rules; OAuth access granted

5.4.2. BRIEF SUMMARY


Test
Enforce RBAC via ABAC outside
security boundary
Enforce RBAC via ABAC to control
access through federated identity
Integrate OAuth with RBAC to
authenticate using federated identity

REsult
passed

Comments
none

passed

none

passed

none

Table 11 federated identity framework test results

5.5. CONCLUSIONS
To make step with RBAC beyond federated identity there might be a need to introduce
public roles that are independent from an organization structure in the meaning that roles are
not native to the organization, however were implemented into the organization to support
model with unified roles that can go beyond organizational structure. Organizations from
various reasons mostly because of security concerns, do not want to expose internal structure to
either public or other organizations. These unified cross-federation roles might help to build
systems that utilize unified RBAC roles to grant access to resources based to group of identities
distinguished by role, which was introduced as a part of an internal RBAC system design.

84

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

To go further with this idea RBAC design can support cross-federation unified roles based on
attributes exposed on different identities via ABAC model implementation, where the ABAC
model based on identity provisioning corresponds to underlying organizational RBAC design.
E.g. specific set of identities from two organizations can be exposed from directories based on
the directory location and then matched to the unified roles using ABAC model where
identities with its attributes were provisioned to reflect organizational RBAC design.

85

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

7. CONCLUSIONS
7.1. OVERALL CONCLUSIONS
This thesis challenged the latest and the most important aspects of secure digital identity
authentication and authorization in era of cloud computing. The Research & Literature Review
section is fundamental for all further sections as it highlights what are the main components of
successful framework implementation that will federate the identity in the cloud under Rolebased security rules that consolidate with OAuth model. The delivered PoC satisfies IDaaS
cloud service requirements where effectively used directory as an enterprise identity store.
This first part of the thesis (Section 2.6) also carries out the critical review of the cloud
computing concept with implications for personal data protection under different governmental
jurisdictions. This highlights the conflict between benefits that come with cloud technology
itself and international law that tries to protect personal data (Section 2.6.1). This part uncovers
the weaknesses of the cloud computing and highlights what is the bottleneck of this technology
as for enterprises who care about reputation and customers trust personal data that can not be
securely held is not an option.
To prove findings from the first chapter custom IDaaS framework was designed that exposes
web-based interfaces for OAuth authentication required to evaluate underlying federated
identity processing including RBAC operations. To implement Role-based security
heterogeneous model was required to expose internal organizational roles outside to deliver
federated identity view what aligns with findings from Section 2.2.1, Section 2.2.3 and Section
2.4.2. The Integrated Windows authentication as a part of the design was selected to provide
backward compatibly with traditional authentication techniques. Before the design decisions
were made regarding IWA selection the first chapter (Section 2.3) helped to thoroughly analyse
constrains that addressed by next generation authentication infrastructures. Both Cloud-based
Implementation and Evaluation sections are compound and interfere together to deliver clear
findings and strictly technical results. These sections proves that the federated identity can be
effectively delivered as a complex enterprise framework which requires additional
customization to support Role-based security and enterprise directories. The OAuth as another
framework proved to be the suitable for cloud based implementations and perfectly matched
the underlying model as both resulted in successful evaluation of selected technologies.

86

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

The created model managed to authenticate and authorize identity with OAuth using
federated identity with Role-base security delivered as IDaaS cloud based solution.

7.2. FUTURE WORK


The delivered with this thesis OAuth model was dedicated to evaluation methods used. The
set of OAuth libraries from Eran Hammer requires thorough review before can be used for any
large implementation. Recently Microsoft released Windows Azure Authentication Library that
delivers

interfaces

for

OAuth

2.0

and

this

is

the

next

technology

next

to

Windows Azure Active Directory that is worth to evaluate with enterprise size implementation.
The delivered framework for federated identity management with Role-based security, which
supports several identity sources including LDAP directories is one of my personal
achievements and currently started working on complete framework that can be customized for
RBAC and ABAC models. There is many serious market players that deliver similar products
to end users, however the model delivered is not a ready product, it is a development
framework, which with several enhancements can be successfully deployed for SME sized
customers. This framework can be very attractive for LE sector, however the business model
that comes with development framework not often suits LE sized customers.
The concept that arises while working with thesis is that all RBAC and ABAC transactions
for security reasons can be hashed with native SQL functions that can deliver MD5 hashing.
This with a good overall design can be used to create a well-secured product with enhanced
internal integrity (see Section 3.10.2).

7.3. ISSUES
During the implementation phase many problems occurred with OAuth model examples
(see Appendix B). Because complete OAuth implementation of the client and the server side
requires OAuth libraries that are not part of the .Net Framework the model required the
complete set of libraries to be either created from scratch or downloaded from other developers
on open license terms. Many examples delivered with more generic or very examples specific
libraries did not work or did not meet the model requirements. The most suitable for the
prototype set of OAuth libraries and examples was delivered by Erran Hammer, as a
DevDefined source code.

87

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Recently several important events took place that are fundamental for the aims and
objectives of this thesis. This thesis responded to those changes as accurate as possible. This
aligns with the subject statement and proves that OAuth (see Appendix B) is a next generation
authentication technology. The most important fact was that one of the leading OAuth
founders and authors Eran Hammer at the 26th of July 2012 have published information that he
is leaving the project from IETF because of personal disappointment related to next release of
OAuth 2.0 that supposed to replace OAuth 1.0 and provide more complete model to the enduser. As per Erans statement OAuth 2.0 is much more complex than is predecessor although
was stripped from some security features that made the default implementation of OAuth 2.0
not well-secured (see Section 2.6.7) and not suitable for large enterprise anymore (Hammer E. ,
2010). This was one of the factors that caused changes to the further design and implementation
sections where instead of OAuth 2.0 libraries the previous version OAuth 1.0 was used.
The next fact is that when the PoC was created for this dissertation there was no official .Net
release of libraries for OAuth. At the 1st of August 2012, Vittorrio Bertocci from Microsoft
published information about official release of Windows Azure Authentication Library that
consists of several authentication interfaces including OAuth 2.0 authentication.

7.1. SELF APPRAISAL


This project was very challenging and actually it was the first time when I was working on
the technology that is evolving from day to day the way that is hard to make any final
statement. The OAuth protocol brings all the great concepts together, however since the project
was handed over to other people there seems to be a lot of inconsistences with OAuth 1.0 and
OAuth 2.0 specifications and many disappointments (see Appendix B). Personally I can not
wait to read more about first large enterprise scale successful OAuth implementations and to
find the note about found OAuth vulnerability in weekly SANS Institute The Consensus
Security Vulnerability Alert report.
To write this thesis I have reviewed several different Honours and Master projects from
different universities. Found that very often authors managed to write section by section what
was documented with thesis Diaries or with Gantt Charts. This thesis was created as one
project where besides the logically organized chapters all was evolving while writing it. E.g.
the findings from evaluation section had implications on the design and to deliver simple but

88

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

rigorous evaluation model was redesigning the prototype many types till it was mature enough
to satisfy the aims and objectives of this thesis.
To create a working cloud-based framework I used all the skills that I have gained during my
technical studies and years of professional work with directories. Because of the study field I
selected for my master studies I was able to look at this thesis from a different perspective. Not
only a technical one but also from the legal and risk perspective. The selected course gave me a
wider and better view on modern systems and problems that are behind IT in the 21st century.
The thesis from other author, Edinburgh Napier University student, were very relevant to the
subject of this thesis (Fernandez Sepulveda, 2008). He successfully compared different
authentication methods and delivered a good technical background for specific FIM
implementation. His work gave me an overview of what should be written about new
authentication techniques and federated identity. Since Fernandezs thesis many things have
changed, including OAuth which completely changed the view on authentication and
authorization systems.
There is much more I wanted to write here about what is related to information security but I
could not find the right place for it in the context and there was no time to go far from the
initial aims and objectives defined. I hope to have a chance in the future to write about the
latest method of making secure codes called Quantum Key Distribution (QKD) or about the Iris
scanning security vulnerability which allows unauthorized person to easily spoof the identity.

89

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

BIBLIOGRAPHY
Walla, M. (2000, May). Kerberos Explained. Windows 2000 Advantege , p. 1.
Windley, P. J. (2005). Digital Identity. Sebastopol, USA: O'Reilly Media.
Andersen, E. (2008, January). The X.500 Directory Standard: A Key Component of Identiy Management.
Telektronikk .
Arkills, B. (2003). LDAP Directories Explained: An Introduction and Analysis. Boston, MA, USA: Addison
Wesley.
Buchanan, W. (2010, March 14). Advanced Security and Network Forensics. Retrieved August 10, 2012
from Bill's Home Page: http://buchananweb.co.uk/unit06.pdf
Bertino, E., Martino, L., Paci, F., & Squicciarini, A. (2010). Security for Web Services and ServiceOriented Architectures. Heidelberg: Springer.
Bertocci, V. (2011). Programming Windows Identity Foundation. Redmond, Washington: Microsoft Press.
BlackBridge. (n.d.). BlackBridge. Retrieved 08 1, 2012 from Cloud Security -Enable Security and SSO in
the Cloud: http://www.blackbridge.it/radiant/cloudsecurity.html
Boeynaems, K. (2010, January 21). Pass-the-hash attacks: Tools and Mitigation. Retrieved August 4,
2012 from SANS: http://www.sans.org/reading_room/whitepapers/testing/pass-the-hash-attacks-toolsmitigation_33283
Deuby, S. (2011, March 9). Ease Cloud Security Concerns with Federated Identity. WindowsITPro , pp. 13.
De Clercq, J. (2004). Windows Server 2003 Security Infrastructures. Burlington, USA: Digital Press.
Desai, J., & Johnson, A. (2012, July 28). The truth about cloud security. (M. Benett, Interviewer)
http://www.on24.com.
Fernandez Sepulveda, A. J. (2008). Evaluation of Digital Identity using Windows CardSpace. Napier
University, School of Computing. Edinburgh: Napier University.
Ferraiolo, D. F., & Kuhn, R. D. (1992, Oct 13-16). Role-Based Access Controls. Gaithersburg, USA:
National Institute of Standards and Technology.
Information Commissioner's Office. (2010). Guide to data protection. Retrieved Aug 18, 2012 from ICO:
http://www.ico.gov.uk/for_organisations/data_protection/~/media/documents/library/Data_Protection/Pract
ical_application/THE_GUIDE_TO_DATA_PROTECTION.ashx
Hammer, E. E., Recordon, D., & Hardt, D. (2012, March 8). The OAuth 2.0 Authorization Protocol.
Retrieved July 20, 2012 from IETF Tools: http://tools.ietf.org/html/rfc5849
Hammer, E. (2010, May 15). OAuth. Retrieved July 21, 2012 from hueniverse:
http://hueniverse.com/oauth/
Lothian Buses. (2012, March 4). Term & Conditions. Edinburgh, United Kingdom: Lothian Buses.
Maples, W. (2008, August 2008). Active Directory database file NTDS.DIT. Retrieved July 14, 2012 from
WindowsNetworking.com:

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

http://www.windowsnetworking.com/kbase/windowstips/windows2000/admintips/activedirectory/activedire
ctorydatabasefilentds.dit.html
Mather, T., Kumaraswamy, S., & Latif, S. (2009). Cloud Security and Privacy. (M. Loukides, Ed.)
Sebastopol, USA: O'Reilly.
OConnor, A. C., & Loomis, R. J. (2010, December). 2010 Economic Analysis of Role-Based Access
Control. Gaithersburg,, USA: National Institute of Standards and Technology.
Pohlman, M. (2003). LDAP Metadirectory Provisioning Methodology. Lincoln, United States of America:
iUniverse, Inc.
Price, J. A., Price, B., & Fenstermacher, S. (2008). Mastering Active Directory for Windows Server 2008.
Indianapolis, Indiana, USA: Wiley Publishing, Inc.
Sandhu, R. S., Coyne, E. J., Feinstein, H. L., & Youman, C. E. (1996). Role-Based Access Control
Models. IEEE Computer , 29 (2), 38-47.
Sean, D. (2012, May 27). Microsoft Active Directory In The Cloud: Windows Azure Active Directory Is
Expanding Its Capabilities. Retrieved July 10, 2012 from Windows IT Pro:
http://www.windowsitpro.com/article/active-directory/microsoft-active-directory-cloud-windows-azureactive-directory-143222
Sosinsky, B. (2011). Cloud Computing Bible. Indianapolis, Indiana, USA: Wiley Publishing, Inc.

II

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

APPENDIXES
Appendix A

SUPERVISION

SUPERVISOR: PROF. WILLIAM BUCHANAN


START DATE: 28 MAY 2012
TECHNOLOGY RECOMMENDATIONS:

Evaluate OAuth implementation

Evaluate federated identity

LITERATURE REVIEW:

Recommended to find relevant academic materials

DOCUMENT MERITORAL CORRECTIONS

Focus on Aims and Objectives

Use only formal language

DOCUMENT CORRECTIONS:

Include referencing for used diagrams

Use relevant font and be consistent with fonts used in document

TECHNICAL CONSULTATIONS:

OAuth

Authentication and Authorization protocols

Federated Identity

Cloud-based services

OTHER ASSISTANCE:

Amazon EC2 cloud instance for academic use

Assistance with all cloud instance problems

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix B

Zrich, 20 August. 2012

DIARY

DIRECTORY VS DATABASE EVALUATION REPRIORITIZED


Initially the main objective was to evaluate a working authentication model with RBAC
security in the cloud and compare performance of specific operations on LDAP directory and
SQL based meta-directory. SAML based authentication was selected as the next generation
authentication model the most suitable for the aims and the objectives specified in the MSc
Dissertation Proposal. When gathered all materials for research section Prof. William
Buchanan recommended using OAuth authentication. After initial research around this
technology decided to focus more on the OAuth evaluation rather than concentrating only on
meta-directory models pros and cons. Because the newly selected authentication technology
brings a lot of new challenges and solves various authentication and authorization problems
that could not be fully addressed before, made a decision to give a new shape to this thesis and
use OAuth based authentication instead of SAML.
OAUTH IMPLEMENTATION
To perform initial tests with a client side used OAuthBase.cs class from Eran Sandler who
contributed a basic C# class that can be used to test the OAuth authentication against common
service providers such as Twitter, Goolge etc.
To develop complete set of OAuth libraries project would have to be stretched over another
couple of weeks. To make decisions on the design and implementation Alex Hendersons
DevDefined libraries and examples seemed to be perfect for this purpose. The OAuth libraries
developed by Alexs are the most complex and complete that can be found in the Internet,
although the examples supplied with libraries caused a lot of implementation problems.
First problems with OAuth model PoC were related to the set of provided libraries. Alexs
examples were returning error that access token has expired, although the access token was
released for no longer than 10 seconds. Two weekends were lost on finding the source of
problems and finally decided to recompile the libraries delivered with examples. Newly
compiled libraries were returning different error related to nonces. To solve this problem,
actually to create a workaround had to spent another two weekends. When this problem was
solved again the problem with expired tokens returned.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Having self-compiled libraries simplified all further debugging required to make the example
running.
Decided to test other set of complete OAuth libraries freely available in the Internet. Tony
Williams DOAP libraries did not compile due to MS Visual Studio conflicts.
Andrew Arnott delivers another examples with DotNetOpenAuth project. The advantage
over the previously tried server side libraries is that it supports the latest OAuth 2.0 version.
When started the project found that project was configured to use Virtual Directories and was
failing. After several tries managed to find the source of the issue and modify all project files to
load the solution with MS Visual Studio 2010, however loaded solution components did not
compile. Reviewed all the dependences of the project and managed to configure the IIS server
to work with DotNetOpenAuth solution. OAuth client example works without problems,
although server side example does not work and returns no errors.
Reconfigured OAuthAuthorizationServer code to use local instance of SQL server. Managed
to run the code with Goolge as an Identity Provider, however fails when try to use the Identity
Provider service delivered with an example.
Implementation of working example brings a lot of frustration because of the bugs that are in
the code that is officially available. Another frustrating factor is that Erran Hammer, one of the
founders of OAuth specification at the 26th of July 2012 has left IETF and the OAuth 2.0
project due to specification disappointment. He has listed serious functionality and security
concerns related with OAuth 2.0 release here: http://hueniverse.com/2012/07/oauth-2-0-andthe-road-to-hell/.
After reviewing Errans publication realized that he actually spotted very important points
that are subjects to serious security concerns. To actually benefit from all best features of
OAuth decided to try once again implementing DevDefined OAuth 1.0 libraries from Alex
Henderson. It took me one day to recompile the libraries and debug it with an example
delivered for these libraries. Managed to solve the problem with token has expired error by
modifying library. The token validation component was testing token expiry data against
current date. In case if the token object was initiated without expiry date constructor was
defining the datetime variable with minimal value allowed being set under datetime variable.
Added additional testing criteria where check if token expiry date is not equal with minimal
allowed datetime value.
C

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Having two working models one from Andrew Arnott and one from Alex Henderson could
select the best suitable one for the PoC that want to deliver.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix C

Zrich, 20 August. 2012

PROFESSIONAL RESEARCH

To find out the current trends in IT and recognize the demand of having OAuth like
authentication that is used in cloud computing based implementation with Role-based security
the several discussions were carried out.

CHRISTOPHER WESTPOINT (NEW YORK, USA) SENIOR IAM ARCHITECT


AT LEADING SWISS BANK; MAIL THREAD
From: Westpoint Christopher (INTERNAL DEP. NO)
Sent: Donnerstag, 28. Juni 2012 18:26
To: Spyra Gregory (INTERNAL DEP. NO)
Subject: Federated Identity
Hi Greg,
Heard that you were getting your Masters and thesis was on Federated Identity. I been involved with Identity Management
since 2001 and helped Microsoft develop their strategy. Im very interested in your ideas around Federation and Cloudbased identity solutions. I have dabbled in Federation with ADFS but have (strong) reservation around implementation.
Currently dont trust how security is handled.
What are your thoughts?
Lets discuss! J
CFrom: Spyra, Gregory
Sent: Friday, June 29, 2012 5:21 AM
To: Westpoint, Christopher
Subject: RE: Federated Identity
Hi Chris,
Im shocked J thats great I can talk to someone in my team about the FIM and ADFS.
As far as I can, I dont want to touch Azure as a ready cloud based MS product. There is a lot of open points for FIM,
especially related to two approaches with cloud based IPs where one has to be always online cause the token has a short
life-time (safer) and the other where token has a long life-time but its vulnerable to Man In The Middle attacks etc.
Im going to evaluate next generation cloud based authentication models in aspects of Patriot Act and DPA/Swiss Federal
Law. What are the risks if you place cloud based IP in locations not approved by European Information Commissioner etc.
Will also evaluate basic searching algorithms to proof that RBAC operations are more suitable for database while
authentication and authorization suit directory based algorithms.
Want to evaluate default implementations of cloud based authorization with FIM in LE (large enterprise) especially in
financial sectors and check if can provide sufficient security level. They may perfectly suit SOHO and SME but might be still
too immature for LE.
Do you have some publications/books/articles around FIM/ADSF product security evaluation?
Thanks J
Youre the boss,
Greg

Gregory Spyra
ZH

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

From: Westpoint, Christopher


Sent: Monday, July 02, 2012 10:53 AM
To: Spyra, Gregory
Subject: RE: Federated Identity
Of course J I live and breathe Identity Management.
The issue with FIM and ADFS is Microsoft never took identity management seriously. Identity management isnt a product
you can buy, its a process (that includes technology) that you develop and design. To Microsoft it was just another way to
penetrate their products into a customer base. For example, MIIS is not an identity management solution because it doesnt
cover access management, virtualization, federation, and the other tenets on IM. MIIS is simply a sync engine (one of the
most efficient out there) that can provision data or duplicate data across multiple data sources. All decisions had to be
made in code (provisioning.dll or MA.dll) and there was no error reporting (except trapping events and writing to a custom
text file), approval model, or easy notifications. I positioned MIIS as the base of IDM but other applications would have to
be built on top. I worked with other vendors such as Bhold and others (all acquired by larger tech companies) to paint a
more complete picture. My visions for an IDM built on SOA differed from the direction MS was going in (FIM product-based
solutions) so we parted ways and looked to implement my vision. I went to Goldman Sachs when my vision was validated
and implemented but cut short due to the crisis.
In the beginning back in 2000 all IDM was provisioning, thats how it started. Reducing cost by automating the creation of
identity. But that is a small piece when considering the entire lifecycle. Access Management is huge but also one of the
hardest tenets to implement today, simply because of the way Microsoft in particular handles security. Identity security is
centralized on the KDC, easy to manage. Access security is distributed and handled on the endpoints. To date, there is no
comprehensive solution that can aggregate what a particular identity has access to across an enterprise. This started to
heat up around 2004 as we tried to figure out what was the best way to handle. This is when RBAC became a hot word and
was introduced. I can tell you stories of 2-3 month Role Engineering engagements I did. The constant issue I ran into was
two fold. One, no one was ever able to create an enterprise role model that fit every scenario. Two, even if one was
developed by the time it was to be implemented it was out-of-date. Then organizations became fractured where App
Development took RBAC into their own hands, using things like Authorization Manager.
Federation solves an interesting issue.
If you wanted someone from one forest/environment to access
application/resources in another forest/environment you had to create a persistent connection, such as a trust. But when
the environments are two separate companies sometimes this wasnt possible. The other way to handle was the use of
shadow accounts, where you duplicate the account from one company to the other, and the user has to remember two
passwords. Managing password resets, account changes, Deprovisioning becomes difficult in that scenario. I have hopes
for Federation as I believe it could be used as the internal access management model. Where all applications are claimsaware. It removes the dependency of being tied to AD (Any SAML-based application could be used), allows for a
centralized policy store (no more crawling all endpoints), and assertions allow for more fine-grained control (i.e. - I can set
access based on dynamic values such as Where you live, who you are), as well as increase security for sensitive materials (i.e
- access to this share requires Kerberos plus biometrics or smartcard, while others can use just Kerberos). Still working this
out as Im not sure if MS is going to continue with their strategy of making ADFS a part of AD. Was supposed to be in
Blackcomb which by release would have been 2008. Perhaps Windows 8? Well see.
Cloud still sounds like an industry buzz word. Something people are excited about but havent really fleshed out its
functionality. All the big tech players are pulling hard for Cloud services. Microsoft started with BPOS which was Exchange
Online services. Essentially your Exchange server is in the cloud. When I was looking at the architecture they had an MIIS
component (IIFP) that would synchronize user information from the internal environment up into the cloud. Again it was
policy issues that provided the challenge. When everything is shared in the cloud how do you handle custom/specific
policies for say like a bank. For example we need to journal every email that comes in and out and seclude Research from
communicating with Investment banking as well as a slew of other rules. How does one control that information for their
partition in the cloud but not anyone else.
I wouldnt put my data in the cloud today because I dont trust the services of the provider to meet my SLAs. What happens
if you lose my sensitive data? Or worse, what happens when someone steals my sensitive data from your off-site? How do
you price that? I can do security better on-site than trusting someone to handle it off-site. Cloud services themselves sound
great, but how does a provider guarantee the security of the information they are brokering, and better yet how can you
validate it. All providers say security is protected but if I dont see the facilities, or how operations are handled or by who
how can I trust it?
From my perspective Im interested in how security is handled to cloud-based services and what options they have as well as
how they are technically handled.
Looking forward to continue this conversation.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Ask away
Christopher Westpoint
NY

From: Westpoint Christopher (INTERNAL DEP.NO)


Sent: Montag, 2. Juli 2012 16:53
To: Spyra Gregory (INTERNAL DEP.NO)
Subject: RE: Federated Identity
Of course J I live and breathe Identity Management.
The issue with FIM and ADFS is Microsoft never took identity management seriously. Identity management isnt a product
you can buy, its a process (that includes technology) that you develop and design. To Microsoft it was just another way to
penetrate their products into a customer base. For example, MIIS is not an identity management solution because it doesnt
cover access management, virtualization, federation, and the other tenets on IM. MIIS is simply a sync engine (one of the
most efficient out there) that can provision data or duplicate data across multiple data sources. All decisions had to be
made in code (provisioning.dll or MA.dll) and there was no error reporting (except trapping events and writing to a custom
text file), approval model, or easy notifications. I positioned MIIS as the base of IDM but other applications would have to
be built on top. I worked with other vendors such as Bhold and others (all acquired by larger tech companies) to paint a
more complete picture. My visions for an IDM built on SOA differed from the direction MS was going in (FIM product-based
solutions) so we parted ways and looked to implement my vision. I went to Goldman Sachs when my vision was validated
and implemented but cut short due to the crisis.
In the beginning back in 2000 all IDM was provisioning, thats how it started. Reducing cost by automating the creation of
identity. But that is a small piece when considering the entire lifecycle. Access Management is huge but also one of the
hardest tenets to implement today, simply because of the way Microsoft in particular handles security. Identity security is
centralized on the KDC, easy to manage. Access security is distributed and handled on the endpoints. To date, there is no
comprehensive solution that can aggregate what a particular identity has access to across an enterprise. This started to
heat up around 2004 as we tried to figure out what was the best way to handle. This is when RBAC became a hot word and
was introduced. I can tell you stories of 2-3 month Role Engineering engagements I did. The constant issue I ran into was
two fold. One, no one was ever able to create an enterprise role model that fit every scenario. Two, even if one was
developed by the time it was to be implemented it was out-of-date. Then organizations became fractured where App
Development took RBAC into their own hands, using things like Authorization Manager.
Federation solves an interesting issue.
If you wanted someone from one forest/environment to access
application/resources in another forest/environment you had to create a persistent connection, such as a trust. But when
the environments are two separate companies sometimes this wasnt possible. The other way to handle was the use of
shadow accounts, where you duplicate the account from one company to the other, and the user has to remember two
passwords. Managing password resets, account changes, Deprovisioning becomes difficult in that scenario. I have hopes
for Federation as I believe it could be used as the internal access management model. Where all applications are claimsaware. It removes the dependency of being tied to AD (Any SAML-based application could be used), allows for a
centralized policy store (no more crawling all endpoints), and assertions allow for more fine-grained control (i.e. - I can set
access based on dynamic values such as Where you live, who you are), as well as increase security for sensitive materials (i.e
- access to this share requires Kerberos plus biometrics or smartcard, while others can use just Kerberos). Still working this
out as Im not sure if MS is going to continue with their strategy of making ADFS a part of AD. Was supposed to be in
Blackcomb which by release would have been 2008. Perhaps Windows 8? Well see.
Cloud still sounds like an industry buzz word. Something people are excited about but havent really fleshed out its
functionality. All the big tech players are pulling hard for Cloud services. Microsoft started with BPOS which was Exchange
Online services. Essentially your Exchange server is in the cloud. When I was looking at the architecture they had an MIIS
component (IIFP) that would synchronize user information from the internal environment up into the cloud. Again it was
policy issues that provided the challenge. When everything is shared in the cloud how do you handle custom/specific
policies for say like a bank. For example we need to journal every email that comes in and out and seclude Research from
communicating with Investment banking as well as a slew of other rules. How does one control that information for their
partition in the cloud but not anyone else.
I wouldnt put my data in the cloud today because I dont trust the services of the provider to meet my SLAs. What happens
if you lose my sensitive data? Or worse, what happens when someone steals my sensitive data from your off-site? How do
you price that? I can do security better on-site than trusting someone to handle it off-site. Cloud services themselves sound
great, but how does a provider guarantee the security of the information they are brokering, and better yet how can you
validate it. All providers say security is protected but if I dont see the facilities, or how operations are handled or by who
how can I trust it?

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

From my perspective Im interested in how security is handled to cloud-based services and what options they have as well as
how they are technically handled.
Looking forward to continue this conversation.
Ask away
Christopher Westpoint
NY

From: Westpoint Christopher (INTERNAL DEP.NO)


Sent: Montag, 16. Juli 2012 18:00
To: Spyra Gregory (INTERNAL DEP.NO)
Subject: RE: Federated Identity
I know this is on your agenda to respond J
Directory)

But am currently doing some research on WAAD (Windows Azure Active

Essentially Microsoft is extending AD into the cloud (nothing new, been extending AD into the DMZ for years) but in this
instance they handle the shadow accounts with federation principles (tying the objects together via a token secured by a
selected authentication mechanism, most likely Kerberos auth). Still trying to understand how it ties in with other Relying
Parties but interesting none-the-less.
A great question for your thesis -- What should/has to be done in order to call a cloud solution secure and how does one
manage privacy concerns (you will have a bunch of cloud engineers managing your data - whats to stop them from
using/reading it? Altruism? Legal contract?)
Federated Identity is the next big thing ;-)
Christopher Westpoint
NY

From: Spyra, Gregory


Sent: Monday, July 16, 2012 2:03 PM
To: Westpoint, Christopher
Subject: RE: Federated Identity
Hi Chris,
Nice bunch of questions, especially as was recently reading about WA AD.
Found that it might be worth to go this direction in financial sector only if we do partial sync (not all AD objects and
properties). The most important concern is actually very simple and not related to WA AD itself but to the cloud nature.
Data is not necessary kept under OECD regulations jurisdiction (not mentioning Swiss Federal law which is in many cases
more restrictive) so in case when US government under Patriot act request access to CS data from lets say Microsoft, if the
data is stored on US servers it means that US gov can get usernames. It cannot be used straight forward as AD accounts are
useless without passwords, however if someone has more time can use this as very successful data access reconnaissance
method which can lead to customer data access.
Its not Microsoft who will lose customer trust.
Im thinking about another thing. We actually have one forest and all data is synced across countries. The only thing that
keeps the data safe is that there is a corporate law that protects that data. What if this data will be on Microsoft servers?
Dont think we are under US Safe Harbour but we still have our CS legal protection.
Microsoft can promise that they will not access our data but they cannot promise that other governments will not do that.
Its not easy to compromise AD security having username and hash of the password but it is still possible.
I would say that at the current Federated Identity stage or would say current Identity as a Service (IDaaS) in cloud stage
we can safely provide selective access to services rather than to data itself.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

I think enterprise AD transition into cloud should be only partial as long as all regulations regarding cloud data are not
clear, and as long as next generation authentication methods are still fresh and mostly having more academic than
enterprise character.
I know quite a few AD bugs and Im bloody scarred when I imagine that I put our AD into public network area.
Do you know what are Azure AD security features that:
1. are implemented at the network level in order to restrict IP pool that can access the instance?
2.

are implemented at most of the system layers that protect against DoS or DDoS attack?

3.
Is there any set of recommendations regarding AD structure/configuration that will be implemented into the cloud
(many AD vulnerabilities now have a very low risk due to internal network facing, what when facing public).

Regarding your previous email, we plan to go into Federated Identity and would be nice to be ready for the cloud but
internally we still dont have Federated Identity model. We have so many different systems and even if they query AD to
validate user information, it often uses home-grown authentication model that has nothing to do with secure
authentication methods we want to use in the cloud. E.g. several times someone came to me telling that the naming
convention doesnt match their system as they read user CN and check the password stored locally in some custom
application server DB.
1.
If I would go into the FIM I say lets go but we need to centralize authentication to have the homogeneous
authentication infrastructure.
2.

If I would go into the WAAD I say lets go but see point 1.

3.
Would you like to get rid of AD at some point as SAML doesnt actually require any directory or did you mean that you
would rather use SAML to replace Windows Integrated Authentication model?
Thanks J
Greg
Gregory Spyra
ZH

From: Westpoint Christopher (INTERNAL DEP.NO)


Sent: Dienstag, 17. Juli 2012 20:34
To: Spyra Gregory (INTERNAL DEP.NO)
Subject: RE: Federated Identity
Very interesting conversation. Is data protected depending on the location of the physical storage? (If I have Swiss data
physically on US servers - can US government access it?) Or is it protected by the cloud service operator?
Anything is possible ;-) Its the probability of that possibility that I think about.
I agree, but I would say thats how IDM itself (internal context) is *supposed* to work. Nobody should have or require
direct access to data. Define the identity, add the identity to the appropriate roles and grant access to the roles (not the
identity).
Agreed, I think we should only extend identity into the cloud *IF* you fully understand the extent of which the identity will
be used (to evaluate potential risk).
1.
Doubt they do anything like that today - but could be implemented via IPSec. Getting the appropriate certificates
distributed could be messy considering we would need a trusted CA.

2.
Doubt there is anything to stop a DDoS attack. If you think about it, there is nothing to stop it from internal AD.
There are multiple (easy) ways to take AD out. 1) write a script that adds users to over 500+ groups blowing out the token.
The DC wont log you on. MS fix was dont add people to that many groups J Second, overload the DNS servers - no SRV

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

record access no DC. Now Internet Providers probably have internal or 3rd party ways to stop this but not aware of the
details of how they work. Probably some type of service looking for a specific pattern (maybe like x number of requests
from host y within time z).

3.

Great question.

This is still in its infancy, but believe they assume security would be handled/maintained by the STS. Remember you get
access to the AAD via a token (not interactive password/etc). Someone would have to intercept the token, be able to open
it, expand the assertions, make a change, sign it (correctly), put it back in the token and then send it back -- all in order to
gain access. The fact that the person is not handling the authentication (by inputting a known identity value - such as
password) makes the request/process a *bit* more secure.
Assertions are the future in my book. It gives you centralized policy and allows flexibility of fine-grained access.
Another question I wonder about is, lets say we federate with a partner or other B2B communication. When they receive
our token they use the assertions to evaluate claims-aware access. What is someone started collecting the assertions from
the token to develop a profile of the source company. As a federated partner I can ask for attributes which may not be
sensitive, but may allow me to derive information -- or perhaps sell to others.
Since information is becoming the valuable commodity and since it is in essence abstract (though has a physical instance
component) - how do you protect it? Especially when it can be duplicated granting both parties involved with a copy.
I look at the Movie industry as an example. Once a movie is distributed from the Distributor there is absolutely no way they
can prevent that distribution from getting out of their channels. So for example there are movies where US rules state must
be banned (See Faces of Death) -- yet due to the fact that information is duplicated I can easily get this within the US
(bypassing the laws).
Laws have to be updated to meet the changes that digital information introduces, but it has to be fair and respect privacy.
For example, the US shouldnt be able to tell me what I am able to see or not see. Thats censorship.
We have to be careful what information we put out there about ourselves because no we have the tools to cobble and
correlate random bits into a bigger picture, perhaps providing information we consciously wouldnt allow to be used as a
whole, but obliviously to the information we give when we sign-up for social media. More is going on behind the scenes
than the public is privy too.
Christopher Westpoint
NY

Spyra Gregory (INTERNAL DEP.NO)


23. Jul (vor 6 Tagen)
an mich
Englisch
Deutsch Nachricht bersetzen
Deaktivieren fr: Englisch
Gregory Spyra
ZH

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

CHRISTOPHER WESTPOINT (NEW YORK, USA) SENIOR IAM ARCHITECT


AT LEADING SWISS BANK; MS LYNC OFFICE COMMUNICATOR THREAD
Spyra Gregory (INTERNAL DEP. NO) [17:53]:
let me go to a quick question
don't you mind if I cite your mail regarding FIM...?
Westpoint Christopher (INTERNAL DEP. NO) [17:54]:
Sure - its my opinion though :D
LOL
or better to say my perspective
Spyra Gregory (INTERNAL DEP. NO) [17:57]:
I actually need some opinins and hate doing questionnaires and it's one of the deliverables during MSc thesis
Westpoint Christopher (INTERNAL DEP. NO) [17:58]:
Of course you can quote me
Come back for me if you need
Spyra Gregory (INTERNAL DEP. NO) [17:58]:
I reply to you when have time.. it's a great thread. Now quite busy as Luigi is on holiday
Westpoint Christopher (INTERNAL DEP. NO) [17:58]:
can talk about this stuff all day
Spyra Gregory (INTERNAL DEP. NO) [17:58]:
yep.. what about oAuth, are you fancy?
Westpoint Christopher (INTERNAL DEP. NO) [17:58]:
completely understand... I am interested/passionate in topic as well
I love the fact that it is 'open' in the sense there is no standard and its being developed as we speak
Spyra Gregory (INTERNAL DEP. NO) [17:59]:
actually it took them years to build it
:D
Westpoint Christopher (INTERNAL DEP. NO) [17:59]:
Need to do some research on oAuth - which I can happily do if you want me to opine on it
Well you know what I mean... defining the standards for federation and federated identity (its a natural evolution of IDM)
Spyra Gregory (INTERNAL DEP. NO) [18:00]:
exactly
Westpoint Christopher (INTERNAL DEP. NO) [18:00]:
:)
Spyra Gregory (INTERNAL DEP. NO) [18:00]:
however we cannot ignore the biggest identity players on the market
like google, facebook etc
Westpoint Christopher (INTERNAL DEP. NO) [18:01]:
My key principles are how is security handled when credentials or sensitive assertions are passed between public entities
Spyra Gregory (INTERNAL DEP. NO) [18:01]:
that's the key
Westpoint Christopher (INTERNAL DEP. NO) [18:01]:
Its one thing when we pass messages internally - we can sniff, protect, understand kerberos etc
But how do you manage the transport over the internet and guarentee security?
Spyra Gregory (INTERNAL DEP. NO) [18:02]:
ha
Westpoint Christopher (INTERNAL DEP. NO) [18:02]:

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Thats why I refuse to go on social sites (Im not on facebook, twitter, instagram, etc)
Spyra Gregory (INTERNAL DEP. NO) [18:02]:
I would say we stuck with Windows Integrated Authentication models for enterprises
Westpoint Christopher (INTERNAL DEP. NO) [18:02]:
yeah, thats the best - but for enterrpise we have to break authN from authZ
Spyra Gregory (INTERNAL DEP. NO) [18:02]:
because before we authenticate there are some pre-requisites we have to meet
yes
Westpoint Christopher (INTERNAL DEP. NO) [18:03]:
access policy should be centralized and customized to the scenario
Spyra Gregory (INTERNAL DEP. NO) [18:03]:
I was actually thinking about what you're saying for the last couple days
Westpoint Christopher (INTERNAL DEP. NO) [18:03]:
for example, who I am (Chris Westpoint) should be separate to what I have access to
and what I have access to should be determined by what I am accessing bringing in other variables such as sensitivity, time,
location, etc
(If chris is NOT in New York, and its between the hours of 8-5pm EST do NOT allow access)
Or - if I access my files I only have to provide password level security - but if I want to access HR data for IDM processes I
have to perform dual-factor auth
Today its up to each app owner to develop this - when it should be defined at the enterprise level
Spyra Gregory (INTERNAL DEP. NO) [18:05]:
this is the global problem, applications derive your permissions based on what you know rather than who you are
Westpoint Christopher (INTERNAL DEP. NO) [18:05]:
yup! :D
Spyra Gregory (INTERNAL DEP. NO) [18:06]:
and have no centralized identity
Westpoint Christopher (INTERNAL DEP. NO) [18:06]:
When I was at the Directory Experts Conference (DEC) in California in 2010 thats what I asked the 'experts'
Spyra Gregory (INTERNAL DEP. NO) [18:06]:
what did they answer
?
Westpoint Christopher (INTERNAL DEP. NO) [18:06]:
How do I handle authroization. And no one had a decent answer
MSFT has something custom but they dont believe in it enough to release to the public. Spoke to the Ops friends at MS and
they say its bloated and it sucks :)
Spoke to David Mowers (ex-MSFT) who was creating a new authorization type model
but when I picked his brain he was just using specific unused attributes in the PAC to convey access information
Again it works, but tightly integrated with MS implementation of Kerberos
AuthZ model has to be agnostic since not everyone in the world uses windows
Thats when I knew it was a valid problem and would need discussion/investigation/research to fix
Spyra Gregory (INTERNAL DEP. NO) [18:09]:
the problem with beloved Kerberos is that the SAT doesn't expire and is valid during whole user session.
another problem is that there is no direct way of rights delegation and in order to give access over resourced to the user
you need to actually add the user to the group
Westpoint Christopher (INTERNAL DEP. NO) [18:10]:
Yes, and as we know with TPA even when revoked you cannot KILL the ticket
Spyra Gregory (INTERNAL DEP. NO) [18:10]:
exactly
Westpoint Christopher (INTERNAL DEP. NO) [18:10]:
yup

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Spyra Gregory (INTERNAL DEP. NO) [18:11]:


you would like oAuth
Westpoint Christopher (INTERNAL DEP. NO) [18:11]:
The whole group-ACL-membership model wont work in a distributed environment
Spyra Gregory (INTERNAL DEP. NO) [18:11]:
it's password/username -less authorization model where token actually expires
Westpoint Christopher (INTERNAL DEP. NO) [18:11]:
If you have any good links for Oauth please pass to me -- I want to analyze to see what it does
Spyra Gregory (INTERNAL DEP. NO) [18:11]:
can quickly give you an overview over it's benefits
Westpoint Christopher (INTERNAL DEP. NO) [18:11]:
WAAD makes mention of it as well and I need to get back into my research mode :)
Spyra Gregory (INTERNAL DEP. NO) [18:12]:
yes but there is no actual implementation of oAuth in WIF
Westpoint Christopher (INTERNAL DEP. NO) [18:12]:
Not even support??
interesting
Spyra Gregory (INTERNAL DEP. NO) [18:12]:
so Bertocci added it to WAAD but I guess from business perspectives it wasn't strategic to add it to WIF
Westpoint Christopher (INTERNAL DEP. NO) [18:12]:
See behind the scenes there is also vendor play
Each vendor wants to be the 'open' standard so they can effectively influence the rules
Nope. Windows is always about support for Windows
Spyra Gregory (INTERNAL DEP. NO) [18:13]:
Kerberos is kind of "two legged" authentication while oAuth is 2+
Westpoint Christopher (INTERNAL DEP. NO) [18:13]:
everything else is just lip service to play nice
Spyra Gregory (INTERNAL DEP. NO) [18:13]:
yes
Westpoint Christopher (INTERNAL DEP. NO) [18:13]:
interesting
I feel if MS doesnt seriously decouple their model people will put an abstraction layer on top
Spyra Gregory (INTERNAL DEP. NO) [18:14]:
it is.. so there are other actors in the oAUth authentication than in Kerberos
Westpoint Christopher (INTERNAL DEP. NO) [18:14]:
marginalizing their influence
Spyra Gregory (INTERNAL DEP. NO) [18:14]:
yes
I found some nice . Net implementation of Client-Server libraries and it was created liaise with MIT
there is a plenty of other programming languages implementations and are much more mature than the .Net one
Westpoint Christopher (INTERNAL DEP. NO) [18:15]:
.NET leveraging MIT Kerberos information
?
Thats MSFT Achilles heel... too MSFT centric
They need to be like google - more abstract
Spyra Gregory (INTERNAL DEP. NO) [18:15]:
yes

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

I fully agree
Westpoint Christopher (INTERNAL DEP. NO) [18:16]:
thats why I left... I just didnt want to be the MS IDM guy
Spyra Gregory (INTERNAL DEP. NO) [18:16]:
:D
Westpoint Christopher (INTERNAL DEP. NO) [18:16]:
I wanted to be THE IDM guy - agnostic to product
Spyra Gregory (INTERNAL DEP. NO) [18:16]:
haha
Westpoint Christopher (INTERNAL DEP. NO) [18:18]:
My goal here is to make the best IDM solution on the street
to the point that the other banks follow what we do
I know the directory/IDM guys at GS, Morgan, Chase, and Citi
they dont have anything on us ;)
Spyra Gregory (INTERNAL DEP. NO) [18:20]:
Would be cool. First need EID guys to actually empower the meta-directory they build .. There is a couple small gaps to fill
in.
Trust me, oAuth is suitable for LE and it can align with RBAC/ABAC model and even beyond it.
you have 3 actors in oAuth
you have a client, resource owner, SP
the tricky part is that client asks SP on behalf of resource owner to get access to the resource
normally in other authentication scenarios client is either added to the SP and permissioned over the resource or it acts as
a resource owner
the second one is mostly dangerous as this is where many implementations accept username/password exchange with the
client
oAuth solves that in a magic way
Westpoint Christopher (INTERNAL DEP. NO) [18:24]:
agreed on the gaps
need to make the product easily extensible
Spyra Gregory (INTERNAL DEP. NO) [18:24]:
client contacts SP on resource owner behalf then owner needs to put a username/password but on the SP site what's effect
of client redirection.
Westpoint Christopher (INTERNAL DEP. NO) [18:24]:
adding the cs attributes is a complete chore
Spyra Gregory (INTERNAL DEP. NO) [18:25]:
resource owner provides u/p securely and then the magic happens..
Westpoint Christopher (INTERNAL DEP. NO) [18:25]:
SP = Service Provider
Spyra Gregory (INTERNAL DEP. NO) [18:25]:
:D
Westpoint Christopher (INTERNAL DEP. NO) [18:25]:
?
Spyra Gregory (INTERNAL DEP. NO) [18:25]:
yep
Westpoint Christopher (INTERNAL DEP. NO) [18:25]:
Hell, Ill have questions for you!
Spyra Gregory (INTERNAL DEP. NO) [18:25]:
I love this.. know other auth models and am inloved in this one

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Westpoint Christopher (INTERNAL DEP. NO) [18:25]:


I find it easier to learn from someone who knows faster than from a book/website
Its the passion that will make you successful
Spyra Gregory (INTERNAL DEP. NO) [18:26]:
and the magic is that it supports both HTTP and HTTPS
in secure way
Westpoint Christopher (INTERNAL DEP. NO) [18:26]:
We can work together to make the model
You can do the development - I can define the requirements and architect the flow
Westpoint Christopher (INTERNAL DEP. NO) [18:27]:
I want to build a federated identity model that is pratical and flexible
Spyra Gregory (INTERNAL DEP. NO) [18:28]:
you can encapsulate PKI with oAuth
Westpoint Christopher (INTERNAL DEP. NO) [18:28]:
high level principles - authN must be mutually exclusive from AuthZ
Spyra Gregory (INTERNAL DEP. NO) [18:28]:
you can do magic and control your FIM scope not with WIA but with PKI
Westpoint Christopher (INTERNAL DEP. NO) [18:28]:
AuthZ should be flexible
Spyra Gregory (INTERNAL DEP. NO) [18:28]:
and then apply oAuth :D
Westpoint Christopher (INTERNAL DEP. NO) [18:28]:
AuthZ policy should be reached centrally
Spyra Gregory (INTERNAL DEP. NO) [18:28]:
it is very
Westpoint Christopher (INTERNAL DEP. NO) [18:29]:
Im going to read about oAuth and then ask you a zillion questions 8-|
Westpoint Christopher (INTERNAL DEP. NO) [18:36]:
The point is if you have a model, you should be able to transition to whatever technology is relevant at the moment
the rest is just implementation
Spyra Gregory (INTERNAL DEP. NO) [18:36]:
I was rather thinking about co-existence phase
Westpoint Christopher (INTERNAL DEP. NO) [18:37]:
how would it work?
Spyra Gregory (INTERNAL DEP. NO) [18:37]:
so was creating rather transactions to roll-out tokens
and authentication model that supports the co-existence
Westpoint Christopher (INTERNAL DEP. NO) [18:37]:
and how would you introduce it to an existing ecosystem
Spyra Gregory (INTERNAL DEP. NO) [18:38]:
just start releasing oAuth tokens and change the way the internal pages interact
support both
Westpoint Christopher (INTERNAL DEP. NO) [18:38]:
ok- get me on your page :) Are we talking about federated identity and Auth Z models using oAuth right now?
Spyra Gregory (INTERNAL DEP. NO) [18:38]:
but with a pressure on oAuth

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

yes
Westpoint Christopher (INTERNAL DEP. NO) [18:38]:
ok. perfect
Who developed oAuth? (major contributors?)
Spyra Gregory (INTERNAL DEP. NO) [18:38]:
but the page will be ready when I finish designing supporting DB structures
Westpoint Christopher (INTERNAL DEP. NO) [18:38]:
individuals or vendors?
Spyra Gregory (INTERNAL DEP. NO) [18:39]:
Individuals

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

MAITANE ZOTES RESINES (GENEVA, SWITZERLAND)


SECURITY SPECIALIST AT CERN; GTALK CONVERSATION
Ich:
19:30
looking for something about cloud security in terms of data protection
you know the data is stored not always where we expect it to be
in US jurisdiction for example
19:31
Maitane: you mean sth for assuring u that the data is were it is supposed to be?
Ich: yes
5 Minuten
19:36
Maitane: looks interesting
at CERN we are working with different clouds
19:37
and also a security issue that we have
Is how to authenticate users against the cloud
because we use Kerberos tickets, and we still have not think about how to put them together
19:38
Ich: have you considered WAAD?
19:39
Maitane: I never heard of it
Ich: it's a mint MS cloud service that provide FIM functionality, integrates organization authentication infrastructure that
are normally based on Active Directory with cloud based authentication service

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix D

Zrich, 20 August. 2012

GANTT CHART

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix E

Zrich, 20 August. 2012

EC2 AMAZON CLOUD SERVER INSTANCE

SPECIFICATION

Figure 45 IaaS cloud server instance specification

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix F
Table Name
Identity

Zrich, 20 August. 2012

IIDMANAGEMENT DATABASE SCHEMA DESCRIPTION

Table Description
FIM implementation component part;
Stores basic information required to
identify federated identity; All other
identity properties are part of the abstract
federated identity view and are available
via iLinking custom SQL joins;

Column Name
pk_id

Surname

FirstName

MiddleName

Country

City

Description

iLinking

FIM implementation component part;


Provides information for federated identity
related to interconnected identities from
meta-directory;

fk_identityID
fk_iSourceID
fk_AccountID

fk_Account

iSource

FIM implementation component part;


Required to uniquely identify account
stores from meta-directory. Are used with
iLinking as a foreign key;

pk_id

name
tableContext
description
iRule

IAM implementation component for RBAC


& ABAC; stores information about
existing rules that are used by stored
procedure to recognize object of access
control operation;

ruleName

isActive
dtCreated

iRuleDef

IAM implementation component for RBAC


& ABAC; Provides filters for ABAC
operations for iRule rules to enforce
underlying RBAC logic;

pk_id

fk_iRuleID

isExclusion

country
division
department

Column Description
Primary key, used to uniquely
identify the identity within
database context;
Automatically propagated;
Identity surname; Potentially
can be filled automatically
when FId view is defined;
Identity first name; Potentially
can be filled automatically
when FId view is defined;
Identity middle name;
Potentially can be filled
automatically when FId view is
defined;
Identity country; Potentially
can be filled automatically
when FId view is defined;
Identity city; Potentially can be
filled automatically when FId
view is defined;
Identity description; Potentially
can be filled automatically
when FId view is defined;
Foreign key to Identity table;
Foreign key to iSource table;
Foreign numeric key to any
account store defined with
iSource;
Foreign free text key to any
account store defined with
iSource;
Primary key, used to uniquely
identify the identity within
database context;
Automatically propagated;
Unique name of the account
store;
Account store table location
with full database context path;
Random information relevant to
registered account store;
Unique name of the new
filtering rule; Used to
distinguished access control
operations specified for
different rules; Anchored in
Stored Procedures;
Specifies, wheter the rule is
active;
Information about data/time
when the rule was created;
Automatically propagated;
Used for auditing purposes;
Primary key, used to uniquely
identify the identity within
database context;
Automatically propagated;
Foreign key to iRule table;
Anchors the ABAC filter
definition to specific rule;
True/False value defines
whether filter specified is to
grant or deny object access;
Filter criteria; SQL wildcards
allowed;
Filter criteria; SQL wildcards
allowed;
Filter criteria; SQL wildcards
allowed;

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

distingusishedName
dtCreated

Filter criteria; SQL wildcards


allowed;
Information about data/time
when the ABAC filter was
created; Automatically
propagated; Used for auditing
purposes;

Table 12 iIdManagement database design details

Appendix G
Table Name
configuration

IADCONNECTOR DATABASE SCHEMA DESCRIPTION

Table Description
Main IADConnector configuration table; All other table
names are derived from this table; Table name can be
changed but the new name have to be set in
iADConnector.exe.config file under configuration key;

Column Name
DNSDomain

Table for user account reports; This table is specific for


domain, but can be used to keep the whole forest
information;
(configured in configuration under UserTable key with
DNSDomain field set to the domain name that will be
stored in that table);

pk_id

Table for contact object reports; This table is specific for


domain, but can be used to keep the whole forest
information;
(configured in configuration under UserTable key with
DNSDomain field set to the domain name that will be
stored in that table);

pk_id

Table for group object reports; This table is specific for


domain, but can be used to keep the whole forest
information;

objectGuid

Column Description
Domain Fully Qualified
Domain Name; Specifies
configuration context;
Unique key name for the
configuration section;
Key value for given
configuration section;
Specifies configuration
context;
Domain Controller Fully
Qualified Domain Name;
This is the server that the
iADConnector synced with;
Domain Controller GUID;
This is the server that the
iADConnector synced with;
Last replication state
number;
Domain Fully Qualified
Domain Name;
Specifies database table sync
context;
Information about data/time
when the sync took place;
Automatically propagated;
Used for sync purposes;
Primary key, used to
uniquely identify the identity
within database context;
Automatically propagated;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Translated flag from
UserAccountControl
attribute;
Primary key, used to
uniquely identify the identity
within database context;
Automatically propagated;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Primary key, used to
uniquely identify the identity
within database context;
Automatically propagated;
Custom directory attribute;

sAMAccountName
distinguishedName

Custom directory attribute;


Custom directory attribute;

KeyName
KeyValue
Description

sync_control

Synchronization control table; Service controls the


synchronization process with DCs using this table;
(configured in configuration under SyncControl key)
If empty the IADConnector service will perform complete
resynchronization with all contacted DCs;

dcDNS

invocationID

highestCommittedUSN
domainName
tableContext
dtSynced

user

contact

group

objectGuid
sAMAccountName
distinguishedName
objectSid
cn
department
c
UAC_ACCOUNTDISABLE

objectGuid
sAMAccountName
distinguishedName
objectSid
cn
department
c
UAC_ACCOUNTDISABLE

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

(configured in configuration under GroupTable key with


DNSDomain field set to the domain name that will be
stored in that table);
computer

Table for computer object reports; This table is specific


for domain, but can be used to keep the whole forest
information;
(configured in configuration under ComputerTable key
with DNSDomain field set to the domain name that will be
stored in that table);

membership

Table for group membership reports; This table is specific


for domain, but can be used to keep the whole forest
information; This table has a different structure than all
above as columns do not reflect real object attribute
names;
(configured in configuration under MembershipTable
key with DNSDomain field set to the domain name that
will be stored in that table);

objectSid
cn
description
objectGuid

Custom directory attribute;


Custom directory attribute;
Custom directory attribute;
Custom directory attribute;

sAMAccountName
distinguishedName
objectSid
cn
department
location
description
operatingSystem
group_dn

Custom directory attribute;


Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Custom directory attribute;
Specifies group
distinguishedName;
Specifies member
distinguishedName;
Specifies group
CommonName;
Specifies member
CommonName;

member_dn
group_cn
member_cn

Table 13 iADConnector database design details

Appendix H
Table Name
iPortal

IPORTAL DATABASE SCHEMA DESCRIPTION


Table Description
Table stores iPortal accounts
credentials

Column Name
username

passwordHASH
status

Table 14 iPortal iADConnector database design details

Column Description
Username that have access to
iPortal and is a Resource
Owner entity in OAuth model
MD5 hashed password
Specifies whether the account is
active and can be used to
access the iPortal.

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix I

Zrich, 20 August. 2012

STORED PROCEDURES

IPORTALACCESSCONTROL
USE [iIdManagement]
GO
/****** Object: StoredProcedure [dbo].[iPortalAccessControl] Script Date: 08/17/2012 03:02:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
Greg Spyra
-- Create date: 12.08.2012
-- Description:
RBAC via ABAC iPortal access control
-- =============================================
CREATE PROCEDURE [dbo].[iPortalAccessControl]
AS
BEGIN
DECLARE @TBL TABLE
(
userName varchar(100),
[status] tinyint
)
INSERT INTO @TBL
SELECT
PORTAL.userName, 1 as status
FROM
iIdManagement.dbo.iRuleDef DEF
JOIN
iIdManagement.dbo.iRule RL
ON
(
DEF.fk_iRuleID = RL.pk_id
AND
RL.ruleName = 'iPortal'
)
JOIN
iADConnector.dbo.[user] INC
ON
DEF.isExclusion = 0
AND
(
INC.c LIKE DEF.country
OR
INC.division LIKE DEF.division
OR
INC.department LIKE DEF.department
OR
INC.distinguishedName LIKE DEF.distinguishedName
)
JOIN
iIdManagement.dbo.iRuleDef DEF_EX
ON
(
DEF_EX.fk_iRuleID = RL.pk_id
AND
DEF.isExclusion = 0
OR
(
DEF.country IS NULL OR (INC.c NOT LIKE DEF.country OR INC.c IS NULL)
AND

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

DEF.division IS NULL OR (INC.division NOT LIKE DEF.division OR


INC.division IS NULL)
AND
DEF.department IS NULL OR (INC.department NOT LIKE DEF.department
OR INC.department IS NULL)
AND
DEF.distinguishedName IS NULL OR (INC.distinguishedName NOT LIKE
DEF.distinguishedName OR INC.distinguishedName IS NULL)
)
)
JOIN
iIdManagement.dbo.iLinking LNK1
ON
LNK1.fk_AccountID = INC.pk_id
JOIN
iIdManagement.dbo.iLinking LNK2
ON
LNK2.fk_iIdentityID = LNK1.fk_iIdentityID
JOIN
iPortal.dbo.Accounts PORTAL
ON
PORTAL.userName = LNK2.fk_Account
UNION ALL
SELECT
PORTAL.userName, 0 as status
FROM
iADConnector.dbo.[user] EXC
JOIN
iIdManagement.dbo.iLinking LNK1
ON
LNK1.fk_AccountID = EXC.pk_id
JOIN
ON

iIdManagement.dbo.iLinking LNK2
LNK2.fk_iIdentityID = LNK1.fk_iIdentityID

JOIN
iPortal.dbo.Accounts PORTAL
ON
PORTAL.userName = LNK2.fk_Account
JOIN
iIdManagement.dbo.iRule RL
ON
RL.ruleName = 'iPortal'
JOIN
iIdManagement.dbo.iRuleDef DEF
ON
AND

DEF.fk_iRuleID = RL.pk_id
(
DEF.isExclusion = 0
AND
(
LEN(DEF.country)>0 AND (EXC.c NOT LIKE DEF.country OR EXC.c IS

NULL)
OR
LEN(DEF.division)>0 AND (EXC.division NOT LIKE DEF.division OR
EXC.division IS NULL)
OR
LEN(DEF.department)>0

AND

(EXC.department

NOT

LIKE

DEF.department OR EXC.department IS NULL)


OR
LEN(DEF.distinguishedName)>0 AND (EXC.distinguishedName NOT LIKE
DEF.distinguishedName OR EXC.distinguishedName IS NULL)
)

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

)
MERGE INTO
iPortal.dbo.Accounts AS DST
USING
(
SELECT DISTINCT
T1.userName,
T1.[status]
FROM
@TBL T1
LEFT JOIN
@TBL T2
ON
(T1.userName = T2.userName
AND
T1.[status] < T2.[status]
)
WHERE
T2.userName IS NULL
) AS SRC
ON
DST.userName = SRC.userName
WHEN MATCHED THEN
UPDATE SET [status] = SRC.[status];
END

LINKIDENTITYFROMAD
USE [iIdManagement]
GO
/****** Object: StoredProcedure [dbo].[LinkIdentityFromAD] Script Date: 08/16/2012 00:55:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
Greg Spyra
-- Create date: 12.08.2012
-- Description:
Link Identity with AD account
-- =============================================
CREATE PROCEDURE [dbo].[LinkIdentityFromAD]
AS
BEGIN
INSERT INTO iIdManagement.dbo.iLinking
(fk_iIdentityID, fk_iSourceID, fk_AccountID)
SELECT
ID.pk_id,
SRC.pk_id,
LDAP.pk_id
FROM
iADConnector.dbo.[user] LDAP
JOIN
iIdManagement.dbo.iIdentity ID
ON
(
ID.Surname = LDAP.sn
AND
ID.FirstName = LDAP.givenName
)
JOIN
iIdManagement.dbo.iSource SRC
ON

AA

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

SRC.name = 'LDAP001'
LEFT JOIN
iIdManagement.dbo.iLinking LNK
ON
(
LNK.fk_iIdentityID = ID.pk_id
AND
LNK.fk_iSourceID = SRC.pk_id
AND
LNK.fk_AccountID = LDAP.pk_id
)
WHERE
LNK.fk_iIdentityID IS NULL
END

BB

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

LINKIDENTITYFROMIPORTAL
USE [iIdManagement]
GO
/****** Object: StoredProcedure [dbo].[LinkIdentityFromiPortal] Script Date: 08/16/2012 00:56:50 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
Greg Spyra
-- Create date: 12.08.2012
-- Description:
Link Identity with iPortal account
-- =============================================
CREATE PROCEDURE [dbo].[LinkIdentityFromiPortal]
(
@Surname varchar(100),
@FirstName varchar(100),
@userName varchar(100)
)
AS
BEGIN
INSERT INTO iIdManagement.dbo.iLinking
(fk_iIdentityID, fk_iSourceID, fk_Account)
SELECT
ID.pk_id,
SRC.pk_id,
PORTAL.userName
FROM
iPortal.dbo.[Accounts] PORTAL
JOIN
iIdManagement.dbo.iIdentity ID
ON
(
ID.Surname = @Surname
AND

ID.FirstName = @FirstName

AND
PORTAL.userName = @userName
)
JOIN
iIdManagement.dbo.iSource SRC
ON
SRC.name = 'iPortal'
LEFT JOIN
iIdManagement.dbo.iLinking LNK
ON
(
LNK.fk_iIdentityID = ID.pk_id
AND
LNK.fk_iSourceID = SRC.pk_id
AND
LNK.fk_Account = PORTAL.userName
)
WHERE
LNK.fk_iIdentityID IS NULL
END

CC

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

REGISTERIDENTITY
USE [iIdManagement]
GO
/****** Object: StoredProcedure [dbo].[RegisterIdentity] Script Date: 08/16/2012 00:57:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
Greg Spyra
-- Create date: 12.08.2012
-- Description:
Create Identity
-- =============================================
CREATE PROCEDURE [dbo].[RegisterIdentity]
(
@Surname AS varchar(100),
@FirstName AS varchar(100),
@MiddleName AS varchar(100) = NULL,
@Country AS varchar(50) = NULL,
@City AS varchar(100) = NULL,
@Description AS varchar(1024) = NULL
)
AS
BEGIN
INSERT INTO iIdManagement.dbo.iIdentity
(Surname, FirstName, MiddleName, Country, City, [Description])
VALUES
(@Surname, @FirstName, @MiddleName, @Country, @City, @Description)
END

REGISTERACCOUNT
USE [iPortal]
GO
/****** Object: StoredProcedure [dbo].[RegisterAccount] Script Date: 08/16/2012 00:57:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:
Greg Spyra
-- Create date: 12.08.2012
-- Description:
Create iPortal account
-- =============================================
CREATE PROCEDURE [dbo].[RegisterAccount]
(
@userName AS varchar(100),
@passwordHASH AS varchar(1024),
@status AS tinyint = 1
)
AS
BEGIN
INSERT INTO Accounts
(userName, passwordHASH, [status])
VALUES
(@userName, @passwordHASH, @status)
END

DD

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix J

Zrich, 20 August. 2012

PROVISIONING.CMD

::******************************************************************************
:: Script Name:
:: Language: NT Shell
:: Author: Gregory Spyra
:: Project: MSc Dissertation
:: Date Written: 29 Jun 2012
:: Reason:
:: Notes:
:: Version: 1.0
:: Version History:
:: 1.0
29 Jun 2012
Created
::******************************************************************************
::******************************************************************************
::******************************************************************************
::******************************************************************************
::******************************************************************************
@ECHO Off
@SETLOCAL EnableDelayedExpansion
SET DOMAIN_DN=dc^=spyraconsulting,dc^=net
SET CUSTOMERS=NAPIER,RBS,NHS,GCHQ,ALL
SET
CUSTOMERS_LOCATIONS=00:ALL,00:NAPIER,UK:NAPIER,00:RBS,UK:RBS,00:NHS,UK:NHS,00:GCHQ,UK:GCHQ,USA:NAPIER,
USA:RBS,JP:RBS,PL:RBS,FR:RBS,FR:NAPIER
SET DEFAULT_OU=Users,SecurityGroups,DistributionGroups,Computers,Contacts
SET USER_OU=Users
SET GROUP_OU=SecurityGroups
SET DEFAULT_GROUPS=MultimediaServices,ITServices,HR,CustomerServices,FinanceServices
SET USER_PER_OU_LIMIT=500
SET LAST_USER_IDX=0
SET GROUP_PER_OU_LIMIT=10
::******************************************************************************
::******************************************************************************
::***************************************MAIN***********************************
::provision customers
FOR %%i IN (%CUSTOMERS%) Do DSADD OU "ou=%%~i,%DOMAIN_DN%"
::provision locations and default sub-structures
FOR %%i IN (%CUSTOMERS_LOCATIONS%) Do (
FOR /F "delims=: tokens=1,2" %%j In ("%%~i") Do (
::customer locations
DSADD OU "ou=%%~j,ou=%%~k,%DOMAIN_DN%" -Desc "Country Code:%%~j"
::sub-structure
FOR %%m In (%DEFAULT_OU%) Do (
DSADD OU "ou=%%~m,ou=%%~j,ou=%%~k,%DOMAIN_DN%" -Desc "Object Category:%%~m"
::provision users
FOR %%n In (%USER_OU%) Do (
IF {%%~m} EQU {%%~n} (
FOR /L %%i In (1,1,%USER_PER_OU_LIMIT%) Do (
SET /A LAST_USER_IDX=!LAST_USER_IDX!+1
DSADD
User
"cn=User!LAST_USER_IDX!,ou=%%~m,ou=%%~j,ou=%%~k,%DOMAIN_DN%"
"User!LAST_USER_IDX!" -fn "User" -ln "!LAST_USER_IDX!" -Company "%%~k"

EE

-SamID

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

)
)
)
::provision groups
FOR %%g In (%GROUP_OU%) Do (
IF {%%~m} EQU {%%~g} (
FOR %%h In (%DEFAULT_GROUPS%) Do (
SET GROUP_NAME=%%~k-%%~j-%%~h
DSADD
Group
"cn=!GROUP_NAME!,ou=%%~m,ou=%%~j,ou=%%~k,%DOMAIN_DN%"
"!GROUP_NAME!" -Desc "%%~h"
FOR /L %%i In (1,1,%GROUP_PER_OU_LIMIT%) Do (
DSADD Group "cn=!GROUP_NAME!%%~i,ou=%%~m,ou=%%~j,ou=%%~k,%DOMAIN_DN%"
"!GROUP_NAME!%%~i" -Desc "%%~h"
)
)
)
)
)
)
)

FF

-SamID
-SamID

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Appendix K

Zrich, 20 August. 2012

IADCONNECTOR

IADCONNECTOR.CS
using System;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
namespace iADConnector
{
public partial class iADConnector : ServiceBase
{
protected EventLog objEventLog;
private int iMinutesElapsed;
DateTime dtLastRun;
public iADConnector()
{
InitializeComponent();
this.objEventLog
=
new
System.Diagnostics.EventLog("Application",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
}
protected override void OnStart(string[] args)
{
try
{
this.objTimer.Interval = 60000;
this.objTimer.Enabled = true;
this.dtLastRun = new DateTime();
this.iMinutesElapsed = 0;
// create message string
string strMessage = "timer successfullly started.\n\ninterval:\t" + (this.objTimer.Interval / 60000) + " minutes";
this.objEventLog.WriteEntry(strMessage, EventLogEntryType.Information, 1000);
using (iADConnectorEngine objReporter = new iADConnectorEngine() )
{
objReporter.OnMessage += this.WriteEventLogMessage;
objReporter.EncryptConfig();
objReporter.Dispose();
}
}
catch (Exception Error)
{
objEventLog.WriteEntry(Error.Message, EventLogEntryType.Error, 1200);
this.Stop();
}
}
protected override void OnStop()
{
try
{
this.objTimer.Enabled = false;
}

GG

".",

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

catch (Exception Error)


{
objEventLog.WriteEntry(Error.Message, EventLogEntryType.Error, 1201);
}
}
private void objTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
objTimer.Enabled = false;
this.iMinutesElapsed
Convert.ToInt32(this.objTimer.Interval/60000);

this.iMinutesElapsed

string strInterval = ConfigurationManager.AppSettings.Get("interval");


string strTime = ConfigurationManager.AppSettings.Get("schedule");

DateTime.Now.Hour)

bool bInterval = (this.iMinutesElapsed % Convert.ToDouble(strInterval) == 0);


bool bSchedule = ((this.dtLastRun.Ticks == 0)
||
(this.dtLastRun.Hour

!=

||

!=

(this.dtLastRun.Date

DateTime.Now.Date))
&& this.checkRunTime(strTime);
if ( bInterval || bSchedule )
{
using (iADConnectorEngine objReporter = new iADConnectorEngine())
{
objReporter.OnMessage += this.WriteEventLogMessage;
objReporter.GetCurrentState(bInterval, bSchedule);
}
this.iMinutesElapsed = bInterval
?0
: this.iMinutesElapsed + 1;
if(bSchedule) this.dtLastRun = DateTime.Now;
}
objTimer.Enabled = true;
}
catch (Exception Error)
{
this.objEventLog.WriteEntry(Error.Message, EventLogEntryType.Error, 1202);
objTimer.Enabled = true;
}
}
private void WriteEventLogMessage(Entry objEntry)
{
try
{
if (objEntry.SeverityLevel == Entry.Severity.Error)
{
this.objEventLog.WriteEntry((objEntry.Message.Length > Byte.MaxValue ?
objEntry.Message.Substring(0, Byte.MaxValue) : objEntry.Message), EventLogEntryType.Error, objEntry.EventId);
}
else if (objEntry.SeverityLevel == Entry.Severity.Warning)
{
this.objEventLog.WriteEntry((objEntry.Message.Length > Byte.MaxValue ?
objEntry.Message.Substring(0, Byte.MaxValue) : objEntry.Message), EventLogEntryType.Warning, objEntry.EventId);
}
else
{

HH

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

this.objEventLog.WriteEntry((objEntry.Message.Length > Byte.MaxValue ?


objEntry.Message.Substring(0, Byte.MaxValue) : objEntry.Message), EventLogEntryType.Information, objEntry.EventId);
}
}
catch (Exception Error)
{
this.objEventLog.WriteEntry((Error.Message.Length
>=
Int16.MaxValue
?
Error.Message.Substring(0, Int16.MaxValue) : Error.Message), EventLogEntryType.Error, 1202);
}
}
private bool checkRunTime(string strTime)
{
bool bResult = false;
try
{
IEnumerator ieSchedule = strTime.Split(';').GetEnumerator();
while (ieSchedule.MoveNext() && !bResult)
{
string[] arTime = ieSchedule.Current.ToString().Split(":".ToCharArray());
DateTime objStartTime = new DateTime();
DateTime objEndTime = new DateTime();
objStartTime = DateTime.Today;
objStartTime = objStartTime.AddHours(Convert.ToDouble(arTime[0]));
objStartTime = objStartTime.AddMinutes(Convert.ToDouble(arTime[1]));
objEndTime = objStartTime.AddHours(1.0);
if (objStartTime < DateTime.Now && objEndTime > DateTime.Now)
{
bResult = true;
}
}
}
catch
{
}
return bResult;
}
private string GetDBConfig(string strDescription, string strDNSDomain, string strKeyName)
{
string strValue = null;
try
{
string strSQL = null;
&& strKeyName != String.Empty)

if (strDescription != null && strDescription != String.Empty && strKeyName != null


{

if (strDNSDomain != null)
{
strSQL = string.Format("SELECT KeyValue FROM {0} WHERE
Description
=
'{1}'
AND
DNSDomain
=
'{2}'
AND
KeyName
=
'{3}'",
ConfigurationManager.AppSettings["Configuration"].ToString(), strDescription, strDNSDomain, strKeyName);
}
else
{
strSQL = string.Format("SELECT KeyValue FROM {0} WHERE
Description = '{1}' AND KeyName = '{2}'", ConfigurationManager.AppSettings["Configuration"].ToString(), strDescription,
strKeyName);
}
using
(Handy.Sql
oSql
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["MigOneBankAD"].ConnectionString))
{

II

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


foreach

(Dictionary<string,

object>

dicRes

in

oSql.RetrieveData(strSQL))
{
strValue = dicRes["KeyValue"].ToString();
}
}
}

}
catch (Exception ex)
{
throw
new
Exception(String.Format("{0}::{1}",
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message));
}
return strValue;
}
}
}

JJ

new

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

IADCONNECTORENGINE.CS
using System;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using XtLdap;
namespace iADConnector
{
#region Global Variables
public enum UserAccountControl
{
UAC_SCRIPT =
0x0000001,
UAC_ACCOUNTDISABLE =
0x0000002,
UAC_HOMEDIR_REQUIRED =
0x0000008,
UAC_LOCKOUT =
0x0000010,
UAC_PASSWD_NOTREQD =
0x0000020,
UAC_PASSWD_CANT_CHANGE =
0x0000040,
UAC_ENCRYPTED_TEXT_PWD_ALLOWED =
0x0000080,
UAC_TEMP_DUPLICATE_ACCOUNT =
0x0000100,
UAC_NORMAL_ACCOUNT =
0x0000200,
UAC_INTERDOMAIN_TRUST_ACCOUNT =
0x0000800,
UAC_WORKSTATION_TRUST_ACCOUNT =
0x0001000,
UAC_SERVER_TRUST_ACCOUNT =
0x0002000,
UAC_DONT_EXPIRE_PASSWORD =
0x0010000,
UAC_MNS_LOGON_ACCOUNT =
0x0020000,
UAC_SMARTCARD_REQUIRED =
0x0040000,
UAC_TRUSTED_FOR_DELEGATION =
0x0080000,
UAC_NOT_DELEGATED =
0x0100000,
UAC_USE_DES_KEY_ONLY =
0x0200000,
UAC_DONT_REQ_PREAUTH =
0x0400000,
UAC_PASSWORD_EXPIRED =
0x0800000,
UAC_TRUSTED_TO_AUTH_FOR_DELEGATION = 0x1000000
};
#endregion
#region Global Supporting Classes
public class Entry
{
public enum Severity
{
Verbose = 1, Info = 2, Warning = 3, Error = 4, Fatal = 5
};
public Severity SeverityLevel;
public string Message;
public int EventId;
}
public class UserCredentials : IDisposable
{

KK

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

public UserCredentials(string Password, string UserName)


{
this.Password = Password;
this.UserName = UserName;
}
private SecureString secPassword;
private SecureString secUserName;
public string Password
{
get
{
return this.getSecureString(this.secPassword);
}
set
{
this.secPassword = this.setSecureString(value);
}
}
public string UserName
{
get
{
return this.getSecureString(this.secUserName);
}
set
{
this.secUserName = this.setSecureString(value);
}
}
private SecureString setSecureString(string String)
{
SecureString secString = null;
if (String == null)
{
return secString;
}
else
{
try
{
secString = new SecureString();
foreach (Char cChar in String.ToCharArray())
{
secString.AppendChar(cChar);
}
secString.MakeReadOnly();
return secString;
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
}
private string getSecureString(SecureString String)
{
if ( String == null)

LL

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
return null;
}
else
{
try
{

IntPtr
System.Runtime.InteropServices.Marshal.SecureStringToBSTR(String);

pointerName

try
{
return
System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pointerName);
}
finally
{
System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(pointerName);
}
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
}

new

StackFrame(0,

#region IDisposable Members


public void Dispose()
{
try
{
if (this.secPassword != null) this.secPassword.Dispose();
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

#endregion
}
#endregion
class iADConnectorEngine : IDisposable
{
#region Variables
private bool bDisposed;
private List<string> lTruncated;
private long iHighestCommittedUsn = 0;
private string sConnectionString = null;
public delegate void MessageEventHandler(Entry objEntry);
public event MessageEventHandler OnMessage;
public string ConnectionString
{
get
{
return this.sConnectionString;

MM

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
set
{
this.sConnectionString = value;
}
}
protected Entry objEntry;
#endregion
#region Constructors
public iADConnectorEngine()
{
try
{
this.bDisposed = false;
this.objEntry = new Entry();
this.lTruncated = new List<string>();
this.sConnectionString
ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
#endregion

new

StackFrame(0,

#region Public Methods


public void GetCurrentState(bool Interval, bool Schedule)
{
try
{
List<string> lDomainsList = this.GetDomains();
if (lDomainsList != null)
{
//BULK-LOAD sections
foreach (string sDomainName in lDomainsList)
{
try
{
}
catch (Exception ex)
{
objEntry.EventId = 1509;
objEntry.SeverityLevel = Entry.Severity.Error;
objEntry.Message = ex.Message;
CreateEventMessage(objEntry);
}
}
//QUICK UPDATES
foreach (string sDomainName in lDomainsList)
{
try
{
using(UserCredentials
Credentials
UserCredentials(this.DecryptString(

NN

new

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

this.GetDBConfig("Default", sDomainName, "Password")),


this.DecryptString(this.GetDBConfig("Default", sDomainName, "User")) ) )
{
List<DomainController> lDomainControllers
= GetSiteDC(
sDomainName,
this.GetDBConfig("default",
sDomainName, "NearSite"),
Credentials.UserName,
Credentials.Password);
DomainController
oDomainController
this.GetLastServerByUsn(this.GetTableName("SyncControl", null), lDomainControllers);
if (oDomainController == null)
{
oDomainController
lDomainControllers[0];
}
string sServer =
oDomainController.Name;
string
sServerGuid
oDomainController.GetDirectoryEntry().NativeGuid;
iHighestCommittedUsn

=
=

Convert.ToInt64(oDomainController.HighestCommittedUsn);
if ((Interval && this.GetDBConfig("Default",
null, "UserEnumeration") == "1")
||

(Schedule

&&

this.GetDBConfig("Default", null, "UserEnumeration") == "0"))


{
try
{
string

sTableName

this.GetTableName("user", sDomainName);
long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);
if
(!String.IsNullOrEmpty(sTableName))
{
using(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))
{
List<string> lAttributesList = GetAttributeList(sTableName);
lAttributesList.Remove("sniff_time");
//get objects that were recently changed in AD
HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("user",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);

OO

true),

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Dictionary<string,
Dictionary<string,
xtLdap.RetrieveTranslatedUpdatedAttributes(hsObjectsToUpdate,
LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

string>>

dicUpdates

=
lAttributesList,

if (iLastHighestCommittedUsn == 0 && ConfigurationManager.AppSettings.Get("firstrun").Equals("1"))


{
this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);
}
else
{
HashSet<string>
hsFreshDelState
LdapEngine.UniqueObjectIdentifier.objectGuid);

xtLdap.FindDeletedObjects(this.GetFilter("user",

false),

this.DeleteFromDb(sTableName,
LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

hsFreshDelState,

this.AdjustMembershipTableWithDnChanges(this.GetTableName("member",
sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sDomainName),

this.AdjustMembershipTableWithDeletions(this.GetTableName("member",
sTableName, hsFreshDelState.GetEnumerator(), LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sDomainName),

this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, false);


}
this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,
iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1511;
objEntry.SeverityLevel =
Entry.Severity.Error;
objEntry.Message
=
ex.Message;
CreateEventMessage(objEntry);
}
}
if ((Interval && this.GetDBConfig("Default",
null, "GroupEnumeration") == "1")
||

(Schedule

&&

this.GetDBConfig("Default", null, "GroupEnumeration") == "0"))


{
try
{

string

sTableName

this.GetTableName("group", sDomainName);
long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);

PP

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

if
(!String.IsNullOrEmpty(sTableName))
{
using
(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))
{
List<string> lAttributesList = GetAttributeList(sTableName);
lAttributesList.Remove("sniff_time");
//get

objects that were recently changed in AD


HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("group",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);
Dictionary<string,
Dictionary<string,
xtLdap.RetrieveTranslatedUpdatedAttributes(hsObjectsToUpdate,
LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

string>>

dicUpdates

true),

=
lAttributesList,
if

(iLastHighestCommittedUsn == 0 && ConfigurationManager.AppSettings.Get("firstrun").Equals("1"))


{
this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);
}
else
{
HashSet<string>
hsFreshDelState
LdapEngine.UniqueObjectIdentifier.objectGuid);

xtLdap.FindDeletedObjects(this.GetFilter("group",

false),

this.DeleteFromDb(sTableName, hsFreshDelState, LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());


this.AdjustMembershipTableWithDnChanges(this.GetTableName("member",
dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sDomainName),

this.AdjustMembershipTableWithDeletions(this.GetTableName("member",
sDomainName),
hsFreshDelState.GetEnumerator(), LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sTableName,
sTableName,

this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, false);


}
this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,
iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1512;

QQ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


objEntry.SeverityLevel

objEntry.Message

Entry.Severity.Error;
ex.Message;
CreateEventMessage(objEntry);

}
}
if ((Interval && this.GetDBConfig("Default",

null, "ComputerEnumeration") == "1")


||

(Schedule

&&

this.GetDBConfig("Default", null, "ComputerEnumeration") == "0"))


{
try
{
string

sTableName

this.GetTableName("computer", sDomainName);
long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);
if
(!String.IsNullOrEmpty(sTableName))
{
using
(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))

List<string> lAttributesList = GetAttributeList(sTableName);


lAttributesList.Remove("sniff_time");
//get
objects that were recently changed in AD
HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("computer",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);
Dictionary<string,
Dictionary<string,
xtLdap.RetrieveTranslatedUpdatedAttributes(hsObjectsToUpdate,
LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

string>>

dicUpdates

true),

=
lAttributesList,
if

(iLastHighestCommittedUsn == 0 && ConfigurationManager.AppSettings.Get("firstrun").Equals("1"))


{
this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);
}
else
{
HashSet<string>
hsFreshDelState
LdapEngine.UniqueObjectIdentifier.objectGuid);

xtLdap.FindDeletedObjects(this.GetFilter("computer",

false),

this.DeleteFromDb(sTableName, hsFreshDelState, LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

RR

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

this.AdjustMembershipTableWithDnChanges(this.GetTableName("member",
dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sDomainName),

this.AdjustMembershipTableWithDeletions(this.GetTableName("member",
sDomainName),
hsFreshDelState.GetEnumerator(), LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sTableName,
sTableName,

this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, false);


}
this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,
iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1513;
objEntry.SeverityLevel =
Entry.Severity.Error;
objEntry.Message
=
ex.Message;
CreateEventMessage(objEntry);
}
}
if ((Interval && this.GetDBConfig("Default",
null, "ContactEnumeration") == "1")
||

(Schedule

&&

this.GetDBConfig("Default", null, "ContactEnumeration") == "0"))


{

try
{
string

sTableName

this.GetTableName("contact", sDomainName);
long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);
if
(!String.IsNullOrEmpty(sTableName))
{
using
(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))
{
List<string> lAttributesList = GetAttributeList(sTableName);
lAttributesList.Remove("sniff_time");
//get
objects that were recently changed in AD

SS

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("contact",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);
Dictionary<string,
Dictionary<string,
xtLdap.RetrieveTranslatedUpdatedAttributes(hsObjectsToUpdate,
LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

string>>

dicUpdates

true),

=
lAttributesList,
if

(iLastHighestCommittedUsn == 0 && ConfigurationManager.AppSettings.Get("firstrun").Equals("1"))


{
this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);
}
else
{
HashSet<string>
hsFreshDelState
LdapEngine.UniqueObjectIdentifier.objectGuid);

xtLdap.FindDeletedObjects(this.GetFilter("contact",

false),

this.DeleteFromDb(sTableName, hsFreshDelState, LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());


this.AdjustMembershipTableWithDnChanges(this.GetTableName("member",
dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sDomainName),

this.AdjustMembershipTableWithDeletions(this.GetTableName("member",
sDomainName),
hsFreshDelState.GetEnumerator(), LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sTableName,
sTableName,

this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, false);


}
this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,
iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1511;
objEntry.SeverityLevel =
Entry.Severity.Error;
objEntry.Message
=
ex.Message;
CreateEventMessage(objEntry);
}
}
if ((Interval && this.GetDBConfig("Default",
null, "MemberEnumeration") == "1")
||

(Schedule

&&

this.GetDBConfig("Default", null, "MemberEnumeration") == "0"))


{
try
{
string

this.GetTableName("member", sDomainName);

sTableName

long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);

TT

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


if

(!String.IsNullOrEmpty(sTableName))
{
using
(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))
{
List<string> lAttributesList = GetAttributeList(sTableName);
lAttributesList.Remove("sniff_time");
//get

objects that were recently changed in AD


HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("group",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);
Dictionary<string,
Dictionary<string,
xtLdap.GetUpdatedMembers(hsObjectsToUpdate);

LdapEngine.MembershipAction>>

true),

dicUpdates

=
if

(iLastHighestCommittedUsn == 0 && ConfigurationManager.AppSettings.Get("firstrun").Equals("1"))


{
this.UpdateDBState(sTableName, dicUpdates, true);
}
else
{
this.UpdateDBState(sTableName, dicUpdates, false);
}
this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,
iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1514;
objEntry.SeverityLevel =
Entry.Severity.Error;
objEntry.Message
=
ex.Message;
objEntry.Message
=
ex.Message;
CreateEventMessage(objEntry);
}
}
if ((Interval && this.GetDBConfig("Default",
null, "SecurityEnumeration") == "1")
||
this.GetDBConfig("Default", null, "SecurityEnumeration") == "0"))

UU

(Schedule

&&

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{
try
{
string

sTableName

this.GetTableName("security", sDomainName);
long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);
if
(!String.IsNullOrEmpty(sTableName))
{
using
(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))
{
List<string> lAttributesList = GetAttributeList( sTableName);
lAttributesList.Remove("sniff_time");
//get
objects that were recently changed in AD
HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("security",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);

true),

//delete changed objects in DB in order to insert updated ones


this.DeleteFromDb(sTableName,
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName.ToString());

hsObjectsToUpdate,

//delete deleted objects in DB


HashSet<string>
hsFreshDelState
=
LdapEngine.UniqueObjectIdentifier.distinguishedName);

xtLdap.FindDeletedObjects(this.GetFilter("security",

this.DeleteFromDb(sTableName,
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName.ToString() );

false),

hsFreshDelState,

//insert changed objects


List<Dictionary<string, string>> lFreshState = xtLdap.GetSecurity(hsObjectsToUpdate, lAttributesList.ToArray(),
LdapEngine.UniqueObjectIdentifier.distinguishedName);
this.UpdateDBState( sTableName, lFreshState, lAttributesList);
this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,
iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1515;

VV

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


objEntry.SeverityLevel

objEntry.Message

Entry.Severity.Error;
ex.Message;
CreateEventMessage(objEntry);

}
}
if ((Interval && this.GetDBConfig("Default",

null, "FspEnumeration") == "1")


||

(Schedule

&&

this.GetDBConfig("Default", null, "FspEnumeration") == "0"))


{
try
{
string

sTableName

this.GetTableName("fsp", sDomainName);
long
iLastHighestCommittedUsn = this.GetLastSyncUsn(this.GetTableName("SyncControl", null), sServerGuid, sTableName);
if
(!String.IsNullOrEmpty(sTableName))
{
using
(LdapEngine xtLdap = new LdapEngine(
sServer,
iLastHighestCommittedUsn,
Credentials.UserName,
Credentials.Password))
{
List<string> lAttributesList = GetAttributeList(sTableName);
lAttributesList.Remove("sniff_time");
//get
objects that were recently changed in AD
HashSet<string>
hsObjectsToUpdate
=
xtLdap.FindObjects(this.GetFilter("fsp",
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);
Dictionary<string,
Dictionary<string,
xtLdap.RetrieveTranslatedUpdatedAttributes(hsObjectsToUpdate,
LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

string>>

dicUpdates

true),

=
lAttributesList,
if

(iLastHighestCommittedUsn == 0 && ConfigurationManager.AppSettings.Get("firstrun").Equals("1"))


{
this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, true);
}
else
{
HashSet<string>
hsFreshDelState
LdapEngine.UniqueObjectIdentifier.objectGuid);

xtLdap.FindDeletedObjects(this.GetFilter("fsp",

false),

this.DeleteFromDb(sTableName, hsFreshDelState, LdapEngine.UniqueObjectIdentifier.objectGuid.ToString());

WW

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

this.AdjustMembershipTableWithDeletions(this.GetTableName("member",
sDomainName),
hsFreshDelState.GetEnumerator(), LdapEngine.UniqueObjectIdentifier.objectGuid, true);

sTableName,

this.UpdateDBState(sTableName, dicUpdates, LdapEngine.UniqueObjectIdentifier.objectGuid, false);


}

this.SetLastSyncUsn(this.GetTableName("SyncControl", null), sServer, sDomainName, sServerGuid, sTableName,


iHighestCommittedUsn);
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1511;
objEntry.SeverityLevel =
Entry.Severity.Error;
objEntry.Message
=
ex.Message;
CreateEventMessage(objEntry);
}
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1509;
objEntry.SeverityLevel = Entry.Severity.Error;
objEntry.Message = ex.Message;
CreateEventMessage(objEntry);
}
}
}
}
catch (Exception ex)
{
objEntry.EventId = 1508;
objEntry.SeverityLevel = Entry.Severity.Error;
objEntry.Message = ex.Message;
CreateEventMessage(objEntry);
}
}
public void EncryptConfig()
{
try
{
using
(Handy.Sql
oSql
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
string strSQL = null;

new

// user encrypting
strSQL = string.Format("SELECT DNSDomain, KeyName, KeyValue FROM
{0} WHERE Description = 'Default' AND KeyName ='User'", ConfigurationManager.AppSettings.Get("configuration"));
foreach (Dictionary<string, object> dicRes in oSql.RetrieveData(strSQL))
{
string strName = dicRes["KeyName"].ToString();
string strValue = dicRes["KeyValue"].ToString();

XX

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


string strDomain = dicRes["DNSDomain"].ToString();
if

(!strValue.StartsWith("ID=",

StringComparison.OrdinalIgnoreCase))
{
if (strDomain != null && strDomain != "")
{
strSQL = string.Format("UPDATE {0} SET
KeyValue='ID={1}' WHERE Description = 'Default' AND KeyName ='User' AND DNSDomain='{2}'",
ConfigurationManager.AppSettings.Get("configuration"), SimpleCrypto.EncryptString(strValue), strDomain);
oSql.ExecuteNonSqlQuery(strSQL);
}
}
}
// password encrypting
strSQL = string.Format("SELECT DNSDomain, KeyName, KeyValue FROM
{0} WHERE Description = 'Default' AND KeyName ='Password'", ConfigurationManager.AppSettings.Get("configuration"));
foreach (Dictionary<string, object> dicRes in oSql.RetrieveData(strSQL))
{
string strName = dicRes["KeyName"].ToString();
string strValue = dicRes["KeyValue"].ToString();
string strDomain = dicRes["DNSDomain"].ToString();
if

(!strValue.StartsWith("PW=",

StringComparison.OrdinalIgnoreCase))
{
if (strDomain != null && strDomain != "")
{
strSQL = string.Format("UPDATE {0} SET
KeyValue='PW={1}' WHERE Description = 'Default' AND KeyName ='Password' AND DNSDomain='{2}'",
ConfigurationManager.AppSettings.Get("configuration"), SimpleCrypto.EncryptString(strValue), strDomain);
oSql.ExecuteNonSqlQuery(strSQL);
}
}
}
}
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}
#endregion

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

#region Private Methods


private void UpdateDBState(string sTableName, List<List<Dictionary<string, string>>> lUpdates)
{
const int CUR_ROW = 0;
const int NEW_ROW = 1;
try
{

//UPDATE

using (Handy.Sql oSql = new Handy.Sql(new SqlConnection(this.sConnectionString)))


{
foreach (List<Dictionary<string, string>> lDRow in lUpdates)
{
if (lDRow[CUR_ROW] != null && lDRow[NEW_ROW] != null)
{
UpdateRecord(sTableName,

lDRow[NEW_ROW], oSql);

YY

lDRow[CUR_ROW],

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


}
else if (lDRow[CUR_ROW] == null) //ADD
{
InsertRecord(sTableName, lDRow[NEW_ROW], oSql);
}
else if (lDRow[NEW_ROW] == null) //REMOVE
{
DeleteRecord(sTableName, lDRow[CUR_ROW], oSql);
}

}
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void UpdateDBState(string sTableName, List<Dictionary<string, string>> lUpdates, List<string>
lAttributes)
{
try
{
using (Handy.Sql oSql = new Handy.Sql(new SqlConnection(this.sConnectionString)))
{
foreach (StringBuilder sbPacket in this.GenerateBulkLoad(sTableName,
lUpdates, lAttributes))
{
oSql.ExecuteNonSqlQuery(sbPacket.ToString());
}
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void UpdateDBState(string sTableName, Dictionary<string, Dictionary<string, string>>
dicUpdates, LdapEngine.UniqueObjectIdentifier enUniqueAttribute, bool bFirstRun)
{
try
{
const int ROW_LIMIT = 1000;
StringBuilder sbSqlQuery = new StringBuilder();
StringBuilder sbSqlBulkUpdates = new StringBuilder();
StringBuilder sbSqlBulkInserts = new StringBuilder();
string sSqlQueryBase = bFirstRun
?String.Format("INSERT INTO [{0}] ([{{3}}],[{1}]) VALUES ({{4}})\n",
sTableName, enUniqueAttribute)
:String.Format("UPDATE [{0}] {{0}} WHERE [{{1}}]='{{2}}'
@@ROWCOUNT=0 INSERT INTO [{0}] ([{{3}}],[{1}]) VALUES ({{4}})\n", sTableName, enUniqueAttribute);

IF

int iRow = 0;
using (Handy.Sql oSql = new Handy.Sql(new SqlConnection(this.sConnectionString)))
{
foreach
(KeyValuePair<string,
Dictionary<string,
string>>
kvDictionariesUpdates in dicUpdates)
{
IEnumerator<KeyValuePair<string,
kvDictionariesUpdates.Value.GetEnumerator();
if (enUpdate.MoveNext())

ZZ

string>>

enUpdate

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{
if (String.IsNullOrEmpty(enUpdate.Current.Value))
{
sbSqlBulkUpdates.AppendFormat(
@"SET

[{0}]=NULL", enUpdate.Current.Key);
sbSqlBulkInserts.Append("NULL");
}
else
{
string

sValue

enUpdate.Current.Value.Replace("'", "''");
sbSqlBulkUpdates.AppendFormat(@"SET
[{0}]='{1}'", enUpdate.Current.Key, sValue);
sbSqlBulkInserts.AppendFormat(@"'{0}'",
sValue);
}
while(enUpdate.MoveNext())
{
if
(String.IsNullOrEmpty(enUpdate.Current.Value))

sbSqlBulkUpdates.AppendFormat(@",[{0}]=NULL", enUpdate.Current.Key);
sbSqlBulkInserts.Append(",NULL");
}
else
{
string

sValue

enUpdate.Current.Value.Replace("'", "''");
sbSqlBulkUpdates.AppendFormat(@",[{0}]='{1}'", enUpdate.Current.Key, sValue);
sbSqlBulkInserts.AppendFormat(@",'{0}'", sValue);
}
}
sbSqlBulkInserts.AppendFormat(@",'{0}'",
kvDictionariesUpdates.Key);
}
enUniqueAttribute,
sbSqlBulkInserts);

kvDictionariesUpdates.Key,

sbSqlQuery.AppendFormat(sSqlQueryBase,
sbSqlBulkUpdates,
String.Join("],[",
kvDictionariesUpdates.Value.Keys.ToArray()),
iRow++;
if ((iRow % ROW_LIMIT) == 0)
{
if (sbSqlQuery.Length > 0)
{

oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
sbSqlQuery = new StringBuilder();
}
}
sbSqlBulkUpdates = new StringBuilder();
sbSqlBulkInserts = new StringBuilder();
}
if (sbSqlQuery.Length > 0 & (iRow % ROW_LIMIT) > 0)
{
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
}

}
}
catch (Exception ex)
{

AAA

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private
void
UpdateDBState(string
sTableName,
Dictionary<string,
Dictionary<string,
LdapEngine.MembershipAction>> dicUpdates, bool bFirstRun)
{
try
{
const int ROW_LIMIT = 3000;
StringBuilder sbSqlQuery = new StringBuilder();
StringBuilder sbSqlAdd = new StringBuilder();
StringBuilder sbSqlDel = new StringBuilder();
string sCondAddBase = "UNION ALL SELECT '{0}','{1}','{2}','{3}'\n";
string sCondDelBase = "(group_dn='{0}' AND member_dn='{1}')\n";
string sSqlAddBase = bFirstRun
?String.Format(@"
INSERT INTO [{0}] (group_dn,member_dn,group_cn,member_cn)
SELECT
RQ.group_dn,
RQ.member_dn,
RQ.group_cn,
RQ.member_cn
FROM
({{0}}) RQ", sTableName)
:String.Format(@"
INSERT INTO [{0}] (group_dn,member_dn,group_cn,member_cn)
SELECT
RQ.group_dn,
RQ.member_dn,
RQ.group_cn,
RQ.member_cn
FROM
({{0}}) RQ
LEFT JOIN
[{0}] CUR
ON
(RQ.group_dn = CUR.group_dn AND RQ.member_dn =
CUR.member_dn)
WHERE CUR.group_dn IS NULL", sTableName);
string sSqlDelBase = String.Format(@"
DELETE FROM [{0}]
WHERE {{0}}", sTableName);
int iRow = 0;
using (Handy.Sql oSql = new Handy.Sql(new SqlConnection(this.sConnectionString)))
{
foreach
(KeyValuePair<string,
Dictionary<string,
LdapEngine.MembershipAction>> kvDictionariesUpdates in dicUpdates)
{
foreach (KeyValuePair<string, LdapEngine.MembershipAction>
kvUpdate in kvDictionariesUpdates.Value)
{
string
sGroupDn
=
kvDictionariesUpdates.Key.Replace("'", "''") ;
string sMemberDn = kvUpdate.Key.Replace("'", "''");
string sGroupCn = this.GetCnFromDn(sGroupDn);
string sMemberCn = this.GetCnFromDn(sMemberDn);
if
LdapEngine.MembershipAction.Add)

BBB

(kvUpdate.Value

==

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{

if (sbSqlAdd.Length == 0)
{
sbSqlAdd.AppendFormat("SELECT
'{0}' as group_dn,'{1}' as member_dn,'{2}' as group_cn,'{3}' as member_cn\n", sGroupDn, sMemberDn, sGroupCn,
sMemberCn);
}
else
{
sbSqlAdd.AppendFormat(sCondAddBase, sGroupDn, sMemberDn, sGroupCn, sMemberCn);
}
}
else
{
if (sbSqlDel.Length == 0)
{
sbSqlDel.AppendFormat(sCondDelBase, sGroupDn, sMemberDn);
}
else
{
sbSqlDel.AppendFormat("OR\n"
sCondDelBase, sGroupDn, sMemberDn);
}
}
iRow++;
if ((iRow % ROW_LIMIT) == 0)
{
if (sbSqlDel.Length > 0)
{
sbSqlQuery.AppendFormat(sSqlDelBase + "\n", sbSqlDel);

}
if (sbSqlAdd.Length > 0)
{

sbSqlQuery.AppendFormat(sSqlAddBase, sbSqlAdd);
}
if (sbSqlQuery.Length > 0)
{
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
sbSqlQuery = new StringBuilder();
sbSqlAdd = new StringBuilder();
sbSqlDel = new StringBuilder();
}

}
}
if (sbSqlDel.Length > 0)
{
sbSqlQuery.AppendFormat(sSqlDelBase + "\n", sbSqlDel);
}
if (sbSqlAdd.Length > 0)
{
sbSqlQuery.AppendFormat(sSqlAddBase, sbSqlAdd);
}
if (sbSqlQuery.Length > 0 & (iRow % ROW_LIMIT) > 0)
{
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
}

CCC

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private void DeleteFromDb(string sTableName, HashSet<string> hsKeyValues, string sKeyColumn)


{
try
{
using
(Handy.Sql
oSql
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
if (hsKeyValues != null && hsKeyValues.Count > 0)
{
foreach (string sValue in hsKeyValues)
{
string sSqlQuery = String.Format(@"
DELETE FROM {0}
WHERE [{1}] = '{2}'",
sTableName,
sKeyColumn,
sValue.Replace("'", "''") );
oSql.ExecuteNonSqlQuery(sSqlQuery);
}
}
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void TruncateTable(string sTableName)
{
try
{
using
(Handy.Sql
objDatabase
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
string sSqlQuery = String.Format(@"TRUNCATE TABLE [{0}];",
sTableName);
objDatabase.ExecuteNonSqlQuery(sSqlQuery);
}

}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private Dictionary<string, Dictionary<string, string>> GetIndexedTable(string sTableName,


List<string> lColumnsToLoad, HashSet<string> hsObjectsToLoad, string sUniqueIndex)
{
const int MAX_RECORDS_PER_QUERY = 10000;
try
{
Dictionary<string, Dictionary<string, string>>
dicTableContent = new
Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
string sColumns;

DDD

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

using (Handy.Sql oSql = new Handy.Sql(this.sConnectionString))


{
sColumns = String.Empty;
foreach (string sCol in lColumnsToLoad)
{
sColumns += String.Format(",[{0}]", sCol);
}
sColumns = sColumns.TrimStart(',');
string sSqlQueryBase = String.Format(@"SELECT {0} FROM [{1}] WHERE",
sColumns, sTableName);
int iBufferFrameSize =
int iObjectsLoaded =

MAX_RECORDS_PER_QUERY;
0;

StringBuilder sbSqlQuery = new StringBuilder(sSqlQueryBase);


IEnumerator<string> enumObject = hsObjectsToLoad.GetEnumerator();
while (enumObject.MoveNext())
{
string sUniqueIdValue = enumObject.Current;
if (--iBufferFrameSize == 0 || iObjectsLoaded

==

hsObjectsToLoad.Count - 1)
{
sbSqlQuery.AppendLine( String.Format(@"[{0}] = '{1}'",
sUniqueIndex, sUniqueIdValue.Replace("'", "''")) );
foreach

(Dictionary<string,

object>

dicRes

in

oSql.RetrieveData(sbSqlQuery.ToString()))
{
Dictionary<string, string> dicRow = new
Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach(string sColumn in dicRes.Keys)
{
string sValue = null;
object oValue = dicRes[sColumn];
if (oValue.ToString().Length > 0)
{
if (oValue.GetType() ==
Type.GetType("System.DateTime"))
{
sValue

sValue

String.Format("{0:yyyy-MM-dd HH:mm:ss}", oValue);


}
else
{
oValue.ToString();
}
}
if (!dicRow.ContainsKey(sColumn))
{
dicRow.Add(sColumn,
sValue);
}
}
string sIndexVal = dicRow[sUniqueIndex];
if (!dicTableContent.ContainsKey(sIndexVal))
{
dicTableContent.Add(sIndexVal,
dicRow);

EEE

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


}
}
iBufferFrameSize = MAX_RECORDS_PER_QUERY;
sbSqlQuery = new StringBuilder(sSqlQueryBase);
}
else
{
sbSqlQuery.AppendLine(String.Format(@"[{0}] = '{1}'

OR", sUniqueIndex, sUniqueIdValue.Replace("'", "''")) );


}
iObjectsLoaded++;
}
}
return dicTableContent;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private Dictionary<string, Dictionary<string, string>> GetIndexedTable(string sTableName,
List<string> lColumnsToLoad, Dictionary<string, Dictionary<string, string>> dicObjectsToLoad, string sUniqueIndex)
{
try
{
HashSet<string>
hsObjectsToLoad
=
new
HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (string sKey in dicObjectsToLoad.Keys)
{
hsObjectsToLoad.Add(sKey);
}
return this.GetIndexedTable( sTableName, lColumnsToLoad, hsObjectsToLoad,
sUniqueIndex);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private Dictionary<string, HashSet<string>> GetIndexedTable( string sTableName, HashSet<string>
hsObjectsToLoad, string sKeyColumn, string sValueColumn)
{
try
{
const int MAX_RECORDS_PER_QUERY = 10000;
Dictionary<string, HashSet<string>> dicTableContent = new Dictionary<string,
HashSet<string>>(StringComparer.OrdinalIgnoreCase);
using (Handy.Sql oSql = new Handy.Sql(this.sConnectionString))
{
string
sColumns
=
String.Format("[{0}],[{1}]",

sKeyColumn,

sValueColumn);
string sSqlQueryBase = String.Format(@"SELECT {0} FROM [{1}] WHERE",
sColumns, sTableName);
int iBufferFrameSize =
int iObjectsLoaded =

MAX_RECORDS_PER_QUERY;
0;

StringBuilder sbSqlQuery = new StringBuilder(sSqlQueryBase);


IEnumerator<string> enumObject = hsObjectsToLoad.GetEnumerator();

FFF

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

while ( enumObject.MoveNext() )
{
string sUniqueIdValue = enumObject.Current;
if (--iBufferFrameSize == 0 || iObjectsLoaded

==

hsObjectsToLoad.Count - 1)
{

sbSqlQuery.AppendLine(String.Format(@"[{0}] = '{1}'",

sKeyColumn, sUniqueIdValue.Replace("'", "''")));


foreach

(Dictionary<string,

object>

dicRes

in

oSql.RetrieveData(sbSqlQuery.ToString()))
{
string

sValue_Key

dicRes[sKeyColumn].ToString();
if
(!dicTableContent.ContainsKey(sValue_Key))
{
dicTableContent.Add(sValue_Key,
new HashSet<string>(StringComparer.OrdinalIgnoreCase));
dicTableContent[sValue_Key].Add(dicRes[sValueColumn].ToString());
}
else
(!dicTableContent[sValue_Key].Contains(dicRes[sValueColumn].ToString()))
{

if

dicTableContent[sValue_Key].Add(dicRes[sValueColumn].ToString());
}
}
iBufferFrameSize = MAX_RECORDS_PER_QUERY;
sbSqlQuery = new StringBuilder(sSqlQueryBase);
}
else
{
sbSqlQuery.AppendLine(String.Format(@"[{0}] = '{1}'
OR", sKeyColumn, sUniqueIdValue.Replace("'", "''")) );
}
iObjectsLoaded++;
}
}
return dicTableContent;
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}
private
lDomainControllers)
{

DomainController

Exception(string.Format("{0}::{1}",

GetLastServerByUsn(string

sTableName,

new

StackFrame(0,

List<DomainController>

try
{
DomainController oDomainController = null;
string sServerName = String.Empty;
string sSqlCondition = String.Empty;
using
(Handy.Sql
oSql
=
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
foreach (DomainController oDC in lDomainControllers)
{

GGG

new

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


try
{
sSqlCondition += String.Format(@"invocationID='{0}'

OR ", oDC.GetDirectoryEntry().NativeGuid);
}
catch
{

}
}
if (sSqlCondition.Length > 0)
{
sSqlCondition = sSqlCondition.Substring(0, sSqlCondition.Length
- 4);

sSqlCondition);

string sQuery = String.Format(@"


SELECT TOP 1 dcDNS
FROM {0}
WHERE {1}
ORDER BY highestCommittedUSN
foreach

(Dictionary<string,

DESC",

object>

sTableName,
dicRes

in

oDC

oSql.RetrieveData(sQuery))
{
IEnumerator<DomainController>
lDomainControllers.GetEnumerator();
while (oDomainController == null && oDC.MoveNext())
{
if
(oDC.Current.Name.Equals(dicRes["dcDNS"].ToString(), StringComparison.OrdinalIgnoreCase))
{
oDomainController = oDC.Current;
}
}
}
}
}
return oDomainController;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private long GetLastSyncUsn(string sTableName, string sInvocationId, string sContext)
{
try
{
long iHighestCommittedUsn = 0;
string sSqlClause = String.Empty;
using
(Handy.Sql
oSql
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
sSqlClause = String.Format("invocationID = '{0}'", sInvocationId);
if (sContext != null)
{
sSqlClause += String.Format(" AND TableContext = '{0}'",
sContext);
}
string sQuery = String.Format(@"
SELECT TOP 1 highestCommittedUSN

HHH

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


FROM {0}
WHERE {1}
ORDER BY

highestCommittedUSN

DESC",

sTableName,

sSqlClause);
foreach (Dictionary<string, object> dicRes in oSql.RetrieveData(sQuery))
{
iHighestCommittedUsn
=
Convert.ToInt64(dicRes["highestCommittedUSN"]);
}
}
return iHighestCommittedUsn;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void SetLastSyncUsn(string sTableName, string sServerName, string sDomainName, string
sInvocationId, string sContext, long iHighestCommittedUsn)
{
try
{
using
(Handy.Sql
oSql
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
string sSqlQuery = String.Format(@"
INSERT INTO {0}
(dcDNS,
highestCommittedUSN,
DomainName,
invocationID, TableContext)
VALUES
({1},{2},{3},{4},{5})",
sTableName,
String.Format("'{0}'", sServerName),
String.Format("{0}", iHighestCommittedUsn),
String.Format("'{0}'", sDomainName),
String.Format("'{0}'", sInvocationId),
String.Format("'{0}'", sContext)
);
oSql.ExecuteNonSqlQuery(sSqlQuery);
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private Dictionary<string, string> GetDiffs(Dictionary<string, string> dicSource, Dictionary<string,
string> dicDestination)
{
try
{
Dictionary<string,
string>
dicDiffs
=
new
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);
foreach (string sSrc_Key in dicSource.Keys)
{
string sNewValue = dicSource[sSrc_Key];
string sOldValue = dicDestination[sSrc_Key];
if (dicDestination.ContainsKey(sSrc_Key))
{
if (sNewValue != null)

III

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{
if

(!sNewValue.Equals(sOldValue,

StringComparison.OrdinalIgnoreCase))
{
dicDiffs.Add(sSrc_Key, sNewValue);
}
}
else if (sNewValue != sOldValue)
{
dicDiffs.Add(sSrc_Key, sNewValue);
}
}
else
{
dicDiffs.Add(sSrc_Key, sNewValue);
}
}
return dicDiffs;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private List<List<Dictionary<string, string>>> GetDiffs(Dictionary<string, Dictionary<string, string>>
dicDSource, Dictionary<string, Dictionary<string, string>> dicDDestination, string KeyAttribute)
{
try
{
List<List<Dictionary<string, string>>> lLDResult = new List<List<Dictionary<string,
string>>>();
foreach (string sIndex in dicDSource.Keys)
{
List<Dictionary<string, string>> lDRes = new List<Dictionary<string,
string>>();
Dictionary<string,

string>

dicDst

new

Dictionary<string,

Dictionary<string,

string>

dicSrc

new

Dictionary<string,

string>(StringComparer.OrdinalIgnoreCase);
string>(StringComparer.OrdinalIgnoreCase);
dicSrc = dicDSource[sIndex];
if (dicDDestination.TryGetValue(sIndex, out dicDst))
{
Dictionary<string, string> dicDiffs = GetDiffs(dicSrc, dicDst);
if (dicDiffs.Count > 0)
{
if (KeyAttribute != null)
{
lDRes.Add(new
Dictionary<string,string>(StringComparer.OrdinalIgnoreCase){{KeyAttribute.ToString(),
dicDst[KeyAttribute.ToString()]}});
}
else
{
lDRes.Add(dicDst);
}
lDRes.Add(dicDiffs);
}
}
else
{
lDRes.Add(null);

JJJ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

lDRes.Add(dicSrc);
}
if (lDRes.Count > 0)
{
lLDResult.Add(lDRes);
}
}
return lLDResult;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private List<List<Dictionary<string, string>>> GetDiffs(Dictionary<string, HashSet<string>>
dicLSource, Dictionary<string, HashSet<string>> dicLDestination, string sKeyColumn, string sValueColumn)
{
try
{
List<List<Dictionary<string, string>>> lLDResult = new List<List<Dictionary<string,
string>>>();
//to add
foreach (string sIndex in dicLSource.Keys)
{
List<Dictionary<string, string>> lDRes;
HashSet<string>
HashSet<string>(StringComparer.OrdinalIgnoreCase);
HashSet<string>
HashSet<string>(StringComparer.OrdinalIgnoreCase);

lDst

new

lSrc

new

lSrc = dicLSource[sIndex];
if (dicLDestination.TryGetValue(sIndex, out lDst))
{
foreach (string sValue in lSrc)
{
lDRes = new List<Dictionary<string, string>>();
if

(!lDst.Contains(sValue,

StringComparer.OrdinalIgnoreCase))
{
//add CN feature
lDRes.Add(null);
lDRes.Add(new
string>(StringComparer.OrdinalIgnoreCase)

Dictionary<string,

{
{ sKeyColumn, sIndex },
{ sValueColumn, sValue },
{ sKeyColumn.Replace("_dn", "_cn"),

this.GetCnFromDn(sIndex) },
{

sValueColumn.Replace("_dn",

"_cn"), this.GetCnFromDn(sValue) }
});
}
if (lDRes.Count > 0)
{
lLDResult.Add(lDRes);
}

}
}
else
{

KKK

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


foreach (string sValue in lSrc)
{
lDRes = new List<Dictionary<string, string>>();
lDRes.Add(null);
lDRes.Add(new

string>(StringComparer.OrdinalIgnoreCase)

Dictionary<string,

{
{ sKeyColumn, sIndex },
{ sValueColumn, sValue },
{
sKeyColumn.Replace("_dn",

"_cn"),

"_cn"),

this.GetCnFromDn(sIndex) },
sValueColumn.Replace("_dn",

this.GetCnFromDn(sValue) }
});
if (lDRes.Count > 0)
{
lLDResult.Add(lDRes);
}
}
}

//to remove
foreach (string sIndex in dicLDestination.Keys)
{
List<Dictionary<string, string>> lDRes;
HashSet<string>
HashSet<string>(StringComparer.OrdinalIgnoreCase);
HashSet<string>
HashSet<string>(StringComparer.OrdinalIgnoreCase);

lDst

new

lSrc

new

lDst = dicLDestination[sIndex];
if (dicLSource.TryGetValue(sIndex, out lSrc))
{
foreach (string sValue in lDst)
{
lDRes = new List<Dictionary<string, string>>();
if

(!lSrc.Contains(sValue,

StringComparer.OrdinalIgnoreCase))
{
lDRes.Add(new Dictionary<string, string>() {
{ sKeyColumn, sIndex }, { sValueColumn, sValue } });
lDRes.Add(null);
}
if (lDRes.Count > 0)
{
lLDResult.Add(lDRes);
}
}
}
else
{
foreach (string sValue in lSrc)
{
lDRes = new List<Dictionary<string, string>>();
lDRes.Add(new
sKeyColumn, sIndex }, { sValueColumn, sValue } });

Dictionary<string,

lDRes.Add(null);
if (lDRes.Count > 0)
{
lLDResult.Add(lDRes);

LLL

string>()

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
}
}
}
return lLDResult;
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private void AdjustMembershipTableWithDnChanges(string sMembershipTable, string sObjectTable,


Dictionary<string, Dictionary<string, string>> dicChanges, LdapEngine.UniqueObjectIdentifier enKeyAttribute, bool
bOnlyMember)
{
try
{
const int ROW_LIMIT = 1000;
using (Handy.Sql oSql = new Handy.Sql(this.sConnectionString))
{
string sSqlQueryMbrBase = String.Format("UPDATE MBR SET
member_dn='{{0}}' FROM [{0}] MBR JOIN [{1}] OBJ ON (OBJ.distinguishedName=MBR.member_dn) LEFT JOIN [{0}] CHK ON
(MBR.group_dn = CHK.group_dn AND CHK.member_dn = '{{0}}') WHERE CHK.group_dn IS NULL AND
OBJ.distinguishedName!='{{0}}' AND OBJ.{2}='{{1}}' IF @@ROWCOUNT>0 DELETE MBR FROM [{0}] MBR JOIN [{1}] OBJ
ON (OBJ.distinguishedName=MBR.member_dn) WHERE OBJ.distinguishedName=MBR.member_dn AND OBJ.{2}='{{1}}'\n",
sMembershipTable, sObjectTable, enKeyAttribute);
string sSqlQueryGrpBase = String.Format("UPDATE MBR SET
group_dn='{{0}}' FROM [{0}] MBR JOIN [{1}] OBJ ON (OBJ.distinguishedName=MBR.group_dn) LEFT JOIN [{0}] CHK ON
(MBR.member_dn = CHK.member_dn AND CHK.group_dn = '{{0}}') WHERE CHK.group_dn IS NULL AND
OBJ.distinguishedName!='{{0}}' AND OBJ.{2}='{{1}}' IF @@ROWCOUNT>0 DELETE MBR FROM [{0}] MBR JOIN [{1}] OBJ
ON (OBJ.distinguishedName=MBR.group_dn) WHERE OBJ.distinguishedName=MBR.group_dn AND OBJ.{2}='{{1}}'\n",
sMembershipTable, sObjectTable, enKeyAttribute);
StringBuilder sbSqlQuery = new StringBuilder();
int iRow = 0;
foreach(KeyValuePair<string, Dictionary<string, string>> kvUpdates in
dicChanges)
{
string sUpdatedDn = null;
if
(kvUpdates.Value.TryGetValue("distinguishedName",
sUpdatedDn))
{

sUpdatedDn = sUpdatedDn.Replace("'", "''");


sbSqlQuery.AppendFormat(sSqlQueryMbrBase,

sUpdatedDn, kvUpdates.Key);
if (!bOnlyMember)
{
sbSqlQuery.AppendFormat(sSqlQueryGrpBase, sUpdatedDn, kvUpdates.Key);
}
}
iRow++;
if (sbSqlQuery.Length > 0 && (iRow % ROW_LIMIT) == 0)
{
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
sbSqlQuery = new StringBuilder();
}

MMM

out

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
if (sbSqlQuery.Length > 0 && (iRow % ROW_LIMIT) > 0)
{
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
}
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void AdjustMembershipTableWithDeletions(string sMembershipTable, string sObjectTable,
IEnumerator<string> enumDeleted, LdapEngine.UniqueObjectIdentifier enKeyAttribute, bool bOnlyMember)
{
try
{
const int ROW_LIMIT = 1000;
using (Handy.Sql oSql = new Handy.Sql(this.sConnectionString))
{
string sSqlQueryMbrBase = String.Format("DELETE MBR FROM [{0}] MBR
JOIN [{1}] OBJ ON (OBJ.distinguishedName=MBR.member_dn) WHERE OBJ.{2} IN ({{0}})\n", sMembershipTable,
sObjectTable, enKeyAttribute);
string sSqlQueryGrpBase = String.Format("DELETE MBR FROM [{0}] MBR
JOIN [{1}] OBJ ON (OBJ.distinguishedName=MBR.group_dn) WHERE OBJ.{2} IN ({{0}})\n", sMembershipTable,
sObjectTable, enKeyAttribute);
StringBuilder sbSqlQuery = new StringBuilder();
StringBuilder sbSqlCond = new StringBuilder();
int iRow = 0;
while (enumDeleted.MoveNext())
{
if ((iRow % ROW_LIMIT) == 0)
{
sbSqlCond.AppendFormat("'{0}'",
enumDeleted.Current);
}
else
{
sbSqlCond.AppendFormat(",'{0}'",
enumDeleted.Current);
}
iRow++;
if ((iRow % ROW_LIMIT) == 0)
{
sbSqlQuery.AppendFormat(sSqlQueryMbrBase,
sbSqlCond);
if (!bOnlyMember)
{
sbSqlQuery.AppendFormat(sSqlQueryGrpBase, sbSqlCond);
}
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
sbSqlQuery = new StringBuilder();
sbSqlCond = new StringBuilder();
}
}
if (sbSqlCond.Length > 0 && (iRow % ROW_LIMIT) > 0)
{
sbSqlQuery.AppendFormat(sSqlQueryMbrBase, sbSqlCond);
if (!bOnlyMember)

NNN

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{
sbSqlQuery.AppendFormat(sSqlQueryGrpBase,

sbSqlCond);
}
oSql.ExecuteNonSqlQuery(sbSqlQuery.ToString());
}
}

}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private List<string> GetAttributeList(string sTableName)


{
try
{
List<string> lAttributeList = new List<string>();
using (Handy.Sql oSql = new Handy.Sql(this.sConnectionString) )
{
string strSQL = String.Format("SELECT COLUMN_NAME
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{0}'", sTableName);

FROM

foreach (Dictionary<string, object> dicRes in oSql.RetrieveData(strSQL))


{
lAttributeList.Add(dicRes["COLUMN_NAME"].ToString());
}
}
return lAttributeList;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private List<string> GetDomains()
{
try
{
List<string> lDomains = new List<string>();
using
(Handy.Sql
oSql
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
string strSQL = String.Format(@"SELECT DISTINCT(DNSDomain) FROM
{0}
WHERE
Description
=
'Default'
AND
LEN(DNSDomain)>0",
ConfigurationManager.AppSettings["configuration"].ToString());
foreach(Dictionary<string, object> dicRes in oSql.RetrieveData(strSQL))
{
lDomains.Add(dicRes["DNSDomain"].ToString());
}
}
return lDomains;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
private List<string> GetForestDomains()
{

OOO

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

try
{
List<string> lDomains = new List<string>();
return lDomains;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
private string GetTableName(string strClass, string strDomain)
{
string strTable = null;

new

StackFrame(0,

switch (strClass.ToLower())
{
case "user":
strTable = this.GetDBConfig("Default", strDomain, "UserTable");
break;
case "ged":
strTable = this.GetDBConfig("Default", strDomain, "GEDTable");
break;
case "group":
strTable = this.GetDBConfig("Default", strDomain, "GroupTable");
break;
case "computer":
strTable = this.GetDBConfig("Default", strDomain, "ComputerTable");
break;
case "contact":
strTable = this.GetDBConfig("Default", strDomain, "ContactTable");
break;
case "member":
strTable = this.GetDBConfig("Default", strDomain, "MembershipTable");
break;
case "security":
strTable = this.GetDBConfig("Default", strDomain, "SecurityTable");
break;
case "fsp":
strTable = this.GetDBConfig("Default", strDomain, "FspTable");
break;
default:
strTable = this.GetDBConfig("Default", strDomain, strClass);
break;
}
return strTable;
}
private string GetDBConfig(string strDescription, string strDNSDomain, string strKeyName)
{
string strValue = null;
try
{
string strSQL = null;
if (strDescription != null && strDescription != String.Empty && strKeyName != null
&& strKeyName != String.Empty)

PPP

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
if (strDNSDomain != null)
{
strSQL = string.Format("SELECT KeyValue FROM {0} WHERE
Description
=
'{1}'
AND
DNSDomain
=
'{2}'
AND
KeyName
=
'{3}'",
ConfigurationManager.AppSettings["Configuration"].ToString(), strDescription, strDNSDomain, strKeyName);
}
else
{
strSQL = string.Format("SELECT KeyValue FROM {0} WHERE
Description = '{1}' AND KeyName = '{2}'", ConfigurationManager.AppSettings["Configuration"].ToString(), strDescription,
strKeyName);
}
using
(Handy.Sql
oSql
=
new
Handy.Sql(ConfigurationManager.ConnectionStrings["iADConnector"].ConnectionString))
{
foreach
(Dictionary<string,
object>
dicRes
in
oSql.RetrieveData(strSQL))
{
strValue = dicRes["KeyValue"].ToString();
}
}
}
}
catch (Exception ex)
{
throw
new
Exception(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message));
}
return strValue;
}
public void UpdateRecord(string sTableName, Dictionary<string, string> dicCur, Dictionary<string,
string> dicNew, Handy.Sql oSql)
{
try
{
string sSqlQuery = String.Empty;
string sClause = String.Empty;
string sUpd = String.Empty;
foreach (string sKey in dicNew.Keys)
{
string sValue = dicNew[sKey];
if (sValue == null)
{
sUpd += String.Format(@",[{0}]=NULL", sKey);
}
else
{
sUpd += String.Format(@",[{0}]='{1}'", sKey,sValue.Replace(@"'",
@"''"));
}
}
sUpd = sUpd.TrimStart(',');
foreach (string sKey in dicCur.Keys)
{
string sValue = dicCur[sKey];
if (sValue == null)
{
sClause += String.Format(@" AND [{0}] Is NULL", sKey);
}
else
{

QQQ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


sClause

+=

String.Format(@"

AND

[{0}]='{1}'",

sKey,

sValue.Replace(@"'", @"''"));
}
}
sClause = sClause.Substring(4);
sSqlQuery = String.Format(@"
UPDATE {0}
SET {1}
WHERE {2}",
sTableName, sUpd, sClause);
oSql.ExecuteNonSqlQuery(sSqlQuery);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public void InsertRecord(string sTableName, Dictionary<string, string> dicNew, Handy.Sql oSql)
{
try
{
string sSqlQuery = String.Empty;
string sColumns = String.Empty;
string sValues = String.Empty;
foreach (string sKey in dicNew.Keys)
{
string sValue = dicNew[sKey];
sColumns += String.Format(@",[{0}]", sKey);
if (sValue == null)
{
sValues += String.Format(@",NULL");
}
else
{
sValues += String.Format(@",'{0}'", sValue.Replace(@"'", @"''"));
}
}
sColumns = sColumns.TrimStart(',');
sValues = sValues.TrimStart(',');
sSqlQuery = String.Format(@"
INSERT INTO {0}
({1})
VALUES ({2})",
sTableName, sColumns, sValues);
oSql.ExecuteNonSqlQuery(sSqlQuery);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public void DeleteRecord(string sTableName, Dictionary<string, string> dicCur, Handy.Sql oSql)
{
try
{
string sSqlQuery = String.Empty;
string sClause = String.Empty;

RRR

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

foreach (string sKey in dicCur.Keys)


{
string sValue = dicCur[sKey];
if (sValue == null)
{
sClause += String.Format(@" AND [{0}] Is NULL", sKey);
}
else
{
sClause += String.Format(@" AND [{0}]='{1}'",

sKey,

sValue.Replace(@"'", @"''"));
}
}
sClause = sClause.Substring(4);
sSqlQuery = String.Format(@"
DELETE FROM {0}
WHERE {1}",
sTableName, sClause);
oSql.ExecuteNonSqlQuery(sSqlQuery);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

StackFrame(0,

private List<StringBuilder> GenerateBulkLoad(string sTableName, IEnumerable<Dictionary<string,


string>> IRecordsCollection, List<string> lAttributes)
{
try
{
const int ROW_LIMIT = 1000;
List<StringBuilder> BulkLoadPackets = new List<StringBuilder>();
StringBuilder sbSqlBulk = new StringBuilder(String.Format("INSERT INTO [{0}]
({1})", sTableName, String.Join(",", lAttributes.ToArray())));
int iRow = 0;
foreach (Dictionary<string, string> dicRecord in IRecordsCollection)
{
string sRow = String.Empty;
if (iRow % ROW_LIMIT == 0)
{
sbSqlBulk.AppendLine("SELECT");
foreach (string sKey in lAttributes)
{
string sValue = String.Empty;
if (dicRecord.TryGetValue(sKey, out sValue))
{
sbSqlBulk.AppendFormat(@"'{0}' as [{1}],",
sValue.Replace("'", "''"), sKey);
}
else
{
sbSqlBulk.AppendFormat(@"NULL as [{0}],",
sKey);

}
}
sbSqlBulk.Remove(sbSqlBulk.Length - 1, 1);
}

SSS

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

else
{
sbSqlBulk.AppendLine("\nUNION ALL SELECT");
foreach (string sKey in lAttributes)
{
string sValue = String.Empty;
if (dicRecord.TryGetValue(sKey, out sValue))
{
sbSqlBulk.AppendFormat(@"'{0}',",
sValue.Replace("'", "''"));
}
else
{
sbSqlBulk.AppendFormat(@"NULL,");
}
}
sbSqlBulk.Remove(sbSqlBulk.Length - 1, 1);
}
iRow++;
if ((iRow % ROW_LIMIT) == 0)
{
if (sbSqlBulk.Length > 0)
{
BulkLoadPackets.Add(sbSqlBulk);
sbSqlBulk = new StringBuilder(String.Format("INSERT
INTO [{0}] ({1})", sTableName, String.Join(",", lAttributes.ToArray())));
}
}
}
if (sbSqlBulk.Length > 0 & (iRow % ROW_LIMIT) > 0)
{
BulkLoadPackets.Add(sbSqlBulk);
}
return BulkLoadPackets;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}

new

StackFrame(0,

}
#endregion
#region Helper Private Methods
private string DecryptString(string strInput)
{
try
{
if (strInput != null && strInput.Length > 0)
{
if (strInput.StartsWith("ID=") || strInput.StartsWith("PW="))
{
return
SimpleCrypto.DecryptString(strInput.Substring(3,
strInput.Length - 3));
}
else
{
return SimpleCrypto.DecryptString(strInput);
}
}
else

TTT

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
return strInput;
}
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private String ConvertSecureStringToString(SecureString secureString)


{
try
{
IntPtr ptSecureString = Marshal.SecureStringToBSTR(secureString);
return Marshal.PtrToStringBSTR(ptSecureString);
}
catch (Exception ex)
{
throw
new
Exception(String.Format("{0}::{1}",
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message));
}
}

new

private string GetCnFromDn(string sDistinguishedName)


{
try
{
string sCommonName = string.Empty;
const char START_CHAR = '=';
const char END_CHAR = ',';
const char ESC_CHAR = '\\';
bool bWrite = false;
if (sDistinguishedName != null && sDistinguishedName.Length > 0)
{
int i = 0;
while
(i
<
sDistinguishedName.Length
!sDistinguishedName[i].Equals(END_CHAR))
{
char c = sDistinguishedName[i];

&&

if (c.Equals(ESC_CHAR)) { i++; c = sDistinguishedName[i]; }


if (bWrite) sCommonName += c;
if (c.Equals(START_CHAR)) bWrite = true;
i++;
}
}
return sCommonName;
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

private string GetFilter(string sObjectClass, bool bExtended)


{
if(sObjectClass.Equals("user", StringComparison.OrdinalIgnoreCase) )

UUU

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
return bExtended
? @"(&(objectCategory=person)(objectClass=user))"
: @"(objectClass=user)";
}
else if (sObjectClass.Equals("ged", StringComparison.OrdinalIgnoreCase))
{
return @"(&(objectClass=csgPerson)(csgPersonStatus=active))";
}
else if (sObjectClass.Equals("group", StringComparison.OrdinalIgnoreCase))
{
return bExtended
? @"(&(objectCategory=group)(objectClass=group))"
: @"(objectClass=group)";
}
else if (sObjectClass.Equals("computer", StringComparison.OrdinalIgnoreCase))
{
return bExtended
? @"(&(objectCategory=computer)(objectClass=computer))"
: @"(objectClass=computer)";
}
else if (sObjectClass.Equals("security", StringComparison.OrdinalIgnoreCase))
{
return bExtended
?
@"(&(objectCategory=organizationalUnit)(objectClass=organizationalUnit))"
: @"(objectClass=organizationalUnit)";
}
else if (sObjectClass.Equals("fsp", StringComparison.OrdinalIgnoreCase))
{
return
@"(&(objectClass=foreignSecurityPrincipal)(objectClass=foreignSecurityPrincipal))";
}
else if (sObjectClass.Equals("contact", StringComparison.OrdinalIgnoreCase))
{
return @"(&(objectCategory=person)(objectClass=contact))";
}
else
{
return @"(objectClass=*)";
}
}
private string[] GetSiteServers(string DomainName, string ADSite)
{
try
{
return this.GetSiteServers(DomainName, ADSite, null, null);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private string[] GetSiteServers(string DomainName, string ADSite, string UserID, string UserPW)
{
string sDomainControllers = null;
try
{
using (Domain oDomain = UserID != null && UserPW != null
?
Domain.GetDomain(new
DirectoryContext(DirectoryContextType.Domain, DomainName, UserID, UserPW))
:
Domain.GetDomain(new
DirectoryContext(DirectoryContextType.Domain, DomainName)))

VVV

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
DomainControllerCollection colDomControllers = (ADSite != null)
? oDomain.FindAllDomainControllers(ADSite)
: oDomain.FindAllDomainControllers();
if (colDomControllers.Count == 0)
{
colDomControllers = oDomain.FindAllDomainControllers();
}
foreach (DomainController DC in colDomControllers)
{
sDomainControllers += String.Format(";{0}", DC.Name);
}
}
sDomainControllers = sDomainControllers.TrimStart(';');
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

return sDomainControllers.Split(';');
}
private List<DomainController> GetSiteDC(string DomainName, string ADSite, string UserID, string
UserPW)
{
try
{
List<DomainController> lDomainControllers = new List<DomainController>();
using (Domain oDomain = UserID != null && UserPW != null
?
Domain.GetDomain(new
DirectoryContext(DirectoryContextType.Domain, DomainName, UserID, UserPW))
:
Domain.GetDomain(new
DirectoryContext(DirectoryContextType.Domain, DomainName)))
{
DomainControllerCollection colDomControllers = (ADSite != null)
? oDomain.FindAllDomainControllers(ADSite)
: oDomain.FindAllDomainControllers();
if (colDomControllers.Count == 0)
{
colDomControllers = oDomain.FindAllDomainControllers();
}
foreach (DomainController oDC in colDomControllers)
{
lDomainControllers.Add(oDC);
}
}
return lDomainControllers;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void CreateEventMessage(Entry objEventEntry)
{
try
{
this.objEntry = objEventEntry;
if (OnMessage != null)
{
OnMessage(this.objEntry);

WWW

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
private void GetEventMessage(Entry objEventEntry)
{
try
{
this.objEntry = objEventEntry;
CreateEventMessage(this.objEntry);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (!this.bDisposed)
{
if (bDisposing)
{
}
this.bDisposed = true;
}
}
#endregion
}
}

XXX

new

StackFrame(0,

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

SIMPLECRYPTO.CS
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
class SimpleCrypto :IDisposable
{
#region Private Variables
private bool bDisposed;
#endregion
#region Constructors
public SimpleCrypto()
{
this.bDisposed = false;
}
#endregion
#region Public Methods
public string Encrypt(string PlainText)
{
try
{
return
Convert.ToBase64String(PlainText.ToCharArray().Select(cChar
=>
(byte)(~Convert.ToByte(cChar))).ToArray());
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}", new StackFrame(0, true).GetMethod().Name,
ex.Message));
}
}
public string Decrypt(string DecryptedText)
{
try
{
return
new
String(
Convert.ToChar((byte)~bByte)).ToArray() );

Convert.FromBase64String(DecryptedText).Select(bByte

=>

}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}", new StackFrame(0, true).GetMethod().Name,
ex.Message));
}
}
#endregion
#region Public Methods
public static string EncryptString(string PlainText)
{
try
{
return
Convert.ToBase64String(PlainText.ToCharArray().Select(cChar
=>
(byte)(~Convert.ToByte(cChar))).ToArray());
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}", new StackFrame(0, true).GetMethod().Name,
ex.Message));

YYY

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
}
public static string DecryptString(string DecryptedText)
{
try
{
return
new
String(Convert.FromBase64String(DecryptedText).Select(bByte
Convert.ToChar((byte)~bByte)).ToArray());

=>

}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}", new StackFrame(0, true).GetMethod().Name,
ex.Message));
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (!this.bDisposed)
{
if (bDisposing)
{
}
this.bDisposed = true;
}
}
#endregion
}

ZZZ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

HANDY.CS
using System;
using System.Collections.Generic;
using System.Data;
//using System.Data.SqlClient;
using System.Diagnostics;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Net;
namespace Handy
{
class Ldap : IDisposable
{
#region Constants
private const int CONN_TIME_OUT = 600; //seconds
#endregion
#region Variables
private bool bDisposed;
private string sBaseSearchDn = null;
private string[] aDcServers = null;
private Int32 iPortNumber = 389;
private Int32 iPageSize = 500;
private NetworkCredential netCredentials = null;
//class properties
public string BaseSearchDn
{
get
{
return this.sBaseSearchDn;
}
set
{
this.sBaseSearchDn = value;
}
}
public string[] DomainControllers
{
get
{
return this.aDcServers;
}
set
{
this.aDcServers = value;
}
}
public Int32 Port
{
get
{
return this.iPortNumber;
}
set
{

AAAA

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

this.iPortNumber = value;
}
}
public Int32 PageSize
{
get
{
return this.iPageSize;
}
set
{
this.iPageSize = value;
}
}
public NetworkCredential NetworkCredentials
{
set
{
this.netCredentials = value;
}
}
#endregion
#region Constructors
public Ldap(string DomainName, string UserName, string Password)
{
try
{
this.bDisposed = false;
netCredentials = new NetworkCredential();
netCredentials.UserName = UserName;
netCredentials.Password = Password;
this.aDcServers = new string[] { DomainName };
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public Ldap(string DomainName, string UserName, string Password, string BaseDn, Int32 Port)
{
try
{
this.bDisposed = false;
this.netCredentials = new NetworkCredential();
this.netCredentials.UserName = UserName;
this.netCredentials.Password = Password;
this.iPortNumber = Port;
this.BaseSearchDn = BaseDn;
this.aDcServers = new string[] { DomainName };
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
#endregion

BBBB

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

#region Public Methods


public IEnumerable<Dictionary<string, object>> RetrieveAttributes(string LdapFilter, string[]
AttributesToLoad, bool ShowDeleted)
{
using (LdapConnection oLdapConnection = this.OpenLdapConnection(this.aDcServers[0],
this.netCredentials))
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
PageResultRequestControl rcPageRequest = null;
PageResultResponseControl rcPageResponse = null;
string sServerName = oLdapConnection.SessionOptions.HostName;
string
sBaseDn
=
(this.sBaseSearchDn
==
null
||
this.sBaseSearchDn.Equals(String.Empty))
?
String.Format("DC={0}",
sServerName.Substring(sServerName.IndexOf('.') + 1).Replace(".", ",DC="))
: this.sBaseSearchDn;
srRequest = new SearchRequest(
sBaseDn,
LdapFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
AttributesToLoad
);
if (ShowDeleted)
{
srRequest.Controls.Add(new ShowDeletedControl());
}
//PAGED
if (this.iPageSize > 0)
{
rcPageRequest = new PageResultRequestControl();
rcPageRequest.PageSize = this.iPageSize;
srRequest.Controls.Add(rcPageRequest);
do
{
try
{
dirRes

rcPageResponse

(SearchResponse)oLdapConnection.SendRequest(srRequest);
(PageResultResponseControl)dirRes.Controls[0];
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}", new
StackFrame(0, true).GetMethod().Name, ex.Message));
}
if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
Dictionary<string, object> dicProperties =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
foreach
(string
sAttribute
in
AttributesToLoad)
{
if
(srEntry.Attributes.Contains(sAttribute))

CCCC

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{

dicProperties.Add(sAttribute,
srEntry.Attributes[sAttribute].GetValues(srEntry.Attributes[sAttribute][0].GetType()));
}
}
yield return dicProperties;
}
}
rcPageRequest.Cookie = rcPageResponse.Cookie;
}
while (Convert.ToBoolean(rcPageResponse.Cookie.Length));
}
//NOT PAGED
else
{
try
{
dirRes
(SearchResponse)oLdapConnection.SendRequest(srRequest);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
StackFrame(0, true).GetMethod().Name, ex.Message));
}

new

if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
Dictionary<string, object> dicProperties = new
Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
foreach (string sAttribute in AttributesToLoad)
{
if (srEntry.Attributes.Contains(sAttribute))
{
dicProperties.Add(sAttribute,
srEntry.Attributes[sAttribute].GetValues(srEntry.Attributes[sAttribute][0].GetType()));
}
}
yield return dicProperties;
}
}
}
//dispose
if (dirRes != null) { dirRes = null; }
if (srRequest != null) { srRequest = null; }
if (rcPageRequest != null) { rcPageRequest = null; }
if (rcPageResponse != null) { rcPageResponse = null; }
}
}
#endregion
#region Private Methods
private LdapConnection OpenLdapConnection(string sServerName, NetworkCredential netCred)
{
try
{
LdapDirectoryIdentifier
oLdapDirectory
=
LdapDirectoryIdentifier(sServerName, this.Port);

new

LdapConnection oLdapConnection = new LdapConnection(oLdapDirectory, netCred,


AuthType.Basic);
oLdapConnection.Bind();

DDDD

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

oLdapConnection.Timeout = TimeSpan.FromSeconds(CONN_TIME_OUT);
oLdapConnection.SessionOptions.TcpKeepAlive = true;
oLdapConnection.SessionOptions.ProtocolVersion = 3;
//prevents ldap connection from connecting to other servers during session
oLdapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
oLdapConnection.AutoBind = false;
return oLdapConnection;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (!this.bDisposed)
{
if (bDisposing)
{
}
this.bDisposed = true;
}
}
#endregion
}
class Sql : IDisposable
{
#region Variables
private bool bDisposed;
private int iCommandTimeout = 300;
private string sConnectionString;
private System.Data.SqlClient.SqlConnection oSqlConnection;
public int CommandTimeout
{
get
{
return this.iCommandTimeout;
}
set
{
this.iCommandTimeout = value;
}
}
public string ConnectionString
{
get
{

EEEE

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

return this.sConnectionString;
}
set
{
this.sConnectionString = value;
}
}
public System.Data.SqlClient.SqlConnection sqlConnection
{
get
{
return this.oSqlConnection;
}
set
{
this.oSqlConnection = value;
}
}
#endregion
#region Constructors
public Sql(string SqlConnectionString)
{
this.bDisposed = false;
this.sConnectionString = SqlConnectionString;
}
public Sql(string SqlConnectionString, int CommandTimeout)
{
this.bDisposed = false;
this.iCommandTimeout = CommandTimeout;
this.sConnectionString = SqlConnectionString;
}
public Sql(System.Data.SqlClient.SqlConnection sqlConnection)
{
this.bDisposed = false;
this.sqlConnection = sqlConnection;
if (this.sqlConnection.State != ConnectionState.Open) this.sqlConnection.Open();
}
public Sql(System.Data.SqlClient.SqlConnection sqlConnection, int CommandTimeout)
{
this.bDisposed = false;
this.iCommandTimeout = CommandTimeout;
this.sqlConnection = sqlConnection;
if (this.sqlConnection.State != ConnectionState.Open) this.sqlConnection.Open();
}
#endregion
#region Public Methods
public IEnumerable<Dictionary<string, object>> RetrieveData(string SqlQuery)
{
using
(System.Data.SqlClient.SqlConnection
sqlConnection
System.Data.SqlClient.SqlConnection(this.sConnectionString))
{
try
{
sqlConnection.Open();
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}", new
true).GetMethod().Name, ex.Message));
}

FFFF

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

using
(System.Data.SqlClient.SqlCommand
sqlCommand
=
System.Data.SqlClient.SqlCommand(SqlQuery, sqlConnection))
{
sqlCommand.CommandTimeout = this.CommandTimeout;
using
(System.Data.SqlClient.SqlDataReader
sqlReader
sqlCommand.ExecuteReader())
{
while (sqlReader.Read())
{
Dictionary<string,
object>
dicRecord
=
Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
for (int i = 0; i < sqlReader.FieldCount; i++)
{
string sKey = sqlReader.GetName(i);

new

new

if (!dicRecord.ContainsKey(sKey))
{
dicRecord.Add(sKey,
sqlReader.GetValue(i));
}
}
yield return dicRecord;
}
}
}
}
}
public void ExecuteNonSqlQuery(string SqlQuery)
{
try
{
if (this.sqlConnection != null)
{
using
(System.Data.SqlClient.SqlCommand
sqlCommand
=
System.Data.SqlClient.SqlCommand(SqlQuery, this.sqlConnection))
{
sqlCommand.CommandTimeout = this.CommandTimeout;
sqlCommand.ExecuteNonQuery();
}
}
else
{
using (System.Data.SqlClient.SqlConnection sqlConnection =
System.Data.SqlClient.SqlConnection(this.ConnectionString))
{
try
{
sqlConnection.Open();
}
catch (Exception ex)
{
throw new Exception(string.Format("{0}::{1}",
StackFrame(0, true).GetMethod().Name, ex.Message));
}
using (System.Data.SqlClient.SqlCommand sqlCommand =
System.Data.SqlClient.SqlCommand(SqlQuery, sqlConnection))
{
sqlCommand.CommandTimeout
this.CommandTimeout;
sqlCommand.ExecuteNonQuery();
}
}
}
}
catch (Exception ex)
{

GGGG

new

new

new
new
=

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics
throw
true).GetMethod().Name, ex.Message));
}
}
#endregion

Zrich, 20 August. 2012


new

Exception(string.Format("{0}::{1}",

#region IDisposable Members


public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (!this.bDisposed)
{
if (bDisposing)
{
if (this.sqlConnection != null)
{
this.sqlConnection.Dispose();
}
}
this.bDisposed = true;
}
}
#endregion
}
}

HHHH

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

XTLDAP.CS
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices.Protocols;
using System.Globalization;
using System.Net;
using System.Runtime.CompilerServices;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Security.AccessControl;
namespace XtLdap
{
class LdapEngine :IDisposable
{
#region Constants
private const int MAX_DC_POOL_THREADS = 4;
private const int CPU_CORE_NO_PER_DC = 4;
private const int NUMBER_OF_OPEN_TCP_CONNECTIONS = 5;
private const int CONN_TIME_OUT = 600; //seconds
private enum UserAccountControl
{
UAC_SCRIPT =
0x0000001,
UAC_ACCOUNTDISABLE =
0x0000002,
UAC_HOMEDIR_REQUIRED =
0x0000008,
UAC_LOCKOUT =
0x0000010,
UAC_PASSWD_NOTREQD =
0x0000020,
UAC_PASSWD_CANT_CHANGE =
0x0000040,
UAC_ENCRYPTED_TEXT_PWD_ALLOWED =
0x0000080,
UAC_TEMP_DUPLICATE_ACCOUNT =
0x0000100,
UAC_NORMAL_ACCOUNT =
0x0000200,
UAC_INTERDOMAIN_TRUST_ACCOUNT =
0x0000800,
UAC_WORKSTATION_TRUST_ACCOUNT =
0x0001000,
UAC_SERVER_TRUST_ACCOUNT =
0x0002000,
UAC_DONT_EXPIRE_PASSWORD =
0x0010000,
UAC_MNS_LOGON_ACCOUNT =
0x0020000,
UAC_SMARTCARD_REQUIRED =
0x0040000,
UAC_TRUSTED_FOR_DELEGATION =
0x0080000,
UAC_NOT_DELEGATED =
0x0100000,
UAC_USE_DES_KEY_ONLY =
0x0200000,
UAC_DONT_REQ_PREAUTH =
0x0400000,
UAC_PASSWORD_EXPIRED =
0x0800000,
UAC_TRUSTED_TO_AUTH_FOR_DELEGATION = 0x1000000
};
#endregion
#region Variables
private bool bDisposed;
private string[] aDcServers = null;
private string sBaseSearchDn = null;
private Int32 iPortNumber = 389;
private Int32 iPageSize = 500;
private NetworkCredential netCredentials = null;

IIII

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

//variables for results


private List<Dictionary<string, object>> lGenResults =

null;

private List<Dictionary<string, string>> lResults = null;


private Dictionary<string, Dictionary<string, object>> dicIndexedResults = null;
private Dictionary<string, Dictionary<string, string>> dicIndexedTranslatedResults = null;
private Dictionary<string, List<string>> dicMshipsResults = null;
private Dictionary<string, Dictionary<string, MembershipAction>> dicMshipsActions = null;
private List<LdapConnection> lOpenLdapConnections = null;
private Dictionary<string, string> dicExtAccessRights = null;
private Dictionary<string, string> dicAttributeList = null;
private long iHighestCommittedUSN = 0;
//class properties
public enum UniqueObjectIdentifier
{
objectSid,
objectGuid,
sAMAccountName,
distinguishedName
}
public enum MembershipAction : sbyte
{
Add = 0x1,
Remove = 0x2
}
public string BaseSearchDn
{
get
{
return this.sBaseSearchDn;
}
set
{
this.sBaseSearchDn = value;
}
}
public Int32 Port
{
get
{
return this.iPortNumber;
}
set
{
this.iPortNumber = value;
}
}
public Int32 PageSize
{
get
{

JJJJ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

return this.iPageSize;
}
set
{
this.iPageSize = value;
}
}
public long HighestCommitedUSN
{
get
{
return this.iHighestCommittedUSN;
}
set
{
this.iHighestCommittedUSN = value;
}
}
public string[] DomainControllers
{
get
{
return this.aDcServers;
}
set
{
this.aDcServers = value;
}
}
public NetworkCredential NetworkCredentials
{
set
{
this.netCredentials = value;
}
}
#endregion
#region Constructors
public LdapEngine()
{
try
{
this.bDisposed = false;
aDcServers

this.GetSiteServers(Domain.GetCurrentDomain().Name.ToString(),

null);
this.LoadLdapAttributes();
this.LoadExtendedRights();
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
true).GetMethod().Name, ex.Message));
}
}
public LdapEngine(string[] DomainControllers, string UserName, string Password)
{
try
{
this.bDisposed = false;

KKKK

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

this.netCredentials = new NetworkCredential();


netCredentials.UserName = UserName;
netCredentials.Password = Password;
this.aDcServers = DomainControllers;
this.LoadLdapAttributes();
this.LoadExtendedRights();

}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public LdapEngine(string[] DomainControllers, string UserName, string Password, string BaseDn, Int32
Port)
{
try
{
this.bDisposed = false;
this.netCredentials = new NetworkCredential();
netCredentials.UserName = UserName;
netCredentials.Password = Password;
this.iPortNumber = Port;
this.BaseSearchDn = BaseDn;
this.aDcServers = DomainControllers;
this.LoadLdapAttributes();
this.LoadExtendedRights();
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public LdapEngine(string DomainController, long HighestCommittedUSN, string UserName, string
Password)
{
try
{
this.bDisposed = false;
this.iHighestCommittedUSN = HighestCommittedUSN;
this.aDcServers = new string[] { DomainController };
this.netCredentials = new NetworkCredential();
netCredentials.UserName = UserName;
netCredentials.Password = Password;
this.LoadLdapAttributes();
this.LoadExtendedRights();
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
public LdapEngine(string DomainName, string UserName, string Password)
{
try
{
this.bDisposed = false;

LLLL

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

netCredentials = new NetworkCredential();


netCredentials.UserName = UserName;
netCredentials.Password = Password;
aDcServers = this.GetSiteServers(DomainName, null, UserName, Password);
//this.aDcServers = new string[] { DomainName };
this.LoadLdapAttributes();
this.LoadExtendedRights();
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public LdapEngine(string DomainName, string UserName, string Password, string BaseDn, Int32 Port)
{
try
{
this.bDisposed = false;
this.netCredentials = new NetworkCredential();
this.netCredentials.UserName = UserName;
this.netCredentials.Password = Password;
this.iPortNumber = Port;
this.BaseSearchDn = BaseDn;
//aDcServers = this.GetSiteServers(DomainName, null, UserName, Password);
this.aDcServers = new string[] {DomainName};
//this.LoadLdapAttributes();
//this.LoadExtendedRights();

}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public LdapEngine(string DomainName, string ADSite, string UserName, string Password)
{
this.netCredentials.UserName =
UserName;
this.netCredentials.Password =
Password;
this.aDcServers = this.GetSiteServers(DomainName, null, UserName, Password);
this.LoadLdapAttributes();
this.LoadExtendedRights();
this.bDisposed = false;
}
#endregion
#region Public Methods
public HashSet<string> FindObjects(string LdapFilter, UniqueObjectIdentifier KeyAttribute, bool
ShowDeleted)
{
HashSet<string> hsSearchResult = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
try
{

MMMM

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

using
(LdapConnection
oLdapConnection
this.OpenLdapConnection(this.aDcServers[0], this.netCredentials))
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
PageResultRequestControl rcPageRequest = null;
PageResultResponseControl rcPageResponse = null;
string sAttribute = KeyAttribute.ToString();
string sServerName = oLdapConnection.SessionOptions.HostName;
string
sBaseDn
=
(this.sBaseSearchDn
==
null

||

this.sBaseSearchDn.Equals(String.Empty))
?
sServerName.Substring(sServerName.IndexOf('.') + 1).Replace(".", ",DC="))
: this.sBaseSearchDn;

String.Format("DC={0}",

if (this.iHighestCommittedUSN > 0)
{
LdapFilter = String.Format(@"(&(uSNChanged>={0})({1}))",
iHighestCommittedUSN, LdapFilter);
}
srRequest = new SearchRequest(
sBaseDn,
LdapFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
sAttribute
);
if (ShowDeleted)
{
srRequest.Controls.Add(new ShowDeletedControl());
}
rcPageRequest = new PageResultRequestControl();
rcPageRequest.PageSize = this.iPageSize;
srRequest.Controls.Add(rcPageRequest);
do
{
dirRes
(SearchResponse)oLdapConnection.SendRequest(srRequest);
rcPageResponse
(PageResultResponseControl)dirRes.Controls[0];

dicAttributeList.ContainsKey(sAttribute)
StringComparison.OrdinalIgnoreCase))

=
=

if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
string sValue = null;
if (srEntry.Attributes.Contains(sAttribute) &&
&&
dicAttributeList[sAttribute].Equals("Sid",
{
object[]

aValues

srEntry.Attributes[sAttribute].GetValues(Type.GetType("System.Byte[]"));
for (int i = 0; i < aValues.Length;
i++)
{
sValue

String.Format("{0}", (new SecurityIdentifier((byte[])aValues[i], 0)).ToString());


}
}

NNNN

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

else
(srEntry.Attributes.Contains(sAttribute)
&&
dicAttributeList.ContainsKey(sAttribute)
dicAttributeList[sAttribute].Equals("Octet", StringComparison.OrdinalIgnoreCase))
{
object[]
aValues
srEntry.Attributes[sAttribute].GetValues(Type.GetType("System.Byte[]"));
sValue
=
Guid((byte[])aValues[0]).ToString();
}
else
{
sValue
srEntry.Attributes[sAttribute][0].ToString();
}
hsSearchResult.Add(sValue);
}
}
rcPageRequest.Cookie = rcPageResponse.Cookie;
}
while (Convert.ToBoolean(rcPageResponse.Cookie.Length));
}
return hsSearchResult;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

if
&&
=
new

StackFrame(0,

public List<Dictionary<string, string>> GetDcSpecificAttributes(string LdapFilter, string[] Attributes)


{
try
{
foreach (string sAttribute in Attributes)
{
LdapFilter += String.Format(@"({0}=*)", sAttribute);
}
LdapFilter = String.Format(@"(&{0})", LdapFilter);
this.lResults = new List<Dictionary<string, string>>();
this.lOpenLdapConnections = new List<LdapConnection>();
int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);
int

iMinThreads

MAX_DC_POOL_THREADS

CPU_CORE_NO_PER_DC

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}
ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
foreach (string sDomainController in this.aDcServers)
{
this.lOpenLdapConnections.Add(this.OpenLdapConnection(sDomainController, this.netCredentials));

OOOO

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

string
sServerName
=
this.lOpenLdapConnections[this.lOpenLdapConnections.Count-1].SessionOptions.HostName;
string
sBaseDn
=
(this.sBaseSearchDn
==
null
||
this.sBaseSearchDn.Equals(String.Empty))
?
String.Format("DC={0}",
sServerName.Substring(sServerName.IndexOf('.') + 1).Replace(".", ",DC="))
: this.sBaseSearchDn;
Interlocked.Increment(ref iThreadCount);
LdapRequest oLdapRequest = new LdapRequest(
this.lOpenLdapConnections[this.lOpenLdapConnections.Count-1],
LdapFilter,
Attributes,
sBaseDn);
ThreadPool.QueueUserWorkItem(delegate
{
try
{
this.GetDcSpecificAttribute(oLdapRequest);
}
finally
{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}
});
}
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();
return this.lResults;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

StackFrame(0,

public Dictionary<string, Dictionary<string, string>> FindObjects(string LdapFilter, string[]


AttributesToLoad, UniqueObjectIdentifier KeyAttribute)
{
return this.FindObjects(LdapFilter, AttributesToLoad, KeyAttribute.ToString());
}
public Dictionary<string, Dictionary<string, string>> FindObjects(string LdapFilter, string[]
AttributesToLoad, string KeyAttribute)
{
try
{
this.dicIndexedTranslatedResults = new Dictionary<string, Dictionary<string,
string>>(StringComparer.OrdinalIgnoreCase);
if (this.iHighestCommittedUSN > 0)
{
LdapFilter
=
String.Format(@"(&(uSNChanged>={0})({1}))",
iHighestCommittedUSN, LdapFilter);
}

PPPP

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

HashSet<string>
hsSearchResult
XtLdap.LdapEngine.UniqueObjectIdentifier.distinguishedName, false);
return

this.FindObjects(LdapFilter,

this.RetrieveTranslatedAttributes(hsSearchResult,

AttributesToLoad,

KeyAttribute);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
finally
{
this.DisposeAllConnections();
}
}
public Dictionary<string, Dictionary<string, string>> FindObjects(HashSet<string> ObjectsCollection,
string ObjectIdAttribute, string[] AttributesToLoad )
{
try
{
this.dicIndexedTranslatedResults = new Dictionary<string, Dictionary<string,
string>>(StringComparer.OrdinalIgnoreCase);
int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);
int

iMinThreads

MAX_DC_POOL_THREADS

CPU_CORE_NO_PER_DC

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}
ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
this.OpenAllConnections();
IEnumerator<LdapConnection>
this.lOpenLdapConnections.GetEnumerator();

enLdapConnection

foreach (string sObject in ObjectsCollection)


{
Interlocked.Increment(ref iThreadCount);
//select LdapConnection from list of open connections
if (!enLdapConnection.MoveNext())
{
enLdapConnection.Reset();
enLdapConnection.MoveNext();
}
LdapRequest oLdapRequest = new LdapRequest(
enLdapConnection.Current,
AttributesToLoad,
sObject,
ObjectIdAttribute);
ThreadPool.QueueUserWorkItem(delegate
{

QQQQ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


try
{
this.RetrieveTranslatedAttributes(oLdapRequest);
}
finally
{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}

});
}
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();

return this.dicIndexedTranslatedResults;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

StackFrame(0,

public IEnumerable<Dictionary<string, object>> RetrieveAttributes(string LdapFilter, string[]


AttributesToLoad, bool ShowDeleted)
{
using (LdapConnection oLdapConnection = this.OpenLdapConnection(this.aDcServers[0],
this.netCredentials))
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
PageResultRequestControl rcPageRequest = null;
PageResultResponseControl rcPageResponse = null;
string sServerName = oLdapConnection.SessionOptions.HostName;
string
sBaseDn
=
(this.sBaseSearchDn
==
null
||
this.sBaseSearchDn.Equals(String.Empty) )
?
String.Format("DC={0}",
sServerName.Substring(sServerName.IndexOf('.') + 1).Replace(".", ",DC="))
: this.sBaseSearchDn;
if (this.iHighestCommittedUSN > 0)
{
LdapFilter
=
String.Format(@"(&(uSNChanged>={0})({1}))",
iHighestCommittedUSN, LdapFilter);
}
srRequest = new SearchRequest(
sBaseDn,
LdapFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
AttributesToLoad
);
if (ShowDeleted)
{
srRequest.Controls.Add(new ShowDeletedControl());
}

RRRR

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

//PAGED
if (this.iPageSize > 0)
{
rcPageRequest = new PageResultRequestControl();
rcPageRequest.PageSize = this.iPageSize;
srRequest.Controls.Add(rcPageRequest);
do
{
dirRes
(SearchResponse)oLdapConnection.SendRequest(srRequest);
rcPageResponse
(PageResultResponseControl)dirRes.Controls[0];

=
=

if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
Dictionary<string, object> dicProperties =
new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
foreach
(string
sAttribute
in
AttributesToLoad)
{
if
(srEntry.Attributes.Contains(sAttribute))
{
dicProperties.Add(sAttribute,
srEntry.Attributes[sAttribute].GetValues(srEntry.Attributes[sAttribute][0].GetType()));
}
}
yield return dicProperties;
}
}
rcPageRequest.Cookie = rcPageResponse.Cookie;
}
while (Convert.ToBoolean(rcPageResponse.Cookie.Length));
}
//NOT PAGED
else
{
dirRes = (SearchResponse)oLdapConnection.SendRequest(srRequest);
if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
Dictionary<string, object> dicProperties = new
Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
foreach (string sAttribute in AttributesToLoad)
{
if (srEntry.Attributes.Contains(sAttribute))
{
dicProperties.Add(sAttribute,
srEntry.Attributes[sAttribute].GetValues(srEntry.Attributes[sAttribute][0].GetType()));
}
}
yield return dicProperties;
}
}
}
//dispose
if (dirRes != null)
if (srRequest != null)
if (rcPageRequest != null)

SSSS

{ dirRes = null; }
{ srRequest = null; }
{ rcPageRequest = null; }

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

if (rcPageResponse != null) { rcPageResponse = null; }


}
}
public Dictionary<string, Dictionary<string, object>> RetrieveAttributes(List<string> ObjectsCollection,
string ObjectIdAttribute, string[] AttributesToLoad)
{
try
{
this.dicIndexedResults
=
new
Dictionary<string,
Dictionary<string,
object>>(StringComparer.OrdinalIgnoreCase);
int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);
int

iMinThreads

MAX_DC_POOL_THREADS

CPU_CORE_NO_PER_DC

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}
ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
this.OpenAllConnections();
IEnumerator<LdapConnection>
this.lOpenLdapConnections.GetEnumerator();

enLdapConnection

foreach (string sObject in ObjectsCollection)


{
Interlocked.Increment(ref iThreadCount);
//select LdapConnection from list of open connections
if (!enLdapConnection.MoveNext())
{
enLdapConnection.Reset();
enLdapConnection.MoveNext();
}
LdapRequest oLdapRequest = new LdapRequest(
enLdapConnection.Current,
AttributesToLoad,
sObject,
ObjectIdAttribute);
ThreadPool.QueueUserWorkItem(delegate
{
try
{
this.RetrieveAttributes(oLdapRequest);
}
finally
{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}
});
}
if (Interlocked.Decrement(ref iThreadCount) == 0)

TTTT

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();

return this.dicIndexedResults;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

StackFrame(0,

public Dictionary<string, Dictionary<string, string>> RetrieveTranslatedAttributes(HashSet<string>


DistinguishedNameCollection, string[] AttributesToLoad, UniqueObjectIdentifier KeyAttribute)
{
try
{
return
this.RetrieveTranslatedAttributes(DistinguishedNameCollection,
AttributesToLoad, KeyAttribute.ToString());
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public Dictionary<string, Dictionary<string, string>> RetrieveTranslatedAttributes(HashSet<string>
DistinguishedNameCollection, string[] AttributesToLoad, string KeyAttribute)
{
try
{
this.dicIndexedTranslatedResults = new Dictionary<string, Dictionary<string,
string>>(StringComparer.OrdinalIgnoreCase);
int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);
int

iMinThreads

MAX_DC_POOL_THREADS

CPU_CORE_NO_PER_DC

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}
ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
this.OpenAllConnections();
IEnumerator<LdapConnection>
this.lOpenLdapConnections.GetEnumerator();

enLdapConnection

foreach (string sObjectDn in DistinguishedNameCollection)


{
Interlocked.Increment(ref iThreadCount);
//select LdapConnection from list of open connections
if (!enLdapConnection.MoveNext())

UUUU

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
enLdapConnection.Reset();
enLdapConnection.MoveNext();
}
LdapRequest oLdapRequest = new LdapRequest(
enLdapConnection.Current,
AttributesToLoad,
sObjectDn,
KeyAttribute);
ThreadPool.QueueUserWorkItem(delegate
{
try
{
this.FastRetrieveTranslatedAttributes(oLdapRequest);
}
finally
{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}
});
}
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();

return this.dicIndexedTranslatedResults;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public
Dictionary<string,
Dictionary<string,
string>>
RetrieveTranslatedUpdatedAttributes(HashSet<string> DistinguishedNameCollection, List<string> AttributesToLoad,
string KeyAttribute)
{
try
{
AttributesToLoad.Add("msDS-ReplAttributeMetaData");
this.dicIndexedTranslatedResults
string>>(StringComparer.OrdinalIgnoreCase);

new

Dictionary<string,

Dictionary<string,

int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);
int

iMinThreads

MAX_DC_POOL_THREADS

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}

VVVV

CPU_CORE_NO_PER_DC

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
this.OpenAllConnections();
IEnumerator<LdapConnection>
this.lOpenLdapConnections.GetEnumerator();

enLdapConnection

foreach (string sObjectDn in DistinguishedNameCollection)


{
Interlocked.Increment(ref iThreadCount);
//select LdapConnection from list of open connections
if (!enLdapConnection.MoveNext())
{
enLdapConnection.Reset();
enLdapConnection.MoveNext();
}
LdapRequest oLdapRequest = new LdapRequest(
enLdapConnection.Current,
AttributesToLoad.ToArray(),
sObjectDn,
KeyAttribute);
ThreadPool.QueueUserWorkItem(delegate
{
try
{
this.FastRetrieveTranslatedUpdatedAttributes(oLdapRequest);
}
finally
{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}
});
}
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();

return this.dicIndexedTranslatedResults;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

StackFrame(0,

public HashSet<string> FindDeletedObjects(string LdapFilter, UniqueObjectIdentifier KeyAttribute)


{
try
{
LdapFilter = String.Format(@"(&(!objectCategory=*)(!sAMAccountType=*)({0}))",
LdapFilter);

WWWW

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

if (this.iHighestCommittedUSN > 0)
{
LdapFilter
=
String.Format(@"(&(uSNChanged>={0})({1}))",
this.iHighestCommittedUSN, LdapFilter);
}
HashSet<string> hsSearchResult = this.FindObjects(LdapFilter, KeyAttribute, true);
return hsSearchResult;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
finally
{
this.DisposeAllConnections();
}
}

new

StackFrame(0,

public object GetRootDseProperty(string DomainController, string UserName, string Password, string


PropertyName)
{
try
{
NetworkCredential ntCred = new NetworkCredential(UserName,Password);
LdapDirectoryIdentifier
oLdapDirectory
=
LdapDirectoryIdentifier(DomainController, 389);

new

LdapConnection oLdapConnection = new LdapConnection(oLdapDirectory, ntCred);


oLdapConnection.Timeout = TimeSpan.FromSeconds(CONN_TIME_OUT);
oLdapConnection.SessionOptions.TcpKeepAlive = true;
oLdapConnection.SessionOptions.ProtocolVersion = 3;
oLdapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
oLdapConnection.AutoBind = false;
oLdapConnection.Bind();
return this.GetRootDseProperty(oLdapConnection, PropertyName);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
public object GetRootDseProperty(LdapConnection oLdapConnection, string PropertyName)
{
try
{
object oValue = null;
SearchResponse dirRes = null;
dirRes = (SearchResponse)oLdapConnection.SendRequest(new SearchRequest(
null,
String.Format(@"{0}=*", PropertyName),
System.DirectoryServices.Protocols.SearchScope.Base,
PropertyName
));
oValue = dirRes.Entries[0].Attributes[PropertyName][0];
return oValue;
}

XXXX

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Zrich, 20 August. 2012

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

public List<Dictionary<string, string>> GetSecurity(HashSet<string> DistinguishedNameCollection,


string[] AccRulesToLoad, UniqueObjectIdentifier KeyAttribute)
{
return
this.GetSecurity(DistinguishedNameCollection,
AccRulesToLoad,
KeyAttribute.ToString());
}
public List<Dictionary<string, string>> GetSecurity(HashSet<string> DistinguishedNameCollection,
string[] AccRulesToLoad, string KeyAttribute)
{
try
{
this.lResults = new List<Dictionary<string, string>>();
int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);
int

iMinThreads

MAX_DC_POOL_THREADS

CPU_CORE_NO_PER_DC

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}
ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
this.OpenAllConnections();
IEnumerator<LdapConnection>
this.lOpenLdapConnections.GetEnumerator();

enLdapConnection

foreach (string sResultDN in DistinguishedNameCollection)


{
Interlocked.Increment(ref iThreadCount);
//select LdapConnection from list of open connections
if (!enLdapConnection.MoveNext())
{
enLdapConnection.Reset();
enLdapConnection.MoveNext();
}
LdapRequest oLdapRequest = new LdapRequest(
enLdapConnection.Current,
AccRulesToLoad,
sResultDN,
KeyAttribute);
ThreadPool.QueueUserWorkItem(delegate
{
try
{
this.RetrieveSecurity(oLdapRequest);
}
finally

YYYY

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}

});

}
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();

return this.lResults;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
finally
{
this.DisposeAllConnections();
}
}
public
DistinguishedNameCollection)
{
try
{

Dictionary<string,

HashSet<string>>

new

StackFrame(0,

GetMembers(HashSet<string>

Dictionary<string, HashSet<string>> dicSearchResult = new Dictionary<string,


HashSet<string>>(StringComparer.OrdinalIgnoreCase);
using
(LdapConnection
oLdapConnection
=
this.OpenLdapConnection(this.aDcServers[0], this.netCredentials))
{
SearchResultEntry srEntry = null;
SearchResponse dirResDet = null;
foreach (string sGroupDn in DistinguishedNameCollection)
{
if (!dicSearchResult.ContainsKey(sGroupDn))
{
dicSearchResult.Add(sGroupDn,
HashSet<string>(StringComparer.OrdinalIgnoreCase));
}

new

string sAttribute = "member";


string sRange = String.Format(@"{0};range={{0}}-{{1}}",
sAttribute);
int iIndex = 0;
int iStep = 0;
string sCurrentRange = String.Format(sRange, iIndex, '*');
bool bMoreData = true;
while (bMoreData)
{
dirResDet
(SearchResponse)oLdapConnection.SendRequest(new SearchRequest(
sGroupDn,
String.Format(@"{0}=*", sAttribute),

ZZZZ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

System.DirectoryServices.Protocols.SearchScope.Base,
new string[] { sCurrentRange }
));
if
dirResDet.Entries[0].Attributes.Count > 0)

(dirResDet.Entries.Count

>

&&

{
srEntry = dirResDet.Entries[0];
foreach
(string
sAttr

in

srEntry.Attributes.AttributeNames)
{
foreach

(string

sMemberDn

in

srEntry.Attributes[sAttr].GetValues(Type.GetType("System.String")))
{
dicSearchResult[sGroupDn].Add(sMemberDn);
iIndex++;
}
if (sAttr.IndexOf('*') > 0)
{
bMoreData = false;
}
else
{
iStep

srEntry.Attributes[sAttr].Count;
sCurrentRange

String.Format(sRange, iIndex, iIndex + iStep);


}
}
}
else
{
}

bMoreData = false;

}
}
}
return dicSearchResult;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
finally
{
this.DisposeAllConnections();
}
}
public
Dictionary<string,
Dictionary<string,
MembershipAction>>
GetUpdatedMembers(HashSet<string> DistinguishedNameCollection)
{
try
{
this.dicMshipsActions
=
new
Dictionary<string,
Dictionary<string,
MembershipAction>>(StringComparer.OrdinalIgnoreCase);
int iThreadCount = 1;
int iMaxThreads;
int iMaxCompletionThreads;
ThreadPool.GetMaxThreads(out iMaxThreads, out iMaxCompletionThreads);

AAAAA

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics
int

iMinThreads

Zrich, 20 August. 2012


=

MAX_DC_POOL_THREADS

CPU_CORE_NO_PER_DC

this.aDcServers.Length;
if (iMinThreads >= iMaxThreads)
{
iMinThreads = iMaxThreads - 1;
}
ThreadPool.SetMinThreads(iMinThreads, iMinThreads);
ManualResetEvent oManualResetEvent = new ManualResetEvent(false);
this.OpenAllConnections();
IEnumerator<LdapConnection>
this.lOpenLdapConnections.GetEnumerator();

enLdapConnection

foreach (string sObjectDn in DistinguishedNameCollection)


{
Interlocked.Increment(ref iThreadCount);
//select LdapConnection from list of open connections
if (!enLdapConnection.MoveNext())
{
enLdapConnection.Reset();
enLdapConnection.MoveNext();
}
LdapRequest oLdapRequest = new LdapRequest(
enLdapConnection.Current,
new
string[]
{
"msDSReplValueMetaData" },
sObjectDn);
ThreadPool.QueueUserWorkItem(delegate
{
try
{
this.FastRetrieveUpdatedMembers(oLdapRequest);
}
finally
{
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
}
});
}
if (Interlocked.Decrement(ref iThreadCount) == 0)
{
oManualResetEvent.Set();
}
oManualResetEvent.WaitOne();

return this.dicMshipsActions;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}
#endregion

BBBBB

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

#region Private Methods


private void RetrieveSecurity(object oLdapRqst)
{
try
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
SearchResultEntry srEntry = null;
Dictionary<string, string> dicTrusteeRights = null;
LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;
srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
@"(objectClass=*)",
System.DirectoryServices.Protocols.SearchScope.Base,
new string[] {"ntSecurityDescriptor", oLdapRequest.KeyAttribute}
);
SecurityDescriptorFlagControl
sdControl
=
SecurityDescriptorFlagControl(System.DirectoryServices.Protocols.SecurityMasks.Dacl
System.DirectoryServices.Protocols.SecurityMasks.Group | System.DirectoryServices.Protocols.SecurityMasks.Owner);
sdControl.IsCritical = false;
srRequest.Controls.Add(sdControl);

new
|

dirRes = (SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
if (dirRes.Entries.Count > 0)
{
srEntry = dirRes.Entries[0];
string sKeyValue = null;
if
(srEntry.Attributes.Contains(oLdapRequest.KeyAttribute)
&&
dicAttributeList.ContainsKey(oLdapRequest.KeyAttribute) && dicAttributeList[oLdapRequest.KeyAttribute].Equals("Sid",
StringComparison.OrdinalIgnoreCase))
{
object[]
aValues
=
srEntry.Attributes[oLdapRequest.KeyAttribute].GetValues(Type.GetType("System.Byte[]"));
sKeyValue
=
(new
SecurityIdentifier((byte[])aValues[0],
0)).ToString();
}
else if (srEntry.Attributes.Contains(oLdapRequest.KeyAttribute) &&
dicAttributeList.ContainsKey(oLdapRequest.KeyAttribute)
&&
dicAttributeList[oLdapRequest.KeyAttribute].Equals("Unicode", StringComparison.OrdinalIgnoreCase))
{
sKeyValue
=
srEntry.Attributes[oLdapRequest.KeyAttribute][0].ToString();
}
else if (srEntry.Attributes.Contains(oLdapRequest.KeyAttribute) &&
dicAttributeList.ContainsKey(oLdapRequest.KeyAttribute)
&&
dicAttributeList[oLdapRequest.KeyAttribute].Equals("String", StringComparison.OrdinalIgnoreCase))
{
sKeyValue
=
srEntry.Attributes[oLdapRequest.KeyAttribute][0].ToString();
}
else if (srEntry.Attributes.Contains(oLdapRequest.KeyAttribute) &&
dicAttributeList.ContainsKey(oLdapRequest.KeyAttribute)
&&
dicAttributeList[oLdapRequest.KeyAttribute].Equals("IString", StringComparison.OrdinalIgnoreCase))
{
sKeyValue
=
srEntry.Attributes[oLdapRequest.KeyAttribute][0].ToString();
}

CCCCC

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

else if (srEntry.Attributes.Contains(oLdapRequest.KeyAttribute) &&


dicAttributeList.ContainsKey(oLdapRequest.KeyAttribute) && dicAttributeList[oLdapRequest.KeyAttribute].Equals("DNBinary", StringComparison.OrdinalIgnoreCase))
{
sKeyValue
=
srEntry.Attributes[oLdapRequest.KeyAttribute][0].ToString();
}
else if (srEntry.Attributes.Contains(oLdapRequest.KeyAttribute) &&
dicAttributeList.ContainsKey(oLdapRequest.KeyAttribute) && dicAttributeList[oLdapRequest.KeyAttribute].Equals("Octet",
StringComparison.OrdinalIgnoreCase))
{
object[]
aValues
=
srEntry.Attributes[oLdapRequest.KeyAttribute].GetValues(Type.GetType("System.Byte[]"));
sKeyValue = new Guid((byte[])aValues[0]).ToString();
}
if (srEntry.Attributes.Contains("ntSecurityDescriptor"))
{
object[]
aValues
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));

ActiveDirectorySecurity adSec = new ActiveDirectorySecurity();


adSec.SetSecurityDescriptorBinaryForm((byte[])aValues[0]);
AuthorizationRuleCollection
colAccRules
=
adSec.GetAccessRules(true, true, typeof(NTAccount));
foreach (ActiveDirectoryAccessRule accRule in colAccRules)
{
dicTrusteeRights
=
new
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);
dicTrusteeRights.Add(oLdapRequest.KeyAttribute,
sKeyValue);
foreach

(string

sAccRuleName

in

oLdapRequest.AttributesToLoad)
{
try
{
if
(sAccRuleName.Equals("IdentityReference", StringComparison.OrdinalIgnoreCase))
{
if
(accRule.IdentityReference.IsValidTargetType(typeof(NTAccount)))
{
dicTrusteeRights.Add(sAccRuleName, accRule.IdentityReference.Value);
}
else
{
try
{
dicTrusteeRights.Add(sAccRuleName,
accRule.IdentityReference.Translate(typeof(System.Security.Principal.NTAccount)).Value);
}
catch
{
dicTrusteeRights.Add(sAccRuleName, accRule.IdentityReference.Value);
}
}
else
(sAccRuleName.Equals("AccessControlType", StringComparison.OrdinalIgnoreCase))

DDDDD

}
if

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{

dicTrusteeRights.Add(sAccRuleName, accRule.AccessControlType.ToString());
}
else
(sAccRuleName.Equals("ActiveDirectoryRights", StringComparison.OrdinalIgnoreCase))
{

if

dicTrusteeRights.Add(sAccRuleName, accRule.ActiveDirectoryRights.ToString());
}
else
(sAccRuleName.Equals("InheritanceFlags", StringComparison.OrdinalIgnoreCase))
{

if

dicTrusteeRights.Add(sAccRuleName, accRule.InheritanceFlags.ToString());
}
else

if

(sAccRuleName.Equals("InheritanceType", StringComparison.OrdinalIgnoreCase))
{
dicTrusteeRights.Add(sAccRuleName, accRule.InheritanceType.ToString());

}
else

if

(sAccRuleName.Equals("IsInherited", StringComparison.OrdinalIgnoreCase))
{
dicTrusteeRights.Add(sAccRuleName, accRule.IsInherited.ToString());
}
else

if

(sAccRuleName.Equals("InheritedObjectType", StringComparison.OrdinalIgnoreCase)
&&
Convert.ToBoolean(ObjectAceFlags.InheritedObjectAceTypePresent & accRule.ObjectFlags))
{
string
sInheritedObjectType = accRule.InheritedObjectType.ToString();
dicTrusteeRights.Add(sAccRuleName, this.dicExtAccessRights.ContainsKey(sInheritedObjectType)
? this.dicExtAccessRights[sInheritedObjectType]
: sInheritedObjectType);
}
else
(sAccRuleName.Equals("ObjectType", StringComparison.OrdinalIgnoreCase)

if
&&

Convert.ToBoolean(ObjectAceFlags.ObjectAceTypePresent & accRule.ObjectFlags))


{
string

sObjectType

accRule.ObjectType.ToString();
dicTrusteeRights.Add(sAccRuleName, this.dicExtAccessRights.ContainsKey(sObjectType)
? this.dicExtAccessRights[sObjectType]
: sObjectType);
}
}
catch
{
}
}
}
}
}

EEEEE

}
this.AddObjectToList(dicTrusteeRights);

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

catch (Exception ex)


{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6666);
oEventLog.Dispose();
}
}
private void FastRetrieveTranslatedAttributes(object oLdapRqst)
{
try
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
SearchResultEntry srEntry = null;
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);

string>

dicProperties

new

Dictionary<string,

LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;


srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
@"(objectClass=*)",
System.DirectoryServices.Protocols.SearchScope.Base,
oLdapRequest.AttributesToLoad
);
//SecurityDescriptorFlagControl
sdControl
SecurityDescriptorFlagControl(System.DirectoryServices.Protocols.SecurityMasks.Dacl);

new

dirRes = (SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
string sServerName = oLdapRequest.ldapConnection.SessionOptions.HostName;
string sDomainFqdn = sServerName.Substring(sServerName.IndexOf('.') + 1);
if (dirRes.Entries.Count > 0)
{
srEntry = dirRes.Entries[0];
foreach (string sAttribute in oLdapRequest.AttributesToLoad)
{
string sValue = null;
if
(sAttribute.Equals("memberOf",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains(sAttribute))
{
foreach
(string
sGroupDN
in
srEntry.Attributes[sAttribute].GetValues(Type.GetType("System.String")))
{
{
sValue += String.Format("|{0}",
sGroupDN);
}
sValue = sValue.TrimStart('|');
}
}
else
if
(sAttribute.Equals("Domain",
StringComparison.OrdinalIgnoreCase))
{
sValue = sDomainFqdn;
}
else
if
(sAttribute.Equals("Path",
StringComparison.OrdinalIgnoreCase) )
{

FFFFF

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


sValue

String.Format(@"LDAP://{0}",

oLdapRequest.AttributeValue );
}
else

if

(sAttribute.Equals("AdsPath",

StringComparison.OrdinalIgnoreCase) )
{
sValue

oLdapRequest.AttributeValue );

String.Format(@"LDAP://{0}",

}
else
if
(sAttribute.StartsWith("UAC_",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains("userAccountControl"))
{
UserAccountControl
enUAC
=
(UserAccountControl)Enum.Parse(typeof(UserAccountControl), sAttribute.ToUpper());
if
(Convert.ToBoolean(Convert.ToInt32(srEntry.Attributes["userAccountControl"][0]) & ((int)enUAC)))
{
sValue = "1";
}
else
{
sValue = "0";
}
}
else
if
(sAttribute.Equals("selective_authentication",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains("ntSecurityDescriptor"))
{
object[]
aValues
=
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));
string
sSecurityDescriptorSDDL
=
this.GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections.Access, (byte[])aValues[0]);
if
(sSecurityDescriptorSDDL.Contains("(OA;;CR;68b1d179-0d15-4d4f-ab71-46152e79a7bc;;S-1-5-1000)"))
{
sValue = "1";
}
else
{
sValue = "0";
}
}
else
if
(sAttribute.Equals("ntSecurityDescriptor",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains(sAttribute))
{
object[]
aValues
=
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));
sValue
=
this.GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections.Owner, (byte[])aValues[0]);
int i = sValue.Length;
}
else
if
(sAttribute.StartsWith("TSL_",
StringComparison.OrdinalIgnoreCase)
&&
srEntry.Attributes.Contains(sAttribute.Substring(4))
&&
dicAttributeList[sAttribute.Substring(4)].Equals("Sid", StringComparison.OrdinalIgnoreCase))
{
//object[]
aValues
=
srEntry.Attributes[sAttribute.Substring(4)].GetValues(Type.GetType("System.Byte[]") );
//for (int i = 0; i < aValues.Length; i++)
//{
// string s = null;
// string x = null;
// try
// {
//
SecurityIdentifier oSID = new
SecurityIdentifier((byte[])aValues[i], 0);

GGGGG

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


//
//

s = oSID.ToString();
x

(oSID).Translate(typeof(NTAccount)).Value.ToString();
//
//sValue = String.Format("{0}|",
// }
// catch
// {
// }
//}
//sValue = sValue.TrimEnd('|');
}
//ALL OTHER ATTRIBUTES
else
if
(srEntry.Attributes.Contains(sAttribute)

&&

dicAttributeList.ContainsKey(sAttribute) )
{
sValue

this.TranslateAtribute(srEntry.Attributes[sAttribute]);
}
dicProperties.Add(sAttribute, sValue);
}
string sKeyValue;
if (dicProperties.TryGetValue(oLdapRequest.KeyAttribute, out sKeyValue))
{
this.AddTranslatedObjectToDictionary(sKeyValue,
dicProperties);
}
}
}
catch (Exception ex)
{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6666);
oEventLog.Dispose();
}
}
private void RetrieveTranslatedAttributes(object oLdapRqst)
{
try
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
SearchResultEntry srEntry = null;
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);

string>

dicProperties

new

Dictionary<string,

LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;


string sServerName = oLdapRequest.ldapConnection.SessionOptions.HostName;
string sDomainFqdn = sServerName.Substring(sServerName.IndexOf('.') + 1);
string sDomainDn = String.Format("DC={0}", sDomainFqdn.Replace(".", ",DC="));
string sFilter = String.Format(@"(&(objectClass=*)(objectCategory=*)({0}={1}))",
oLdapRequest.KeyAttribute, oLdapRequest.AttributeValue);
if
(oLdapRequest.KeyAttribute.Equals(LdapEngine.UniqueObjectIdentifier.distinguishedName.ToString(),
StringComparison.OrdinalIgnoreCase))
{
srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
@"(objectClass=*)",
System.DirectoryServices.Protocols.SearchScope.Base,

HHHHH

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


oLdapRequest.AttributesToLoad
);

}
else
{
srRequest = new SearchRequest(
sDomainDn,
sFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
oLdapRequest.AttributesToLoad
);
}
dirRes = (SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
if (dirRes.Entries.Count > 0)
{
srEntry = dirRes.Entries[0];
foreach (string sAttribute in oLdapRequest.AttributesToLoad)
{
string sValue = null;
if
(sAttribute.Equals("memberOf",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains(sAttribute))
{
foreach
(string
sGroupDN
in
srEntry.Attributes[sAttribute].GetValues(Type.GetType("System.String")))
{
{
sValue += String.Format("|{0}",
sGroupDN);
}
sValue = sValue.TrimStart('|');
}
}
else
if
(sAttribute.Equals("Domain",
StringComparison.OrdinalIgnoreCase))
{
sValue = sDomainFqdn;
}
else
if
(sAttribute.Equals("Path",
StringComparison.OrdinalIgnoreCase))
{
sValue
=
String.Format(@"LDAP://{0}",
oLdapRequest.DistinguishedName);
}
else
if
(sAttribute.Equals("AdsPath",
StringComparison.OrdinalIgnoreCase))
{
sValue
=
String.Format(@"LDAP://{0}",
oLdapRequest.DistinguishedName);
}
else
if
(sAttribute.StartsWith("UAC_",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains("userAccountControl"))
{
UserAccountControl
enUAC
=
(UserAccountControl)Enum.Parse(typeof(UserAccountControl), sAttribute.ToUpper());
if
(Convert.ToBoolean(Convert.ToInt32(srEntry.Attributes["userAccountControl"][0]) & ((int)enUAC)))
{
sValue = "1";
}
else
{

IIIII

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


sValue = "0";
}

}
else
if
(sAttribute.Equals("selective_authentication",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains("ntSecurityDescriptor"))
{
object[]
aValues
=
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));
string
sSecurityDescriptorSDDL
=
this.GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections.Access, (byte[])aValues[0]);
if
(sSecurityDescriptorSDDL.Contains("(OA;;CR;68b1d179-0d15-4d4f-ab71-46152e79a7bc;;S-1-5-1000)"))
{
sValue = "1";
}
else
{
sValue = "0";
}
}
else
if
(sAttribute.Equals("ntSecurityDescriptor",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains(sAttribute))
{
object[]
aValues
=
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));
sValue
=
this.GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections.Owner, (byte[])aValues[0]);
int i = sValue.Length;
}
else
if
(sAttribute.StartsWith("TSL_",
StringComparison.OrdinalIgnoreCase)
&&
srEntry.Attributes.Contains(sAttribute.Substring(4))
&&
dicAttributeList[sAttribute.Substring(4)].Equals("Sid", StringComparison.OrdinalIgnoreCase))
{
//object[]
aValues
=
srEntry.Attributes[sAttribute.Substring(4)].GetValues(Type.GetType("System.Byte[]") );
}
//ALL OTHER ATTRIBUTES
else
if
(srEntry.Attributes.Contains(sAttribute)

&&

dicAttributeList.ContainsKey(sAttribute))
{
sValue

this.TranslateAtribute(srEntry.Attributes[sAttribute]);
}
dicProperties.Add(sAttribute, sValue);
}
this.AddTranslatedObjectToDictionary(oLdapRequest.AttributeValue,
dicProperties);
}
}
catch (Exception ex)
{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6666);
oEventLog.Dispose();
}
}
private void RetrieveAttributes(object oLdapRqst)
{
try

JJJJJ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
SearchResultEntry srEntry = null;
Dictionary<string,
object>(StringComparer.OrdinalIgnoreCase);

object>

dicProperties

new

Dictionary<string,

LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;


if
(oLdapRequest.KeyAttribute.Equals(LdapEngine.UniqueObjectIdentifier.distinguishedName.ToString(),
StringComparison.OrdinalIgnoreCase))
{
srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
@"(objectClass=*)",
System.DirectoryServices.Protocols.SearchScope.Base,
oLdapRequest.AttributesToLoad
);
}
else
{
string
sServerName
=
oLdapRequest.ldapConnection.SessionOptions.HostName;
string sDomainFqdn = sServerName.Substring(sServerName.IndexOf('.') +
1);
string sDomainDn = String.Format("DC={0}", sDomainFqdn.Replace(".",
",DC="));
string
sFilter
=
String.Format(@"(&(objectClass=*)(objectCategory=*)({0}={1}))",
oLdapRequest.KeyAttribute,
oLdapRequest.AttributeValue);
srRequest = new SearchRequest(
sDomainDn,
sFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
oLdapRequest.AttributesToLoad
);
}
dirRes = (SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
if (dirRes.Entries.Count > 0)
{
srEntry = dirRes.Entries[0];
foreach (string sAttribute in oLdapRequest.AttributesToLoad)
{
if (srEntry.Attributes.Contains(sAttribute))
{
dicProperties.Add(sAttribute,
srEntry.Attributes[sAttribute].GetValues(srEntry.Attributes[sAttribute][0].GetType()));
}
}
this.AddObjectToDictionary(oLdapRequest.AttributeValue, dicProperties);
}
}
catch (Exception ex)
{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6666);
oEventLog.Dispose();

KKKKK

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
}
private void FastRetrieveTranslatedUpdatedAttributes(object oLdapRqst)
{
try
{
const int RETRY_NO = 10;
SearchResponse dirRes = null;
SearchRequest srRequest = null;
SearchResultEntry srEntry = null;
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);

string>

dicProperties

new

Dictionary<string,

LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;


srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
@"(objectClass=*)",
System.DirectoryServices.Protocols.SearchScope.Base,
oLdapRequest.AttributesToLoad
);
//SecurityDescriptorFlagControl
sdControl
SecurityDescriptorFlagControl(System.DirectoryServices.Protocols.SecurityMasks.Dacl);
ushort iTries = 0;
bool bRetry = false;
do
{
try
{
iTries++;

new

dirRes
=
(SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
bRetry = false;
}
catch (DirectoryOperationException ex)
{
if (iTries % RETRY_NO == 0)
{
bRetry = false;
throw new Exception(string.Format("{0}::{1}", new
StackFrame(0, true).GetMethod().Name, ex.Message));
}
else
{
bRetry = true;
}
}
} while (bRetry);
string sServerName = oLdapRequest.ldapConnection.SessionOptions.HostName;
string sDomainFqdn = sServerName.Substring(sServerName.IndexOf('.') + 1);
if (dirRes.Entries.Count > 0)
{
HashSet<string>
HashSet<string>(StringComparer.OrdinalIgnoreCase);

hsUpdatedAttributes

srEntry = dirRes.Entries[0];
if (srEntry.Attributes.Contains("msDS-ReplAttributeMetaData"))
{

LLLLL

new

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

foreach
(object
oValue
in
srEntry.Attributes["msDSReplAttributeMetaData"].GetValues(Type.GetType("System.String")))
{
Dictionary<string, string> dicAttributeReplData =
GetNodesInnertext(oValue.ToString(), new string[] { "pszAttributeName", "usnLocalChange" }, true);
if
(Convert.ToInt64(dicAttributeReplData["usnLocalChange"]) > this.iHighestCommittedUSN)
{
hsUpdatedAttributes.Add(dicAttributeReplData["pszAttributeName"]);
hsUpdatedAttributes.Add("whenChanged");
if
(dicAttributeReplData["pszAttributeName"].Equals("Name", StringComparison.OrdinalIgnoreCase))
{
hsUpdatedAttributes.Add("DistinguishedName");
hsUpdatedAttributes.Add("Path");
}
else
if
(dicAttributeReplData["pszAttributeName"].Equals("userAccountControl", StringComparison.OrdinalIgnoreCase))
{
foreach (UserAccountControl enUAC
in Enum.GetValues(typeof(UserAccountControl)))
{
hsUpdatedAttributes.Add(enUAC.ToString());
}
}
else
(dicAttributeReplData["pszAttributeName"].Equals("ntSecurityDescriptor", StringComparison.OrdinalIgnoreCase))
{

if

hsUpdatedAttributes.Add("selective_authentication");
}
}
}
foreach (string sAttribute in oLdapRequest.AttributesToLoad)
{
if
(hsUpdatedAttributes.Contains(sAttribute)
||
sAttribute.Equals(oLdapRequest.KeyAttribute, StringComparison.OrdinalIgnoreCase))
{
string sValue = null;
if
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains(sAttribute))
{

(sAttribute.Equals("memberOf",
foreach

(string

sGroupDN

in

srEntry.Attributes[sAttribute].GetValues(Type.GetType("System.String")))
{
{
sValue

+=

String.Format("|{0}", sGroupDN);
}
sValue

sValue.TrimStart('|');
}
}
else
StringComparison.OrdinalIgnoreCase))

if

(sAttribute.Equals("Domain",

{
sValue = sDomainFqdn;
}

MMMMM

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


else

if

(sAttribute.Equals("Path",

StringComparison.OrdinalIgnoreCase))
{
sValue

String.Format(@"LDAP://{0}", oLdapRequest.AttributeValue);
}
else

StringComparison.OrdinalIgnoreCase))

if

(sAttribute.Equals("AdsPath",

{
sValue

String.Format(@"LDAP://{0}", oLdapRequest.AttributeValue);
}
else
if
(sAttribute.StartsWith("UAC_",
StringComparison.OrdinalIgnoreCase) && srEntry.Attributes.Contains("userAccountControl"))
{
UserAccountControl
enUAC
=
(UserAccountControl)Enum.Parse(typeof(UserAccountControl), sAttribute.ToUpper());
if
(Convert.ToBoolean(Convert.ToInt32(srEntry.Attributes["userAccountControl"][0]) & ((int)enUAC)))
{
sValue = "1";
}
else
{
sValue = "0";
}
}
else
if
(sAttribute.Equals("selective_authentication",
StringComparison.OrdinalIgnoreCase)
&&
srEntry.Attributes.Contains("ntSecurityDescriptor"))
{
object[]
aValues
=
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));
string sSecurityDescriptorSDDL =
this.GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections.Access, (byte[])aValues[0]);
if
(sSecurityDescriptorSDDL.Contains("(OA;;CR;68b1d179-0d15-4d4f-ab71-46152e79a7bc;;S-1-5-1000)"))
{
sValue = "1";
}
else
{
sValue = "0";
}
}
else
if
(sAttribute.Equals("ntSecurityDescriptor",
StringComparison.OrdinalIgnoreCase)
&&
srEntry.Attributes.Contains(sAttribute))
{
object[]
aValues
=
srEntry.Attributes["ntSecurityDescriptor"].GetValues(Type.GetType("System.Byte[]"));
sValue
=
this.GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections.Owner, (byte[])aValues[0]);
int i = sValue.Length;
}
else
if
(sAttribute.StartsWith("TSL_",
StringComparison.OrdinalIgnoreCase)
&&
srEntry.Attributes.Contains(sAttribute.Substring(4))
&&
dicAttributeList[sAttribute.Substring(4)].Equals("Sid", StringComparison.OrdinalIgnoreCase))
{
}
//ALL OTHER ATTRIBUTES
else
if
(srEntry.Attributes.Contains(sAttribute) && dicAttributeList.ContainsKey(sAttribute))
{

NNNNN

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


sValue

this.TranslateAtribute(srEntry.Attributes[sAttribute]);
}
if
(sAttribute.Equals(oLdapRequest.KeyAttribute, StringComparison.OrdinalIgnoreCase))
{
oLdapRequest.AttributeValue
sValue;
}
else
{
dicProperties.Add(sAttribute,
sValue);
}
}
}

if (dicProperties.Count > 0)
{
this.AddTranslatedObjectToDictionary(oLdapRequest.AttributeValue, dicProperties);
}
}
}
}
catch (Exception ex)
{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6663);
oEventLog.Dispose();
}
}
private void GetDcSpecificAttribute(object oLdapRqst)
{
Dictionary<string, string> dicSearchResult = null;
try
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
PageResultRequestControl rcPageRequest = null;
PageResultResponseControl rcPageResponse = null;
LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;
string sServerName = oLdapRequest.ldapConnection.SessionOptions.HostName;
string sDomainFqdn = sServerName.Substring(sServerName.IndexOf('.') + 1);
srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
oLdapRequest.LdapFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
oLdapRequest.AttributesToLoad
);
rcPageRequest = new PageResultRequestControl();
rcPageRequest.PageSize = this.iPageSize;
srRequest.Controls.Add(rcPageRequest);
do

OOOOO

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
dirRes
(SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
rcPageResponse = (PageResultResponseControl)dirRes.Controls[0];

if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
dicSearchResult
=
new
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);
foreach

(string

sAttribute

in

oLdapRequest.AttributesToLoad)
{
string sValue = null;
if
(sAttribute.Equals("logonDomain",
StringComparison.OrdinalIgnoreCase))
{
sValue = sDomainFqdn;
}
else

StringComparison.OrdinalIgnoreCase))

if

(sAttribute.Equals("logonServer",

{
sValue = sServerName;
}
else
(srEntry.Attributes.Contains(sAttribute) && dicAttributeList.ContainsKey(sAttribute))
{

if
sValue

this.TranslateAtribute(srEntry.Attributes[sAttribute]);
}
dicSearchResult.Add(sAttribute, sValue);
}
this.AddObjectToList(dicSearchResult);
}
}
rcPageRequest.Cookie = rcPageResponse.Cookie;
}
while (Convert.ToBoolean(rcPageResponse.Cookie.Length));
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private void RetrieveGroupMembers(object oLdapRqst)


{
List<string> lMembers = new List<string>();
try
{
SearchResponse dirRes;
SearchResultEntry srEntry;
SearchResultEntry srMember;
LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;
string sGroupFilter = @"(&(objectClass=group)(objectCategory=group))";
dirRes

(SearchResponse)oLdapRequest.ldapConnection.SendRequest(new

SearchRequest(

oLdapRequest.AttributeValue,
String.Format("(&{0}(member=*))", sGroupFilter),
System.DirectoryServices.Protocols.SearchScope.Base,
"member","objectSid"

PPPPP

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

));
if (dirRes.Entries.Count > 0)
{
object[] aValues = null;
SecurityIdentifier oSID = null;
srEntry = dirRes.Entries[0];
aValues
srEntry.Attributes["objectSid"].GetValues(Type.GetType("System.Byte[]"));
oSID = new SecurityIdentifier((byte[])aValues[0], 0);

string sObjectSid = oSID.ToString();


if (srEntry.Attributes.Contains("member"))
{
foreach
(string
sMemberDN
in
srEntry.Attributes["member"].GetValues(Type.GetType("System.String")))
{
dirRes
=
(SearchResponse)oLdapRequest.ldapConnection.SendRequest(new SearchRequest(
sMemberDN,
@"(&(objectClass=*)(!objectClass=contact))",
System.DirectoryServices.Protocols.SearchScope.Base,
"objectSid"
));
if (dirRes.Entries.Count > 0)
{
srMember = dirRes.Entries[0];
aValues
srMember.Attributes["objectSid"].GetValues(Type.GetType("System.Byte[]"));
oSID
SecurityIdentifier((byte[])aValues[0], 0);

=
=

new

lMembers.Add(oSID.ToString());
}
}
}
this.AddMshipsToDictionary(sObjectSid, lMembers);
}
}
catch (Exception ex)
{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6666);
oEventLog.Dispose();
}
}
private void FastRetrieveUpdatedMembers(object oLdapRqst)
{
try
{
const ushort RETRY_NO = 10;
SearchResponse dirRes = null;
SearchRequest srRequest = null;
SearchResultEntry srEntry = null;
LdapRequest oLdapRequest = (LdapRequest)oLdapRqst;

QQQQQ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

Dictionary<string, MembershipAction>
MembershipAction>(StringComparer.OrdinalIgnoreCase);

dicActions

new

Dictionary<string,

//SecurityDescriptorFlagControl
sdControl
=
SecurityDescriptorFlagControl(System.DirectoryServices.Protocols.SecurityMasks.Dacl);
//ResultCode.bu
string sAttribute = "msDS-ReplValueMetaData";
string sRange = String.Format(@"{0};range={{0}}-{{1}}", sAttribute);

new

int iIndex = 0;
int iStep = 0;
string sCurrentRange = String.Format(sRange, iIndex, '*');
bool bMoreData = true;
while (bMoreData)
{
ushort iTries = 0;
bool bRetry = false;
do
{
try
{
iTries++;
srRequest = new SearchRequest(
oLdapRequest.AttributeValue,
@"(&(objectClass=group)(objectCategory=group))",
System.DirectoryServices.Protocols.SearchScope.Base,
new string[] { sCurrentRange }
);
dirRes
(SearchResponse)oLdapRequest.ldapConnection.SendRequest(srRequest);
bRetry = false;
}
catch (DirectoryOperationException ex)
{
if (iTries % RETRY_NO == 0)
{
bRetry = false;
throw
Exception(string.Format("{0}::{1}", new StackFrame(0, true).GetMethod().Name, ex.Message));
}
else
{
bRetry = true;
}
}
} while (bRetry);

new

if (dirRes.Entries.Count > 0 && dirRes.Entries[0].Attributes.Count > 0)


{
srEntry = dirRes.Entries[0];
foreach (string sAttr in srEntry.Attributes.AttributeNames)
{
foreach
(object
oValue
in
srEntry.Attributes[sAttr].GetValues(Type.GetType("System.String")))
{
Dictionary<string,
string>
dicAttributeReplData = GetNodesInnertext(oValue.ToString(), new string[] { "pszAttributeName", "pszObjectDn",
"ftimeDeleted", "usnLocalChange" }, true);
if
(dicAttributeReplData["pszAttributeName"].Equals("member", StringComparison.OrdinalIgnoreCase))

RRRRR

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


{
string sUsnLocalChange = null;
if

(dicAttributeReplData.TryGetValue("usnLocalChange", out sUsnLocalChange))


{
if
(Convert.ToInt64(dicAttributeReplData["usnLocalChange"]) > this.iHighestCommittedUSN)

if
(dicAttributeReplData["ftimeDeleted"].Equals("1601-01-01T00:00:00Z", StringComparison.OrdinalIgnoreCase))
{
dicActions.Add(dicAttributeReplData["pszObjectDn"], MembershipAction.Add);
}
else
{
dicActions.Add(dicAttributeReplData["pszObjectDn"], MembershipAction.Remove);
}
}
}
iIndex++;

}
if (sAttr.IndexOf('*') > 0)
{
bMoreData = false;
}
else
{
iStep = srEntry.Attributes[sAttr].Count;
sCurrentRange = String.Format(sRange,
iIndex, iIndex + iStep);
}

}
else
{
bMoreData = false;
}
}
if (dicActions.Count > 0)
{
this.AddMshipActionsToDictionary(oLdapRequest.AttributeValue,
dicActions);
}
}
catch (Exception ex)
{
EventLog oEventLog = new System.Diagnostics.EventLog("Application", ".",
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
oEventLog.WriteEntry(String.Format("{0}::{1}",
new
StackTrace(true).GetFrame(0).GetMethod().Name.ToString(), ex.Message), EventLogEntryType.Error, 6663);
oEventLog.Dispose();
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
private void AddObjectToList(Dictionary<string, string> dicObjectDetails)
{
try
{
this.lResults.Add(dicObjectDetails);
}
catch (Exception ex)

SSSSS

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

{
throw
true).GetMethod().Name, ex.Message));
}
}

new

Exception(string.Format("{0}::{1}",

[MethodImpl(MethodImplOptions.Synchronized)]
private void AddGenObjectToList(Dictionary<string, object> dicObjectDetails)
{
try
{
this.lGenResults.Add(dicObjectDetails);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
}

new

StackFrame(0,

new

StackFrame(0,

[MethodImpl(MethodImplOptions.Synchronized)]
private void AddTranslatedObjectToDictionary(string sKey, Dictionary<string, string> dicObjectDetails)
{
try
{
if (!dicIndexedTranslatedResults.ContainsKey(sKey))
{
this.dicIndexedTranslatedResults.Add(sKey, dicObjectDetails);
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
private void AddObjectToDictionary(string sKey, Dictionary<string, object> dicObjectDetails)
{
try
{
if (!this.dicIndexedResults.ContainsKey(sKey))
{
this.dicIndexedResults.Add(sKey, dicObjectDetails);
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
private void AddMshipsToDictionary(string sGroupSid, List<string> lMemberSids)
{
try
{
if (!this.dicMshipsResults.ContainsKey(sGroupSid))
{
this.dicMshipsResults.Add(sGroupSid, lMemberSids);
}
}
catch (Exception ex)
{

TTTTT

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics
throw
true).GetMethod().Name, ex.Message));
}
}

dicActions)

Zrich, 20 August. 2012


new

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

[MethodImpl(MethodImplOptions.Synchronized)]
private void AddMshipActionsToDictionary(string sGroupDn, Dictionary<string, MembershipAction>
{
try
{
if (!this.dicMshipsActions.ContainsKey(sGroupDn))
{
this.dicMshipsActions.Add(sGroupDn, dicActions);
}

}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}

Exception(string.Format("{0}::{1}",

new

StackFrame(0,

private LdapConnection OpenLdapConnection(string sServerName, NetworkCredential netCred)


{
try
{
LdapDirectoryIdentifier
oLdapDirectory
=
LdapDirectoryIdentifier(sServerName, this.Port);
//LdapConnection

oLdapConnection

new

new

LdapConnection(oLdapDirectory,

netCred, AuthType.Basic);
LdapConnection oLdapConnection = new LdapConnection(oLdapDirectory, netCred);
oLdapConnection.Bind();
oLdapConnection.Timeout = TimeSpan.FromSeconds(CONN_TIME_OUT);
oLdapConnection.SessionOptions.TcpKeepAlive = true;
oLdapConnection.SessionOptions.ProtocolVersion = 3;
//prevents ldap connection from connecting to other servers during session
oLdapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
oLdapConnection.AutoBind = false;
return oLdapConnection;
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void OpenAllConnections()
{
try
{
this.lOpenLdapConnections = new List<LdapConnection>();
for (int i = 0; i < NUMBER_OF_OPEN_TCP_CONNECTIONS; i++)
{
foreach (string sDC in this.aDcServers)
{
try
{
LdapDirectoryIdentifier oLdapDirectory = new
LdapDirectoryIdentifier(sDC, 389);

UUUUU

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


LdapConnection

oLdapConnection

(this.netCredentials == null)
?

new

new

LdapConnection(oLdapDirectory)
LdapConnection(oLdapDirectory, netCredentials);
oLdapConnection.Timeout

TimeSpan.FromSeconds(CONN_TIME_OUT);
oLdapConnection.SessionOptions.TcpKeepAlive = true;
oLdapConnection.SessionOptions.ProtocolVersion = 3;
oLdapConnection.SessionOptions.ReferralChasing

ReferralChasingOptions.None;
oLdapConnection.AutoBind = false;
oLdapConnection.Bind();
this.lOpenLdapConnections.Add(oLdapConnection);
}
catch
{

}
}
}
if (!(this.lOpenLdapConnections.Count > 0))
{
throw new Exception(string.Format("{0}::{1}", new StackFrame(0,
true).GetMethod().Name, "Couldn't establish any LDAP connection with Domain Controlers"));
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void DisposeAllConnections()
{
try
{
if (this.lOpenLdapConnections != null)
{
foreach (LdapConnection ldapConn in this.lOpenLdapConnections)
{
ldapConn.Dispose();
}
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void LoadLdapAttributes()
{
try
{
using
(LdapConnection
oLdapConnection
this.OpenLdapConnection(this.aDcServers[0], this.netCredentials))
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
PageResultRequestControl rcPageRequest = null;

VVVVV

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

PageResultResponseControl rcPageResponse = null;


dicAttributeList

new

Dictionary<string,

string>(StringComparer.OrdinalIgnoreCase);
Dictionary<string, Dictionary<string, string>> dicAttributeMappings = new
Dictionary<string, Dictionary<string, string>>(){
{"2.5.5.1",
new
Dictionary<string,string>(){{"127",
"DN-Binary"}}},
{"2.5.5.2",
new
Dictionary<string,string>(){{"6",
"Object-Identifier"}}},
{"2.5.5.3",
new
Dictionary<string,string>(){{"27",
"String"}}},
{"2.5.5.4",
new
Dictionary<string,string>(){{"20",
"IString"}}},
{"2.5.5.5",
new
Dictionary<string,string>(){{"19",
"Printable"}, {"22", "IA5"}}},
{"2.5.5.6",
new
Dictionary<string,string>(){{"18",
"Numeric"}}},
{"2.5.5.7",
new
Dictionary<string,string>(){{"127",
"Object"}}},
{"2.5.5.8",
new
Dictionary<string,string>(){{"1",
"Boolean"}}},
{"2.5.5.9",
new
Dictionary<string,string>(){{"2",
"Integer"}, {"10", "Enumeration"}}},
{"2.5.5.10",
new Dictionary<string,string>(){{"4", "Octet"}}},
{"2.5.5.11",
new Dictionary<string,string>(){{"23",
"UTCTime"}, {"24",
"Generalized-Time"}}},
{"2.5.5.12",
new
Dictionary<string,string>(){{"64",
"Unicode"}}},
{"2.5.5.13",
new
Dictionary<string,string>(){{"127",
"Presentation-Address"}}},
{"2.5.5.14",
new
Dictionary<string,string>(){{"127",
"Object"}}},
{"2.5.5.15",
new Dictionary<string,string>(){{"66",
"NTSec-Desc"}}},
{"2.5.5.16",
new
Dictionary<string,string>(){{"65",
"LargeInteger"}}},
{"2.5.5.17",
new Dictionary<string,string>(){{"4", "Sid"}}}
};
string
@"(&(objectClass=attributeSchema)(oMSyntax=*)(attributeSyntax=*))";

sAttributesFilter

string sServerName = oLdapConnection.SessionOptions.HostName;


dirRes

(SearchResponse)oLdapConnection.SendRequest(new

SearchRequest(
null,
"(schemaNamingContext=*)",
System.DirectoryServices.Protocols.SearchScope.Base,
"schemaNamingContext"
));
string
dirRes.Entries[0].Attributes["schemaNamingContext"][0].ToString();

sConfPartDN

srRequest = new SearchRequest(


sConfPartDN,
sAttributesFilter,
System.DirectoryServices.Protocols.SearchScope.OneLevel,

WWWWW

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


new string[] { "oMSyntax", "attributeSyntax",

"LdapDisplayName" }
);
rcPageRequest = new PageResultRequestControl();
rcPageRequest.PageSize = this.iPageSize;
srRequest.Controls.Add(rcPageRequest);
do
{
dirRes
(SearchResponse)oLdapConnection.SendRequest(srRequest);
rcPageResponse
(PageResultResponseControl)dirRes.Controls[0];

=
=

if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
string
sAttributeStx
=
srEntry.Attributes["attributeSyntax"][0].ToString();

string

sAttributeoMStx

srEntry.Attributes["oMSyntax"][0].ToString();
if
(dicAttributeMappings.ContainsKey(sAttributeStx))
{
if
(dicAttributeMappings[sAttributeStx].ContainsKey(sAttributeoMStx))
{
string sAttributeType =
dicAttributeMappings[sAttributeStx][sAttributeoMStx];
string sAttributeName =
srEntry.Attributes["LdapDisplayName"][0].ToString();
dicAttributeList.Add(sAttributeName, sAttributeType);
}
}
}
}
rcPageRequest.Cookie = rcPageResponse.Cookie;
}
while (Convert.ToBoolean(rcPageResponse.Cookie.Length));
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private void LoadExtendedRights()
{
try
{
using
(LdapConnection
oLdapConnection
=
this.OpenLdapConnection(this.aDcServers[0], this.netCredentials))
{
SearchResponse dirRes = null;
SearchRequest srRequest = null;
PageResultRequestControl rcPageRequest = null;
PageResultResponseControl rcPageResponse = null;
dicExtAccessRights
string>(StringComparer.OrdinalIgnoreCase);

XXXXX

new

Dictionary<string,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

string sAttributesFilter = @"(objectClass=controlAccessRight)";


string sServerName = oLdapConnection.SessionOptions.HostName;
dirRes

(SearchResponse)oLdapConnection.SendRequest(new

SearchRequest(
null,
sAttributesFilter,
System.DirectoryServices.Protocols.SearchScope.Base,
"configurationNamingContext"
));
string
dirRes.Entries[0].Attributes["configurationNamingContext"][0].ToString();

sConfPartDN

srRequest = new SearchRequest(


sConfPartDN,
sAttributesFilter,
System.DirectoryServices.Protocols.SearchScope.Subtree,
new string[] { "cn", "objectGUID" }
);
rcPageRequest = new PageResultRequestControl();
rcPageRequest.PageSize = this.iPageSize;
srRequest.Controls.Add(rcPageRequest);
do
{
dirRes
(SearchResponse)oLdapConnection.SendRequest(srRequest);
rcPageResponse
(PageResultResponseControl)dirRes.Controls[0];

=
=

if (dirRes.Entries.Count > 0)
{
foreach (SearchResultEntry srEntry in dirRes.Entries)
{
string
sObjectCN
=
srEntry.Attributes["cn"][0].ToString();
Guid
oObjectGuid
Guid((byte[])srEntry.Attributes["objectGUID"].GetValues(Type.GetType("System.Byte[]"))[0]);

new

this.dicExtAccessRights.Add(oObjectGuid.ToString(), sObjectCN);
}
}
rcPageRequest.Cookie = rcPageResponse.Cookie;
}
while (Convert.ToBoolean(rcPageResponse.Cookie.Length));
}
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
#endregion
#region Helper Private Methods
private string TranslateAtribute(DirectoryAttribute daProperty)
{

YYYYY

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

try
{
string sValue = null;
Type tpAttribute = daProperty[0].GetType();
if
(this.dicAttributeList.ContainsKey(daProperty.Name)
&&
this.dicAttributeList[daProperty.Name].Equals("Sid", StringComparison.OrdinalIgnoreCase))
{
object[] aValues = daProperty.GetValues(Type.GetType("System.Byte[]"));
for (int i = 0; i < aValues.Length; i++)
{
sValue
+=
String.Format("|{0}",
(new
SecurityIdentifier((byte[])aValues[i], 0)).ToString());
}
sValue = sValue.TrimStart('|');
}
else
if
(this.dicAttributeList.ContainsKey(daProperty.Name)
&&
this.dicAttributeList[daProperty.Name].Equals("Octet", StringComparison.OrdinalIgnoreCase))
{
object[] aValues = daProperty.GetValues(Type.GetType("System.Byte[]"));
sValue = new Guid((byte[])aValues[0]).ToString();
}
else
if
(this.dicAttributeList.ContainsKey(daProperty.Name)
this.dicAttributeList[daProperty.Name].Equals("LargeInteger", StringComparison.OrdinalIgnoreCase))
{
Int64 lVal = Convert.ToInt64(daProperty[0]);
if (lVal > 0)
{
sValue

String.Format("{0:yyyy-MM-dd

&&

hh:mm:ss}",

DateTime.FromFileTime(lVal));
}
}
else
if
(this.dicAttributeList.ContainsKey(daProperty.Name)
&&
this.dicAttributeList[daProperty.Name].Equals("Generalized-Time", StringComparison.OrdinalIgnoreCase))
{
if (daProperty[0] != null)
{
sValue
=
String.Format("{0:yyyy-MM-dd
HH:mm:ss}",
DateTime.ParseExact(daProperty[0].ToString(), @"yyyyMMddHHmmss.f'Z'", null));
}
}
else if (Type.GetTypeCode(tpAttribute) == TypeCode.Boolean)
{
object[] aValues = daProperty.GetValues(tpAttribute);
sValue = String.Format("{0}", aValues[0]);
}
else
if
(Type.GetTypeCode(tpAttribute)
==
TypeCode.Int32
||
Type.GetTypeCode(tpAttribute) == TypeCode.Int16)
{
object[] aValues = daProperty.GetValues(tpAttribute);
sValue = String.Format("{0}", aValues[0]);
}
else if (Type.GetTypeCode(tpAttribute) == TypeCode.String)
{
object[] aValues = daProperty.GetValues(tpAttribute);
foreach (string sVal in aValues)
{
sValue += String.Format("|{0}", sVal);
}
sValue = sValue.TrimStart('|');
}
return sValue;

ZZZZZ

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private string[] GetSiteServers(string DomainName, string ADSite)
{
try
{
return this.GetSiteServers(DomainName, ADSite, null, null);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
new
StackFrame(0,
true).GetMethod().Name, ex.Message));
}
}
private string[] GetSiteServers(string DomainName, string ADSite, string UserID, string UserPW)
{
string sDomainControllers = null;
try
{
using (Domain oDomain = UserID != null && UserPW != null
?
Domain.GetDomain(new
DirectoryContext(DirectoryContextType.Domain,
DomainName, UserID, UserPW))
:

Domain.GetDomain(new

DirectoryContext(DirectoryContextType.Domain,

DomainName)))
{
DomainControllerCollection colDomControllers = (ADSite != null)
? oDomain.FindAllDomainControllers(ADSite)
: oDomain.FindAllDomainControllers();
if (colDomControllers.Count == 0)
{
colDomControllers = oDomain.FindAllDomainControllers();
}
foreach (DomainController DC in colDomControllers)
{
sDomainControllers += String.Format(";{0}", DC.Name);
}
}
sDomainControllers = sDomainControllers.TrimStart(';');
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}

Exception(string.Format("{0}::{1}",

new

return sDomainControllers.Split(';');
}
private string GetDomainNetBIOS(string sDomainFqdn, NetworkCredential netCred)
{
LdapDirectoryIdentifier oLdapDirectory = null;
LdapConnection oLdapConnection = null;
try
{
string sNetBIOS = null;
oLdapDirectory = new LdapDirectoryIdentifier(sDomainFqdn, 389);
oLdapConnection = (netCred == null)

AAAAAA

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


? new LdapConnection(oLdapDirectory)
: new LdapConnection(oLdapDirectory, netCred);

oLdapConnection.Timeout = TimeSpan.FromSeconds(45);
oLdapConnection.SessionOptions.TcpKeepAlive = true;
oLdapConnection.SessionOptions.ProtocolVersion = 3;
//prevents ldap connection from connecting to other servers during session
oLdapConnection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
oLdapConnection.AutoBind = false;
oLdapConnection.Bind();
SearchResponse

dirRes

(SearchResponse)oLdapConnection.SendRequest(new

SearchRequest(
null,
"configurationNamingContext=*",
System.DirectoryServices.Protocols.SearchScope.Base,
"configurationNamingContext"
));
string
sConfPartDN
dirRes.Entries[0].Attributes["configurationNamingContext"][0].ToString();

dirRes = (SearchResponse)oLdapConnection.SendRequest(new SearchRequest(


sConfPartDN,
String.Format("(&(nETBIOSName=*)(dnsRoot={0}))", sDomainFqdn),
System.DirectoryServices.Protocols.SearchScope.Subtree,
"nETBIOSName"
));
if ( dirRes.Entries.Count > 0 )
{
sNetBIOS = dirRes.Entries[0].Attributes["nETBIOSName"][0].ToString();
}
return sNetBIOS;

}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));
}
finally
{
oLdapDirectory = null;

new

StackFrame(0,

oLdapConnection.Dispose();
oLdapConnection = null;
}

private
string
GetSecurityDescriptorSDDL(System.Security.AccessControl.AccessControlSections
secSection, byte[] baSecurityDescriptor)
{
try
{
ActiveDirectorySecurity adSec = new ActiveDirectorySecurity();
adSec.SetSecurityDescriptorBinaryForm(baSecurityDescriptor);
return adSec.GetSecurityDescriptorSddlForm(secSection);
}
catch (Exception ex)
{
throw
new
Exception(string.Format("{0}::{1}",
true).GetMethod().Name, ex.Message));

BBBBBB

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

}
}
private Dictionary<string, string> GetNodesInnertext(string sXmlNodes, string[] aNodeNames, bool
bOrdered)
{
try
{
Dictionary<string,
string>(StringComparer.OrdinalIgnoreCase);

string>

dicResult

new

Dictionary<string,

if (bOrdered)
{
int iStart = -1;
int iEnd = -1;
foreach (string sNode in aNodeNames)
{
if (sXmlNodes.Length > iEnd)
{
iStart = sXmlNodes.IndexOf(String.Format(@"<{0}>",

sNode), iEnd + 1);

if (iStart >= 0)
{
iStart += (sNode.Length + 2);
iEnd

sXmlNodes.IndexOf(String.Format(@"</{0}>", sNode), iStart);


dicResult.Add(sNode,
sXmlNodes.Substring(iStart, iEnd - iStart));
}
}
}
}
else
{
foreach (string sNode in aNodeNames)
{
int iStart = -1;
int iEnd = -1;
iStart = sXmlNodes.IndexOf(String.Format(@"<{0}>", sNode), 0);
if (iStart >= 0)
{
iStart += (sNode.Length + 2);
iEnd = sXmlNodes.IndexOf(String.Format(@"</{0}>",
sNode), iStart);
dicResult.Add(sNode, sXmlNodes.Substring(iStart, iEnd
- iStart));
}
}
}
return dicResult;
}
catch (Exception ex)
{
throw
new
true).GetMethod().Name, ex.Message));
}
}
#endregion

Exception(string.Format("{0}::{1}",

CCCCCC

new

StackFrame(0,

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

#region Supporting Classes


private class LdapRequest
{
public LdapRequest(LdapConnection ldapConnection, string LdapFilter, string[]
AttributesToLoad, string DistinguishedName)
{
this.oLdapConnection = ldapConnection;
this.aAttributesToLoad = AttributesToLoad;
this.sAttributeValue = DistinguishedName;
this.sLdapFilter = LdapFilter;
}
public LdapRequest(LdapConnection ldapConnection, string[] AttributesToLoad, string
AttributeValue, string KeyAttribute)
{
this.oLdapConnection = ldapConnection;
this.aAttributesToLoad = AttributesToLoad;
this.sAttributeValue = AttributeValue;
this.sKeyAttribute = KeyAttribute;
}
public LdapRequest(LdapConnection ldapConnection, string[] AttributesToLoad, string
DistinguishedName)
{
this.oLdapConnection = ldapConnection;
this.aAttributesToLoad = AttributesToLoad;
this.sAttributeValue = DistinguishedName;
}
public LdapRequest(LdapConnection ldapConnection, string DistinguishedName)
{
this.oLdapConnection = ldapConnection;
this.sAttributeValue = DistinguishedName;
}
private LdapConnection oLdapConnection =
private string[] aAttributesToLoad =
private string sAttributeValue =
private string sKeyAttribute =
private string sLdapFilter =

null;
null;

public LdapConnection ldapConnection


{
get
{
return this.oLdapConnection;
}
set
{
this.oLdapConnection = value;
}
}
public string[] AttributesToLoad
{
get
{
return this.aAttributesToLoad;
}
set
{
this.aAttributesToLoad = value;
}
}
public string AttributeValue
{
get
{
return this.sAttributeValue;
}

DDDDDD

null;
null;

null;

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

set
{
this.sAttributeValue = value;
}
}
public string DistinguishedName
{
get
{
return this.sAttributeValue;
}
set
{
this.sAttributeValue = value;
}
}
public string KeyAttribute
{
get
{
return this.sKeyAttribute;
}
set
{
this.sKeyAttribute = value;
}
}
public string LdapFilter
{
get
{
return this.sLdapFilter;
}
set
{
this.sLdapFilter = value;
}
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if (!this.bDisposed)
{
if (bDisposing)
{
if(this.lGenResults != null)
{
this.lGenResults = null;
}
if(this.lResults != null)
{
this.lResults = null;
}
if(this.dicIndexedTranslatedResults != null)
{

EEEEEE

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012


this.dicIndexedTranslatedResults = null;

}
if(this.dicMshipsResults != null)
{
this.dicMshipsResults = null;
}
if(this.dicExtAccessRights != null)
{
this.dicExtAccessRights = null;
}
if (this.dicAttributeList != null)
{
this.dicAttributeList = null;
}
if (this.netCredentials != null)
{
this.netCredentials = null;
}
this.DisposeAllConnections();
}
this.bDisposed = true;
}
}
#endregion
}
}

FFFFFF

Grzegorz K. Spyra 06012419


MSc Advanced Security and Digital Forensics

Zrich, 20 August. 2012

IADCONNECTOR.CONFIG.XML
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="configuration" value="configuration" />
<!-- service modes configuration -->
<add key="interval" value="1" />
<add key="schedule" value="22:00" />
<!--1 when have new empty inventory; 0 when doing full resync; 1 or 0 in normal operation-->
<add key="firstrun" value="0" />
</appSettings>
<connectionStrings>
<add
name="iADConnector"
connectionString="Persist
Security
Info=False;Integrated
Security=SSPI;database=iADConnector;server=IP-0A74C61D\SQLEXPRESS;Connect Timeout=120" />
</connectionStrings>
</configuration>

GGGGGG

Das könnte Ihnen auch gefallen