Weekly Reading List for 5/23/14

###Radare2 Book Maijin on GitHub is in the process of putting together an online book for Radare2. I’ve been looking for a good resource for using Radare2, and this is a great start.

###Reverse Engineering for Beginners Dennis Yurichev has a free eBook on Reverse Engineering. I haven’t gotten through it yet, but it looks interesting, and you can’t beat the price.

###Hacker Playbook Finally, I finished up The Hacker Playbook: Practical Guide To Penetration Testing this week. You can find my full review here.


DEF CON 22 CTF Quals: 3dttt

Unlike most of the challenges in DC22 quals, this one required no binary exploitation, no reversing, just writing a little code. You needed to play 3-D Tic Tac Toe, and you needed to play fast. Unfortunately, I didn’t record the sessions, so I don’t have the example output.

Basically, you just received an ASCII representation of each of the 3 boards making up the 3d-tic-tac-toe environment, and were prompted to provide x,y,z coordinates for your next move. However, you had only a very short period of time (fractions of a second) to send your move, so playing by hand was impossible. The winner of each board was the player with the most rows won, and it did go to the full 27 moves each time. Also, it’s important to note that the player always goes first, and that you have to win 50 rounds in order to receive the flag.

I chose this basic algorithm:

  1. On the first move, play in the very center of the boards (1,1,1)
  2. For each subsequent move, consider each available position.
    1. Consider each row that the position sits on.
    2. If the row has both X and O on it, award 0 – the row is a lost cause.
    3. If playing would win that row for us, or block a win for our opponent (they have 2/3), award 3 points.
    4. If we already have something on that row, or they already have something on that row, award 1 point. We’re either making progress or blocking.
    5. Otherwise, no points.
  3. Sum the row points for each position, and play in the highest scoring position.

I had no idea if this algorithm would work, but it was actually successful resulting in the flag on the first try.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!python
import re
import socket

REMOTE = ('3dttt_87277cd86e7cc53d2671888c417f62aa.2014.shallweplayaga.me', 1234)

class TTT(object):

  def __init__(self, host, port):
    self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.s.connect((host, port))
    self.state = [[[' ', ' ', ' '] for i in xrange(3)] for k in xrange(3)]
    self._buf = ''
    self._moves = 0

    self._read_intro()
    self._read_state()
    self._print_state()

  def _read_intro(self):
    buf = ''
    while 'Play well and play fast....' not in buf:
      buf += self.s.recv(1024)
    self._buf = buf.split('and play fast....')[1]

  def _read_state(self):
    buf = self._buf
    while True:
      if '\n' not in buf:
        buf += self.s.recv(2048)
      line, buf = buf.split('\n', 1)
      m = (re.match(' x.*z=([0-2])', line) or 
          re.match('Choose .* x.*z=([0-2])', line))
      if m:
        z = int(m.group(1))
        continue
      m = re.match('([0-2])  (.) \| (.) \| (.)', line)
      if m:
        y = int(m.group(1))
        for x in xrange(3):
          self.state[z][y][x] = m.group(x+2)

        if y == 2 and z == 2:
          break

    self._buf = buf

  def _send_move(self, x, y, z):
    self.s.send('%d,%d,%d\n' % (x,y,z))

  def _print_state(self):
    print '\nMove: %d' % self._moves
    for board in self.state:
      print '[[' + ']\n ['.join(','.join(c for c in r) for r in board) + ']]'

  @staticmethod
  def _score_row(*row):
    x = 0
    o = 0
    for p in row:
      x += 1 if p == 'X' else 0
      o += 1 if p == 'O' else 0
    if x+o == 3 or (x and o):
      # All 3 filled or lost cause, we're fucked
      return 0
    if x == 2 or o == 2:
      # Either blocking or winning a row
      return 3
    if x or o:
      return 1
    # Empty row
    return 0

  @staticmethod
  def _find_diagonals(x, y, z):
    """This is terrible, but works."""
    # Diagonals of 2 degrees of freedom
    if x == y:
      yield ((0, 0, z), (1, 1, z), (2, 2, z))
    if x+y == 2:
      yield ((0, 2, z), (1, 1, z), (2, 0, z))
    if x == z:
      yield ((0, y, 0), (1, y, 1), (2, y, 2))
    if x+z == 2:
      yield ((0, y, 2), (1, y, 1), (2, y, 0))
    if y == z:
      yield ((x, 0, 0), (x, 1, 1), (x, 2, 2))
    if y+z == 2:
      yield ((x, 0, 2), (x, 1, 1), (x, 2, 0))
    # Now the 4 big diagonals
    if x == y == z:
      yield ((0, 0, 0), (1, 1, 1), (2, 2, 2))
    for dia in [
        ((2, 0, 0), (1, 1, 1), (0, 2, 2)),
        ((2, 2, 0), (1, 1, 1), (0, 0, 2)),
        ((0, 2, 0), (1, 1, 1), (2, 0, 2))]:
      if (x, y, z) in dia:
        yield dia

  def _score_move(self, x, y, z):
    if self.state[z][y][x] != ' ':
      # Not a possible move
      return -1
    # Straight rows
    score = self._score_row(
        self.state[z][y][0],
        self.state[z][y][1],
        self.state[z][y][2])
    score += self._score_row(
        self.state[z][0][x],
        self.state[z][1][x],
        self.state[z][2][x])
    score += self._score_row(
        self.state[0][y][x],
        self.state[1][y][x],
        self.state[2][y][x])
    # Diagonals
    for d in self._find_diagonals(x, y, z):
      score += self._score_row(
          self.state[d[0][2]][d[0][1]][d[0][0]],
          self.state[d[1][2]][d[1][1]][d[1][0]],
          self.state[d[2][2]][d[2][1]][d[2][0]])
    return score

  def _optimal_move(self):
    # Initial move, go for center
    if self._moves == 0:
      return (1, 1, 1)
    # Score each position
    bestpos = None
    max_score = -1
    for x in xrange(3):
      for y in xrange(3):
        for z in xrange(3):
          score = self._score_move(x, y, z)
          if score > max_score:
            max_score = score
            bestpos = (x, y, z)
    print bestpos, 'score:', max_score
    return bestpos

  def move(self):
    where = self._optimal_move()
    if where is None:
      m = re.search('You\'ve won [0-9]+ rounds', self._buf)
      if m:
        print m.group(0)
      self._moves = 0
    else:
      self._send_move(*where)
      self._moves += 1
    self._read_state()
    self._print_state()
    return True


