I have this code that I need to use to perform a ret2libc
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buf[256];
printf("buff is at:%p\n",buf);
printf("%s",argv[1]);
strcpy(buf, argv[1]);
printf(buf);
}
I compile it as gcc -m32 -fno-stack-protector ./rt2.c -ort2
and than start it with a cyclic patter (generated with pwntools) as follows:
./rt2 aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaac
I was expecting a segmentation fault at the end of the main...it instead happens at the end of the strcpy...actually what happens (by looking with gdb) is that at the end of the strcpy the ESP points to 0x6361616e which is part of the input string.
Another strange thing is that printf before the strcpy does not print out anything
this is the result of the execution:
$ ./rt2 aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaac
buff is at:0xffffcf20
Segmentation fault (core dumped)
$ dmesg | tail -1
[ 4432.704356] rt2[3280]: segfault at 6361616e ip 00000000565555e0 sp 000000006361616e error 4 in rt2[56555000+1000]
Even more strange, to me, if I comment the strcpy the printf before of it does instead print out...
I tried to execute it with with valgrind and it confirmed that at some point ESP got overwritten.
valgrind ./rt2 aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaac
==2735== Memcheck, a memory error detector
==2735== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2735== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2735== Command: ./rt2 aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaac
==2735==
buff is at:0xfeffce80
==2735== Warning: client switching stacks? SP change: 0xfeffcf98 --> 0x6361616e
==2735== to suppress, use: --max-stackframe=1684115926 or greater
==2735== Invalid read of size 4
==2735== at 0x1085E0: main (rt2.c:20)
==2735== Address 0x6361616e is on thread 1's stack
==2735==
==2735==
==2735== Process terminating with default action of signal 11 (SIGSEGV)
==2735== Access not within mapped region at address 0x6361616E
==2735== at 0x1085E0: main (rt2.c:20)
==2735== If you believe this happened as a result of a stack
==2735== overflow in your program's main thread (unlikely but
==2735== possible), you can try to increase the size of the
==2735== main thread stack using the --main-stacksize= flag.
==2735== The main thread stack size used in this run was 8388608.
--2735-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--2735-- si_code=1; Faulting address: 0x6361616E; sp: 0x82d8cf20
valgrind: the 'impossible' happened:
Killed by fatal signal
host stacktrace:
==2735== at 0x5803F9F6: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable (lwpid 2735)
==2735== at 0x482A4D0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-x86-linux.so)
I also tried to compile with as: gcc -g -m32 -fno-stack-protector -z stack-size=4194304 ./rt2.c -ort2
but nothing changed