• Welcome to Valhalla Legends Archive.
 
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - herzog_zwei

#1
Quote from: Ringo on November 13, 2008, 01:31 AM
I can't see why, once we figger out how to generate the responce to 0x05 plus the new encryption keys, why we can't just hardcode the requests vs responces, like before.
Basicly, If Checksum(Request) = X then send Y -- should be as simple as that, thank's to blizzards wunderfull imagination.
Figgering out how to generate the responce to 0x05, should be pretty easy -- you could set up an array of buffers containing all the value's you know go into it, then brute force every combination possible untill you get a matching value to that seen in 0x04.

It's only true in theory but not in practice.  0x05 is a challenge and 0x04 is the response to verify that the challenge was computed correctly.  It also changes other things, one of them being the pad.  The computation of 0x05 is different in each module so you're not going to have much luck brute forcing a 128 bit challenge (nor would you want to) when the modules change every few hours.  So module 1 might compute 0x05 as X^2+5 while module 2 computes it as sqrt(X+3)/2 (it's much more involved and complicated than that but you get the idea).  0x04 is SHA1(f(0x05)).  One other improvement to this version over earlier ones is it attempts to foil replaying of responses.  Other than those, the protocol remains the same as before.  Things like these are the reason why I've said not to worry about how to compute checksums, what hasher to use, what protocol to use, what encryption scheme to use, etc., because it is all dependent upon the module they give.  A generic warden responder won't work in the long run; the specific warden module's code has to run or be analyzed at some point to get the correct response (which for now can mostly be replayed).
#2
It's been a long time since I've looked at Warden (maybe a year?) but other than the info that iago has given out, the rest of Warden can't be discussed as Warden itself.  Some of it may have changed since then but it should be pretty close.  The Warden engine is just an infrastructure that loads up the initial mini-programs into memory and executes queries specific to the modules loaded up.  In order to talk about the Warden modules, you have to indicate which module it is since all the parsing is done inside the module and not in the Warden engine itself.

Initially Warden didn't contain checksums in the 02 replies but I think it's standard in all the Warden modules now.  I believe all the Warden modules for all the games used to be the same but all compiled differently and have different hashes (WoW Warden modules used to contain the detection methods for D2 and even contained the D2Client.dll string).  Generally there are hundreds/thousands of modules for a given version of the Warden modules and each one is compiled differently and the 02 protocol for each is different.  The 02 format I've seen has always been 02 <cmd1> <cmd2> ... <cmdn>, though they can change it at any time.  It took a long time, but they eventually switched it up so cmd1 ... cmdn weren't always in the same order, and they eventually split it up so each packet won't always have all n commands (it'll be n1, n2, n3, etc commands per packet out of m total queries).  The number of queries I saw for SC was around 2-4.  In D2, there are probably around 10-20.  For WoW, there were probably over 20-30 when I last checked.

How the to encrypt/decrypt messages, perform hashes, calculate checksums, etc is irrelevant, as it is all described in the Warden module and can change at any time.  I've never seen them change the encryption/decryption routines but they've modified the other stuff in the past.  The other protocol commands (00, 01, etc) can be changed as well so you can't assume those will remain the same after loading the initial module.  That's the beauty of it and why it's tough for most people to figure out a safe, general solution to it, and it's also why it's a big security concern since it's running code that you generally won't be able to check (nor will file scanners detect any malicious code since the format isn't coded into the virus scanners).  From what I saw, they've implemented enough in the Warden engine that it'd be hard for a man in the middle attacker to inject their own malicious Warden module into your client.

In WoW, the session keys from both the server and the client are used to initialize the initial RC4 tables.

The SHA1 used for initializing the tables is standard.
#3
Quote from: Don Cullen on October 22, 2007, 06:25 PM
How would I best determine whether my code is NAT unfriendly? Also, how would I make my router be NAT friendly?

The key to designing a NATP friendly (as much as possible) UDP protocol has to do with:

QuoteI believe most transparent NATP implementations open up a random port on the initial outbound UDP packet and incoming UDP must have a matching destination IP/port of what was opened on the router and a matching source IP/port of the initial UDP packet sent to. 

