how do you become a hacker?

I sometimes get asked how one can develop the skills needed to do what I do for a living. This is a tricky thing to answer, because being a good hacker ultimately means you think “wrong”, not just that you understand tech.

When I interview people for a job, of course I’m looking to see if you have technical chops. More importantly though, I’m looking to see how you think, and how you handle unexpected things.

That “hacker mindset” quality is hard to define, tough to extract over the course of a brief interview, and impossible to teach. We can bring people up to speed in tech stuff, business stuff, project management stuff, etc., but thinking crooked, that’s not really a teachable skill; you either do it, or you don’t.

All that said, understanding tech is definitely a requirement, and fortunately there are tons of ways to gain skills in this (one fantastic resource for this is the book “The Web Application Hackers Handbook” written by PortSwigger).

There are a bunch of resources online as well, (free in most cases), so I threw together a small list of some quality sites that teach tech/hacking:

Programming

Basics of Computing

Hacking

Crypto

This list is obviously not exhaustive, or even complete really, but hopefully it’s useful to someone.

Another recommendation I would make to anyone looking to get into this field, is definitely get to a hacker con – specifically one like BSides. These are pretty much everywhere at this point, and are very good for learning new things and getting a feel for what hacker culture is like.

Scapy Notes

Scapy is an “interactive packet manipulation program” written in python. It basically is a packet workshop framework which allows one to craft their own packets from scratch to match a variety of protocols, then send them on the wire and capture the results for analysis. Since it is written in python, it allows one to essentially create any number of tools, including scanners, fuzzers, DoS tools, etc. More info on it can be found at the scapy home page.

Basic Usage
When scapy is run from the command line, it loads the scapy modules and then drops you at the python shell prompt. This is useful for a number of reasons, but primary among them is that this means anything you can do in python, you can do in scapy as well. For the moment though, we’re going to focus solely on the scapy specific modules.

Building a Packet
Scapy makes it extremely easy to build a packet, here’s what it looks like:

First, we call scapy interactively:

[root@snsvc]# scapy
Welcome to Scapy (v1.1.1 / f88d99910220)
>>>

Next, we create the IP frame, then the TCP packet:

>>> a=IP()
>>> b=TCP()

Now we combine the two to create the TCP/IP datagram:

>>> c=a/b

We can use scapy’s ls command to view the contents of the packet:

>>> ls(c)
version    : BitField             = 4               (4)
ihl        : BitField             = None            (None)
tos        : XByteField           = 0               (0)
len        : ShortField           = None            (None)
id         : ShortField           = 1               (1)
flags      : FlagsField           = 0               (0)
frag       : BitField             = 0               (0)
ttl        : ByteField            = 64              (64)
proto      : ByteEnumField        = 6               (0)
chksum     : XShortField          = None            (None)
src        : Emph                 = '127.0.0.1'     (None)
dst        : Emph                 = '127.0.0.1'     ('127.0.0.1')
options    : IPoptionsField       = ''              ('')
--
sport      : ShortEnumField       = 20              (20)
dport      : ShortEnumField       = 80              (80)
seq        : IntField             = 0               (0)
ack        : IntField             = 0               (0)
dataofs    : BitField             = None            (None)
reserved   : BitField             = 0               (0)
flags      : FlagsField           = 2               (2)
window     : ShortField           = 8192            (8192)
chksum     : XShortField          = None            (None)
urgptr     : ShortField           = 0               (0)
options    : TCPOptionsField      = {}              ({})

Changing Packet Details
Now, if we want to change any of the fields in the packet, we can do so by altering their values. For example, to change the IP destination to 192.168.1.1 and set the TCP destination port to 443, we do the following:

>>> a.dst='192.168.1.1'
>>> b.dport=443

Now we recreate the TCP/IP packet again, and view the changes using ls:

>>> c=a/b
>>> ls(c)
version    : BitField             = 4               (4)
ihl        : BitField             = None            (None)
tos        : XByteField           = 0               (0)
len        : ShortField           = None            (None)
id         : ShortField           = 1               (1)
flags      : FlagsField           = 0               (0)
frag       : BitField             = 0               (0)
ttl        : ByteField            = 64              (64)
proto      : ByteEnumField        = 6               (0)
chksum     : XShortField          = None            (None)
src        : Emph                 = '192.168.1.3'   (None)
dst        : Emph                 = '192.168.1.1'   ('127.0.0.1')
options    : IPoptionsField       = ''              ('')
--
sport      : ShortEnumField       = 20              (20)
dport      : ShortEnumField       = 443             (80)
seq        : IntField             = 0               (0)
ack        : IntField             = 0               (0)
dataofs    : BitField             = None            (None)
reserved   : BitField             = 0               (0)
flags      : FlagsField           = 2               (2)
window     : ShortField           = 8192            (8192)
chksum     : XShortField          = None            (None)
urgptr     : ShortField           = 0               (0)
options    : TCPOptionsField      = {}              ({})

