- P H R A C K M A G A Z I N E -
Volume 0xa Issue 0x38
05.01.2000
0x06[0x10]
|------------------------------ PROJECT AREA52 -------------------------------|
|-----------------------------------------------------------------------------|
|------------------------ Jitsu-Disk <jitsu@nmrc.org> ------------------------|
|----------- Simple Nomad <thegnome@nmrc.org> Irib <irib@nmrc.org> -----------|
"Delirium Tremens"
----| Background
Military tactics have evolved along with technology. Reaching an objective is
done with computed strategies gathering the impact of warfare on the field.
This information is used to plan the next offensive. As the NSA has pointed
out, cyber-warfare happens much like its real-life counterpart, hence the
same intelligence can be used. This draft will try to explore the means and
tools with which to build an automated attack engine based on a universal
classification of attack strategies (regardless of the actual attacks).
----| Classification
Writing the proper classification of computer attacks actually fills entire
books [1], yet we can devise levels of access -- Read, Write and Modify --
that an attacker can gain over a system. The steps to achieve your goal will
vary depending upon whether you are attacking remotely, locally, or even
physically. Achieving the goal is also dependent upon the security policy
of the targeted system.
The objective of the classification is to provide a means to universally
describe the levels of acquired access, depending on one's situation.
Later we will explore the building of a generic engine to defeat various
security policies on target systems through the steps described in the
classification.
To illustrate this we will attempt to define the classification of remote
intrusion, based upon the OSI model. A similar classification for physical
and local intrusion can be derived, although this paper will mainly focus
on the remote element.
Various levels of access holds both logical properties and mathematical
ones. For example, a logical property might be "if you can read the TCP/IP
stream you can read the networked layer". A mathematical example might be
"the Write property is intransitive; you can spoof traffic on the network
yet not Modify existing data or hijack a session". The mathematical issues
are left as an exercise to the reader, the logical ones will be used as
the basis for the attack engine.
The following is our classification:
[ Acc : Access level
M = Modify capabilities
W = Write capabilities
R = Read capabilities ]
Situation : Remote
------------------
OSI Layers Acc Implication
*--------------*
| Application |
| 6 | M Application rights, compromise all layers below
| | W DoS, unprivileged access
| | R Data gathering
|--------------|
| Session |
| 5 | M Session redirection, compromise all layers below
| | W DoS, service scanning
| | R Session Data gathering
|--------------|
| Presentation |
| 4 | M Redirection, compromise all layers below
| | W DoS, scanning
| | R Data gathering
|--------------|
| Transport |
| 3 | M Redirection, compromise all layers below
| | W DoS, scanning
| | R Data gathering
|--------------|
| Network |
| 2 | M Redirection, compromise all layers below
| | W DoS, scanning
| | R Data gathering
|--------------|
| Data Link |
| 1 | M Redirection, compromise all layers below
| | W DoS, scanning
| | R Data gathering
|--------------|
| Physical |
| 0 | M Redirection
| | W DoS, scanning
| | R Data gathering
*--------------*
This attack-based model works top/down: if you can control the Application
(Modification rights to what it does), all dependent layers are compromised.
To be more specific, all dependent layers of the specific process you control
are now "owned" by you. If you control sendmail you may fool around with
all associated network functions, in the scope of access rights. Hence, if we
define our "attack goal" to be "running a shell as root on the target system",
a listening sendmail daemon running as root would be a good target. If
sendmail is compromised to the point of executing commands as root, the remote
attacker could easily gain a root shell, thereby meeting the goal. If the goal
was to establish a covert channel to the target for Denial of Service (DoS)
purposes or for launching further attacks, then appropriate actions would be
taken.
On the other hand, having control of a lower level layer doesn't automatically
guarantee you control of the above layer. For example, as an attacker you
might be sniffing the network and see two computers exchanging data. But if
this conversation is encrypted (and assuming you cannot decrypt the session)
you could at best simply disrupt the conversation -- you would not control it.
On the same layer their is a subtlety regarding the Read and Write
capabilities: being able to Read and Write only your own data is of limited
interest from an attacking standpoint, port scanning notwithstanding. Hence
we assume Read and Write capabilities are reached if you can Read and/or
Write data we don't "own".
Given the above definition of Read/Write for a layer, if one can both Read and
Write a layer it MAY be able to Modify it at that layer as well. However if
encryption is in use, this is not guaranteed. Therefore Read/Write
capabilities on a layer is required yet insufficient for Modify capabilities.
On a perfectly designed and secured system, one should not be able to get
additional rights on a higher layer. The attack engine works by exploiting
security breach to progressively reach a desired goal given a starting point.
For instance, achieving administrative access by starting with just the IP
address of the victim.
In order to illustrate some of this, let's define a very primitive
"Local Situation Access Classification" :
LS
6 kernel level (R,W,M)
5 drivers level (R,W,M)
4 process level (R,W,M)
3 user/group admin (R,W,M)
2 user/group "average" (R,W,M)
1 user/group null (R,W,M)
Now that we hold a classification hierarchy of access level, we need to
apply this to the security breach we know of.
For example in the NMRC Pandora project, a Hijacking attack called
"Level 3-1" would be referenced in this manner:
Name Systems Versions Level required Level gained
----------- -------- -------------- -------------- ------------
"Level 3-1" "Novell" "4.11","5 IPX" "Remote 3 M" "Local 3 R W"
This hack works on two levels -- a remote compromise of the IPX session,
and the payload that will actually give you admin privilege.
Another attack from Pandora called "GameOver" that exploits a bug looks
like so:
Name Systems Versions Level required Level gained
----------- -------- -------------- -------------- ------------
"GameOver" "Novell" "4.11","5 IPX" "5 W" "Local 4 R W"
In this case the process attacked is Bindery Supervisor equivalent in
rights. The Bindery Supervisor holds a restricted set of the Admin
rights. In this example we clearly see that this primitive description
of Local Situation doesn't quite fit -- although we have achieved a
higher level we have a restricted set of rights compared to previous
attack. A better Classification is to be devised.
The NMap[2] tool would be:
Name Systems Versions Level required Level gained
----------- -------- -------------- -------------- ------------
"NMAP" "ALL" "ALL" "3 W*" "5 R*"
W* and R* mean Write and Read in a restricted sense. Write implies valid
data you can legitimately write, Read data that you "own".
Two advantages are immediately obvious from this approach
-- Recognition of re-usability in attacks (e.g. if you only have R*/W*
access in a 3com switched environment running an attack to overload the
switch MAC table would provide you with R/W access and opens doors to
new attacks).
-- Independence of the type of code used for the attacks (scripts, Perl,
C, etc.) with the actual hack engine.
To facilitate the reference, the web's most popular hack archives [3][4][5]
could automate this in their commentary. This will be highlighted in the
next section.
Before we get there let's refine the classification method:
Assumptions
-----------
(1) For each situation (via network, via local process, via physical
access) a set of layer between you and the goal are defined.
(2) Each layer, independent from any other, are linked top-down.
(3) A layer is defined by its uniqueness and the ability to associate
Read/Write and Modify access levels for it.
Implications
------------
(1) Modify access in the highest layer implies control of all the preceding
layers (Layer N+1 includes Layer N), restricted by the given
Classification (in a Remote Situation that would be the process's
dependant layers, in a Local Situation, the runlevels).
(2) R/W/M access is a superset of R*/W*/M* where R*/W*/M* is the
legitimate privilege access for a layer and R/W/M includes access
to more privileges for the same layer (M>M*,W>W*,R>R*).
(3) Read/Write access to a layer is required to gain Modify access but
is not sufficient.
(4) The concept of security breach comes from the fact that there exists
a way to gain access to a higher layer (or access level) by defeating
the security policy protocol between two layers (or access levels).
For classification to be really universal and easily implemented, the three
situations (Remote, Local, Physical) must be devised in layers that apply
to all known systems. This might sound a bit utopic, yet the OSI model for
remote access seems universal enough since virtually every networked system is
either based on it or can be appropriately mapped against it. For Local access
to a system (via a remote shell, local session or whatever) to be properly
specified in layers, we should first look into what could be universally
considered as local system security layers such as run levels, groups and
users and hardware access (this has yet to be done). Physical access, brings
into light a world ruled by other means than just electricity, so things
might not be so obvious.
----| Storage : A Hack Database
Now that we have a Universal Classification for Remote, Local and Physical
access, let's set the following abbreviations:
Remote Situation : RS
Local Situation : LS
Physical Situation : PS
Layer N : L(N)
Layer N-1 : L(N-1)
Read access : R
Write access : W
Modify access : M
Restricted Read access : R*
Restricted Write access : W*
Restricted Modify access : M*
A privilege level is defined by the "tuple" : (situation, layer(x), access).
For example, ability to modify the application sendmail remotely (given OSI
model above) would be sendmail (RS,L(6),M). A remote buffer overflow in
sendmail, that just requires an attacker to send a mail to the daemon would be
listed this way:
Name Systems Versions Level required Level gained
--------------- -------- --------------- -------------- ------------
Sendmail-sploit All Unix Sendmail 8.10.1 (RS,L(6),W*) (LS,L(3),M)
We would also store the attack code in the database as well (remembering
the actual attack engine will be separate).
The stored code would return a value indicating attack success or failure,
and could also return parameters to be used with further attacks on completion.
For instance, a successful remote Sendmail buffer overflow would return TRUE
and a handle to the remote shell; then the attack would be taken to the
LS level where local attacks would be run to get runlevel 0 access (or root).
This means the attack engine would run stored functions in a dynamic database,
such as:
*------------* *-----------*
| Attacks | | Results |
*------------* *-----------*
| Attack_ID | | Result_ID |
| Name | | Type |
| System | 0,1---0,N-> | Identifier|
| Version | *-----------*
| Level Req | | Handle |
| Level Gain | *-----------*
*------------*
| Code |
*------------*
Attack_ID and Result_ID are unique.
The relation between the Attack table and the Result table is "one to many".
An attack could have been completed successfully on various targets. A
"result" is linked to one and only one attack.
In the result table the Type defines whatever it is, a temporary hack or a
permanent one (like a backdoor), the Identifier specifies a unique name to
the target (IP address, DNS name...).
The handle would be a pointer to a successful hack, based on the situation,
i.e. in a Remote attack a pointer to a Libnet[6] structure, in a Local attack
a pointer to a shell, a remote cmd.exe...
The "Code" part in the "Attack table" would be either the source code, which
means we have a built-in compiler in the engine, the attack binary code that
would require platform specific code to be pre-built, or some sort of
scripting language we would rewrite all attacks with (see Nessus in comparison
chapter below).
Those specifications are far from completed and the database is very simple,
but you get the point. The idea is to separate on the diagram what is gained
from knowledge (Attacks), to what is gained in the wild (Results). Just as
an example, that could be :
(known exploits code)
Systems-0,1-0,N-Vulnerabilities-0,N-0,1-Instructions
(known systems) | (known related instructions/daemons/programs...)
|
0,1
|
0,N
|
Result (handles to hack, Libnet stack, shell ...)
| (& collected info, e.g. [10.0.0.1] is [Novell 5sp3])
0,N
|
0,1
|
Target (standard specification of target IP,Name...)
This approach implies either standardized interfaces of hacks (normalized input
parameters and output handles), or a "Superset Code" could be written, that
given the attacks specifications (input parameters, Level Req'd, Level Gained),
would wrap the attack, run it, and return values in our standard form. Since
writing regular expression engines is, ahem, NOT fun maybe we could decide for
the first solution.
With respect to what we have seen in the Classification of the Remote
Situation, we stated that compromising a layer is understood in the restricted
sense of the attacked application's layers. Yet we could assume that
compromising an application, say Sendmail, would give you control over another
one, maybe DNS in this case. We need to be able to describe this in the
database -- compromising an application might give you control over some
others. A schematic representation would be:
0,1-[hack_id]-0,N (recursive link - a hack grants you access to more than)
| | (one system/instructions)
(known exploits code)
(and access levels)
Systems-0,1-0,N-Vulnerabilities-0,N-0,1-Instructions
(known systems) | (known related instructions/daemons/programs...)
|
0,1
|
0,N
|
Result (handles to hack, Libnet stack, shell ...)
| (& collected info, e.g. [10.0.0.1] is [Novell 5sp3])
0,N
|
0,1
|
Target (standard specification of target IP,Name...)
So we have now a pretty good idea of what the unified hack database would look
like:
1) A knowledge database of known systems, systems instructions and associated
exploits.
2) The database would have a standard for describing all fields.
3) It would define the level required/level gained "tuples" (situation,
layer(x),access), for each known exploit.
4) Exploit code would be stored in the database and follow a standard
representation of the interface (normalized input parameters and
output handles).
There exists today an international effort for a standard way to describe
exploits. Such databases are in their infancy, but strong projects like
CVE[7] are certainly breaking new ground.
The aim of such standardization is to achieve unified descriptions of attack
scenarios (to be used in attack automation, either via vulnerability
assessment tools or actual penetration tools). Therefore our attack engine
would offer three modes:
- Simulation (no actual attack performed, but we could use results for
vulnerability assessments, future attack scenarios, etc),
- Manual (attack performed manually, no wrap code, like the mils;-)),
- Automated (the ultimate Hacking Machine).
----| Artificial Intelligence
The reader might not be trained in AI, so let's attempt to define some
of the principles we need for this discussion.
--| Intelligence
AI is by no means meant to "create", but rather to "think". Thinking,
logically and reproducibly, is a process, therefore it may be mimicked by a
machine. In fact, given the proper thinking strategy and process a computer
solves known problems much faster than humans. Building a new Hack is a
simple process if the methodology is known. If the methodology is not known
you must create it. When no logical path takes you to where you want to go you
have to create a new Hack when it can't be related to any other hacks. The
new Hack then enrichs the world of known hacks, and can possibly be added to
the overall Hack process. It is assumed that AI can solve our problems, given
the following restrictions:
1) The problem solving time is, generally, unpredictable and may
even take years if done manually.
2) The problems that can't be solved because an individual doesn't
hold enough "process knowledge" for resolution (or the knowledge
necessary can't be described with the formalism we've chosen, see
the Godel theorem of incompleteness and the book "Godel Escher
Bach, The Eternal Golden Braid" by Douglas Hofstadter).
In other words, any system can be hacked; granted we have enough time and
known hacks for this purpose.
--| Inference
The "thinking engine" we want to use here will have to use known facts
(hacks) against field results, to explore the paths that takes us to the
ultimate goal (or result). Such engines are described in AI as "inference
engines", starting from the goal and finding a possible path to the knowledge
base is called "backward inference", starting from the knowledge base and
finding a path to the goal is called "forward inference". In the present case
"backward inference" is only good for simulation, but in the field we can only
use "forward inference" (which is algorithmically known as being slower than
backward inference).
The initial theory behind inference engines is based on two "logic" rules,
one for forward inference called Modus Ponens (MP) the other for backward
inference called Modus Tollens (MT). MP states that [if (P) AND (P includes Q)
THEN (Q)], MT says [if (NOT Q) AND (P implies Q) THEN (NOT P)].
--| The Inference Engine
Algorithmically speaking, the Inference Engine is a recursive algorithm that
takes a set of known facts as input (target is www.blabla.bla), processes it
against the database of rules (if RedHat 5.0 then SendMail is vulnerable) and
adds a new facts to the set (if target is RedHat 5.0 then target is vulnerable
to SendMail bug). The engine stops when either we have reached our goal
(target is compromised) or we can't add anything new to the set of facts (all
possibilities have been explored). In order to optimize the process, the
Inference Engine is set to use strategies in choosing which rules to test first
(buffer overflow might be easier to try than "tmp race", so we set the engine
to try a buffer overflow first). As discussed in the following "distributed"
section, it is essential to see that the hacking process is not in the engine
itself, but in the database rulesets. For instance, tests would be performed
to understand the target installation/setup/OS and match the subsequent hacks,
the engine provides the mechanism for this and the rulesets the paths to
understand how one must attack. It is in the description of the ruleset that
we have the actual "Intelligence", hence if a new OS appears on the market
with a new security mechanism, we do not need to rewrite the engine, but
specify new rules specific to this OS.
--| An Inference Engine of order 0
Consider a ruleset that contains no variables, only static facts:
If monkey close to tree, monkey on tree
If monkey on tree AND banana on tree, monkey eat banana
We use "order 0" inference engine (O.K AI pals, this is not quite the
definition, yes there is a whole theory behind this, we know, don't flame us).
With the initializing fact
monkey close to tree
we will get
monkey on tree
and finally
monkey eat banana
--| An Inference Engine of order 1
If the ruleset contains variables :
If monkey close to (X), monkey on (X)
If monkey on (X) AND banana on (X), monkey eat banana
The inference engine that processes the rules and operates variable
substitution is said to be of order 1 (And if you're curious to know, there is
no engine of order 2 or higher, all problems are proven to be described in
order 1). This is the type of engine we want to use, as it allow us to use
variables -- they will be the "handles" resulting of our hacks.
--| Pattern Matching
Just like there are interpreted languages and faster-running compiled ones,
there are AI Inference Engines based on "interpreted rulesets" and other
based on "compiled rulesets". Compiling the ruleset means you have to
rearrange it in such a way that is "immediately efficient". The compilation
method we're interested in is called Pattern Matching and is based on binary
trees. For instance, lets assume the following:
Initial database:
Name Systems Versions Level required Level gained
----------- -------- -------------- -------------- ------------
d0_v8-BOF Unix,All Sendmail 8.8.* (RS,L(6),W*) (LS,L(3),M)
d0_v9-BOF Unix,All Sendmail 8.9.1 (RS,L(6),W*) (LS,L(3),M)
Ruleset:
if system[X] is Unix AND Version[Y] is Sendmail 8.8.* AND
Level_s[Z] is RS AND Level_l[Z] is 6 AND Level_a[Z] is W* AND
Hack(d0_v8-BOF,X) THEN Level_a[Z] is [LS,L3,M]
if system[X] is Unix AND Version[Y] is Sendmail 8.9.1 AND
Level_s[Z] is RS AND Level_l[Z] is 6 AND Level_a[Z] is W* AND
Hack(d0_v9-BOF,X) THEN Level_a[Z] is [LS,L3,M]
Compiled ruleset for pattern matching:
system
|
[Sendmail]
|
version
|
[UNIX]
|
level_s
|
[RS]
|
level_l
|
[6]
|
level_a
|
[W*]
|
FUNC
/ \
/ \
/ \
/ \
[d0_v8-BOF] [d0_v9-BOF]
\ /
----------
|
*
level_s [L]
level_l [3]
level_a [M]
[] are used to represent variables, filled in for clarity
The tree is parsed from the top every time a new fact is added to the
knowledge database, and this allows for a dynamic-algorithm (i.e. intelligent
self-modifying knowledge base). When the tree is parsed and brings in a new
fact, the knowledge base is increased with this fact, and the tree is parsed
again for more facts...
Since an attack happens in different phases (see distributed chapter below),
facts may have different impacts. They may just be collected facts (system is
RH6.0, buffer overflow on sendmail possible, "poor default config" exploit
on sendmail possible), or facts that trigger attacks (buffer overflow and
"poor config" exploits possible, rule says test config first -- config exploit
will be tested and result added to database, we gain new rights or we move on).
Optimization comes from the fact that whereas in the flat ruleset sample all
rules must be parsed to find the matching one, in a tree-like representation a
simple pattern matching mechanism shows the right branch. Although it's a pain
to compile such a ruleset into a tree is not obvious for a few rules on our
database, it really shows if the database contains thousands of facts. Besides,
once the database is compiled into a tree, it's done and you dont have to do it
again (insertion of new elements into a tree is possible, yet the tree could
also be recompiled on each new addition).
More optimization, not for engine itself but in the hacking sense, can be
achieved if we set some "grading rules" per attack and organize the tree this
way -- say we know two attacks for Sendmail, same version, one relies on a
complex buffer overflow and the other on misconfiguration. The
misconfiguration should be tried first (if the buffer overflow fails we might
kill Sendmail altogether), hence given a higher mark. This marking process
would look at two factors -- the level required to perform attack and method
use, for instance:
Situation - Grade - Level - Grade - Method - Grade
Remote +100 6 +60 Config +3
Local +200 5 +50 Filesys +2
4 +40 BuffOver +1
...
The guarding mechanism can be automated in the AI, the method is another piece
of information to be Classified and stored in the Hack Database.
--| A Pattern Matching, Forward Inference Engine of Order 1
So what we're looking for is :
An AI engine, of forward inference type, of order 1. The engine is better
optimized, like in pattern matching for instance and it allows for function
executions.
An academic sample of such an algorithm is the RETE algorithm (beyond the scope
of this preliminary discussion) and the interested reader is directed to the
paper by Charles L. Forgy in "Artificial Intelligence" : "The RETE Matching
Algorithm" (Dept of Computer Science, Carnegie-Mellon University). You could
also look into a similar systems called OPS and TANGO ("OPS5 user's manual" by
the same author and "TANGO" by Cordier-Rousset from L.R.I of Orsay Faculty in
France). Working code of RETE can be found at the MIT repository [8]. You
can also check Pr. Miranker's Venus project [9]. Original code for OPS exists
in LISP [10]. However, the one piece of work that would definitely match
our expectation is a system called CLIPS, written in C, by NASA (initially
by NASA, but now it is maintained in the public domain) [11].
--| The Hacking Engine
The engine will first query the database of facts for all known hacks sorted
in the classification form we defined along with systems and versions
information, these known hacks are written as a set of rules the exact
representation of hacks into rules is linked to the engineitself and is yet to
be defined.
Then this ruleset is compiled into a binary tree (or some other efficient
data structure) for better optimization, provided a proper optimizing
strategy (which may branch to the left-most side for instance, maybe granted a
difficulty grade per attack). The optimizing strategy might take the
classification rules into account to decide that if a higher level is reached,
all branches that refer to lower level attacks must be ignored -- this would
be a called "restrictive optimization".
The engine is initialized with the initially known facts (target id), and
starts applying rules to these facts in order to get more information out of
them, until the goal is reached or all branches have been explored. The
engine in simulation mode would only use the initializing facts and match
function calls with them, in manual mode the hacker would be provided the
function code by the engine that would then wait for the result, in automatic
mode the engine would run the code itself.
----| Distributed paradigm
Distributed hacking theory, analysis and advantage has been extensively
reviewed in an excellent article by Andrew J. Stewart entitled "Distributed
Metastasis [12]. Hence we will base this proposed implementation on it,
please refer to the above article.
--| Distributed Schematic
In a distributed attack, the attacker (A) is the "parent" of all nodes
(agents). Each node is characterized by a running agent (the hacking engine),
its address (IP,IPX...), and the level the agent is running at. For instance:
[10.0.0.1,A,parent], knows (10.0.2.1,10.0.2.5,10.0.3.1)
|
|
----------------- -----------
| |
[10.0.3.1,A1,(LS,L(3),M)] [10.0.2.1,A2,(LS,L(3),M)], knows 10.0.2.5
|
[10.0.2.5,A3,(LS,L(3),M)]
The attacker knows the existence of all nodes, but communicates through the
hierarchy (to send a command to 10.0.2.5, he issues this to 10.0.2.1 for
routing). This keeps risk to a minimum, should any of the agents be
discovered. When 10.0.2.5 tries to talk to the attacker, he sends stuff via
10.0.2.1 -- A3 knows A2 but not A. It is obvious that if any of the nodes
are to be uncovered, attached parent node and child nodes could be too. In
this case, the Attacker could issue a direct order to any of the potentially
compromised agents to either "attach" themselves to somewhere else, or to
sacrifice the agent's "territory" and have the agent eliminate itself.
Example: Agent 10.0.2.1 was discovered, the Attacker decides to attach
10.0.2.5 to 10.0.3.1 and sacrifice 10.0.2.1.
[10.0.0.1,A,parent], knows (10.0.2.5,10.0.3.1)
|
|
----------------- -----------
| |
[10.0.3.1,A1,(LS,L(3),M)] x
|
[10.0.2.5,A3,(LS,L(3),M)]
To ensure better privacy, encryption is to be used at each node for the
database of "parent&child" they have.
At least two other secret-routing systems can be used:
1. A child knows its parent address, but parent doesn't know its children.
All communication to a child would first require a request to the top
node (A) to learn the location of the children. This would ensure lesser
risk to compromise an entire branch in case one of the node is uncovered
[10.0.0.1,A,parent], knows (10.0.2.5,10.0.3.1)
|
|
----------------- -----------
|
[10.0.3.1,A1,(LS,L(3),M)]
* |
| x
[10.0.2.5,A3,(LS,L(3),M)]
A3 knows how to talk to A1, A1 asks A for who to talk with.
2. All nodes in the tree (except for A) don't know the other nodes' addresses
but know the subnet on which the node resides and may sniff packets. For
instance A1 would send packets to 10.0.2.6, whereas 10.0.2.6 discards it but
10.0.2.5 sees the data and replies to 10.0.3.2. [13]
--| Distributed & Simultaneous Attack
Phase 0
The actual attack happens in phases. The attacker decides on a target and the
level desired. Then the AI will look in the known set of Agents, and the
defined rules for attack optimization. For instance, if we want to attack
10.0.3.2, the AI could decide to pass the attack to 10.0.3.1. The AI could
also decide for multiple agents to attack at once (hence the distributed
paradigm), in this case, collected information (the knowledge base) is passed
between each phase to the Attacker, who could decide to redistribute it to
the attacking agents.
Phase 1
Once a given Agent has received an order to attack, it queries its parent node
for updated hacking database entries. Depending on the initial Attack order
issued, this query might move up to the Attacker or not happen at all. If
the communication model used is hierarchical, we could even implement this in
DNS queries/replies to benefit from the existing code (see Phrack [14] issues
50-53 on this).
Phase 2
The agent performs ruleset optimization as discussed previously chapter.
Phase 3
The agent updates or build its RETE vulnerability tree.
Phase 4
The agent satisfies the first "target detection" ruleset (this includes host,
service, network topology, OS, Application layer info detection), before
moving to the next phase. This happens exclusively as an RS. In the case of
a simultaneous attack (by many agents for one target) information gathered is
moved to the Attacker who might push back other info gathered by the other
agents.
Phase 5
The Agent actually attempts to compromise the target. This phase is not
completed until the level of access the attacker decided upon is reached, and
the "target clean-up" (cleaning the logs) rulesets are satisfied. The cleanup
rules might even trigger the necessary hack of another box where the logs may
reside -- it is common practice in security administration to log to a
different machine (especially at high profile sites with high profile targets).
This phase might fail upon unsuccessful hacks or a timeout.
Phase 6
Install the hacking engine child on target. Target becomes part of the tree as
a subordinate of the successful attacking agent. The Attacker is notified of
the new acquisition.
Phase 7
The new agent goes into passive mode -- it waits for input from its parent and
monitors traffic and trust relationships locally to increase its local
knowledge database. On a regular basis the agent should "push" info to its
parent, this is necessary if the agent is behind a firewall or the address is
set dynamically.
Note: Phase 4+5+6 are the so-called "consolidation components".
The Simultaneous aspects of attack are controlled by the Attacker and not by
delegation to other parent nodes. This could be called Centrally Controlled
Distributed and Simultaneous Attack.
Let's summarize the phases:
Engine Phase Comments
----------- ----- --------
AI 0 Decide for agent(s) to attack target
Incremental 1 Database query
AI 2 Ruleset optimization
Incremental 3 Tree build
AI 4 Target information gathering
AI 5 Compromise target, cleanup
Incremental 6 Seed target
AI 7 New agent enters passive mode
Other concepts can be put into this, such as cryptography and multiple target
acquisition at once. It would certainly be an interesting exercise to write a
valid algorithm for all this.
----| Comparison
--| COPS Kuang system
The "Kuang system", a security analysis tool developed by Robert W. Baldwin of
MIT is included in COPS security package available from Purdue University [15].
The Kuang system is a ruleset-based system used to check UID/GID's rights on a
local system, i.e. it processes a knowledge base (list of privilege
users/files, list of rights needed on users/files to attain their level of
privilege) against a set of rules (if any user can write a startup file of
root, any user can become root). The ruleset is written as such that it is
"string parsable" in the inference engine (which is a forward inference engine
of order 1). The system can perform tests stored in a shell script to decide
if a rule is satisfied by the configuration of the system it is currently
running on.
In comparison to what is described in this paper, the Kuang system evolves
between (LS,L(1)) and (LS,L(3)). It uses a non-optimized forward inference
engine that performs Phase(4) of our distributed scheme.
We should consider the Kuang system as a working-case study, to build Area52.
--| A sample vulnerability scanner : Nessus
The Nessus Open source project [16] aims at providing a free security scanner.
It works by testing systems (remote/local) for known vulnerabilities. The
Nessus developers wrote a scripting language for this purpose -- we mentioned
earlier that the actual coding attacks should be freely coded in a highly
portable language for our proposed system. Yet the Nessus approach is not to
be neglected -- could we use the Nessus effort and extend its scripting
language so to actually re-write all exploits? This would mean a continuous
effort in writing the project, but then alleviates many compatibility and
database issues. We could even hope for a "common hacking language" relying
on multi-platform libraries like libpcap and libnet as core components.
Until an open source vulnerability scanner that can run on multiple platforms
comes along, this is a fairly attractive piece of technology.
--| Another Approach : Attack Trees
As is probably obvious, this "ultimate hack tool" could be used to help
protect as well as compromise. While most of the discussion has been from the
intruder perspective, we could easily use the tool for our own vulnerability
assessment. If we feed the knowledge database with all relevant information
about our own network and run the engine in simulation mode, this will output
a possible sequence of attack. Then, if the engine is told to search for ALL
possible sequences of attack, and the output can be arrange as a tree of
attack sequences (much like the tree of known vulnerabilities describe above),
this would provide a means to help automatically generate "Attack Trees", as
described by Bruce Schneier of Counterpane Internet Security in Dr. Dobb's
Journal [17] (December 1999).
--| Others...
Some distributed denial of service tools, have caused quite a stir in security
circles lately [18]. Those tools expose an interesting sample of distributed
communication and data tunneling, which code could be reused in the project
outlined in this paper. The main problem with these denial of service tools
is that their main output (floods of packets against a target) is never seen
by the Attacker, which is what we would certainly require.
----| References
[1] See discussions by Dr Ross Anderson from University of Cambridge
http://www.cl.cam.ac.uk/Teaching/1998/Security/
[2] NMap by Fyodor.
http://www.insecure.org/nmap
[3] PacketStorm
http://packetstorm.securify.com
[4] Security Bugware
http://oliver.efri.hr/~crv
[5] Security Focus
http://www.securityfocus.com/
[6] Libnet multi-platform packet mangling
http://www.packetfactory.net/libnet/
[7] Common Vulnerabilities and Exposures
http://cve.mitre.org, a unified hack database
[8] RETE LISP implementation
http://www.mit.edu/afs/cs.cmu.edu/project/ai-repository/ai/areas/expert/systems/frulekit/
[9] Prof. Miranker Venus project in C++
http://www.arlut.utexas.edu/~miranker/
[10] Original OPS LISP code
http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/areas/expert/systems/ops5/
[11] NASA RETE-like system, coded in C, very impressive!
http://www.ghg.net/clips/CLIPS.html
[12] "Distributed Metastasis: A Computer Network Penetration Methodology"
by Andrew J. Stewart
http://www.phrack.com/search.phtml?view&article=p55-16
[13] "Strategies for Defeating Distributed Attacks" by Simple Nomad
http://packetstorm.securify.com/papers/contest/Simple_Nomad.doc
[14] Phrack Magazine
http://www.phrack.com/
[15] Home archive of the COPS system
ftp://coast.cs.purdue.edu/pub/Purdue/cops/
[16] The Nessus Project
http://www.nessus.org
[17] "Attack Trees: Modeling Security Threats" by Bruce Schneier
http://www.ddj.com/articles/1999/9912/9912a/9912a.htm, DDJ article on Attack Trees
[18] Analysis of distributed denial of service tools by David Dittrich
http://staff.washington.edu/dittrich/
Also, the source code for these DoS tools can be found at [3].
|EOF|-------------------------------------------------------------------------|