Most UDP based games probably don't follow that rule so you have to use other routing tricks like port redirection and forwarding on the router.

A simple test to make sure your code is NATP friendly (assuming you have a router that implements what I described) is to have one side of the network NATed (internal) and the other side normal (external).  Have your program run on the NATed side (making sure the program initiates the connection to open up a random port on the router) and set up a data reflector/echoer on the other side to send back the data.  If you receive the reflected data no matter what random port is opened on the router, it's as (transparent) NATP friendly as you're going to get.  You should not have any code on the client that expects data to be received from any specific port nor embed local/internal IPs/ports to try to traverse the NATed network (some protocols do this and IMO is the wrong way to do it due to security issues and requiring proprietary routing code, not to mention it doesn't always work).

Cheap routers generally don't give you much control over NAT so you'll need to play around with it to figure out how their NAT is implemented and work around it.  Because most peer to peer UDP multiplayer (with more than 2 players) based games weren't designed with NAT in mind, you'll likely need to resort to port forwarding and/or redirection on the router.  For a single player behind NAT using a game that locally binds to a static port A, you can use port forwarding of port A between the external and NATed side.  For multiple players in a game that locally binds to static ports but the game server doesn't care about which port the datagram was sent on, you can redirect the ports and forward them based upon the redirected port on the external side and the internal IP on the NATed side.  For games that aren't NAT friendly, dynamically bind, or expects data sent to the server came from a specific port, your only choice would be to use direct connection or DMZ for single player and multiple IP NAT/forwarding for multiple players.  If your router supports UPnP, you can implement that to dynamically deal with port forwarding.

If you have an old machine lying around with nothing to do, set up Linux/BSD on it to do the routing/firewalling.  If you know what you're doing, you can fit everything you need onto a floppy disk (harder to do) or CD-ROM and not even have a HDD/monitor/keyboard/mouse installed.  You will need two NICs though, one for each of the internal and external sides.
#4
Since the same code works for some but not others, it's likely routing/NAT/firewall issue.  Disable any firewalls you have on your OS and connect your machine directly to the modem to avoid any problems that might be caused by the router.  If that works, your network and/or your code might be NAT unfriendly.  I believe most transparent NATP implementations open up a random port on the initial outbound UDP packet and incoming UDP must have a matching destination IP/port of what was opened on the router and a matching source IP/port of the initial UDP packet sent to.  If this isn't the behavior you want, you'll need to do more sophisticated routing/port forwarding.

You mentioned that sometimes you see UDP packets and sometimes you don't.  UDP is unreliable so when resources are low, UDP packets have a higher chance of getting dropped compared to other types.  You should run the code without any other heavily resource (CPU, network) intensive programs running to make sure this isn't the problem.
#5
Quote from: betawarz on June 05, 2007, 04:17 PM
According to Saren, from bwhacks.com:

Quote
This is a very lite-version of warden that actually reports (believe it not) the vm memory size of Starcraft along with some other data (version number, operating system, etc tied to your cd key + account) whenever you log into battle.net. It's been known for a while.

It has really nothing to do with preventing hacks at all. They added a separate 'protection' for that.

He doesn't know what he's talking about.  What he's describing is more like the system info extrawork.  The warden mods being used are the latest or near latest full blown ones; they're the same ones (in functionality) as WoW.  There are thousands of warden mods and from what I've seen, none give the same hash, even though some are completely functionally the same as another mod.

Quote from: Joex86] link=topic=16758.msg169998#msg169998 date=1181577661]
Quote from: UserLoser on June 10, 2007, 12:54 PM
Funny that people release working versioncheck then this is enabled? ::)

Thank you. You do not know how happy I am to know I'm not the only one in the world to make that connection. Until this, apparently I was.

Quote from: ·RealityRipple· on June 11, 2007, 01:54 PM
I didn't want to say "I told you so". But I did, and I'm sorry I insulted you, iago, but I ended up being right anyway...

Before you go on blaming people and making accusations without much evidence, consider these:

