목록Wargame Write Up/pwnable.kr write up (5)
밍키의 마법세상

랜덤으로 돌려서 0과 xor한 값이 deadbeef면 flag를 출력해주는 바이너리이다. 여기서 중요한 점은 rand는 매번 바뀌는 값을 지정해주지 않으면 매번 같은 값으로 계산을 해준다. 그러므로 같은 값을 알아내면 random값을 구할 수 있을 것이다. gdb로 까보자. main+59번째 줄에서 cmp로 eax와 deadbeef를 비교해주는 부분을 찾을 수 있다. 이 부분에서 eax값을 봐보자. 6b8b4567이란 값이 들어가 있다. xor은 key ^ random = deadbeef == deadbeef ^ random = key 이므로 b526fb88 값을 얻었다. 마지막으로 입력을 받을때, 정수로 입력을 받으므로 그럼 이제 값을 넣어주면 될 것이다. 성공적으로 플래그를 따냈다.

아주 친절하게 C파일을 준다. overflowme에서 key까지 가서 key값을 조작할 수 있을 것 같다. IDA로 주소를 확인해보자. 둘의 주소 차이가 2C + 8 = 52만큼 차이나는 것을 알 수 있다. 그럼 익스코드를 짜보자. 성공적으로 플래그를 따내었다.

welcome 함수를 먼저 실행하고 login 함수를 실행한다. welcome 함수를 봐보면, name을 입력받는 scanf에서 BOF가 터진다. login 함수를 봐보면, passcode1과 passcode2를 scanf로 받는데. &없이 입력을 받아, passcode에 값을 저장하는 것이 아닌, passcode를 주소로 갖는 부분에 저장을 하는 것이다. 그러니 이 passcode에 다른 함수의 got 주소를 넣게 되면, passcode는 got의 그 함수의 주소로 바뀔 것이다. 적당히 바로 뒤에 있는 fflush_got주소로 넣어주는 게 나을 것이다. 이렇게 got를 바꾸면, int passcode1은 fflush_got가 될 것이고, scanf("passcode1") 은 scanf("fflush_g..

우선 인자가 1개 이상이여야 한다. 첫번째 인자의 바이트를 20으로 맞춰주어야 하고, check_password를 통해 나온 값이 0x21DD09EC여야 한다. 그럼 check_password를 봐보자! 인자를 받아서 int형 포인터로 바꾼뒤 반복문에서 20바이트를 4바이트씩 다섯번 읽어 res에 더해준다. 그럼 우리는 0x21DD09EC를 5개로 나눠서 20바이트짜리 인자로 넣어주면 될 것이다. 21DD09EC / 5 = 6C5 CEC8 21DD09EC - (6C5 CEC8 * 5 = 21DD 09E8) = 4 마지막 6C5 CEC8는 + 4 를 해주어야 한다. 그러니 "\xc8\xce\xc5\x06"*4 + "\xcc\xce\xc5\x06" 을 해주면 될 것이다!

pwnable.kr 에 접속하여 로그인을 한 후 시작해보자! 나는 putty를 활용하여 진행할 것이다! 시작 해보자! 우선 인자를 한개 이상 넣어줘야 하고, 정수형 fd를 만들어 첫번째 인자를 정수로 바꾼뒤 0x1234만큼 뺀다. 그리고 len에 read함수를 사용하여 값을 넣어준다. 마지막으로 "LETMEWIN\n"과 buf를 비교하여 같을 경우 flag를 출력한다. read 함수에 대해 짧게 알아보자! read(int fd, void *buf, size_t count); fd는 파일 디스크립터값, buf는 읽은 데이터를 저장할 버퍼, count는 읽을 데이터의 크기이다. 여기서 파일 디스크립터는 시스템이 할당하여 준 파일이나 소켓을 대표하는 정수로서 예약된 값이 있다. 0 : 표준 입력 1 : 표준 ..