This website is available in your language Deutsch Close. Offering your audience to invest via Coinhouse allows you to generate significant commissions. Choose to pay in Euro or Bitcoin! An additional offer to improve your performance when customers pay a Premium subscription. Our platform compiles all your data for you in your dedicated space. Find click here performances and payments in 3 clicks. Do not hesitate to contact us, a dedicated team is available to answer your needs.
At this point we starting searching for attacks on DSA. Based on who the organizers are and half of the other challenges, we figured there was some paper we had to implement. Thankfully, we found a slide deck that summarized a bunch of attacks, one of which being ECDSA key recovery given known most significant bits MSB of k. In the specific case of the challenge, the most significant 60 bits of k would always be 0. There are a few differences in notation. As already mentioned, we used q as their n.
The secret key x is referred to as d in their slides. The least straightforward part was B on slide They split up k into the known MSB part a and the unknown part b , and they assign B to be the maximum value of the of unknown bits. All skill levels are encouraged to play! Skip to primary navigation Skip to main content Skip to footer. Teams or individuals can gain points for every solved task.
There are more points for more complicated tasks usually. The team or individual with the most points when the game is over is the CTF winner. Attack-defense is another interesting kind of competition. Here every team has their own network or only one host with vulnerable services. Your team has time for patching your services and developing exploits usually.
But in fact it appeared to be what was explained in the description "sumthing is not like the other", only consider bytes that only reside in this packet and concatenate sum them. They even gave us the perl script responsible for it. If you too are curious why this rotation worked: according to the yEnc spec , it is a "good rotation value for common binary formats, proof is in progress and will be done in the future, see: Hitchhikers Guide to the Galaxy".
If you don't know the reference shame on you , read this. Posted by StalkR at Labels: ctf , defcon , nibbles , scapy. Anonymous July 25, at PM. StalkR July 26, at AM. Anonymous July 27, at PM. StalkR July 27, at PM. Newer Post Older Post Home. Subscribe to: Post Comments Atom. Labels ctf python nibbles linux exploitation defcon cop go golang codegate race smpctf corruption dns iptables sha1 buffer overflow challenge crypto csaw ferm forensic freebsd got hack.
So now we've found a function that looks at the password and the connection id. That sounds like the hashing function to me and note that I'm using the word "hashing" in its literal sense, it's obviously not a secure hash!
I could have used a debugger to verify that it was actually returning a hashed password, but the clock was ticking and I had to make some assumptions in order to keep moving - if the the assumptions turned out to be wrong, I wouldn't have finished the level, but I wouldn't have finished it either if I verified everything. I wasn't entirely sure what had to be done from here, but it seemed logical to me that reverse engineering the password-hashing function was something I'd eventually have to do.
So I got to work, figuring it couldn't hurt! There are lots of ways to reverse engineer a function. Sometimes I'll try to understand the code, mentally, but I'm not super great at that. So I used a variation of this tried-and-true approach I often use for crypto code:.
Because I only had about an hour to reverse this, I had to cut corners. I reversed it to Ruby instead of C so I wouldn't have to deal with sockets in C , I didn't set up proper instrumentation and instead used Wireshark, and I didn't simplify anything till afterwards. In the end, I'm not sure whether this was faster or slower than doing it "right", but it worked so I can't really complain.
As I said, the first thing I do is translate the code directly, line by line, to assembly. I had to be a little creative with loops and pointers because I can't just use goto and cast everything to an integer like I would in C, but this is what it looked like. Note that I've fixed all the bugs that were in the original version - there were a bunch, but it didn't occur to me to keep the buggy code - I did, however, leave in the printf-style statements I used for debugging!
After I got it working and returning the same value as the real implementation, I had a problem! The value I returned - even though it matched the real program - wasn't quite right! It had a few binary characters in it, whereas the value sent across the network never did. It turns out, that function replaces all the low- and high-ASCII characters with proper ones the added lines are in bold :.
As you can see, it's quite long and difficult to follow. But, now that the bugs were fixed, it was outputting the same thing as the real version! I set it up to log in with the username 'grumpy' and the password 'grumpy' and it worked great! I didn't actually clean up the code until after the competition, but here's the step-by-step cleanup that I did, just so I could blog about it.
And a final cleanup pass where I eliminated the "bad paths" - things that I know can't possibly happen:. And that's the final product! Remember, at each step of the way I was testing and re-testing to make sure it worked for a few dozen test strings. That's important because it's really, really easy to miss stuff. As we saw above, after logging in, the real client sends "list users" then "print key". I went through and manually entered each user into the program, with the same username as password seemed like the thing to do, since grumpy's password was "grumpy" until I reached the user "duchess".
When I tried "duchess", I got the prompt:. The difference was that instead of passing the integer 1 as the mode, it passed 7. I submitted the key with literally three minutes to go. I was never really sure if I was doing the right thing at each step of the way, but it worked! If I'd had the presence of mind to realize that the username would always be the password, there's another obvious solution to the problem that probably would have been a whole lot easier.
The string "grumpy" as both the username and the password is only read in three different places in the binary. It would have been fairly trivial to:.
I reversed it to Ruby instead of C so I wouldn't have to deal with sockets in C , I didn't set up proper instrumentation and instead used Wireshark, and I didn't simplify anything till afterwards. In the end, I'm not sure whether this was faster or slower than doing it "right", but it worked so I can't really complain. As I said, the first thing I do is translate the code directly, line by line, to assembly. I had to be a little creative with loops and pointers because I can't just use goto and cast everything to an integer like I would in C, but this is what it looked like.
Note that I've fixed all the bugs that were in the original version - there were a bunch, but it didn't occur to me to keep the buggy code - I did, however, leave in the printf-style statements I used for debugging! After I got it working and returning the same value as the real implementation, I had a problem!
The value I returned - even though it matched the real program - wasn't quite right! It had a few binary characters in it, whereas the value sent across the network never did. It turns out, that function replaces all the low- and high-ASCII characters with proper ones the added lines are in bold :. As you can see, it's quite long and difficult to follow. But, now that the bugs were fixed, it was outputting the same thing as the real version!
I set it up to log in with the username 'grumpy' and the password 'grumpy' and it worked great! I didn't actually clean up the code until after the competition, but here's the step-by-step cleanup that I did, just so I could blog about it. And a final cleanup pass where I eliminated the "bad paths" - things that I know can't possibly happen:. And that's the final product! Remember, at each step of the way I was testing and re-testing to make sure it worked for a few dozen test strings.
That's important because it's really, really easy to miss stuff. As we saw above, after logging in, the real client sends "list users" then "print key". I went through and manually entered each user into the program, with the same username as password seemed like the thing to do, since grumpy's password was "grumpy" until I reached the user "duchess".
When I tried "duchess", I got the prompt:. The difference was that instead of passing the integer 1 as the mode, it passed 7. I submitted the key with literally three minutes to go. I was never really sure if I was doing the right thing at each step of the way, but it worked! If I'd had the presence of mind to realize that the username would always be the password, there's another obvious solution to the problem that probably would have been a whole lot easier.
The string "grumpy" as both the username and the password is only read in three different places in the binary. It would have been fairly trivial to:. That would have been quicker and easier, but I wasn't confident enough that the usernames and passwords would be the same, and I didn't want to risk going down the wrong path with almost no time left, so I decided against trying that. This wasn't the most exciting level I've ever done, but it was quick and gave me the opportunity to do some mildly interesting reverse engineering.
The main idea was to show off my process - translate line by line, instrument it, debug till it works, then refactor and reduce and clean up the code! Save my name, email, and website in this browser for the next time I comment. Running it If you wnat to follow along, I uploaded all my work to my Github page , including a program called server. Hello If you look at a packet capture of this, you'll see that a connection is made but nothing is sent or received.
Then it just sits there. Connection IDs and passwords I surmised, based on this, that the connection id was probably random it looks random and that the password is probably hashed poorly and not replay-able that'd be too easy.
Reversing the hashing function There are lots of ways to reverse engineer a function. Here we split the given string by! For example, base64 uses 64 characters to encode since 2 to the sixth power is 64, each 6 bit is an element that corresponds to a printable character. Three bytes have 24 bits, corresponding to four Base64 elements, so three bytes are needed to represent four printable characters.
The printable characters in Base64 include the letters A-Z, a-z, numbers that are 62 characters and two printable characters differ in different systems. Similar to base64, base32 uses 32 characters to encode since 2 to the fifth power is 32, each 5 bit is an element that corresponds to a printable character.
The challenge details can be found in the data.
Agenda ○ Defcon CTF ○ Defcon Quals ○ The Score Board ○ Powtent Pownable ; 3. Defcon CTF ○ One of the most prestigious CTF ○ Qualification to. I was one of the Tea Deliverers at DEF CON 29 CTF Quals. tags: crypto. solves: Reversing. For Tania, the handout consists of a single file: an x86_64 ELF binary. Looking at the references to.