if __name__ == '__main__':
  ttt = TTT(REMOTE[0], REMOTE[1])
  while ttt.move():
    continue
  print ttt._buf
  print ttt.s.recv(1024)

Book Review: The Hacker Playbook...

The Hacker Playbook: Practical Guide To Penetration Testing is an attempt to use a continuous series of football metaphors to describe the process of a network penetration test. Maybe the metaphors would work better for someone who actually watches sports, but I felt they were a bit strained and forced at times. That being said, the actual content and techniques described are solid and generally useful information. It’s arranged in the stages of a good penetration test, and reads like a strong guide for those relatively new to penetration testing. Unfortunately, it doesn’t set up general guides for each area as much as describing specific “plays” for each area, so once those techniques start to fall flat, it doesn’t leave you with a lot of depth.

  • Chapter 1. Introduction is unsurprisingly lackluster, describing only the flow of the book and the benefits perceived by the author in thinking about the penetration test like a series of football plays.
  • Chapter 2. Pregame – The Setup is all about getting into a position to conduct your test, including reconnaissance, scoping, and all of the prep required before the actual pentest.
  • Chapter 3. Before the Snap – Scanning the Network will be familiar territory to anyone who’s used Nmap before, but goes into more depth and explores the other scanning tools, such as vulnerability scanners like Nexpose/Nessus, and how to get the most out of using your scanners (as well as how you can be covert when scanning).
  • Chapter 4. The Drive – Exploiting Scanner Findings describes a step that too many pentesters do not follow. Altogether too many “penetration testers” deliver a report that is little more than straight output from a web security scanner. If clients wanted a Nexpose report, they’d just buy a Nexpose license and skip the pentester’s markup. The value of a pentester is in verifying findings, evaluating the real risk to the organization, and providing advice on remediation or mitigation. This chapter handily covers how you can not only verify scanner findings, but use them to pivot and escalate.
  • Chapter 5. The Throw – Manual Web Application Findings really just scrapes the surface of the world of web. There’s so much to be covered in web that you really ought to go far beyond this and review The Tangled Web for an overview of the problems faced by modern web applications, and The Web Application Hacker’s Handbook for a more practical approach to web pentesting through vulnerability discovery and exploitation. However, if you’re going to be focusing on internal enterprise networks, the Playbook gives you some handy approaches to looking at internal webapps that you might find on a corporate network.
  • Chapter 6. The Lateral Pass – Moving Through the Network covers basic Pass-the-Hash and other approaches to leverage the access you already have into more access. It’s important to see how far an attacker could take things, so pivot & escalate is critical, and this chapter provides a handful of plays that could fit the bill.
  • Chapter 7. The Screen – Social Engineering is, again, just a brief preview into a topic far too deep to be adequately covered in a book as broad as this one. The plays here are quite basic, and focus on phishing-style social engineering, leaving out the many ways social engineering can be leveraged in reconnaissance, physical pentesting, and other scenarios.
  • Chapter 8. The Onside Kick – Attacks that Require Physical Access was a little disappointing. While there are good parts to it (like the use of the Odroid U2 as a dropbox), nothing was particularly groundbreaking and I was hoping for a little more unique aspect to physical. (On the other hand, maybe I just want to live vicariously through this book – I don’t do get to do much physical pentesting.)
  • Chapter 9. Special Teams – Cracking, Exploits, Tricks
  • Chapter 10. Post Game Analysis – Reporting provides some sage advice on producing the report that gets you paid. Since I work on an internal Red Team, I don’t have to write the type of reports described here, but if you’re in a position to be writing reports, this will really help in crafting a clear and concise report. Most importantly: don’t ever hand a client a Nessus scan and expect to be getting paid.
  • Chapter 11. Continuing Education is surprisingly thorough, though it is mostly a list of resources to help you find more things to try, such as conferences to attend, vulnerable targets to practice on, and more. There were a few vulnerable targets I hadn’t heard of, but will definitely be giving a try in the near future.

