Jump to content

Recommended Posts

  • Premium

 

I don't think he could be in trouble for doing this. He doesn't store any personal data or sets of data that contains personal data.

Even if the data is not encrypted doesn't really matter. The only thing that must be kept hidden is the license number but I guess it doesn't matter much since it cannot be used for two servers simultaneously (I'm assuming). The IP address is also public or could be accessed with ease (I am talking about the customer's server IP address).

If the database can only be accessed via localhost then it should be ok.

I guess this GDPR thing is misinterpreted by many. Should be ok as long as there is no personal data stored and as long as he doesn't gain access to servers remotely.

  • Honorable Member
50 minutes ago, masodikbela said:

I really don't care about all this, just want to understand the logic behind all this, and one thing is not clear for me (sorry if it has been already answered I CBA reading all this yapping): If you only need the username/pw combo for verification, why is it not even hashed? If it would be hashed by the same algorithm every time it would be actually somewhat safe (depending on the algorithm) and the same input would always generate the same output.

Also another thing I just realized: (I don't want to comment on the practice of sending plain credentials its not my business) You basically use http if I'm not mistaken which basically means all the data you transport to your server even IF you really don't store it or use it or whatever, is actually anything but secure, as it travels through the internet anything can read it. Now that is something that is really concerning.

Before anything, I would like to state that the decompiled library is from an older version.

I used Base64 encoding as a simple and fast solution to avoid sending the credentials in a raw form within the URI string. I know Base64 doesn't provide any encryption or protection so in newer versions of the library I added XOR encryption with a key and before you say it, I know it isn't the best solution either but it does the job and for the purpose I didn't need something to robust because I had to reverse the process. Regardless, on the backend (PHP), the Base64 string is decoded and the system verifies whether the provided username and password match the default credentials for the server which are: "localhost", "mt2", and "mt2!@#".

Yes, I use HTTP and still do (I was working on another version but I canceled it) but I don't think it's necessary to encrypt an IP address, Channel, Port and a default publicly available Metin2 database credential which by default you cannot access remotely unless you manually change it. Regardless, on newer version of the library the full URI is encrypted with XOR, you would not see plain text.

I understand this approach might seem questionable at first and sketchy while looking at the library request. However, I did it this way to "enforce" the use of these default database credentials. This is necessary because the database setup (script to install the database tables) and operation rely on these specific credentials.

Sure they can change it but they need to know what they're doing. As long as these default credentials are strictly assigned to "localhost," I believe this approach is secure and ensures proper installation and functioning of the database.

I have no problem sharing this small procedure with everyone, but I can’t reveal every single line of code publicly just to prove that I'm not doing anything harmful with the data or storing it. Even if I did, some people still wouldn't believe me. I've already messaged the forum administrator to offer a full review of the "system" if they're interested, but I'm not going to share it publicly here.

Spoiler
/*
* $addr : The machines IP address.
* $key : The unique license key assigned to the member
* $config : Additional paramenters sent in the URI string. (hostname, channel, sqlu, sqlp)
* $version : Version of the license library file.
*/
function verify_license($addr, $key, $config, $version)
{
	// establish the connection to my database
	$db = MySqliDb::getInstance() ?: new MysqliDb(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_NAME);

	// get settings based on the version of the library file
	$osp = $db->where('version', $db->escape($version))->get('osp');

	// fetches the user linked to this license key
	$account = $db->where('license', $db->escape($key))->get('users');

	// fetches the auth key based on the version of the library file
	$auth_key = $osp[0]['authKey'];
	if ($auth_key == "")
		return AUTH_FAILURE;

	// currently in new versions this is turned of but it strictly checks if the user is using the default credentials, if not, the server fails to execute.
	if (STRICT_DB_USER_CHECK && !$account[0]['allow_db_user_change'])
	{
		if (!($config['sql_host'] === "localhost" && $config['sql_user'] === "mt2" && $config['sql_password'] === "mt2!@#"))
		{
			log_request($addr, $key, "WRONG_DB_USER", $config, $version, LOG_LEVEL_ERROR);
			return AUTH_FAILURE;
		}
	}

	// checks if this user is allowed to bypass the license version
	if (ALLOW_LICENSE_BYPASS && $account[0]['allow_bypass'])
	{
		log_request($addr, $key, "BYPASS_ALLOWED", $config, $version, LOG_LEVEL_INFO);
		return $auth_key;
	}

	...

 

Edited by Owsap
  • Premium
1 minute ago, Owsap said:

I used Base64 encoding as a simple and fast solution to avoid sending the credentials in raw form within the URI string. I know Base64 doesn't provide any encryption or protection so In newer versions of the library I added XOR encryption with a key and before you say it, I know it isn't the best but does the job and for the purpose I didn't need something to robust. Regardless, on the backend (PHP), the Base64 string is decoded and the system verifies whether the provided username and password match the default credentials for the server which are: "localhost", "mt2", and "mt2!@#".

I understand this approach might seem questionable at first and sketchy while looking at the library request. However, I did it this way to "enforce" the use of these default database credentials. This is necessary because the database setup (script to install the database tables) and operation rely on these specific credentials.

Sure they can change it but they need to know what they're doing. As long as these default credentials are strictly assigned to "localhost," I believe this approach is secure and ensures proper installation and functioning of the database.

I have no problem sharing this small procedure with everyone, but I can’t reveal every single line of code publicly just to prove that I'm not doing anything harmful with the data or storing it. Even if I did, some people still wouldn't believe me. I've already messaged the forum administrator to offer a full review of the "system" if they're interested, but I'm not going to share it publicly here.

  Reveal hidden contents
/*
* $addr : The machines IP address.
* $key : The unique license key assigned to the member
* $config : Additional paramenters sent in the URI string. (hostname, channel, sqlu, sqlp)
* $version : Version of the license library file.
*/
function verify_license($addr, $key, $config, $version)
{
	// establish the connection to my database
	$db = MySqliDb::getInstance() ?: new MysqliDb(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_NAME);

	// get settings based on the version of the library file
	$osp = $db->where('version', $db->escape($version))->get('osp');

	// fetches the user linked to this license key
	$account = $db->where('license', $db->escape($key))->get('users');

	// fetches the auth key based on the version of the library file
	$auth_key = $osp[0]['authKey'];
	if ($auth_key == "")
		return AUTH_FAILURE;

	// currently in new versions this is turned of but it strictly checks if the user is using the default credentials, if not, the server fails to execute.
	if (STRICT_DB_USER_CHECK && !$account[0]['allow_db_user_change'])
	{
		if (!($config['sql_host'] === "localhost" && $config['sql_user'] === "mt2" && $config['sql_password'] === "mt2!@#"))
		{
			log_request($addr, $key, "WRONG_DB_USER", $config, $version, LOG_LEVEL_ERROR);
			return AUTH_FAILURE;
		}
	}

	// checks if this user is allowed to bypass the license version
	if (ALLOW_LICENSE_BYPASS && $account[0]['allow_bypass'])
	{
		log_request($addr, $key, "BYPASS_ALLOWED", $config, $version, LOG_LEVEL_INFO);
		return $auth_key;
	}

	...

 

What I'm trying to understand is why do you need the credentials in a reversible format, if you are only doing a comparison. To be clear: I'm just trying to fact check the stuff you say and the stuff you do. Of course I cannot do that on the backend we don't see so I'm just gonna take your word for it. But again I only want to know this very thing: why is the credentials reversible if you only need comparison and why is there no encryption on the transit layer while sending raw credentials. Please explain this to me because I want to understand this part.

  • Good 1

The one and only UI programming guideline

  • Honorable Member
9 minutes ago, masodikbela said:

What I'm trying to understand is why do you need the credentials in a reversible format, if you are only doing a comparison. To be clear: I'm just trying to fact check the stuff you say and the stuff you do. Of course I cannot do that on the backend we don't see so I'm just gonna take your word for it. But again I only want to know this very thing: why is the credentials reversible if you only need comparison and why is there no encryption on the transit layer while sending raw credentials. Please explain this to me because I want to understand this part.

As I mentioned, I didn't want to send the plain text in the URI string so I used Base64 to encode the credentials, then on the backend I decoded it. It was just my way of saying (reversible format, encode / decode).

Yes, I could have hashed the credentials and compared the hashes, which would have been more secure for transmitting the data via HTTP. However, that would still require an explanation as to why I'm reading the credentials from the library file and sending them via an HTTP request, bringing us back to the beginning of this topic.

The usage of that sql data was and is simple, a direct comparison to check if they are the default credentials, nothing more. As for the rest of the data (ip, key, hostname, port, etc...), I believe they're self explanatory.

Edited by Owsap
  • Premium
4 minutes ago, Owsap said:

Like I said, I didn't want to send the plain text in the URI string so I used Base64 to encode the credentials, then on the backend I decoded it. It was just my way of saying (reversible format, encode / decode). Yes I could've hashed the credentials and compared them by hash which would be more secure in sending that data via HTTP but still I would have to explain myself why I would read the mysql credentials on the library file and send them via HTTP request and then we're back to beginning of this post again.

Okay I will skip on the network part lets say that's fine. (Its not, but it would take some extra effort on the routers in the way to extract it, very unlikely someone would do a man in the middle on this.) Reading the credentials on the library part is one thing and can be easily argued with even if you get caught in a shitstorm like this one you can say that its hashed with a strong cryptographically safe algorithm and done. Encrypting it then reversing it on the server side is another thing, harder to argue about, but I would say it is justifiable in some cases. On the other hand decrypting it on the serverside and saying that "ye basically I don't need it its just works like this" is not a good point in my opinion and raises some hard questions and as you said you cannot prove it in any believable way, maybe you should consider changing it to use some sha2 at least.

The one and only UI programming guideline

  • Honorable Member
30 minutes ago, masodikbela said:

Okay I will skip on the network part lets say that's fine. (Its not, but it would take some extra effort on the routers in the way to extract it, very unlikely someone would do a man in the middle on this.) Reading the credentials on the library part is one thing and can be easily argued with even if you get caught in a shitstorm like this one you can say that its hashed with a strong cryptographically safe algorithm and done. Encrypting it then reversing it on the server side is another thing, harder to argue about, but I would say it is justifiable in some cases. On the other hand decrypting it on the serverside and saying that "ye basically I don't need it its just works like this" is not a good point in my opinion and raises some hard questions and as you said you cannot prove it in any believable way, maybe you should consider changing it to use some sha2 at least.

Like you said, it's very unlikely a man in the middle would want to extract this data, there is nothing really interesting. The only stress here was about the credentials being sent too, which I understand. However, I've explained that already many times during this topic and for whatever it's worth, for years there hasn't been a single problem with this and I would never do things to damage my name and reputation. I could have done things differently, this was probably a mistake, we live and learn but no harm was ever done.

Regardless, I still propose the same as I mentioned before, both for the review of the system and as for the removal of my license system.

  • Former Staff

Although the recovery of MySQL credentials is questionable, OWSAP has explained himself.
Still, I don't think he has any interest in harming his own reputation or brand image.

He did not try to conceal the recovery of this data, although he should have done it differently to avoid this drama.
As mentioned previously on this topic.

I'm going to lock this topic, I think OWSAP has explained himself and said everything.

  • kekw 1
  • Lmao 1
  • Good 3

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.