Installing CakePHP 3.0.x on Debian 7.5

The official repos have CakePHP 1.3.15, but this version is old and the CakePHP documentation for 1.3 is flaky (20140610 – 502 Bad Gateway).

To install the latest CakePHP source, we need to be running a later version of PHP than is available on the official repos, so let’s add a new repo to the /etc/sources.list file:

deb http://packages.dotdeb.org wheezy all
deb-src http://packages.dotdeb.org wheezy all

Once you’ve added these repos to the file, you need to update the list of available packages:

aptitude update

Now you’re ready to install the packages you need from the dotdeb repo:

aptitude install php5 mysql-server php5-intl php5-mcrypt php5-mysql

In order to install composer (which you’ll need to grab CakePHP), you need to install curl and git:

aptitude install curl git

Now that’s done you can install composer:

root@debian:~# curl -s https://getcomposer.org/installer | php
#!/usr/bin/env php
All settings correct for using Composer

Composer successfully installed to: /root/composer.phar
Use it: php composer.phar

The last step is to install the CakePHP package and dependencies:

root@debian:~# mkdir php
root@debian:~# mv composer.phar php/
root@debian:~# cd /var/www/
root@debian:/var/www# ls -alh
total 12K
drwxr-xr-x  2 root root 4.0K Jul  8 11:58 .
drwxr-xr-x 12 root root 4.0K Jul  8 11:58 ..
-rw-r--r--  1 root root  177 Jul  8 11:58 index.html
root@debian:/var/www# php /root/php/composer.phar create-project -s dev cakephp/app
Installing cakephp/app (dev-master 05bdc480602ea7c736815f51c059f844fc26c4b5)
  - Installing cakephp/app (dev-master master)
    Cloning master

Created project in /var/www/app
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing ircmaxell/password-compat (1.0.3)
    Downloading: 100%         

  - Installing nesbot/carbon (1.8.0)
    Downloading: 100%         

  - Installing cakephp/cakephp (3.0.x-dev 160f56c)
    Cloning 160f56c557baa5514f3781ecbf2389510f3dc9e4

I created a php directory under /root and moved the composer.phar file to tidy things up a bit. Before running the command to install CakePHP make sure you change to the directory you want to install the app into.

Make sure you set the DocumentRoot to /var/www/app (or whatever your path) and AllowOverride All so the htaccess files can be applied. You also need to enable mod_rewrite in Apache:

a2enmod rewrite
apachectl restart

crackmes.de – monkey keygen #1

I’ve just created a keygen for the “monkey keygen #1” challenge on crackmes.de, it was fun and far from “boring crap” which it has been rated as on the site. If this challenge is considered by some to be easy to keygen then consider me humbled, this was a difficult and rewarding challenge for me. This post is going to be long and technical, if you don’t know the difference between eax and al then I suggest you stop reading here :)

Being fairly new to the RE game I decided to search for a string which indicated a valid key had been entered into the program. I managed to find this string at 0x46666C, contents being ‘Valid Key’. That’s cool, let’s see all references to this string:

UMessageBoxValidKey is a custom name I assigned to the subroutine when I had established this was responsible for displaying the message box. Okay, let’s see what’s going on in the UMessageBoxValidKey subroutine:

CODE:00466580 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
CODE:00466580 ; Attributes: bp-based frame
CODE:00466580 UMessageBoxValidKey proc near           ; DATA XREF: CODE:00466521o
CODE:00466580 var_18          = dword ptr -18h
CODE:00466580 var_14          = dword ptr -14h
CODE:00466580 var_10          = dword ptr -10h
CODE:00466580 var_C           = dword ptr -0Ch
CODE:00466580 var_8           = dword ptr -8
CODE:00466580 var_4           = dword ptr -4
CODE:00466580                 push    ebp
CODE:00466581                 mov     ebp, esp
CODE:00466583                 add     esp, 0FFFFFFE8h
CODE:00466586                 xor     ecx, ecx
CODE:00466588                 mov     [ebp+var_18], ecx
CODE:0046658B                 mov     [ebp+var_14], ecx
CODE:0046658E                 mov     [ebp+var_C], ecx
CODE:00466591                 mov     [ebp+var_10], edx
CODE:00466594                 mov     [ebp+var_4], eax
CODE:00466597                 xor     eax, eax
CODE:00466599                 push    ebp
CODE:0046659A                 push    offset loc_466660
CODE:004665BD                 xor     eax, eax
CODE:004665BF                 push    ebp
CODE:004665C0                 push    offset sub_466636
CODE:004665C5                 push    dword ptr fs:[eax]
CODE:004665C8                 mov     fs:[eax], esp
CODE:004665CB                 lea     eax, [ebp+var_C]
CODE:004665CE                 push    eax
CODE:004665CF                 lea     edx, [ebp+var_14]
CODE:004665D2                 mov     eax, [ebp+var_4]
CODE:004665D5                 mov     eax, [eax+2FCh]
CODE:004665DB                 call    sub_4320E8
CODE:004665E0                 mov     edx, [ebp+var_14]
CODE:004665E3                 mov     cx, 4DE1h
CODE:004665E7                 mov     eax, [ebp+var_8]
CODE:004665EA                 call    sub_466230
CODE:004665EF                 lea     edx, [ebp+var_18]
CODE:004665F2                 mov     eax, [ebp+var_4]
CODE:004665F5                 mov     eax, [eax+300h]
CODE:004665FB                 call    sub_4320E8
CODE:00466600                 mov     eax, [ebp+var_18]
CODE:00466603                 mov     edx, [ebp+var_C]
CODE:00466606                 call    UCheckValidCombo
CODE:0046660B                 jnz     short loc_466620
CODE:0046660D                 push    0               ; uType
CODE:0046660F                 push    offset aValidKey ; "Valid Key"
CODE:00466614                 push    offset aValidKey ; "Valid Key"
CODE:00466619                 push    0               ; hWnd
CODE:0046661B                 call    MessageBoxA_0
CODE:00466620 loc_466620:                             ; CODE XREF: UMessageBoxValidKey+8Bj
CODE:00466620                 xor     eax, eax
CODE:00466622                 pop     edx
CODE:00466623                 pop     ecx
CODE:00466624                 pop     ecx
CODE:00466625                 mov     fs:[eax], edx
CODE:00466628                 push    offset loc_46663D
CODE:0046662D loc_46662D:                             ; CODE XREF: CODE:0046663Bj
CODE:0046662D                 mov     eax, [ebp+var_8]
CODE:00466630                 call    sub_4030FC
CODE:00466635                 retn
CODE:00466635 UMessageBoxValidKey endp ; sp = -30h

Okay so if this challenge allowed for patching, all that would be necessary to fool the program into thinking you had entered a correct key would be to NOP out the jnz op at 0x0046660B. Unfortunately for us the task is to create a keygen, so we need to find the code responsible for generating and checking the key. UCheckValidCombo looks like a good place to start.

