My intros are getting thin...
Break Main
continue
Main is very simple, call login function
get sn looks very simple:
INT looks interesting. It appears to be calling a function at 0x10 (at 4552), unnamed similar to the previous challenge. Looking at memory, there doesn't appear to be much there, just \x3041
Which just returns us right back into the INT function... why?
After we complete INT, we return back to getsn
Interestingly, it looks like we return to puts, and not getsn
It looks like puts here will modify a few registers, jumps backup to the top, and will end up calling INT again, and this loops. So I'll break just after the jnz and continue through the loop.
Once out of the loops I step through the remainder, and I am put back up towards the top of login function, at 450c, which is confusing to me, because we continued past that.
I reset the program, stepped through again, and this time the behavior is different. When I reset again, it's different a third time. I am assuming this is some developer fun that is meant to confuse me. However all of this occurs before the password prompt, so I'll remove my breakpoints for getsn, and then continue right into the password promt, and step through from there.
RESET
continue
input test password
Looking at memory immediately after prompt, I see my password stored at 0x43ee. I do not see a register pointed to it; however, sp is pointed to 43e2, just before it.
Stepping through we immediately add \x06 to sp and change sp to point two bytes before my password location.
When we ret back to login function, for some reason sp changes again, and this time, it is now pointing to my password. I'm not sure how a ret instruction changed sp here... BUT we then move sp into r15, and call the test_password_valid function.
Once in the test password valid function, the first thing I notice is that there are no cmp instructions. So I'll have to pay extra close attention as I step through.
No we decrement sp and then more \x00 into -4 r4, which is where sp is pointed.
We then shove fffc into r14, and add r4 to it to make it 43e8, which is where sp is currently pointed.
push r14 and r15 and \x7d then call int
As I step through this test password, I see nothing testing my password. and then I eventually exit, where it tst r15 followed by a jz. So I need r15 to equal 1 in order to unlock the door.
So I decide to reset, and pay extra attention to r15, and try and determine how it is set. It doesn't appear to be comparing against a string that I can tell.
RESET
Walking through, it looks like the last time r15 is set, is at 4470, where we move -0x4(r4) into it. Which is zero at the time. So I reset, and pay special attention to r4.
RESET
I notice that r4 is ultimately set via this instruction.
Since it nulls out that byte, I'm currently trying to think of says that I could possibly get that byte to by \x01 after that set.
After a few more rounds, I can't figure out how I can affect r4, it just doesn't look like it is comparing it against a password, and that it's just hard coded to null out r14 and then tst against that. And so I start looking for other options rather than trying to cmp the passwords together.
After a little bit, I notice that the address space where the instructions are executing are after the memory location that the password is stored—and not tooooo far after. Soooooo, I'm currently thinking overflow and execute jmp 4528? Or fill the buffer with nops all the way up to 4528?
So I reset, and throw a million As into the prompt.
So now I step through, hoping that it attempts to execute instruction 4141 and crashes. No luck on the attempted overflow as there is no 4141 execution attempt.
I finish stepping through, fail the check obviously, reset, and try the same thing again. 60x As into input, and try again.
Except this time I run into this...
If I'm looking at the state at the time of crash, r4 is 0000, and its trying to write -0x4(r4) to r15. Which doesn't exist.
Somehow, r4 has changed?
Reset. Try 60x As again?
This time it looks happy
After many attempts I was unable to get it to crash :(
After MANY attempts of stepping through execution, I came across this...
At the very end of execution, AFTER it was already put "This password is not correct", we jmp to 443c,
execute a bis instruction, then execute stop progexec function.
Buffer overflow back on the table!
So I reset, fill with As and check to see if it can control 443c
BOOM, crash, now, I just need to replace the nops with call 0x4446?
So new pass, 40x nops with 1x b012 5244, hopefully I get endian correct first try...
So here is memory after input:
I remove all break points until right before the ret out of login (when we execute the nops).
And then I slowly step through and watch the current instruction.
Hmmm
Crashes.
Ok, so now I'm thinking ditch the sled, and land b012 5244 RIGHT on 443c.
My password is stored at 43ee, so 18 buffer chars, and then b012 5244?
RESET
new pass
Hmmm
My stack pointer is located at 4141... so I did something wrong. My hexi math is off.
I clearly have too many As.
So after manually adjusting where I put my instruction, I just put in all hex chars to determine where it is attempting to execute.





























0 comments:
Post a Comment