📜 ⬆️ ⬇️

How I once hacked an online casino

Inspired by the story of Chikey about how he again “broke the Internet”, Egor stopped breaking everything, deal with some business , decided to tell one story with a fairly well-known online casino. The name of this "organization" I do not call, because 50 percent sure that they either did not fix it at all, or made it more crooked than it was before.

The story is very similar to the hacking of Egor, except that it is not exactly a race, or rather, not a race condition in its pure form. I do not know how it will be completely, I am more a practitioner than a theorist. Let's call it “conditional race condition” - although the oil is oily, it reflects the essence correctly.

One evening, the family fell asleep, there was only one murkiness in the box, our losers again had nothing to do, I decided to score on the open source, I wanted to break something. And what to break (when Egor broke everything) , if not a bank or a casino (ego, the need to sometimes feel like a cool guy, everything is in general). It was one of the first online casinos, which I then liked in search.
')
It is no secret that they save on programmers, testers, etc. all or almost all. I sometimes do audits, and by the nature of this activity sometimes you see that hair is on end. But here is the casino! With the possibility of withdrawing (won) evergreens, etc. Those. the office should seem to correspond.

I got an account, and let's go ...

Actually hacking


As it turned out - here, too, saved considerably.

At first I decided to throw myself some “virtual” money. Virtual currency is not displayed there (pure play - to practice). It was possible through paypal (10ct = 10V $), once a day through the captcha (20V $).

When scrolling through the “purchase” page (loading it several times), I found a token linked to a time (modulo 180 increment is noticeable), which starts with a captcha after clicking “Order”. Probably, the date for the time of “purchase” was written to the base for my account (so that means only once a day), but for us it is now unnecessarily.