CODE:004043AC ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
CODE:004043AC UCheckValidCombo proc near              ; CODE XREF: sub_414450+6Bp
CODE:004043AC                                         ; sub_418FBC+Ep ...
CODE:004043AC                 push    ebx
CODE:004043AD                 push    esi
CODE:004043AE                 push    edi
CODE:004043AF                 mov     esi, eax
CODE:004043B1                 mov     edi, edx
CODE:004043B3                 cmp     eax, edx
CODE:004043B5                 jz      loc_40444A
CODE:004043BB                 test    esi, esi
CODE:004043BD                 jz      short loc_404427
CODE:004043BF                 test    edi, edi
CODE:004043C1                 jz      short loc_40442E
CODE:004043C3                 mov     eax, [esi-4]
CODE:004043C6                 mov     edx, [edi-4]
CODE:004043C9                 sub     eax, edx
CODE:004043CB                 ja      short loc_4043CF
CODE:004043CD                 add     edx, eax
CODE:004043CF loc_4043CF:                             ; CODE XREF: UCheckValidCombo+1Fj
CODE:004043CF                 push    edx
CODE:004043D0                 shr     edx, 2
CODE:004043D3                 jz      short loc_4043FB
CODE:004043D5 loc_4043D5:                             ; CODE XREF: UCheckValidCombo+45j
CODE:004043D5                 mov     ecx, [esi]
CODE:004043D7                 mov     ebx, [edi]
CODE:004043D9                 cmp     ecx, ebx
CODE:004043DB                 jnz     short loc_404435
CODE:004043DD                 dec     edx
CODE:004043DE                 jz      short loc_4043F5
CODE:004043E0                 mov     ecx, [esi+4]
CODE:004043E3                 mov     ebx, [edi+4]
CODE:004043E6                 cmp     ecx, ebx
CODE:004043E8                 jnz     short loc_404435
CODE:004043EA                 add     esi, 8
CODE:004043ED                 add     edi, 8
CODE:004043F0                 dec     edx
CODE:004043F1                 jnz     short loc_4043D5
CODE:004043F3                 jmp     short loc_4043FB
CODE:004043F5 ; ---------------------------------------------------------------------------
CODE:004043F5 loc_4043F5:                             ; CODE XREF: UCheckValidCombo+32j
CODE:004043F5                 add     esi, 4
CODE:004043F8                 add     edi, 4
CODE:004043FB loc_4043FB:                             ; CODE XREF: UCheckValidCombo+27j
CODE:004043FB                                         ; UCheckValidCombo+47j
CODE:004043FB                 pop     edx
CODE:004043FC                 and     edx, 3
CODE:004043FF                 jz      short loc_404423
CODE:00404401                 mov     ecx, [esi]
CODE:00404403                 mov     ebx, [edi]
CODE:00404405                 cmp     cl, bl
CODE:00404407                 jnz     short loc_40444A
CODE:00404409                 dec     edx
CODE:0040440A                 jz      short loc_404423
CODE:0040440C                 cmp     ch, bh
CODE:0040440E                 jnz     short loc_40444A
CODE:00404410                 dec     edx
CODE:00404411                 jz      short loc_404423
CODE:00404413                 and     ebx, 0FF0000h
CODE:00404419                 and     ecx, 0FF0000h
CODE:0040441F                 cmp     ecx, ebx
CODE:00404421                 jnz     short loc_40444A
CODE:00404423 loc_404423:                             ; CODE XREF: UCheckValidCombo+53j
CODE:00404423                                         ; UCheckValidCombo+5Ej ...
CODE:00404423                 add     eax, eax
CODE:00404425                 jmp     short loc_40444A
CODE:00404427 ; ---------------------------------------------------------------------------
CODE:00404427 loc_404427:                             ; CODE XREF: UCheckValidCombo+11j
CODE:00404427                 mov     edx, [edi-4]
CODE:0040442A                 sub     eax, edx
CODE:0040442C                 jmp     short loc_40444A
CODE:0040442E ; ---------------------------------------------------------------------------
CODE:0040442E loc_40442E:                             ; CODE XREF: UCheckValidCombo+15j
CODE:0040442E                 mov     eax, [esi-4]
CODE:00404431                 sub     eax, edx
CODE:00404433                 jmp     short loc_40444A
CODE:00404435 ; ---------------------------------------------------------------------------
CODE:00404435 loc_404435:                             ; CODE XREF: UCheckValidCombo+2Fj
CODE:00404435                                         ; UCheckValidCombo+3Cj
CODE:00404435                 pop     edx
CODE:00404436                 cmp     cl, bl
CODE:00404438                 jnz     short loc_40444A
CODE:0040443A                 cmp     ch, bh
CODE:0040443C                 jnz     short loc_40444A
CODE:0040443E                 shr     ecx, 10h
CODE:00404441                 shr     ebx, 10h
CODE:00404444                 cmp     cl, bl
CODE:00404446                 jnz     short loc_40444A
CODE:00404448                 cmp     ch, bh
CODE:0040444A loc_40444A:                             ; CODE XREF: UCheckValidCombo+9j
CODE:0040444A                                         ; UCheckValidCombo+5Bj ...
CODE:0040444A                 pop     edi
CODE:0040444B                 pop     esi
CODE:0040444C                 pop     ebx
CODE:0040444D                 retn
CODE:0040444D UCheckValidCombo endp

So, the cmp at 0x004043B3 is interesting because the EDX register appears to contain a string which could be the key. Let’s test this..

