목록Hack/DreamHack(로드맵) (94)
CIDY

지난 시간에 _IO_FILE에 대해 설명하며 파일을 읽어오거나, 열고 쓰는 과정은 라이브러리 함수 내부 파일 구조체의 포인터와 값들을 이용한다고 했었다. 파일 구조체를 조작하면 임의의 메모리 값을 읽어올 수 있다. 파일에 데이터를 쓰는 함수로는 fwrite나 fputs같은 게 있다. 이 함수는 라이브러리 내부에서 _IO_sputn함수를 호출한다. #define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n) _IO_size_t _IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) { ... if (to_do + must_flush > 0) { _IO_size_t block_size, do_wr..

파일을 열 때는 접근 유형을 명시해야 함 -> 읽기모드, 쓰기모드 등... -> 파일 관련 함수들은 fopen이 반환한 파일 포인터를 토대로 파일 정보를 확인한다. -> 파일 작업 이해를 위해서는 파일 구조체 이해가 선행되어야 함. *_IO_FILE 리눅스 시스템 표준 라이브러리에서 파일 스트림을 나타내기 위한 구조체이다. -> fopen함수 사용 시 힙 영역에 할당된다. struct _IO_FILE_plus { FILE file; const struct _IO_jump_t *vtable; }; struct _IO_FILE { int _flags;/* High-order word is _IO_MAGIC; rest is flags. */ /* The following pointers correspond t..

C코드를 안 줬다.. void __noreturn start() { setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 1, 0LL); write(1, "++++++++++++++++++Welcome to dreamhack++++++++++++++++++\n", 0x39uLL); write(1, "+ You can send a signal to dreamhack server. +\n", 0x39uLL); write(1, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n", 0x39uLL); sub_4010B6(); exit(0); } 아이다로 까 보니 이렇게 생겼다. 일단 서브함수부터 까 보자. ssize_t ..

// Name: srop.c // Compile: gcc -o srop srop.c -fno-stack-protector -no-pie // 64-bit, nx, partial relro #include int gadget() { asm("pop %rax;" "syscall;" "ret" ); } int main() { char buf[16]; read(0, buf ,1024); } 이상한 (긴)가젯을 줬다. 그리고 bof가 엄청 일어난다. 아마 스택을 원하는 값으로 설정한 다음 원하는 번호의(rax) syscall을 제때 호출해서 쉘을 얻어내라는 문제 같다. 근데 생각해보면 아까 그 구조체 순서에 맞춰서 레지스터를 다 설정해 주는 건 좀 귀찮다. -> 그래서 폰툴즈에서는 SigreturnFrame이라는..

*Signal 예전에 syscall에 대해 설명하면서 (Ck수업) 운영체제는 유저모드와 커널 모드로 나뉜다고 한 적이 있다. 프로그램을 실행하는 과정은 이 두 모드가 상호작용하며 이루어진다. 시그널은 프로세스에 특정 정보를 전달하는 매개체인데, 지겹게 보던 그 SIGSEGV같은것도 시그널의 일종이다. 리눅스에서는 다양한 시그널을 제공하는데, *+--------------------+------------------+ *| POSIX signal | default action | *+--------------------+------------------+ *| SIGHUP | terminate| *| SIGINT |terminate| *| SIGQUIT |coredump | *| SIGILL |coredu..

// gcc -o rtld rtld.c -fPIC -pie #include #include #include #include #include void alarm_handler() { puts("TIME OUT"); exit(-1); } void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); signal(SIGALRM, alarm_handler); alarm(60); } void get_shell() { system("/bin/sh"); } int main() { long addr; long value; initialize(); printf("stdout: %p\n", stdout); printf("addr:..

*환경변수 환경변수는 모든 운영체제에서 사용되며, 매번 변할 수 있는 동적인 값들의 모임이며, 시스템 정보를 갖고 있는 변수이다. -> 사용자가 직접 추가/수정/삭제 가능. 리눅스에서 제공하는 명령어들은 /bin, /usr/bin과 같은 디렉토리에 있다. -> 우리가 명령어 입력 -> 환경변수에 명시된 디렉토리에서 명령어 탐색/실행 -> 명령어 경로 입력 불필요 환경변수는 터미널뿐만 아니라, 프로그램에서도 참조함 -> 프로그램도 명령어를 실행해야 하는 경우가 있는데, 절대경로를 입력하지 않아도 명령어 실행 가능 -> 프로세스 로드 시 환경변수를 초기화하기 때문 환경변수에 대한 정보는 스택 영역에 존재한다. + 라이브러리 함수 실행 시에도 그 정보 참조함 -> 환경 변수를 가리키는 포인터가 별도로 선언되어..

// Name: ow_rtld.c // Compile: gcc -o ow_rtld ow_rtld.c // 64-bit, canary, nx, pie, full relro #include #include void init() { setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); } int main() { long addr; long data; int idx; init(); printf("stdout: %p\n", stdout); while (1) { printf("> "); scanf("%d", &idx); switch (idx) { case 1: printf("addr: "); scanf("%ld", &addr); printf("data: "); scanf("%l..