1. Currently, Warden is checking for at least 3 public hacks.  It is not some "lite" warden mod enabled just to thwart bots.  Those hacks were released a few weeks before Warden was enabled.  A hack with a release date very near the date that rob/warz released their code isn't detected.

2. Blizzard needs sufficient time to figure out how to detect the hacks, create/run it through their warden mod polymorpher (to generate thousands more warden mods that are functionally similar), and test it to make sure the hacks in question are detected and doesn't give false positives.

3. Warden is supposedly made by a third party, not Blizzard.  If the warden mods and detection queries are still outsourced, it'll delay it even further.  rob/warz released their lockdown workaround around June 2nd.  Warden was enabled on June 5th.

4. Usually it takes weeks to months after a certain hack is released before they even get Warden to detect it.

IMO, it was just coincidental, as iago said.  Even though it'd only take a few minutes to figure out how they can use Warden to detect those hacks, it'd probably take longer to sign off on the paperworks so they can do it and put it up on the servers (the Warden mods can contain arbitrary code that can make it do anything so they'll need someone to review it to make sure a disgruntled employee doesn't put in anything bad).  A two day emergency Warden response is possible but I don't think it's likely (unless it's for WoW and they can't get an emergency server patch ready).

Generally, new Warden detections only flag people and they'll ban them later (few weeks or a month later).  They've skewed from their norm lately for D2 and now SC.  They've yet to ban the people they've flagged in D2 for over 3 months and now with SC, they're notifying people right away by giving them losses.  Bannings for SC may come later but I suppose they're relying on the element of surprise/inexperience right now and giving near immediate feedback on what hacks are detected.

Quote from: Ringo on June 06, 2007, 06:35 AM
I already have a working D2WS, so a BNWS should be just as easy, altho im still having afew problems with warden over bnet :)
When finished it should beable to support up to 80+ clients :)

You're playing with fire here, as it's easily detectable and I'm surprised they haven't taken action yet.  Even if they don't specifically target it soon, there are other hacks they could target that'd hit this in the crossfire.
#6
General Programming / Re:Unbreakable Encryption
March 17, 2004, 11:28 PM
The encryption itself may be unbreakable and secure,  but as Adron pointed out, other parts of it isn't.  It'd be easier to tap it before it is encrypted or after it is decrypted.  You could also try to hack into the computers that sends/receives the messages, social engineer the couriers that give messages to be sent/received to the operators, look through the trash to try to find the hardcopy of that message, break in and steal the keys, etc.

Quote from: Adron on March 17, 2004, 03:52 PM
What they seem to be doing is use something similar to spread spectrum modulation where you modulate a signal so that it's lower than the noise level, until you apply a filter to it where the filter is the "key". That's still brute forceable, all you need is some equipment that can record the transmission including all noise.

That was my initial thought but I think what they mean is that there is no known equipment that can record the transmission perfectly w/o knowing the right energy levels to look at.  So for each message, you'd only be able to try out a small number of keys before the signals disappear.  If only one key was ever used, eventually you'll be able to brute force the key but you would only be able to read future messages, not past ones.
#7
Nice info.  I don't disagree with you that it's improbable to do for almost (maybe even all) 100% of the population with today's technology.  However, adding the challenge at minimal cost to your time will make it improbable for many future technologies to come.  If it took weeks to add in the challenge, it wouldn't be worth the effort for a simple game.

That page did mention that differential cryptanalysis was effective against 1 of the MD5 rounds.  Perhaps a better brute forcer will do it based upon analysis of the rounds and not the finalized digest (it probably wouldn't be that easy otherwise people would have come up with it by now, but it's something to consider).

Off topic, but if the need arises, md5sum is a great tool to use for finding duplicate files (mainly email attachments) under different file names on corporate file servers.
#8
K: That sounds more like Adron's adaptation than Storm's: Storm's used symmetric key encryption with all parts of the key and message generated by the same client.

Quote from: Adron on March 17, 2004, 03:41 PM
I still think someone producing collisions for a 128-bit hash is very unlikely to happen. I base that on my personal experience with cracking des (56-bit) keys for personal somewhat financial gain. Consider the amount of time and memory you'd have to spend...