Let’s enter the “2C6B91” string as the key with the name “aaa”.

Yay, that’s not terribly good practice, storing the answer in a string like that. It would be more convoluted in ‘real life’ one would hope. Okay, let’s insert a write break so we know which subroutine is responsible for populating this part of memory. So far we can either patch or generate keys using the challenge binary to bypass it, but we really need to create our own binary to prove that we understand how the key is created (something we don’t yet know).

CODE:004028B8 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
CODE:004028B8 sub_4028B8 proc near                    ; CODE XREF: sub_4025F8+81p
CODE:004028B8                                         ; sub_402A08+14p ...
CODE:004028B8 push    esi
CODE:004028B9 push    edi
CODE:004028BA mov     esi, eax
CODE:004028BC mov     edi, edx
CODE:004028BE mov     eax, ecx
CODE:004028C0 cmp     edi, esi
CODE:004028C2 ja      short loc_4028D7
CODE:004028C4 jz      short loc_4028F5
CODE:004028C6 sar     ecx, 2
CODE:004028C9 js      short loc_4028F5
CODE:004028CB rep movsd
CODE:004028CD mov     ecx, eax
CODE:004028CF and     ecx, 3
CODE:004028D2 rep movsb
CODE:004028D4 pop     edi
CODE:004028D5 pop     esi
CODE:004028D6 retn
CODE:004028D7 ; ---------------------------------------------------------------------------
CODE:004028D7 loc_4028D7:                             ; CODE XREF: sub_4028B8+Aj
CODE:004028D7 lea     esi, [ecx+esi-4]
CODE:004028DB lea     edi, [ecx+edi-4]
CODE:004028DF sar     ecx, 2
CODE:004028E2 js      short loc_4028F5
CODE:004028E4 std
CODE:004028E5 rep movsd
CODE:004028E7 mov     ecx, eax
CODE:004028E9 and     ecx, 3
CODE:004028EC add     esi, 3
CODE:004028EF add     edi, 3
CODE:004028F2 rep movsb
CODE:004028F4 cld
CODE:004028F5 loc_4028F5:                             ; CODE XREF: sub_4028B8+Cj
CODE:004028F5                                         ; sub_4028B8+11j ...
CODE:004028F5 pop     edi
CODE:004028F6 pop     esi
CODE:004028F7 retn
CODE:004028F7 sub_4028B8 endp

The rep movsb instruction at 0x004028F2 copies strings from [ESI] to [EDI], so we need to insert another write break at the ESI address specified (0x0012F5B9).

I needed to repeat this process a couple of times to find the subroutine which was responsible for checking the key, but eventually I determined it was sub_466230. If you look in the screenshot it’s a couple of subroutines up from the routine responsible for the 0x0012F5B9 write. Here’s sub_466230, the heart of the program.

