echod bleeds... -by atlas
(One of these days I'm going to make atlas get his own blog, but probably not until I start posting more)
Program received signal SIGSEGV, Segmentation fault.
0xbfaedf4d in ?? ()
Finally, after weeks of teeth-gnashing I have been able to get echod to consistently bleed, yet some of the blood is my own.
(for those you not fortunate enough to understand it, this indicates that I have changed the instruction pointer to someplace in the stack where it doesn't belong... one or two steps from shell-access)
It's bleeding, not dead yet. I have to inject shellcode (in reverse for this vuln) before I can stick a fork in this baby.
I wish I could say "I finally got around to looking at it..." but I've been working on it ever since Def Con (many times only 1/2 hour at a time, which is awful). I have learned quite a bit, however, and have been intentionally taking my time, capitalizing on the opportunity to improve my skills (I've played and explored a bit. Big fun the "pay-for" guys might not get to enjoy as much). Still, I gotta get faster, even with the tough ones.
echod presents challenges, although much of my pain was self-inflicted. echod is multi-threaded, presenting oddities with both debugging and fuzzing. gdb would be piping along and suddenly it would inform me that it just thread-hopped and I was starting from a different location, working different logic. It became particularly difficult because I had my pseudo-fuzzer (it doesn't deserve to be called a real one) set in a loop most of the time... which I think somehow caused several threads to be pumping information into the binary, while I'm also attempting to debug and make sense out of the assembly. argggh! Aside from turning "0x0a" to "0x00" and splitting stings on "0x20", the string was pretty much straightforward, although the "reversing" functionality employed some logic I couldn't quite follow without stepping through it (and even then, it's up in the air).
That isn't to say that I didn't learn a great deal along the way.. You could say that I learned many things about reverse engineering, particularly threaded apps. Here are a few:
- Printing the dis/assembly is invaluable!
- Rather than avoiding "jump" calls to focus on the "meat", recognize that they are the structure. Capitalize on the opportunity to determine program flow. Draw the jumps with an arrow for each early in the reversing process
- Determine the "conditional statements" from the "jump" statements. Is it a "while (???) { }" or an "if (???){ } and what are the constraints? This helps determine where the "edges" of the program are
- "Ignore %reg, look around for meaning!" ie. Pay more attention to what memory location each register *represents*, instead of focusing on %eax specifically. Map this out on paper, being interested more in 0xffffffbe(%ebp) or 0x8(ebp) instead.
- Each sub has a finite number or variables (locals, parms, and heap)... know them. Label them if you can tell their purpose.
- For (%reg), look for %reg assignment BEFORE this line
- For %reg, look for %reg storage AFTER this line
So I sit down at a coffeeshop I don't frequently visit, because Skeletones (Coffee for the coming apocolypse!) is having a concert I'm too focused to enjoy. I end up sitting in 5 different spots throughout the night, making them hate the "bottomless mug" deal I chose, and being slightly distracted as the two employees mash right at the counter. I was expecting some wetware to come out but thankfully was wrong. After doing some Biblestudy (which is the real reason for my night out), I figure out that I left my reverse-dump hardcopy at work and they had all my scribblings and notes! SUCK BUTT! So, I tinkered and played. Probably the best thing, since I happened upon the "chink in the armor" by doing so. I continued having bad results until I changed approaches in fuzzing and reveng. more on that in a minute.
If this all seems a bit confusing, it's because I'm still somewhat unsure of what went wrong... I know that I was unable to produce consistent results when piping "perl -e" commands to netcat. I know I was able to produce some consistency with a total rewrite in perl. I also know that I've been rather cavalier with my fuzzing, which probably caused issues with consistency (not paying close attention to having multiple threads going at once, so long as I kept data pumping into my gdb/echod session for analysis. Again, ni puta idea!
This perl/bash combo was similar to what I used with poor results:
CX=1100; while true ; do CX=`expr $CX - 1`;echo $CX; perl -e "print(\"REV \" . \"\\x1\"x$CX);" | nc -v localhost 2000 ;done
I first started getting consistent results when I scrapped the command-line approach and used Perl's networking Socket interface to handle the network connectivity. Not as "slim" as using NetCat, but it works. And I was able to build the loop for fuzzing right into my perl-based sploit engine rather than the ugly bash code listed above. But consistency is key.
I have to take back all the evil wicked things I cursed about the author of echod. He may still be an evil bastard, but not nearly so much as I was giving him credit for. (sorry Visi)
Thanks to the nologin folks (thanks slow!) for helping me figure out the stack alignment oddities. Many thanks to Visigoth, Snit and the other kenshoto guys for the hours of wholesome fun ;D
I still have a few questions bouncing around:
* How do I get gdb to hold on to Display and Breakpoint settings between sessions (or perhaps simply preload them from a file at startup)?
* How do I get a service like echod to dump core? (a core dump is the contents of program memory at the time of a program fault. It allows a debugger to recreate the environment to better troubleshoot and correct issues)
Any comments can be sent to atlas@r4780y.com (thanks for the account, r4780y!)
@
0 Comments:
Post a Comment
<< Home