Trucos. Brujerías en la línea de comandos
TRUQUIS
Trucos. Brujerías en la línea de comandos
2017-12-05
Por
Tamariz el de la Perdiz

Como siempre, en este número os traigo una buena selección de los mejores trucos para GNU/Linux... Continuad leyendo para descubrir los secretos de los wizards.

Comprimir Binarios

Si andamos cortos de espacio solemos comprimir nuestros datos. Pero y si no hay más datos que comprimir?. Por qué no comprimir los programas?. Uhm.. pero para eso necesitamos poder ejecutarlos en su forma comprimida, sino de poco nos va a valer... No Problemo.
 
$  ls -l xeyes
-rwxr-xr-x 1 occams razor 20472 Nov 1 00:00 xeyes
$  gzexe xeyes
xeyes:   58.5%
$  ls -l xeyes
-rwxr-xr-x 1 occams razor 9319 Nov 1 00:00 xeyes
    

Así de fácil. Podremos descomprimir el programa y volverlo a su forma original utilizando el comando:

$ gzexe -d my_binario
    

gzexe simplemente comprime el binario y lo sustituye por un script que contiene la imagen comprimida del programa. Cuando el script se ejecuta simplemente descomprime los datos y los ejecuta!

cURL to C

El super-poderoso programa cURL tiene nos permite convertir cualquier secuencia de parámetros que le pasemos en código C que podemos compilar directamente o incluir en nuestras aplicaciones:

$ curl http://URL [parámetros] --libcurl /tmp/prog.c
$ gcc -o prog /tmp/prog.c -lcurl
    

Genera ficheros vacíos mú rápido

A veces necesitamos generar grandes ficheros vacíos. Por ejemplo si queremos generar una imagen de un disco de un cierto tamaño. En esos casos, podemos escribir ceros en el fichero hasta alcanzar el tamaño que deseemos (con dd), o utilizar fallocate.

$ time fallocate -l 1G kk.img

real    0m0.072s
user    0m0.000s
sys     0m0.000s
$  time dd if=/dev/zero of=kk.img bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.7525 s, 99.9 MB/s

real    0m10.767s
user    0m0.000s
sys     0m0.844s
    

Ejecutando Scripts Remotos como un Pro

Imaginad por un momento que necesitáis ejecutar un script en una máquina para la que solo tenemos permisos de escritura en un directorio en el que no tenemos permisos de ejecución... O incluso ni siquiera tenemos permisos de escritura en ningún lado. Suena raro? No tanto, algo así lo podéis encontrar fácilmente en routers o teléfonos Android (bueno, el directorio /tmp suele dejarnos escribir y ejecutar... pero y si no?...).

Como solía decir mi abuela: Mientras haya red, hay esperanza. Vamos a crear rápidamente un entorno como el que acabamos de describir, en el que poder probar este truco.

$  fallocate -l 50M kk.img
$  mkfs.ext4 ./kk.img
(...)
$  mkdir test
$  sudo mount -o noexec kk.img ./test/
$ sudo mkdir test/tmp
$ sudo chown TU_USUARIO_PREFERIDO test/tmp
    

Las líneas de arriba crean un sistema de ficheros ext4 en un fichero, lo monta sin permisos de ejecución y luego crea un directorio para nuestro usuario habitual... básicamente para no tener que escribir sudo todo el rato.

Ahora intentaremos crear y ejecutar un script en este sistema de ficheros:

$  cd test/tmp/
$  cat <<EOM > test.sh
> #!/bin/sh
> echo "Hola Mundo"
> EOM
$  chmod +x test.sh
$  ls -l test.sh | awk '{print $1, $9}'
-rwxrwxr-x test.sh
$ ./test.sh
bash: ./test.sh: Permission denied
 $  sudo ./test.sh
sudo: unable to execute ./test.sh: Permission denied
Hangup   
    

Bien, nuestro entorno está configurado para probar nuestro truco, que simplemente consiste en descargar el script de un servidor remoto y empiparlo a la shell. Algo como esto:

$ curl -s MiServidorWeb/test.sh | sh
$ lynx --dump MiServidorWeb/test.sh | sh
$ wget -q MiServidorWeb/test.sh -O - | sh
    

Bueno... vale... ya que estamos vamos a poner todas las instrucciones. Podéis lanzar un servidor web con los comandos siguientes (los dos primeros comandos simplemente hacen que nuestro script sea accesible a través del servidor web).

$ cp test.sh /tmp
$ cd /tmp
$ python -m SimpleHTTPServer 8080
    

Ahora solo tenéis que sustituir MiServidorWeb por localhost:8080.

Y si curl, lynx o wget no están instalados

Buena pregunta... En ese caso, si la shell es bash no está todo perdido.
exec 5<> /dev/tcp/localhost/8080
bash$ echo -e "GET /test.sh HTTP/1.0\n" >&5
bash$ cat <&5 | tail -n +8 | sh
    

El comando tail es necesario para saltarnos la cabecera HTTP que nos envía el servidor. Si sustituimos el servidor web por netcat, podremos omitir tanto el echo como el tail. La cosa se nos quedaría entonces en:

$ cat test.sh | nc -l -p 8000         # Ejecutar en el servidor
-----
$ cat < /dev/tcp/localhost/8000 | sh  # Ejecutar en el client
    

Y esto es todo... hasta el próximo número!

Créditos Imagen Cabecera: abednego setio gusti

SOBRE Tamariz el de la Perdiz
Tamaríz es un mago de la línea de comandos, un ilusionista de las pipes, un nigromante guardián de las ancestrales herramientas olvidadas por los mortales. Vamos, el tío de la sección de trucos.