Learning an advanced skillset
by Don Parker
It was almost two years ago now that I wrote the SecurityFocus article on TCP/IP skills required for security analysts. That article offered advice on how one can seek employment in the security field through education, training, and a strong focus on TCP/IP. The idea came about from all of the questions this author has been asked on the subject.
There is often a lot of uncertainty as to what one should study to further one’s career in the network security world. Much as I mentioned previously, it can be a daunting task. What was laid out as core skills required for a fully competent security analyst are in reality, but a baseline. From that foundation of skills learnt, and honed over time can you begin to think about acquiring more advanced skills.
The purpose of this article is to guide network security analysts towards learning the advanced skillset required to help further their careers. We'll look at two key pillars of knowledge, protocols and programming, and why they're so both so important in the security field.
Two pillars of knowledge
In this author’s opinion, there is perhaps a basic truth about network security and obtaining the skills required to practice it. Network security really boils down to understanding two key pillars: protocols (starting with TCP/IP), and programming. Everything else can generally fall within those two broad categories. That includes everything from web application security to exploit development, and many things in between. While we all understand that the base unit of computer-to-computer communications is the packet, there is still a tremendous amount of knowledge required to understand what is behind that small packet.
That very small packet incorporates a great amount of networking knowledge to understand and be able to parse effectively. Contained in that very packet is a good deal of information. What is required of you as an analyst, though, is the knowledge of protocols in order to extract the relevant information. Not all of the TCP/IP protocol world evolves around the four core protocols of TCP, UDP, IP, and ICMP. A good amount of other protocols reside at the application layer. It's also good to not only understand how protocols work, but also understand some of the design considerations that went it them. For example, knowing such things as why there are only 16 bits assigned to a port, and its relevance to the actual protocol will help give an analyst a far deeper insight into his daily work.
TCP/IP is a good start, but what about the other pillar of network security knowledge? The strong silent partner of the security field is programming. While there is a lot to be said for understanding networking and protocols, they are all related to the programs that use them. It is therefore with an understanding of programming and the ability to actually program that a far more profound knowledge of network security will come.
It could be argued that one need not program to be good at network security. However the point remains that to obtain an advanced skill set, you will have no choice but to pick up programming to make it to the next level.
Learning advanced skills
Network security analysts have all come to realize that there is one inevitable conclusion. We must learn how to program to take our skills to next level. Talented security researches like Mike Sues, Dave Aitel, and HD Moore are all very proficient at programming. But what actual languages should one learn? That is a relatively easy question to answer. Most every application or operating system in existence today is (or has been) written in either C or C++, and some have parts of it done in Assembly.
Now that you know you need to learn some high level programming languages like C and C++ you have to decide which you pick up first. There is no real definitive answer to that one. Most universities and colleges will teach you object oriented programming first, as embodied by C++ or Java. Gone are the days where C was the introductory language.
It can largely be agreed upon, though, that having the ability to code in C and C++ is a de-facto standard in the programming world. There are not too many heavyweight applications written in Java, in reality. Quite a few talented programmers that I know actually shudder at the thought of using Java for anything. Bottom line is that once you have learned how to program in one high level language it will be that much easier to pick up another one. There is a great deal more to programming then simply sitting down and banging out some code. A great deal of thought must go into what you want first, particularly when considering security, and the whole process can be mapped to what is called the Programming Lifecycle. Though the whole cycle may not be applicable to, say, exploit development there are steps to be followed when programming.
Let's apply this to the real world of security. As a network security professional you may be required to conduct a web application security test of a custom program. To do so effectively, you would need to have some additional skills beyond those of a typical analyst. Reverse engineering comes to mind readily as one such skill. Once you have reverse engineered an executable and identified any weakness, you then need to code the exploit for it.
It's not realistic to foresee a network analyst or security researcher coding an enterprise-class software project - but to conduct a security test of it, you will definitely have to write some code. That is a given. It would be highly recommended, then, to take formal training in the field prior to self teaching yourself via a book. One of the biggest downfalls when it comes to learning how to program is jumping ahead. You need to take a methodical approach when learning this subject matter, and a formal process forces you to do this. Few methods are better then going to a true "brick and mortar" learning institution such as your local college or university.
Reverse engineering and assembly
We've looked at the need for programming skills. That is stated because having the ability to program will in turn allow you to pick up other esoteric skills. If you are subscribed to some of the Securityfocus mailing lists then you have no doubt read or heard about people doing some reverse engineering of executables. This is done in order to try and find hidden flaws in the program itself without having access to the original code - as is often the case with closed-source applications.
Quite often when performing quality assurance trials of a new software program, all you have to work with is the binary itself. This is a good time to draw the parallel between a source code audit and reverse engineering. They're quite different. A source code audit is just that. As a programmer you would be hired to do quality assurance on the source code of a program in order to find any programming errors that could result in a format string attack or buffer overflow. In contrast, reverse engineering of a binary will result in you looking at the program's contents at the machine instruction level. This is where you have to step beyond the knowledge of C and C++, where the knowledge of Assembler is crucial.
When applications written in C and C++ (or other high-level languages) are compiled, they become an executable that is more difficult to understand. Often programs like Ollydbg, IDAPro, or SoftICE will be used to reveal the underlying set of Assembler instructions. Reverse engineering applications is not necessarily the easiest or most fun part of programming, but it is a necessary step. Understanding Assembly is the key. Outside of university courses in either Computer Science or Computer Engineering, one might want to pick up a book such as Jeff Duntemann’s, "Assembly Language Step-by-Step." Much as the author states in the book itself, a large part to understanding Assembly is in understanding of memory management.
Static and dynamic reverse engineering
To further the argument that the needs to have some reverse engineering knowledge, let's take a further look at its methodology. We can broadly break down reverse engineering into two camps. Those consist of both static and dynamic reverse engineering. Each method has a different approach and can be performed with a variety of tools.
In essence, when performing static analysis you are not actually invoking the executable itself. You would, for example, open it up with a tool such as IDAPro, and from there check the strings found in the executable itself. The strings that are extracted via IDAPro will give you a pretty good idea of what the executable itself will do once invoked. During static analysis you can also identify breakpoints to be used later whilst performing dynamic analysis. There is a great deal of information to be gleaned during static analysis. Once done you typically move onto dynamic analysis, which entails actually executing the binary itself. This is where the specific break points of interest found earlier during static analysis are examined.
It's important to take a reality check when considering when to do reverse engineering. Realistically, most of us simply do not have the time or budget to go to a college or university if we've already started our path through the security field. The question begs, then, just how do you learn how to program and by extension reverse engineering while in the field? This author would definitely advise a blended approach to the two. While beginning to take your first baby steps towards programming with C or C++, you would also start with some reverse engineering as well.
Specifically, a recommended approach would be to write your very first “Hello world!” program as is traditionally done. Then compile the code, turning it from source into an executable. Now take the executable and do a static analysis of it via the earlier mentioned IDAPro or Ollydb. This will help equate what you are seeing at the Assembler level with what it was you actually wrote in C or C++. This is the best of both worlds, you might say. You can directly see what high level language programs look like in comparison to machine code, Assembler. This method of learning how to both program and reverse engineer at the same can very well pay off handsomely for you.
Not everything must be written in C or C++ and understood in Assembly to be useful in the security world. There is no denying the sheer versatility that a scripting language such as PERL or Python brings to the table for a network security professional. Not convinced? HD Moore wrote the Metasploit Framework using PERL, and Dave Aitel wrote CANVAS using Python. These are good examples of the power of both scripting languages. Where and how will PERL and Python impact you as a security analyst? To be honest, if you haven't noticed already, scripting languages can be used as just about every juncture of your work day. If you disagree then it is likely because you are not yet adept at using them yet. Whether it is writing a small script to parse out specific fields of a program's output, or creating a small program to test out specific parts of your webserver or web application, they can all be done with a PERL or Python script.
Every language has its own strength, and both PERL and Python are powerful - but of the two it can be argued that nowadays you are probably better off learning Python over PERL. For one, Python is object oriented whereas PERL is not. Also, you don’t have the ";" denoting the end of a line in Python that you have in PERL, as Python takes a different approach when you write code. That plus the fact that the Python syntax is clearly easier to understand than PERL.
For those who plan to do a security test of web-based applications, you will also need a good understanding of the language used to code the program. Today this could be any one of a number of languages, including the ones mentioned about. However, it could also be in PHP or ASP - with PHP being by far the most popular scripting language on the Web. With this popularity comes various security issues, and so to audit PHP applications you would want to have a good understanding of PHP.
Whatever you choice of scripting language to learn, they clearly give you a powerful and easy-to-use tool. Once you are comfortable in using them, you can quickly bang out a script for just about any need. It's absolutely amazing the number of things that can be automated with scripts. And the extensive list of modules for both of these languages is impressive, cutting down on your work that can instead be done with a script. The final advantage I will mention when learning either one of these scripting languages is related to their portability. All you need is the associated interpreter installed and you are good to go whether on win32, *nix, or other operating system. A pretty powerful and handy feature.
This article sought to offer some guidance to security analysts on how to further their knowledge towards an advanced skill set. Sometimes being pointed in the right direction is exactly what one needs to take his career to the next level.
Once you are able to devote the time necessary to accumulating the above noted skills, it doesn't stop there. There are still other skills to be developed. That's part of the joy of the computer world, and is often reflected in some of the great work and information shared within the security community. Join some mailing lists and get involved.
One somewhat esoteric area is to specialize in exploit development. This is a natural offshoot of reverse engineering, and should not really be lumped in with reverse engineering itself. Some people that I know are able to do reverse engineering quite proficiently, however they are then unable to then code an exploit for the bug they have found. Quite often this process is non-trivial. It's also often due to a lack of a solid understanding of either C or C++. To be really good at network security, and all of its incarnations you really do need to have a solid ability to program.
While this article was not an exhaustive list of skills that an advanced skill set encompasses it does however touch on the core ones. Remember that one does not need to immerse himself into programming to learn it well. Simply budget your time accordingly and learn as you go. With both time, and patience your abilities will grow. I sincerely hope this article was of interest to you, and as always I welcome your feedback.
This article originally appeared on SecurityFocus.com -- reproduction in whole or in part is not allowed without expressed written consent.