I don't have a good knowledge of SSL principles, but just want the encryption to work for me.
I have a DB and a user with "REQUIRE X509" specified.
The necessary certificates have been created as described in MySQL docs, and work well - i can connect to the server from Windows command line.
The problem arises, when i try to do the same from my program using MySQL Client API (without SSL, the program also works fine).
The unit used is: http://www.audio-data.de/mysql.html.
These are my action paths:
1) if i just add mysql_ssl_set() call (with proper params) before mysql_real_connect(), the last one gives generic SSL Connection Error.
2) the MySQL docs in en/mysql-ssl-set.html say, that the function always returns 0. But when i checked that, it appeared that the result is the number 11150848. Then i wrote it like that:
showmessage(inttostr(mysql_ssl_set(mys, '.\certs\client-key.pem', '.\certs\client-cert.pem', '.\certs\ca-cert.pem', nil)));
...and repeated the line 8 times.
Each time it returned a slightly greater number - 11158528, 11158784, 11159040, ... and two zeroes for the last two calls.
After which mysql_real_connect() was finally successful! The program even managed to execute some queries, return proper results for them (i know the data), but then it crashed with an Access Violation: write of address ... at some place.
The crash point varied between runs and slight changes to code.
It looks much like a version incompatibility issue. I tried libraries from both MySQL 5.0 and 5.1 Windows installations (the server is 5.1 and runs under Linux remotely; however, 5.0 mysql-client programs do not have troubles when SSL-connecting to it), but with no success.
Is anybody familiar with the issue? Thanks a lot for the help & sorry for the mistakes in the question.
As I see the mysql_ssl_set declaration is incorrect. It is declared:
function mysql_ssl_set(_mysql: PMYSQL; key, cert, ca, capath: PAnsiChar): longint; stdcall;
But the mysql.h contains:
my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
const char *capath, const char *cipher);
That explains the garbage in return value, AV's and so on.
Related
update: It appears that what I'm naively trying to do here, of manually appending the salt to the password, will not work because of the way the crypt algorithm works (see Unix crypt using SHA-256 and SHA-512), so this is now really not a Stack Overflow question, but a purely Server Fault question on MySQL 8 functions. Leaving this here, in case anyone else has this problem. You can see the question on Server Fault here.
There's a long backstory here, but the short story is, I can't seem to get MySQL 8 and Dovecot to generate the same SHA256 hashes, given the same salt and password. I suspect either a trivial error, or some string encoding problem (or possibly both).
NB I asked this same question on Server Fault, as it seemed more appropriate for there, but it's not getting any love, and I see several similar questions here, so ...
Dovecot:
$doveadm pw -s SHA256-CRYPT -p apassword
{SHA256-CRYPT}$5$h1JEsg1tmnTGS9Ub$Saoi1jr/uddYVD.n5p0hz70H9slnubpG7MQCkzpAiu4
Then, I grab that salt (h1JEsg1tmnTGS9Ub), and try and get the same output from MySQL 8:
SELECT CONCAT('$5$', 'h1JEsg1tmnTGS9Ub', '$', TO_BASE64(UNHEX(SHA2(CONCAT('apassword', 'h1JEsg1tmnTGS9Ub'), 256)))) WHERE true
$5$h1JEsg1tmnTGS9Ub$Vm9gPbWHuXt/zslurPQ7Nx0JLp1CphlBQbnL9R86XbM=
As I mentioned, there seem to be several similar quesitons here, but either they're with MySQL 5.x using the ENCRYPT function, which has been removed in 8.0.3, or people seem to have decided to drop the salt and just use SHA512 unsalted. It seems to me that this should be easy, and yet ...
Anyone have any ideas on how to get MySQL 8 to generate the same hash as doveadm, with same password and salt?
FWIW, I've tried the MySQL with and without TO_BASE64 and with and without UNHEX (I believe in all combinations).
Thanks!
I'm trying to blackbox pentest a website, the URL has the form http://example.com/a/[integer_value]/something_else
When trying to change [integer_value] to quotes (double and single), characters. It does not have any affect. But, when the [integer_value] larger than UNSIGNED BIGTINT, there'll be an SQL error throwed. That's to say:
if 0 <= [integer_value] <= ( UNSIGNED BIGTINT, which is 2^64-1) => no error
if [integer_value] > UNSIGNED BIGTINT => error: e.g. "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '18446744073709551616' at line 1"
Any ideas ?
Is this exploitable ?
This is probably not exploitable directly, if
it is truly the only scenario where an incoming request can induce your MySQL server to throw an error, and
the web site only performs side-effect-free SELECT operations in response to those URLs.
But, those are big ifs. When you're doing blackbox testing, in principle you cannot know whether they are true.
Plus, when your system throws the error it reveals information about the way the website works. That's not wise on the dirty wire, also known as the public internet.
You're much better off doing some sanity checking of these values before you hand them to your MySQL server. For example, you could attempt to convert the incoming string to a 64-bit number. If the conversion fails, you can stop there. Or, you could check the number of digits in the number and reject numbers that are longer than your application requires.
Your website shoud respond to this kind of URL with a simple 404 not found, just as it would to any other requested URL that it cannot process.
You're not paranoid. Highy motivated and very clever criminals are working hard to pwn your web site.
I'm working on a django application with a MySQL backend. I use south to migrate my schema.
I've just written a migration that drops indexes on some columns, because of a foreign key change AND a name change for said colums.
I did not want to go through the "add the column"->"copy the data"->"remove the old column".
So my migration code chunks look like this (sample given for one table):
# Change FK link from 'reference_workobject' to 'assets_asset'
db.delete_foreign_key('reference_snapshot', 'workObject_id')
db.delete_index('reference_snapshot', ['workObject_id'])
db.rename_column('reference_snapshot', 'workObject_id', 'asset_id')
db.alter_column('reference_snapshot', 'asset_id',
self.gf('django.db.models.fields.related.ForeignKey')(null=True, to=orm['assets.Asset'])
But I get an error that looks like:
DatabaseError: (1091, "Can't DROP 'reference_snapshot_6232368c; check that column/key exists")
Indeed, I fed my development DB (Windows 7 workstation) with a dump from the production server (CentOS 6.5). And I saw that the call to the index name generation (db.create_index_name) does not return the same value on the distinct platforms.
>>> # On WINDOWS
>>> db.create_index_name('reference_snapshot',['workObject_id'])
'reference_snapshot_6232368c'
>>> # On Linux
>>> db.create_index_name('reference_snapshot',['workObject_id'])
'reference_snapshot_9dcdc974'
After investigation, I saw that south should generate my index name as follows:
index_name = '%s_%x' % (table_name, abs(hash((column_name,))) % 2**32)
EDIT
Executing such code snippet yields the same value on both platforms. However the call to create_index_namedoes not. Paradox. Maybe south is not using the code I thought it would.
The call to that snippet of code does actually yields differents results.
>>> # On windows
>>> hash((column_name,))
1965709063
>>> # On Linux
>>> hash((column_name,))
-791966850447943929
If the 32 bits truncation/padding (% 2**32) part was made without the call to abs(), though, the results would be the same.
I conclude from this that the hashing is 32 bits based on windows (even if I use a 64bits python), and 64 bits based on linux.
end edit
So I'm stuck as I can't use the production dumps on windows so as to test my migrations.
Any ideas? Maybe monkey-patching something on my dev workstation could do the trick.
Thanks
Too bad. We can't help but suffer the differences in hash implementation.
However I've just read that the index name calculation will now (as of django 1.5) use md5 because of Python3's randomization in hash(). http://south.aeracode.org/ticket/1222
I run a PHP script which does a lot of mysql work
At some point mysql fails, without printing any errors
I'd like to go then to mysql from console, and ask it what was the last error.
How can I do it?
(I'm aware of php's mysql_error(), but I'm looking for mysql command that I can run directly independently of a php script)
You can run
SHOW ERRORS;
And a similar useful one is:
SHOW WARNINGS;
EDIT
Apparently this will only show errors (or warnings) from your own sessions. So I guess it will not suit your purpose (using console to find errors caused by php).
Anyway, you can read the manual for more info (it says nothing about cross session error logging): http://dev.mysql.com/doc/refman/5.0/en/show-warnings.html
I understand that it's too late, but suddenly someone will find this question just like me ...
For better debugging, you can save the MySQL query to a text file on the server.
For example, before the request:
$mysql->query("Select x from y where y.x = ".$_GET['yx']);
Write the following lines:
error_log("Select x from y where y.x = ".$_GET['yx']);
And after that you will be able to see all database requests from different sessions in text file.
For better experience:
if (!$mysql->query("Select x from y where y.x = ".$_GET['yx']))
error_log("Select x from y where y.x = ".$_GET['yx']);
else
{
you code here...
}
i got a problem and its driving me nuts.
in a function called cargo_id_whitelist(MYSQL * conexion,struct info * data)
i perform a mysql Query. but every time i call the mysql api funcion
mysql_use_res(conexion) it stomp over used memory, ruining data (mostly of the data structure)
example
printf("-kind-> %d \n",conf_var->next->next->id) //work its display the third node id info;
res=( MYSQL_RES *)mysql_use_result(conexion); //this break my memory
printf("puntero %p \n",res);
printf("-kind-> %d \n",conf_var->next->next->id); //segfault
conf_var is a linked list.
theres is something i need to know?
If, as in your comment, your code is as follows:
MYSQL *conn;
if (!mysql_real_connect(conn, blah, blah, blah)) {
return 1;
}
then you're breaking the rules and all bets are off. The MySQL documentation page for mysql_real_connect() states:
The first parameter should be the address of an existing MYSQL structure. Before calling mysql_real_connect() you must call mysql_init() to initialize the MYSQL structure.
The statement MYSQL *conn; (assuming it's not static storage duration) simply creates a pointer that points to an arbitrary location and, unless you init it, using it is likely to cause you a great deal of grief.
The fix is probably simply replacing:
MYSQL *conn;
with:
MYSQL *conn = mysql_init (NULL);
That will give you a new object, properly initialised, that you can then pass to mysql_real_connect().