I wanted to try a clean race first (I'm not so stupid as to believe about 3 minutes, well, or 1.5 minutes if I use the formula with offset), but I had doubts that there was not even a few milliseconds, i.e. with high probability this token was probably also marked as used in DB, so that means “until tomorrow” (by the way, it turned out later).

As a result, I decided to start trying right away from my “conditional race”. Suppose that the token is written to the int-th database (of the unixtime type, i.e., an integer), because they assume that the next token will be issued only after 3 minutes (although it is usually still with some kind of offset, so that at the border, its validity has expired). Those. I think we have something like:

create table user_order (usrid int, token bigint, lasttoken bigint, lastorder datetime, ...) 

Here is a bit of technology: I do not like things like Greasemonkey and to, although sometimes I use it. But I do not like (there is little such as Yegor). A lot can be done from the dev console of firefox, but in trifles. I also quite rarely “work”. I have my own (well, almost) plugin that expands the “full-fledged” tickle interpreter (tcl) from api to javascript of the current window. Type greasemonkey, only on the tickle. Conveniently creepy.

In general, the tickle-jail script for “hacking” looked like this:

 set tok [js form.ordertoken.value] set i 0 set cntr 0 time { ##     -    : elm duplicate -overwrite form[expr $i % 5] form ##   "float"      (0-4) ... js { var f = form[expr $i % 5]; f.target = '_tmp_win_[expr $i % 5]'; f.ordertoken.value = f.ordertoken.value + '.' + '[format %05d [incr cntr]]'; f.submit(); } ##  ,    ... update; after 5 incr i } 10 

Those. for each new dubbed form, we make the value of the ordertoken as a floating point number.
We have the following in javascript:

  ... var f = form0; f.target = '_tmp_win_0'; f.ordertoken.value = f.ordertoken.value + '.' + '00001'; f.submit(); ... var f = form1; f.target = '_tmp_win_1'; f.ordertoken.value = f.ordertoken.value + '.' + '00002'; f.submit(); ... 

The quick-witted reader has probably understood what is going on.

The following SQL-statement will be legally executed if we have autoconversion and the float is cut to (big) int without an overflow error, and the condition is positive (since the comparison will be made in float):

 UPDATE user_order set lasttoken = 1432254060.00007, lastorder = now(), vmoney = vmoney + 20 WHERE ... AND lasttoken != 1432254060.00007 AND ... 

What did they check there, affected rows or just if begin ... end in a transaction, and whether it is SQL at all, I don’t know, but once again running the script, I’ve become a “virtual” millionaire! Well, that is, time casino-virt-order 50000 .
Explanation under the spoiler
Roughly speaking, an integer T1 is saved somewhere (like int or bigint), for example, 180.
And then it is compared with the number T2, which is transmitted from the outside and is changed by us to a floating point number (say float) 180.01.
If the comparison of T1 with T2 occurs integer (in int), they are equal, if like a float (which happens if you do not keep track of some algorithms or systems or do not explicitly indicate), then they are different!
 int(180) = int(180.01) float(180) != float(180.01) 
After comparison, the T2 token is legal, and, just as important, the T2 token has not yet been used - the balance of money increases (payment takes place), and T2 rewrites T1 (the token is used), while it is truncated to whole if there is no precision overflow. those. 180 again. And the standard flight is all over and over again. Until the token becomes obsolete, well, or until time passes ...
The constant increase in the float-token (as in my script), allows you to “prevent” a situation where the token is still not stored integerly, but checking it in the token’s “legality” formula is performed integrally but checking “token used” for any reason like float.

How long do you think the site went on with the real payment ?! Day (and that is because already very much wanted to).
There, of course, there was no time casino-real-order 50000 , and I think that they would have noticed it once or twice. Well, some kind of monitoring of funds (cheating, etc.) should still be. Albeit with ten thousand customers. But 50–20 I did it once (i.e. by paying “only” 20 ever-growing ones, because at that time it was the lowest possible payment).

In fairness, I must say that I naturally closed this account without withdrawing funds, returning only my invested money.

Morality


There seems to be nothing to discuss. The only thing I can add is that the clean race condition did not work there, I checked (the second parallel call issued “already used”). But judging by the "professionalism" of the guys - it was more like fool protection (like F5 after requisition, etc.).

Another interesting moment, when the token became outdated (+ 180), it did not work anymore because of the verification of the date of the last “payment” of the type lastorder < now() + '1 day' . But for some reason, not with the "same" token. I think that the sore one was not.
Although it should be added that the token was completely honestly marked as used (i.e., a transaction with a table lock or isolation level of the serializable type). The new token itself cannot be generated either (probably it should be in their database for an account). Or maybe just issuing a new token depended on the lastorder .

And yes, the captcha was apparently bound in the same way to the token + something else in the form. Or “race” worked for her, I had no need to search for it.

By the way, everything else, from SQL-Injection to various tricks with exploits known to me on that platform, looked pretty solid, but somehow it was still semi-professional or something, i.e. there was nothing to complain about (some things aren’t already years dtsat how).

Yes, one more thing: this is a casino, i.e. a person not constrained by means has any advantage over his rivals, all other things being equal. At the very least can afford to risk more. In general, if I played there, I could have “almost” legally won a lot of money from other clients of this casino, “deceiving” the company itself for a much smaller amount. Plus, at least the interests of the clients of this platform for selecting funds from the public would be affected. I do not think that the casino did not understand this when they tried to deal with me.

"Showdown" with me - a villainous hacker


I don't even want to tell.

I, as usual, at first laid out to them only the results of the "exploit" - i.e. Here is the account, it has a virtual milen of money. The account was created the day before yesterday, well, and a hint - they say I’ll tell you how it is after donation. About breaking with real money, I first kept silent at all (another account is another donate). I am not poor, but any work must be paid. Naturally "repented", i.e. “Purely from sporting interest” and “of course never (give a tooth) will not apply.”

Result:

What is funny, after the account was closed, already with real money (previously only their 20 euros were withdrawn) for some time still received letters from them, they say, “take the money” ... I wanted to answer them first - spend on charity, but they are not mine . So they are probably there ...

People, do not save all the same on the pros. We, the pros, are worth the money that we pay.

[UPD # 1] Here the moralists came along, like, “They didn’t ask you to check their site. Let me do something good to you too, and ask for money ”or is it“ Extortion, ”etc.
I will answer immediately to all who wish to postebatsya for my conscience:
Hidden text
  • then let me not give you money (yes I have rights), but at the same time I will say - “this is something good, definitely leave it anyway, without money, and I will sue you in court anyway”.
  • my personal attitude to the “client” will depend on him, at least on the tone, how it will be said.
  • I spent a lot of time writing a post, and I don’t have the slightest desire to listen to the nagging of another troll about my moral qualities, for which only people who really know me can speak.
  • Sites such as "about cats" of social projects or from the opera "open-source" are always served out of turn, with a completely different attitude and absolutely free.
    But not people who earn money, while saving them on their customers and their safety. Especially if they threaten me or are rude.
  • Receiving is my hobby, let me implement it, independently assessing the moral aspects of the issue. I do not earn on it and even usually do not earn extra money. I myself consider myself a law-abiding citizen, and I will remain so, the opinion of the trolls on this side of the issue does not affect this in any way.
Since I can’t ban in my post on Habré, I’ll just ask for it humanly: please leave me your opinion on my moral qualities. You will save both your and my time.
The desire to share with people "knowledge" and the time spent on the post while overpowering the desire to remove the hell out of this post in the drafts, but the balance is clearly broken.
Constructive and opinions on the topic of the article, i.e. I will listen to the discussion of the technical side of the question with great pleasure (and there will be free time and I will answer).

Source: https://habr.com/ru/post/258513/


All Articles