Note that even though we didn’t change the IP source, the value has changed. This is because scapy determined which interface would be used to send the packet to the destination we configured, and changed the source to that interface’s address for us. We can override this if desired.

Sending the Packet
We use the sr() function to send the data across the wire. This function sends the packet, sniffs the response, and matches sent packets with the received responses. It works at layer 3, and will return the whole result of a probe.

>>> sr(c)
Begin emission:
...Finished to send 1 packets.
*
Received 4 packets, got 1 answers, remaining 0 packets
(, )

Viewing Results
We can view the results by assigning them to variables:

>>> res,unans=_
>>> res.nsummary()
0000 IP / TCP 192.168.1.3:ftp_data > 192.168.1.1:https S ==> IP / TCP 192.168.1.1:https > 192.168.1.3:ftp_data SA / Padding

Here we see we sent a SYN packet to port 443, and received a SYN/ACK packet back from the destination. We also see there was some Padding added to the SYN/ACK. We can view the information in the padding by accessing the results list directly:

>>> res[0][1]
>>

Scripted Usage
Because scapy is written in python, it can be used from within any python script simply by using the import scapy statement.
For example, here’s a simple script to perform a TCP SYN scan of ports 0-1024 on a given host (provided as a parameter to the script):

#!/usr/bin/env python
import sys
from scapy import sr,IP,TCP,conf
conf.verb = 0
dstip = sys.argv[1]

print "nBeginning scan of "+dstip
res,unans = sr(IP(dst=dstip)/TCP(dport=[(0,1024)]),timeout=1)
if res:
   print "nReceived answers from the following ports:n"
   for s,r in res:
      print r.sprintf("%TCP.sport%")
print "nScan completedn"

And here’s the results of running this:

[root@snsvc]# ./scanner 192.168.1.1

Beginning scan of 192.168.1.1

Received answers from the following ports:

telnet
http
https

Scan completed

Install/Config Notes
“Error during evauluation of config file”
When running scapy from inside other python scripts, you may encounter the following error message:

ERROR: Error during evaluation of config file [None]
Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/scapy.py", line 12183, in read_config_file
execfile(configfile)

Not very helpful, but easy to fix. The problem is that scapy is looking for a config file which doesn’t exist. The good news is that one just has to be present, no configuration is required. To fix this, simply do the following:

# touch ~/.scapy_startup.py

Using the Loopback Interface
The loopback interface is a special interface, in that packets going through it are not really assembled and dissassembled. The kernel routes the packet to its destination while it is still stored an internal structure.

In order to use the loopback interface, you need to send your packets using PF_INET/SOCK_RAW instead of PF_PACKET/SOCK_RAW. This can be done by changing the supersocket used by scapy, which is accessed via the configuration.

The default scapy values for sockets are as follows:

+------------------------+----------------+
| Configuration Variable | Default Value  |
+------------------------+----------------+
| L2listen               | L2ListenSocket |
+------------------------+----------------+
| L2socket               | L2Socket       |
+------------------------+----------------+
| L3socket               | L3PacketSocket |
+------------------------+----------------+

To use the loopback interface, change the L3socket setting to L3RawSocket.
This can be done using the following command (either via the scapy CLI or inside a script):

conf.L3socket=L3RawSocket

AJAX Fun

A little snippet of code I’m playing with. This started as me learning more about XST, to understand why TRACE being enabled was considered a BadThing(tm). [see: this white paper (.pdf format) for more on that].

In my opinion, the best way to learn is to do, so I quickly whipped up the following so I could play, and handily, this finally gives me a good reason to write my first bit of AJAX even =)

A couple of points:

    • If you change the method from GET to HEAD, this makes a handy banner grabber

 

    • If you change the method to TRACE, it may or may not work, depending on the browser you are using.

To explain the latter item:

The current versions of both Firefox and IE refuse to run TRACE via XMLHttpRequest.
This is the correct behaviour, per the spec, and is certainly more secure (it goes a fair way to mitigate XST in general in fact). I have not tried older versions or other browsers to see how they handle it.

Note that I snarfed bits and pieces of this code from various places on the net, and didn’t create all of this from scratch. However, I have tweaked and changed things enough to feel OK calling this “my code”.

I’ll probably tweak this further. I’m considering just making different buttons for the different types of requests and letting the function figure out what method to use based on that, for example.

Anyway, here’s the code as it stands after about 20 minutes of crash course in AJAX:

[EDIT:
if anyone knows how to post HTML/Javascript to blogspot, I’d be grateful for the tip, it keeps trying to render regardless of my use of pre or code. I even tried to settle for textarea, but it borked the formatting of the code unfortunately and added br tags all over the place. *sigh*. ]

Here’s a pastebin of the code instead

[EDIT 2010-03-02:
Oh for … Apparently IE8 renders the pastebin code as HTML instead of displaying it as text/plain. *cry*.