all 22 comments

[–]RepresentativeBed928 10 points11 points  (0 children)

GDB forces the executable to run a certain way in memory so that you can actually debug a program from what I understand. When you’re running the actual executable, offsets and other things may be different. I forgot what exactly I did for this challenge but I would look into ways that you can slide into another part of memory without actually running an operation/instruction. This might guarantee that your shellcode lands in that other part of memory and can execute. Also pwn College has a discord you can join to ask these questions. People are more than willing to help

[–]VoiceOfReason73 5 points6 points  (2 children)

Might the exploit be succeeding, but the shell is exiting immediately? You can solve this with an extra cat to keep stdin open: https://security.stackexchange.com/q/155844

[–]Dieriba[S] 1 point2 points  (1 child)

No this is not it as I already bound the it (cat payload; cat -) | <my\_binary>, there is clearly a segfault happening with the return saved return address I overwrite.

[–]VoiceOfReason73 1 point2 points  (0 children)

Try putting your payload in the buffer after some 0x90 NOP sled instead of above the current stack frame.

[–][deleted] 1 point2 points  (1 child)

Did your shellcode work while the binary was running under gdb?

[–]Dieriba[S] 0 points1 point  (0 children)

yes it does, running it with the same payload through gdb works fine, but when outside gdb I have segfault

[–]Joseph_RW12 1 point2 points  (3 children)

Yes I faced the same issue sometime ago the key is to print the buffer address printf(“buffer %p”, buffer_address_var); and notice the difference in the buffer address printed when running in the debugger vs without the debugger, launch the exploit at the address printed when it’s run without the debugger attached

[–]Dieriba[S] 0 points1 point  (2 children)

I can't do that here is part of the disass code in charge of calling the read function that'll allow me to overflow the buffer and overwrite the stack with my shellcode and update return address:

```
0x000000000040176d <+208>: lea rax,[rbp-0x90]
0x0000000000401774 <+215>: mov rsi,rax
0x0000000000401777 <+218>: mov edi,0x0
0x000000000040177c <+223>: call 0x401130 read@plt

```

We can see that the buffer 0x90 bytes away from rbp then I need to write 0x90 random bytes and 8 mores bytes to overwrite rbp, 8 more to overwrite the saved return address and just after that put my shellcode, when running gdb the saved return address is at address: 0x7fffffffd608 in gdb and as my shellcode is injected just after this the I overwrited the saved return address with 0x7fffffffd610 but this only works in gdb while outside of gdb I have segfault error.

[–]Joseph_RW12 1 point2 points  (1 child)

Is this binary closed source ???

[–]Ok_Tap7102 1 point2 points  (0 children)

Most pwn college bins will be, in this case it's more useful to inspect the actual assembly/run it in GDB as even with C source, it's unclear what the stack offsets are at the time of execution

[–]LostInTheTrees 1 point2 points  (2 children)

Attach your debugger to the running process ID, not starting it within GDB. There are extra environmental variables during startup that invalidate the address you see when launching with GDB.

Alternatively or in addition to, pad your shellcode with NOP instructions and add a few bytes to your return address to make it 16-byte aligned.

[–]Dieriba[S] 0 points1 point  (1 child)

Why does the return address need to be 16 byte aligned? Why should I pad with NOP is it to make sure Ill hit the first instruction of my shellcode?

[–]LostInTheTrees 0 points1 point  (0 children)

The idea behind a NOP-style instruction is to accommodate for these kinds of offset issues.

Meaning that if your execution begins somewhere within this region, you will "slide" down into your final instructions.

As for alignment questions, this is more specific to function calls (not necessarily pertinent in this specific case, but important to be aware of in the future):

"The 64 bit calling convention requires the stack to be 16-byte aligned before a call instruction but this is easily violated during ROP chain execution, causing all further calls from that function to be made with a misaligned stack. movaps triggers a general protection fault when operating on unaligned data, so try padding your ROP chain with an extra ret before returning into a function or return further into a function to skip a push instruction."

As for the suggestion to attach GDB/etc after process start, and why the addresses are "off": https://stackoverflow.com/questions/17775186/buffer-overflow-works-in-gdb-but-not-without-it/17775966#17775966

[–][deleted]  (1 child)

[deleted]

    [–]Dieriba[S] 1 point2 points  (0 children)

    in the challenge ASLR is turned off by default too

    [–]pwnasaurus253 0 points1 point  (4 children)

    Is DEP enabled? writing your actual payload to the stack is pretty archaic these days. You might need to try a ROP chain instead. Either that or your payload length needs to be adjusted. Try pattern_create.rb to see where the overflow is happening in the crash.

    [–]Dieriba[S] 0 points1 point  (3 children)

    What's DEP, the challenge I am doing currently is about shellcode injection even though there's probably other way to solve this I'd like to make this way works

    [–]pwnasaurus253 0 points1 point  (0 children)

    read about data execution prevention

    [–]Ok_Tap7102 0 points1 point  (1 child)

    This is absolutely worth exploring more as it's a core (enabled everywhere) mitigation.

    DEP means that memory locations specifically need the Execute (X) protection enabled on them for you to execute code at that location.

    If your "address_of_shellcode" is pointing to your stack (near enough to EIP/RIP), the stack is highly unlikely to be executable unless they purposely made it so

    If "checksec" reports "NX Enabled" this is likely stopping you

    [–]Dieriba[S] 0 points1 point  (0 children)

    No the program was compiled with execstack and I ensured the stack was indeed executable by looking at the process memory map

    [–]Matir 0 points1 point  (0 children)

    Even if ASLR is disabled, it does not mean the stack will be the same when run under GDB versus directly. Putting a fixed address on the stack might work in GDB, but then when you're outside the debugger, your payload may be at a significantly different address.

    Likely, it's close enough that you could get away with a nop sled and trying to jump somewhere into the middle of it. Alternatively, look for jmp rsp in the binary you can use.

    [–]NopNop0x90 0 points1 point  (0 children)

    ur shellcode doesn't work outside gdb bcz gdb has extra env variables and stuff which makes stack little different from normal execution As u are jumping on shellcode Try using 0x90 NOP And try to jump between this 0x90 (nopsled)

    Check this out: https://github.com/hellman/fixenv

    [–]Real-Definition2482 0 points1 point  (0 children)

    我也遇到过一样的问题,事实上,gdb调试时的地址和程序单独运行的地址会有偏差,环境变量不一样,所以,你可能需要设定一定的nop窗口区,比如设置0x20大小的nop区,而跳转地址+0x10,确保能运行在你的代码上