[Release - Hack/Exploit] Login To Anyones accounts on Binary servers

12/04/2012 02:37 CptSky#61
Hum. Anybody remembering the japanese servers ? They're like ghost server, still at patch ~5065. This technique would work ?
12/04/2012 22:55 © Haydz#62
Quote:
Originally Posted by CptSky View Post
Hum. Anybody remembering the japanese servers ? They're like ghost server, still at patch ~5065. This technique would work ?
They use the official account servers.
12/05/2012 11:32 IAmHawtness#63
Quote:
Originally Posted by © Haydz View Post
They use the official account servers.
Code:
bool CUserList::LoginUser(LPCTSTR szAccount, LPCTSTR szPassword, SOCKET_ID idSocket)	// ½öÓÃÓÚ·ÇÕʺŷþÎñÆ÷Æô¶¯
{
#ifdef	ACCOUNT_ENABLE
	return false;
#endif
	bool	bRet = false;
	SQLBUF	szSQL;
	sprintf(szSQL, "SELECT id, name, account_id, recordmap_id FROM %s WHERE account='%s' && password='%s'", _TBL_USER, szAccount, szPassword);
	IRecordset*	pRes = GameWorld()->GetDatabase()->CreateNewRecordset(szSQL);		//VVVVVVVVVVVVVVVVVVVVVVVV
	if(pRes)
	{
		OBJID	idUser	= pRes->LoadDWord("id");
		NAMESTR	szName = "ÎÞ";
		pRes->LoadString(szName, "name", _MAX_NAMESIZE);
		OBJID	idAccount	= pRes->LoadDWord("account_id");
		OBJID	idMap	= pRes->LoadDWord("recordmap_id");
		PROCESS_ID	idProcess	= MapList()->GetMapProcessID(idMap);
		ASSERT (idProcess != PROCESS_NONE);
		int		nLevel	= 0;		// δÕʺŷþÎñÆ÷µÇ¼£¬²»ÐèÒªµÈ¼¶
		CreateUser(idProcess, idUser, szName, idAccount, idSocket, nLevel, szAccount);

		bRet = true;
		pRes->Release();;		//AAAAAAAAAAAAAAAAAAAAAAAAAA

		GameWorld()->SendFee(idAccount, CMsgFee_A::FEE_BEGIN);
	}

	{
		m_nPlayerAmount++;
		if(m_nMaxPlayerAmount < m_nPlayerAmount)
			m_nMaxPlayerAmount = m_nPlayerAmount;
		extern struct STAT_STRUCT	g_stat;
		InterlockedExchange(&g_stat.nAllPlayers, m_nPlayerAmount);
		InterlockedExchange(&g_stat.nMaxPlayers, m_nMaxPlayerAmount);
		InterlockedIncrement(&g_stat.nLoginPlayers);
	}
	return bRet;
}
Taken from UserList.cpp in the official Eudemons server source code. Doesn't seem to have a lot of protection against SQL injection
12/05/2012 12:28 nTL3fTy#64
Quote:
Originally Posted by IAmHawtness View Post
Taken from UserList.cpp in the official Eudemons server source code. Doesn't seem to have a lot of protection against SQL injection
That's not the code that's used for the login server. The source I have (whether it is official or not) does escape the username and password that is received from the client before querying the database.

Code:
void InsertBackslash(char * bufTarget, const char * pszSource)
{
	const char * pSour = pszSource;
	char * pTarg = bufTarget;
	while(*pSour)
	{
		if(*pSour == '\\' || *pSour == '\'')
			*(pTarg++) = '\\';

		*(pTarg++) = *(pSour++);
	}
	*pTarg = 0;
}
12/05/2012 12:36 IAmHawtness#65
Quote:
Originally Posted by nTL3fTy View Post
That's not the code that's used for the login server. The source I have (whether it is official or not) does escape the username and password that is received from the client before querying the database.

Code:
void InsertBackslash(char * bufTarget, const char * pszSource)
{
	const char * pSour = pszSource;
	char * pTarg = bufTarget;
	while(*pSour)
	{
		if(*pSour == '\\' || *pSour == '\'')
			*(pTarg++) = '\\';

		*(pTarg++) = *(pSour++);
	}
	*pTarg = 0;
}
Oh, I just remember a case like a long time ago when people were logging other people's accounts, way before the whole incident with the "hack case forums" or whatever that got broken into. I just thought it had to do with the SQL injection into the username/password. Probably not then
12/05/2012 12:38 © Haydz#66
Quote:
Originally Posted by IAmHawtness View Post
Taken from UserList.cpp in the official Eudemons server source code. Doesn't seem to have a lot of protection against SQL injection
That's code from the server source code right?

I'm fairly sure that method is called after the account server has received and verified the information, before passing it over to the game server.

Taken from the account server source:
Where InsertBackslash replaces any bad SQL characters.