Overall, it’s an interesting book, and would definitely be good for someone who hasn’t been pentesting much, but ultimately, it’s just a collection of specific tasks (“plays” in the parlance of the book) that you can execute. I wasn’t expecting much more, and plays in there are solid, but eventually you’ll need to learn to craft your own plays, and I feel the book falls short there. It’s 294 pages and attempts to cover an entire field while remaining practical. Naturally, this is very difficult, and while there may be some shortcomings, Peter Kim manages to provide several useful plays, but probably best for those who haven’t yet developed their own playbook.


DEF CON 22 CTF Quals: Hackertool

Hackertool was one of the Baby's First challenges in DEF CON CTF Quals this year, and provided you with a .torrent file, and asked you to download the file and MD5 it. Seems easy enough, so I knew there must be more to it. The torrent file itself was a whopping 4 MB in size, very large for a torrent file. Looking at it, we see it contains just one file, named every_ip_address.txt, and the file is ~61GB in size. Hrrm, there must be an easier way than torrenting 61GB, especially at <1k/s.

So what is this every_ip_address.txt? Seems like it might be a list of all IP addresses. In fact, if you add up the length of all IP addresses written in decimal dotted-quad form, separated by newlines, you get 61337501696 bytes, exactly the same as the length of our target torrent. But is it newline separated? What order are they in? Fortunately, torrents also contain the SHA-1 of each 256kb block of the file. So I wrote a little python script to quickly check if we had a match for the first block:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib

def get_block():    
  block = 256 * 1024
  v = ''
  for a in xrange(0, 256):
    for b in xrange(0, 256):
      for c in xrange(0, 256):
        for d in xrange(0, 256):
          v += '%d.%d.%d.%d\n' % (a,b,c,d)
          if len(v) > block:
            return v[:block]       


print hashlib.sha1(get_block()).hexdigest()

This matched the value from the torrent file, so I knew we were on the right track. Unfortunately, python is too slow to hash 61GB this way, so I turned to C for the final solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <openssl/md5.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv){
  char buf[64];
  MD5_CTX md5_ctx;
  int i,j,k,l;

  MD5_Init(&md5_ctx);
  for (i=0;i<256;i++) {
    printf("%d.\n", i);
    for (j=0;j<256;j++) {
      for (k=0;k<256;k++) {
        for (l=0;l<256;l++) {
          sprintf(buf, "%d.%d.%d.%d\n", i, j, k, l);
          MD5_Update(&md5_ctx, buf, strlen(buf));
        }
      }
    }
  }
  MD5_Final(buf, &md5_ctx);
  for (i=0;i<128/8;i++) {
    printf("%02ux", buf[i] & 0xFF);
  }
  printf("\n");
  return 0;
}

There might’ve been prettier ways, but this ran in the background while I moved on to another hash, and got us our first flag not too long afterwards.


Weekly Reading List for 5/16/14

###How Target Blew It Normally, I stick to more technical articles, but this article from Businessweek is a very interesting read on how, despite doing most of the right things technically, company procedures and humans can still be the weak link in your security infrastructure.