Buffer Overflow poprzez MOTD

Odrazu mówię zjawisko które jest wymienione w tytule wkońcu nie wystąpiło , raczej w tym artykule chce pokazać sposób myślenia i dochodzenia do pewnych rzeczy ;).

Najpierw o sposobie wysyłania MOTD tzn.

https://wiki.alliedmods.net/index.php/Half-Life_1_Game_Events#MOTD

Krótki wpis o MOTD

This message displays the MOTD window.
Note: Max. Text length is 60. A larger MOTD is sent in multiple messages. Flag will be set to 1 for the final segment.
Name:	MOTD
Structure:	
byte	Flag
string	Text

Czyli wysyłając wiadomość MOTD dzielimy ją na części po 60 znaków oraz powiadamiamy odpowiednia flagą że jest to koniec wiadomości.

Pytanie jaki jest limit MOTD oraz co się stanie jak będziemy wysyłać wiadomości nie kończąc wysyłania 😉 ?

Przejdźmy do testowania.

Początkowy plugin

/* Script generated by Pawn Studio */

#include <amxmodx>
#include <amxmisc>

#define PLUGIN	"New Plugin"
#define AUTHOR	"DarkGL"
#define VERSION	"1.0"

public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	register_clcmd( "say /testBuffer" , "testBuffer" );
}

public testBuffer( id ){
	for( new iPosition = 0 ; iPosition < 16 ; iPosition++ ){
		new szText[ 60 ];
		
		for( new positionText = 0; positionText < sizeof( szText ) ; positionText++ ){
			szText[ positionText ] = random_num( 'a' , 'z' );
		}
		
		szText[ 59 ] = '^0';
		
		message_begin( MSG_ONE, get_user_msgid( "MOTD" ) , {0,0,0} , id );
		write_byte( 0 );
		write_string( szText );
		message_end();
	}
	
	new szText[ 60 ];
	
	formatex( szText  , charsmax( szText ) , "" );
	
	message_begin( MSG_ONE, get_user_msgid( "MOTD" ) , {0,0,0} , id );
	write_byte( 1 );
	write_string( szText );
	message_end();
}

Jak narazie wszystko ok , zwiększamy ilość wiadomości.

/* Script generated by Pawn Studio */

#include <amxmodx>
#include <amxmisc>

#define PLUGIN	"motdBuffer"
#define AUTHOR	"DarkGL"
#define VERSION	"1.0"

public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	register_clcmd( "say /testBuffer" , "testBuffer" );
}

public testBuffer( id ){
	for( new iPosition = 0 ; iPosition < 35 ; iPosition++ ){
		new szText[ 60 ];
		
		for( new positionText = 0; positionText < sizeof( szText ) ; positionText++ ){
			szText[ positionText ] = random_num( 'a' , 'z' );
		}
		
		szText[ 59 ] = '^0';
		
		message_begin( MSG_ONE, get_user_msgid( "MOTD" ) , {0,0,0} , id );
		write_byte( 0 );
		write_string( szText );
		message_end();
	}
	
	
	new szText[ 50 ];
	
	formatex( szText  , charsmax( szText ) , "" );
	
	message_begin( MSG_ONE, get_user_msgid( "MOTD" ) , {0,0,0} , id );
	write_byte( 1 );
	write_string( szText );
	message_end();
}

W tym momencie mogłem już ustalić maksymalną ilość znaków na około ~1536 no to idziemy dalej.

Zwiększenie iteracji powodowało już Reliable channel overflow trzeba było to rozwiązać inaczej.

/* Script generated by Pawn Studio */

#include <amxmodx>
#include <amxmisc>

#define PLUGIN	"motdBuffer"
#define AUTHOR	"DarkGL"
#define VERSION	"1.0"

public plugin_init()
{
	register_plugin(PLUGIN, VERSION, AUTHOR)
	
	register_clcmd( "say /testBuffer" , "testBuffer" );
}

public testBuffer( id ){
	static iteration = 0;
	
	for( new iPosition = 0 ; iPosition < 35 ; iPosition++ ){
		new szText[ 60 ];
		
		for( new positionText = 0; positionText < sizeof( szText ) ; positionText++ ){
			szText[ positionText ] = random_num( 'a' , 'z' );
		}
		
		szText[ 59 ] = '^0';
		
		message_begin( MSG_ONE, get_user_msgid( "MOTD" ) , {0,0,0} , id );
		write_byte( 0 );
		write_string( szText );
		message_end();
	}
	
	if( iteration < 1200 ){
		set_task( 0.1 , "testBuffer" , id );
	}
	
	if( iteration == 0 ){
		set_task( 120.0 , "endBuffer" , id );
	}
	
	iteration++
}

public endBuffer( id ){
	
	new szText[ 60 ];
	
	formatex( szText  , charsmax( szText ) , "" );
	
	message_begin( MSG_ONE, get_user_msgid( "MOTD" ) , {0,0,0} , id );
	write_byte( 1);
	write_string( szText );
	message_end();
}

Ale nawet wysłanie tylu znaków ( ~70800 ) nie powodowało żadnego crasha etc. klienta.

Podsumowując klient prawdopodobnie ma zarezerwowane 1536 znaków w pamięci i na więcej nie pozwala oczywiście można sprawdzić bardziej ekstremalne przypadki
tzn. wysłanie większej ilości znaków i obserwowanie co się wydarzy , konkretnego efektu nie osiągnęliśmy ale sprawdzi było warto ;).

Dodaj komentarz