완료됨
제발 도와주세요 ㅠㅠ

이때 free는 해제한 메모리의 데이터를 초기화하지 않으므로, nametag에는 secret의 값이 일부 남아있게 됩니다


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct NameTag {
char team_name[16];
char name[32];
void (*func)();
};
struct Secret {
char secret_name[16];
char secret_info[32];
long code;
};
int main() {
int idx;
struct NameTag *nametag;
struct Secret *secret;
secret = malloc(sizeof(struct Secret));
strcpy(secret->secret_name, "ADMIN PASSWORD");
strcpy(secret->secret_info, "P@ssw0rd!@#");
secret->code = 0x1337;
free(secret);
secret = NULL;
nametag = malloc(sizeof(struct NameTag));
strcpy(nametag->team_name, "security team");
memcpy(nametag->name, "S", 1);
printf("Team Name: %s\n", nametag->team_name);
printf("Name: %s\n", nametag->name);
if (nametag->func) {
printf("Nametag function: %p\n", nametag->func);
nametag->func();
}
}

이코드에서 해제한 메모리의 데이터를 초기화하지않았다는데
secret = NULL 로 초기화한거 아닌가요?

#시스템_해킹 #use-after-free #메모리오염 #uaf
작성자 정보
더 깊이 있는 답변이 필요할 때
드림핵 팀과 멘토에게 직접 문의해 보세요!
답변 1
kimht__
강의 수강: 1
kimht__
강의 수강: 1

여기서 해제한 메모리의 데이터를 초기화하지 않았다가 의미하는 바는,
secret이 free() 이후 NULL로 초기화되기 전 본래 가리키던 메모리에 있는 데이터를 지우지 않았다는 뜻으로
이해할 수 있을 것 같습니다.

즉, 32번 라인의 secret = NULL;이 실행됨으로써 secret이 NULL로 초기화되는 것은 맞지만,
아직 메모리에는 "ADMIN PASSWORD", "P@ssw0rd!@#", 0x1337과 같은 데이터가 남아있는 상태인 것이죠.
(엄밀히 따지면 "ADMIN PASSWORD", "P@ssw0rd!@#", 0x1337과 같은 데이터 일부분이 남아있게됨)

가령 해제한 메모리의 데이터를 초기화했다고 말할 수 있으려면,

// Name: uaf.c
// Compile: gcc -o uaf uaf.c -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct NameTag {
  char team_name[16];
  char name[32];
  void (*func)();
};

struct Secret {
  char secret_name[16];
  char secret_info[32];
  long code;
};

int main() {
  int idx;
  
  struct NameTag *nametag;
  struct Secret *secret;
  
  secret = malloc(sizeof(struct Secret));
  strcpy(secret->secret_name, "ADMIN PASSWORD");
  strcpy(secret->secret_info, "P@ssw0rd!@#");
  secret->code = 0x1337;
  
  memset(secret, 0x00, sizeof(struct Secret)); // 요부분이 패치된 부분!
  free(secret);
  secret = NULL;
  
  nametag = malloc(sizeof(struct NameTag));
  
  strcpy(nametag->team_name, "security team");
  memcpy(nametag->name, "S", 1);
  
  printf("Team Name: %s\n", nametag->team_name);
  printf("Name: %s\n", nametag->name);
  
  if (nametag->func) {
    printf("Nametag function: %p\n", nametag->func);
    nametag->func();
  }
}

위와 같이 secret->code = 0x1337;free(secret); 사이에
memset(secret, 0x00, sizeof(struct Secret));를 넣어주는 식으로 패치하면 될 것 같습니다.

이렇게 하면 secret이 NULL로 초기화되기 전 본래 가리키던 메모리에 있는 데이터를 다 널바이트(0x00)로 밀어버리기 때문에,
해제한 메모리"ADMIN PASSWORD", "P@ssw0rd!@#", 0x1337과 같은 데이터가 남아있지 않겠죠?

2022.07.06. 11:59