Code:
//////////////////////////////////////////////////////////////////////
// password == "" ±íʾ²»¼ì²éÃÜÂë
BOOL CAccount::Create(const char* pszName, const char* pszPassword)
{
	try{
		if(!pszName || _MAX_NAMESIZE <= strlen(pszName))
			return false;

		if(!pszPassword || _MAX_PSWSIZE <= strlen(pszPassword))
			return false;

		if (m_pRes != NULL)
		{
			::LogSave("WARNING: CAccount::Create() m_pRes not NULL.");
			this->Destroy();
		}

		char bufName[256];
		InsertBackslash(bufName, pszName); //
//		if(strchr(pszName, '\'') || strchr(pszName, '\\'))			// µ¥ÒýºÅ(')³£Á¿ºÍ·´Ð±¸Ü(\)³£Á¿
		{
//			::LogSave("ERROR: Login with illegal username [%s]. can't login.", pszName);	//¡ï DEBUG
//			return false;
		}

		char bufPassword[256];
		InsertBackslash(bufPassword, pszPassword);
//		if(strchr(pszPassword, '\'') || (strlen(pszPassword) && pszPassword[strlen(pszPassword)-1] == '\\'))	// µ¥ÒýºÅ(')³£Á¿ºÍ·´Ð±¸Ü(\)³£Á¿
//		if(strchr(pszPassword, '\'') || strchr(pszPassword, '\\'))	// µ¥ÒýºÅ(')³£Á¿ºÍ·´Ð±¸Ü(\)³£Á¿
		{
//			::LogSave("ERROR: Login with illegal password [%s]. can't login.", pszPassword);	//¡ï DEBUG
//			return false;
		}

		m_pRes = new CMyRecordset(&g_db);
		if(!m_pRes)
		{
			::LogSave("ERROR: CAccount::Create() can't new CMyRecordset object.");
			return false;
		}
		if(bufPassword[0])
			sprintf(m_szSQL, SQL_ACCOUNT_STMT, POINTTABLE, bufName, bufPassword);
		else
			sprintf(m_szSQL, SQL_ACCOUNT_STMT2, POINTTABLE, bufName);

		if (!m_pRes->Open(m_szSQL))  
		{	
			::LogSave("ERROR: CAccount::Create(char*) can't Open() database for [%s]", m_szSQL);
			delete m_pRes;
			m_pRes = NULL;
			return false;
		}

		if (m_pRes->RecordCount() == 0)  
		{	
			m_pRes->Close();
			delete m_pRes;
			m_pRes = NULL;
			return false;
		}

		if(!this->LoadInfo())
		{
			::LogSave("ERROR: CAccount::Create() can't LoadInfo()");
			return false;
		}

		return true;
	}
	catch(...)
	{
		::LogSave("exception catch at CAccount::Create(%s).", pszName);
		return false;
	}
}
Edit: whoops, didn't see the earlier post.
12/05/2012 12:39 IAmHawtness#67
Quote:
Originally Posted by © Haydz View Post
That's code from the server source code right?

I'm fairly sure that method is called after the account server has received and verified the information, before passing it over to the game server.

Taken from the account server source:
Where InsertBackslash replaces any bad SQL characters.

Edit: whoops, didn't see the earlier post.
Haha yeah, my bad. I don't have the account server source :(
12/05/2012 12:42 © Haydz#68
Quote:
Originally Posted by IAmHawtness View Post
Haha yeah, my bad. I don't have the account server source :(
I'm not really sure if the one I have is official, nor can I remember where I got it, although it has the usual Tq characteristics.
12/05/2012 20:17 Kiyono#69
Well you probably got it from e*PvP. The source code for client and server were both floating around in the EO section.
12/18/2012 22:16 ha.ho.a#70
any hint how to get a seed right?
12/18/2012 23:49 pro4never#71
Quote:
Originally Posted by ha.ho.a View Post
any hint how to get a seed right?
Start at 1 million and increment by 1.

Unless they've manually changed the numbering for their account ids then those should be the valid range.
12/19/2012 01:13 _DreadNought_#72
Quote:
Originally Posted by pro4never View Post
Start at 1 million and increment by 1.

Unless they've manually changed the numbering for their account ids then those should be the valid range.
FallenCO PM was 1 and they didnt manually change them ;)
12/19/2012 07:35 pro4never#73
Quote:
Originally Posted by _DreadNought_ View Post
FallenCO PM was 1 and they didnt manually change them ;)

That means they used a weird database backup.

The client (and server) expect player uid's to be above 1 million. It's fairly well documented and while changing it to a non default range might 'help' versus this type of a tool... it's really quite a pointless measure and will likely screw up various gameplay elements.
12/19/2012 11:41 ha.ho.a#74
o well ive tried on a server with no success,,,
12/19/2012 20:22 lostsolder05#75
Quote:
Originally Posted by pro4never View Post
That means they used a weird database backup.

The client (and server) expect player uid's to be above 1 million. It's fairly well documented and while changing it to a non default range might 'help' versus this type of a tool... it's really quite a pointless measure and will likely screw up various gameplay elements.
In binaries certain commands will not work if your account UID is in that range.

e.x.: /player all & /player map