흠.. 한동안 다른 것을 하기도 했었고 해서, 이번에는 조금 어려운 문제를 풀어보려고 한다. bounty program alpha라는 이름으로 hitcon ctf final 2019에 출제되었던 문제이다. 사실 solver 수를 보고 포기할까 했는데 strtok 취약점을 이용한 문제같아서 도전했다. 

 

 이 문제는 wrapper와 bounty_program으로 이루어져있다. 먼저 wrapper을 보면 seccomp이 걸려있다. 

 

 

음.. 신기하게도 execveat 도 사용가능하고, sigreturn도 사용이 가능하다. execveat이 가능하면 그냥 쉘을 딸 수 있다. 

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+10h] [rbp-1110h]
  char value; // [rsp+110h] [rbp-1010h]
  unsigned __int64 v6; // [rsp+1118h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  init_proc(argc, argv, envp);
  memset(&s, 0, 0x100uLL);
  memset(&value, 0, 0x1000uLL);
  printf("Name:");
  read_input(&s, 0xF8LL);
  if ( strstr(&s, "LD") || strstr(&s, "MALLOC") )
  {
    printf("Danger!");
    _exit(-1);
  }
  printf("Value:");
  read_input(&value, 512LL);
  setenv(&s, &value, 1);
  my_sandbox();
  syscall(322LL, 100LL, "/home/bounty_program/bounty_program", argv, environ, 0LL, argv);
  return 0;
}

wrapper의 main에서는 Name 을 받아서 이를 인자로 bounty_program을 실행시켜준다. 

 

bounty program에는 상당히 메뉴가 많아서 하나하나 분석하지는 않았고, strtok이 있는 것을 보고 바로 이부분을 캐치했다. 따라서 strtok을 위주로 쉘을 따는 방법을 구상했다. 다음은 취약점 부분이다. (add type)

 

void sub_180E()
{
  __int64 size; // rsi
  int v1; // [rsp+4h] [rbp-1Ch]
  char *i; // [rsp+8h] [rbp-18h]
  char *s; // [rsp+18h] [rbp-8h]

  printf("Size:");
  size = read_long();
  s = (char *)calloc(1uLL, size);
  puts("(Note:You can add many types at the same time)");
  puts("(Example: SQLI,Buffer overflow,LFI)");
  printf("Type:");
  read_str((__int64)s, size);
  for ( i = strtok(s, ","); i; i = strtok(0LL, ",") )
  {
    printf("type: %s\n", i);
    printf("Price:");
    v1 = read_long();
    if ( add_type_internal(i, v1) )
      puts("Success !");
    else
      puts(&byte_360F);
  }
  free(s);
}

 보면 size를 받는데, size 검사를 해주지 않는다. 따라서 size에 음수가 입력되면 calloc은 null을 반환할 것이고, strtok에서 이전에 마지막으로 사용했던 s 에 접근이 가능하다. 그런데 여기서 이전에 사용되었던 s 가 free되었고, 그 주소에 아스키코드로 , 에 해당하는 0x2c가 fd에 적혀있으면 이를 null로 바꿀 수 있다. 이를 이용해 heap을 변조시켜서 쉘을 딸 수 있을 것 같다. 

 귀찮아서 잠시 중단. 뭐 이래저래 하고 calloc 으로 rop 해서 쉘따면 될듯 하다. 

 

 

 

 

'전공쪽 > pwnable.tw' 카테고리의 다른 글

[pwnable.tw] starbound  (0) 2020.12.31
[pwnable.tw] death note  (0) 2020.12.29
[pwnable.tw] tcache tear  (0) 2020.12.27
[pwnable.tw] Re-alloc  (0) 2020.12.24
[pwnable.tw] apple store  (0) 2020.12.24