CODE:00466230 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
CODE:00466230 ; Attributes: bp-based frame
CODE:00466230 sub_466230      proc near               ; CODE XREF: UMessageBoxValidKey+6Ap
CODE:00466230 var_1C          = dword ptr -1Ch
CODE:00466230 var_18          = dword ptr -18h
CODE:00466230 var_12          = word ptr -12h
CODE:00466230 var_10          = dword ptr -10h
CODE:00466230 var_B           = byte ptr -0Bh
CODE:00466230 var_A           = word ptr -0Ah
CODE:00466230 var_8           = dword ptr -8
CODE:00466230 var_4           = dword ptr -4
CODE:00466230 arg_0           = dword ptr  8
CODE:00466230                 push    ebp
CODE:00466231                 mov     ebp, esp
CODE:00466233                 add     esp, 0FFFFFFE4h
CODE:00466236                 push    ebx
CODE:00466237                 xor     ebx, ebx
CODE:00466239                 mov     [ebp+var_1C], ebx
CODE:0046623C                 mov     [ebp+var_A], cx
CODE:00466240                 mov     [ebp+var_8], edx
CODE:00466243                 mov     [ebp+var_4], eax
CODE:00466246                 xor     eax, eax
CODE:00466248                 push    ebp
CODE:00466249                 push    offset sub_4662E9
CODE:0046624E                 push    dword ptr fs:[eax]
CODE:00466251                 mov     fs:[eax], esp
CODE:00466254                 mov     ax, [ebp+var_A]
CODE:00466258                 mov     [ebp+var_12], ax
CODE:0046625C                 mov     eax, [ebp+arg_0]
CODE:0046625F                 call    sub_403FA0
CODE:00466264                 mov     eax, [ebp+var_8]
CODE:00466267                 call    sub_404260
CODE:0046626C                 test    eax, eax
CODE:0046626E                 jle     short loc_4662D3
CODE:00466270                 mov     [ebp+var_18], eax
CODE:00466273                 mov     [ebp+var_10], 1
CODE:0046627A loc_46627A:                             ; CODE XREF: sub_466230+A1j
CODE:0046627A                 mov     eax, [ebp+var_8]
CODE:0046627D                 mov     edx, [ebp+var_10]
CODE:00466280                 mov     al, [eax+edx-1]
CODE:00466284                 movzx   edx, [ebp+var_12]
CODE:00466288                 shr     edx, 8
CODE:0046628B                 xor     al, dl
CODE:0046628D                 mov     [ebp+var_B], al
CODE:00466290                 xor     eax, eax
CODE:00466292                 mov     al, [ebp+var_B]
CODE:00466295                 add     ax, [ebp+var_12]
CODE:00466299                 mov     edx, [ebp+var_4]
CODE:0046629C                 imul    word ptr [edx+4]
CODE:004662A0                 mov     edx, [ebp+var_4]
CODE:004662A3                 add     ax, [edx+6]
CODE:004662A7                 mov     [ebp+var_12], ax
CODE:004662AB                 lea     ecx, [ebp+var_1C]
CODE:004662AE                 xor     eax, eax
CODE:004662B0                 mov     al, [ebp+var_B]
CODE:004662B3                 mov     edx, 2
CODE:004662B8                 call    USubKeyCalcNO
CODE:004662BD                 mov     edx, [ebp+var_1C]
CODE:004662C0                 mov     eax, [ebp+arg_0]
CODE:004662C3                 call    sub_404268
CODE:004662C8                 mov     eax, [ebp+arg_0]
CODE:004662CB                 inc     [ebp+var_10]
CODE:004662CE                 dec     [ebp+var_18]
CODE:004662D1                 jnz     short loc_46627A
CODE:004662D3 loc_4662D3:                             ; CODE XREF: sub_466230+3Ej
CODE:004662D3                 xor     eax, eax
CODE:004662D5                 pop     edx
CODE:004662D6                 pop     ecx
CODE:004662D7                 pop     ecx
CODE:004662D8                 mov     fs:[eax], edx
CODE:004662DB                 push    offset loc_4662F0
CODE:004662E0 loc_4662E0:                             ; CODE XREF: CODE:004662EEj
CODE:004662E0                 lea     eax, [ebp+var_1C]
CODE:004662E3                 call    sub_403FA0
CODE:004662E8                 retn
CODE:004662E8 sub_466230      endp ; sp = -28h

Okay, this key algorithm is quite involved:

1. al = <nth character in name>
2. edx = 0x4DE1 (or eax if 2nd or more character pass)
3. dl = dl >> 8 (0x4D in this case)
4. al = al ^ 0x4D (0x2C in this case)
5. ax = ax + 0x4DE1 (or eax as it was at step 2 if 2nd or more character pass) (0x4ED0 in this case)
6. ax = ax * 0xCE6D = (0xB189)
6. ax = ax + 0x58BF (0x0A48 (which will be edx in the next round))

Should be accurate (might not be). If that dosen’t make sense, just have a look at the C code (which does work, for me at least).

At first, this code didn’t work at all because the bit shifting I was doing was only 2 bits (as indicated by the commented out debug printf). Once I had fixed that it was necessary to uppercase the hex output and ensure that in case the value was less than 16, a 0 is prepended to the string.

How to treble your Internet speed ..for free

You may remember my post slagging off BT about their piss poor performance regarding Internet speeds and slow remediation techniques. In the end, the problem was down to some old copper wire stretching from the telephone pole to the master socket in the property. It was patched up (twice) and everything was fine for about 5 minutes. Over the course of the last couple months the net began slowing down from 400-500KB/sec, to 250KB/sec, to 140KB/sec.