Also, every client should generate a piece of the challenge, so the server + a client can't conspire to use hashes with collisions.

You could feed back the resulting random number chosen by all clients back into the challenge so no one client will have absolute say over what the challenge is.  The very first roll will need to be thrown out since it'd probably be seeded by one of the clients or set to an initial value (to keep the protocol simple).

As impossible as it might seem, someone with lots of cryptography knowledge might be able to produce a good attack on it.  You're also looking for colliisions of any hash in the number space, not just for a specific hash, which was probably what you were doing with DES.  Also, to conserve memory, you don't have to store all of the hash; just enough to recognize that there might be a match so you can redo the calculation again to see if there really was one.

There was a seemingly impossible challenge I had years back when 286/386 machines were top of the line, 20-80MB HD space was godly, and 640K of memory was typical.  The challenge was to come up with all solutions of the combination of N numbers ranging from 1 to x that added up to S.  For some sums of S, there were millions of solutions which would take many MBs to store on disk.  Typical bruteforcing of it would have taken months and consume lots of memory.  However, my intuition told me ther was a much better way of bruteforcing it than the traditional one so I had a go at it and was able to come up with something that could produce all solutions (even if there were millions) in maybe 40 seconds at worst and store all of it in under 500K (not sure how much memory it really took up since I never checked but it definitely didn't use up all of the 640K).  I did this by saving part of the state at every i iterations and since what I was doing could be computed fast, I could come up with the next j iterations in real-time.  I implemented it in ASM, C, and interpreted BASIC (the BASIC version ran much faster than the typical bruteforcing method done in C).  Bruteforcing cryptography is orders of magnitudes harder than this but it shows that just because most people think something is not feasible doesn't mean it really is; it might just require a different look at the problem.  An example is 512-bit RSA was once thought secure but later on found that 2048-bit should be used, not because computers have gotten faster but because there was an attack on it that could weaken it greatly.
#9
Quote from: Adron on March 16, 2004, 04:51 PM
Your statement of the possibility to brute force numbers that match a hash is a weakness of every system like this, including virtually every system for signing electronic messages. The assumption you'll have to make for a cryptographically secure message digest algorithm (which is what you need here) is that it's unfeasible to produce two messages that hash to the same value.

It is not feasible to do it in real-time, but it is feasible to have machines crunching numbers for months to get a few collisions that could be used later on to cheat the system.  Use a challenge/salt and you will solve multiple problems.  It'd take 10 minutes to modify what you have to make it magnitudes more secure than what it is now, yet you're against such a change.  Why?  If you've ever been to a casino, any visible marks on any card in any deck is tossed out because it has an identifying feature that you can correlate with a card value.  No matter how remote the chances of getting that card is, people can still figure out that the card with a torn corner on the top right edge is the king of hearts.  What you're suggesting w/o a challenge poses the exact same problem (though the chances of getting the card is even less likely); if someone sends hash H1, it will always represent N1 (or possibly others as well).  Add the challenge and you'll prevent precomputation of collisions and knowing what someone else's number is before it's given to you because H1 will only represent N1 once in a long while, N2 once in a long while, etc, rendering knowledge of H1 useless for all practical purposes with today's computers.  Unix and many other systems have salts on passwords to lessen the chances of password correlation for users that have the same passwords; it wasn't done to add more bits to the hash because adding more bits won't help any more, though it could make the hash less effective.

Would someone be willing to spend time to exploit that flaw?  Not likely if a good digest was used.  However, if money or access into a system were at stake, don't underestimate what others might do just because you're not willing to do it.

BTW: your method is probably the best one mentioned in this thread since it has the promise of rendering accomplice clients meaningless.  You just need to throw in a new challenge to it with each roll (you've already spent hours developing it, what's a few more minutes?).
#10
Quote from: Adron on March 16, 2004, 07:35 AM
The risk of having collisions isn't something you'll typically have to worry about. They'll be few and far between. If that was an issue, you'd want to never type a longer message than 16 characters if it was going to be signed with an algorithm using a 128-bit message digest. This way, you cannot change your random number based on knowledge of the random numbers chosen by other people.

Yes, it's not typically what you need to worry about, but in this case, it would be something you should avoid.  Since you are not presenting any sort of challenge, a hash of X will always mean it can be N1, N2, N3, etc (though hopefully it will stop at just N1).  With a challenge, X can represent N1, N2 on the first roll, but the same hash of X in the next roll with a different challenge would likely mean it's not N1 nor N2.  With enough incentive, someone can brute force 1024 bit numbers (or whatever the range you choose) until they come up with a list of say 20 collisions and use those hashes sparingly to lessen the chances of being caught.  If you use a 128-bit number with a 128-bit digest, you weaken it further since there's a better chance of finding collisions.  If the range of the final answer will end up being from 1 to 6, having 2 possible outcomes could give you a big advantage.  The better choice would not be a bigger range on the random number but to present challenges for each roll while using a reasonable range for the number.

Quote from: Adron on March 16, 2004, 07:35 AM
"... you will probably also want to include each players choice/move/whatever in the hash that is shared with every other player...."

(Taking it out of context since you're using it to make the PRNG better; I'll use it in this discussion to mean it's a challenge).  That'd help out a bit more though you could still brute force the space based upon number (choice/move) concatenate number.  Usually the scenario you'd want to cheat in will only be of 1 or a small set of choices so adding that to the hash is still weak.  Use a new challenge for each roll; it's simple to do and would improve it significantly.

I don't quite understand what you're trying to say with it taken in context.  I thought you meant all clients negotiate a seed at the beginning of the session to feed into a global (meaning all clients use the same seed in the game's PRNG, hence the parallelism) PRNG when taken along with the other parts of the method you suggested, though the "and then share your move with the others upon receipt of their move+number hashes" part seems to suggest it's done for each roll.  I'll take it that I misinterpreted it earlier and it's not being used as a global seed for all future rolls (which is probably why you quoted it back).

If you're worried about a weak PRNG from each client, it's easy enough to add entropy from other sources to the PRNG (amount of network traffic you've received, where your mouse is, etc) so prediction of the next number from a client shouldn't be as big an issue.
#11
Quote from: Adron on March 15, 2004, 10:09 PM
Ah, the random number wouldn't be in the range 1-6, it would be a large, say 128-bit random number. With that design, noone has the potential to cheat as far as I can see. The properties of the random number and the hash function must be such that the random number cannot be determined from the hash you receive in the first step.

Be careful that you don't overdo it.  If you're going to use a 128-bit hash like MD5, you wouldn't want a 128-bit number since it raises the possibility of having collisions.  Also, adding more bits might not change the result (such as if you do something stupid like use say mod 8 to figure out a random number between 1 and 8 ).  If someone does find out collisions for it, they could delay their final response for the random number until it receives the answers from the other clients and send out the number that would benefit it more.

What really should be done is to present a challenge for each roll.  The challenge would make it so collisions can't be predetermined so they'd have to be figured out on the fly.  If the hashing algorithm used can do 100 hashes/sec, choose a range on the numbers that would require minutes/hours to hash a small percentage of that range.  So using MD5 on numbers with a 31 bit range would probably work as long as you present different challenges for each roll.  You'd have to make sure clients don't try to reuse the same challenge multiple times and you'd probably want a challenge be sent by a different client each time and isn't the roller.  You could make it a feedback based challenge that would be updated with the summation of numbers from the previous roll so no client can easily force a particular challenge (except on the very first roll).  You should also impose a reasonable timeout period (factoring in latency, packet loss, etc) so anything received later than say 15 seconds would be invalid and needs to be rerolled.  

You probably wouldn't want to use the resulting number as a seed for a psuedo-random number generater for all subsequent rolls (though it could be used for the x rolls (where x should be a low number, with 1 being preferred)) since a cheater could determine what the next roll(s) will be so they'll be able to bid less if they're gambling and has no chance of winning...  or they could enter a defense mode because if an enemy client were to attack on the next move, they'd do major damage to whomever they chose to attack.
#12
Quote from: Adron on March 05, 2004, 10:57 AM
Use a fully interconnected peer-to-peer topology.

Everyone generates a random number.

Everyone generates a hash of their random number.

Everyone sends their hashes to everyone else.

Upon receipt of everyone elses hash, everyone sends their random numbers to everyone.

Everyone verifies that the received random numbers match the hashes received before.

A new hash generated from all the random numbers is either used as the resulting random number, or as a seed for a random number generator that runs in parallell on all machines.

Whether you can use a random number generator that runs in parallell or have to redo the procedure for each random number depends upon whether players can make better decisions (cheat) if they know what the next random numbers will be.

If players can make better decisions knowing more about the random numbers that will follow, you will probably also want to include each players choice/move/whatever in the hash that is shared with every other player first, and then share your move with the others upon receipt of their move+number hashes.

This is design is intended to mimic the functionality of putting everyones secret move/number into a sealed envelope in an urn and only opening them all when everyone has submitted theirs.


This isn't quite the same as what St0rm.iD's; it's weaker since all clients have the potential to cheat in your solution while in the other, the server has an easier time cheating (clients may be able to cheat if they can guess the contents of the message based upon the key, which might not be too difficult for a small message with a known set of ranges on the data).

You'd have to add some sort of challenge to it or else the hash will basically be the same as the number (after doing a reverse lookup from a precomputed table, which would likely only be the size of 0..5 or 0..INT_MAX, an amount that'd be easy to store in memory or on disk, or possibly be produced on the fly (0-5)).  Clients can just wait for others to answer or some maximum amount of time (so if there were 2 cheating clients with the same approach, it wouldn't be obvious that there are cheating clients waiting for others to answer) before sending out a hash of a number that would influence the roll.
#13
Quote from: St0rm.iD on March 07, 2004, 01:04 PM
This was discussed on another forum I used to frequent. Here's the solution that was obtained.

Player A wants to roll the dice. Player B is his opponent. When A rolls, he randomizes a list of possible outcomes (1 through 6), encrypts them with a secret key K, and sends the list to B (B doesn't know the key). B replies with a random index on that list. A replies with the decryption key. A and B now know the result, and neither can control which one is picked. Of course, sanity checks on the list will be performed by B after he decrypts the list (to make sure the list doesnt say 6 6 6 6 6 6 for example).

This is also somewhat flawed.  With such a system, the server can generate keys that would decrypt the randomized list into a different list than it had originally intended.  Since there aren't that many possible outcomes of a die, you could come up with multiple keys beforehand for certain encrypted messages that would give you multiple answers that would pass sanity checks for B.  Since your encrypted data is so small (likely only 6 bytes long), encryption wouldn't be as effective no matter how long your key is.  To make it more effecitve, you'd want to add extra junk to the data (which would need more bandwidth requirements) and include some sort of hash/checksum (on the key and message) to lessen the chances of finding keys that decrypt it into multiple lists.

An easier approach (for more than two rollers) would be to have the server generate a random number and distribute it to all clients.  Each client will then send back a random number to the server.  Once the server receives a number back from all clients, it will send all clients the random numbers generated by all clients.  Each client will have to verify that the number it sent the server is indeed what the server said it is; if so and no other clients object to their numbers, it can add all the numbers up and mod 6 it to get a final answer.  The protocol is fairly easy to do but it'd require more fault tolerance for when clients get disconnected.

With the proposed approach (and possibly many other ones), you'd have to make sure that the one running the server doesn't also have some accomplice/non-existant client that'd influence the resulting answer, or that the server is kicking certain clients off to come up with a favorable roll.  This would be impossible to guarantee but precautions can be made to alleviate the problem.  For example, to combat the server kicking clients to come up with a favorable roll, you could nullify that roll.  To combat servers that stack the results with its own clients, one solution would be to maintain a list of cheating servers/clients on a central server (but if you're going to do that, why not just make a central die rolling server that all clients connect to (clients are grouped together so all rolls from a client will cause the server to send the roll to all clients in the group), thereby eliminating having to come up with elaborate schemes to try to prevent cheating).