I started looking into alternatives such as satellite, and then came crashing back down to earth when I researched the upfront cost for the gear, the limited data allowance (even on ‘unlimited’ plans), the latency between you and the rest of the world, and the relatively lame connection speed. Determined to get my Internet back to the glory days of 450KB/sec, I ventured outside to check the integrity of the cable from the telephone pole to the master socket. I came across this:

This part of the cable had obivously been subject to some trauma, the jacket had split and it had been squashed. I decided that squeezing it might make my Internet faster, so I did. I laughed it off and rebooted my router to see what would happen. Upopn conducting a speed test, I noticed my Internet speed was now three times faster than 5 minutes ago. I laughed again, and got some PVC tape on that shit. Now I just need to get around to calling BT to fix it properly.. maybe later.

Untrusted (Level 13)

Ball ache level, AI without memory is hard, so I cheated a bit.



Cool site with JS-based challenges. Here are my solutions thus far:

  1. Level 1
  2. Level 2
  3. Level 3
  4. Level 4
  5. Level 5
  6. Level 6
  7. Level 7
  8. Level 8
  9. Level 9
  10. Level 10
  11. Level 11
  12. Level 12

I’m not sure the authors intended for some of the methods I used, but that’s half the fun..


I have been asked to revoke access to some of my blog posts relating to some technical challenges which were being used inappropriately, diminishing their educational potential for some individuals. [Retracted, nothing to see here] I’ll leave you with a summary of the challenges I had provided technical details for, without revealing the answers. [Retracted] The following posts have been made inaccessible on this website, any references to these posts made on any other site are not under my control and cannot be retracted by me:

  1. Bacterial Vaginosis – Windows Domain Pwning
  2. AIDS – Windows 2000 challenge
  3. HIV – File upload
  4. Genital Warts – X11
  5. Syphilis – Third party software challenge
  6. Crabs – SNMP challenge
  7. Chlamydia – PostgreSQL challenge
  8. Gonorrhea – chroot challenge #2
  9. Hepatitis – chroot challenge
  10. Scabies – Network challenge
  11. Hackme challenge #2 – Weak encryption

The majority of the challenges, and indeed real life engagements, can be broken down into roughly three distinct phases (excluding scoping); recon, attack, and report. The recon phase is important, if not the most important phase, because any mishaps here could lead to pain down the line when you don’t find any vector in the stuff you’ve discovered. The recon phase involves establishing what is accessible, usually through port scans. You have a selection of tools you can use here, including:

  1. nmap
  2. masscan
  3. udp-proto-scanner

My approach typically involves firing masscan to get some quick hits and then running nmap while looking at the results of the masscan. masscan is quick, which is why I use it first, but it can also be inaccurate insofar as nmap reporting open ports masscan didn’t. That’s fine for a quick pass, as long as it is backed up by an nmap scan.

Once I’ve established TCP connectivity, I’ll move onto udp-proto-scanner, which covers some of the UDP ports. For full coverage, I’d use nmap -sU, but for the standard services udp-proto-scanner is sufficient (maybe even better), because it sends the expected datagram for the service on that port.

Recon doesn’t end at port discovery though – depending on the service listening, I’d consider version reconnaissance, directory bruting, user enumeration, and unauthenticated web spidering, just be wary you don’t breach the scope.

The line between recon and attack is murky. If an attacker pulls the MySQL version via unsanitised user input is that recon or attack, or both? The recon and attack phases cannot be represented as two distinct junks on a timeline, they compliment and feed into one another, and happen constantly over the course of an engagement.

The reporting phase is designated for creating a document which encapsulates the work you’ve done for the client in a form which is digestable by non-technical people, while also providing technical details of any findings which merit mention.

The report should include an ‘executive’ summary, which provides a 10 000 foot view of the issues raised in the target test, as well as more technical details, to prove and demonstrate vulnerable vectors.

Okay, enough fluffy bullshit, let’s get technical. One of the problems with the challenges I wrote about is rooted in the fact that discrepancies between them stick out. That is, if one challenge box has a port open that isn’t open on any other challenge boxes, you can be relatively sure that this will be your vector. In real life, this won’t necessarily be the case. Another issue with challenges in general is that as an attacker, you know that the target is vulnerable *somehow*, this acts as a sort of motivator, which you wouldn’t inhibit on a real engagement, because some targets won’t necessarily be vulnerable, no matter how hard you try.

That isn’t to say the challenges aren’t useful – on the contrary, I believe them to be instrumental in standardising my recon process, as well as refining my knowledge in rooting Linux boxes, which is why I consider it a shame that I cannot share the technical details with you, the reader … [retracted, I shouldn’t keep this bit]. I would like to [retracted] apologise on behalf of my employer for this. Sorry.

Once you’ve got a standard user account on a Linux box, typically through a network service, the things you should be looking out for are:

  • Setuids
  • Crontabs
  • File permissions
  • SSH keys
  • Local ports
  • Binaries which interact with files on the filesystem with suspect permissions
  • Third party tools
  • Log files
  • Backups
  • Sudo capabilites (sudo -l)
  • Shell histories (.bash_history / .zsh_history)

Safe SQLi

It may sound like an oxymoron, but it’s a legitimate concern among the good guys in the security industry. Under the circumstance that a company has authorised you to try and hack into their live system, you really don’t want to be pissing around with ‘dangerous’ SQL injections. Dangerous is defined here as an SQL injection which results in undesirable data modification in the database, which could have otherwise have been avoided if the SQLi was considered more carefully (or wasn’t present in the first place). Let’s have a quick demonstration.

Mr Developer decides that passing unsanitised user input is a good idea, and that prepared statements are not. He wants to use a SELECT query to determine if the username and password are correct, and he also wants to update a table containing login information using an UPDATE statement. The company Mr Developer works for have received a tip that the developer might be a bit of a tit, and decide to hire Mr Security Man to try and break into Mr Developer’s web application. Unfortunately, Mr Security Man is also a bit of a tit, and thinks that still using some variant of ‘ or 1=1 — is a good idea. Let’s see how it all unravels:

SELECT * FROM tbl_test WHERE username = 'test' AND password = 'pass';

Above we have an innocent enough looking SQL statement. The attacker finds the login form associated with this statement and injects the password field with ‘ or 1=1 —

SELECT * FROM tbl_test WHERE username = 'test' AND password = 'pass' or 1=1 -- '

Mr Security Man is excited, he’s bypassed the login form and is now sitting on the site with a message reaffirming his suspicion that his non-skiddy SQLi has landed him the test user. “Hello test!”. Excellent.

Unfortunately, Mr Security Man didn’t realise that Mr Developer runs an UPDATE statement on an audit table using his username and password. This is where brown hits blade.

mysql> select * from audit;                                                                                                                        
| id   | username | password | last_login |
|    1 | test     | pass     | yesterday  |
|    2 | admin    | password | yesterday  |
2 rows in set (0.00 sec)

mysql> UPDATE audit SET last_login = 'today' WHERE username = 'test' AND password ='pass' or 1=1 -- '
    -> ;
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from audit;                                                                                                                        
| id   | username | password | last_login |
|    1 | test     | pass     | today      |
|    2 | admin    | password | today      |
2 rows in set (0.00 sec)


Whoops? It’s okay though right because it’s only an audit table? Well, not really. It was only an audit table in this example, and a few things had to happen for this injection to be ‘dangerous’, but are they that inconceivable in real life?

Okay, so if ‘ or 1=1 — is bad, what should be used instead? Well, that’s a tough question, because any form of SQLi transforms the structure of the statement, which could potentially manipulate data in ways unintended or by second-order. I’m currently of the opinion that the safest way to test for SQLi is by forcing a syntax error. Doing this shouldn’t get you passed a login page, but it will at least indicate the presence of an SQL injection.

A slightly riskier stratedgy would be the utilisation of the ORDER BY or LIMIT clauses, or the BENCHMARK function. While the web app probably has to be of particularly bad quality for the aforementioned clauses or function to result in undesirable data modification, this is still a possibility you have to assume if you don’t want to be Mr Security Man.