cred 구조체 소스코드를 elixir를 통해 확인해보니 다음과 같았습니다. (실습 버전인 5.8.5 기준) struct cred { atomic_t usage; #ifdef CONFIG_DEBUG_CREDENTIALS atomic_t subscribers; /* number of processes subscribed */ void *put_addr; unsigned magic; #define CRED_MAGIC 0x43736564 #define CRED_MAGIC_DEAD 0x44656144 #endif kuid_t uid; /* real UID of the task */ kgid_t gid; /* real GID of the task */ kuid_t suid; /* saved UID of the task */ kgid_t sgid; /* saved GID of the task */ kuid_t euid; /* effective UID of the task */ kgid_t egid; /* effective GID of the task */ kuid_t fsuid; /* UID for VFS ops */ kgid_t fsgid; /* GID for VFS ops */ unsigned securebits; /* SUID-less security management */ kernel_cap_t cap_inheritable; /* caps our children can inherit */ kernel_cap_t cap_permitted; /* caps we're permitted */ kernel_cap_t cap_effective; /* caps we can actually use */ kernel_cap_t cap_bset; /* capability bounding set */ kernel_cap_t cap_ambient; /* Ambient capability set */ #ifdef CONFIG_KEYS unsigned char jit_keyring; /* default keyring to attach requested * keys to */ struct key *session_keyring; /* keyring inherited over fork */ struct key *process_keyring; /* keyring private to this process */ struct key *thread_keyring; /* keyring private to this thread */ struct key *request_key_auth; /* assumed request_key authority */ #endif #ifdef CONFIG_SECURITY void *security; /* subjective LSM security */ #endif struct user_struct *user; /* real user ID subscription */ struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ /* RCU deletion */ union { int non_rcu; /* Can we skip RCU deletion? */ struct rcu_head rcu; /* RCU deletion hook */ }; } __randomize_layout; 이 중 마지막 __randomize_layout 이 뭔지 찾아보니 커널에서 정의한 매크로이고 구조체의 순서를 랜덤화하는 일종의 보호 기법이라는 것을 알았습니다. 실습을 따라가보니 uid, gid, suid, sgid를 순서대로 덮기 때문에 현재 커널에서 이 보호 기법이 적용되지 않았다는 것을 알 수 있었습니다. 이 매크로의 정의 부분은 총 두 부분이고 다음과 같았습니다. #if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) #define __randomize_layout __attribute__((randomize_layout)) #define __no_randomize_layout __attribute__((no_randomize_layout)) /* This anon struct can add padding, so only enable it under randstruct. */ #define randomized_struct_fields_start struct { #define randomized_struct_fields_end } __randomize_layout; #endif #ifndef __randomize_layout # define __randomize_layout __designated_init #endif 첫 번째 부분에서는 flag처럼 보이는 RANDSTRUCT_PLUGIN 과 __CHECKER__ 에 cross reference(?)가 더이상 안돼서 확인은 못했습니다만, 이게 define 되어있으면 __randomize_layout 매크로를 정의하는 것 같아보입니다. 반대로 flag가 켜져있지 않아 첫 번째 부분에서 매크로 선언이 이뤄지지 않으면 두 번째 부분에서 __designated_init 으로 어쨌든 선언은 되는 것 같습니다. 마지막으로 __designated_init 의 선언 부분을 보면 다음과 같습니다. #if __has_attribute(__designated_init__) # define __designated_init __attribute__((__designated_init__)) #else # define __designated_init #endif 첨부는 했지만 어떻게 동작하는건지 잘 모르겠어서 여기부터 이해가 안됐습니다... 제 질문은 다음과 같습니다. 구조체 멤버 랜덤화가 적용되어야 할 것 같은데 강의자님께서 일부러 커널을 빌드할 때 소스코드를 수정하신건가요? 아니라면 __designated_init__ 이 없기 때문에 빈 매크로가 할당된 것 같은데, 이게 어떤 플래그이며 어떻게 키고 끌 수 있는건가요? 커널 소스코드를 확인할 때 RANDSTRUCT_PLUGIN 과 __CHECKER__ 같이 더 이상 cross reference가 불가능한 경우는 어떻게 값을 확인할 수 있나요? 정작 __randoimze_layout 이 붙었을 때 어떻게 메모리 레이아웃을 변경하는지에 대한 로직은 못찾았는데, 이런 부분은 어디서 확인할 수 있을까요? 강의자님 경험상 대회나 리얼월드 커널에서 구조체 멤버 랜덤화가 잘 적용되어있는 편인가요? 질문이 길어졌는데, 답변주시면 큰 도움이 될 것 같습니다. 감사합니다.
안녕하세요 강사님. 8강과 9강에서는 testFunc을 targetFunc의 도입부에 넣어 실행을 시키고 main으로 다시 돌아오도록 코드가 되어있는데요 main의 시작점과 리턴을 희망하는 위치를 계산해보면 강의 자료보다 큰 값이 나옵니다. 질문1. x86으로 최적화를 하지 않고 똑같이 실행을 했는데 왜 다른지 궁금합니다. 제 코드를 디스어셈블리에서 보면 강의에서 보이는것보다 많은 기계어들이 보입니다. 질문2. "jmp main + 86h" 에서 86대신 D0 이런식으로 계산 결과가 나왔을 때 빌드 에러가 발생하고 있습니다. 0xD0 이런식으로 넣으면 빌드 에러는 나지 않지만 다른곳으로 점프를 하는것 같고요. 어떻게 해결을 해야할까요?
이 강의 전의 기존 ROP방식에서는 카나리 다음에 레지스터값들이 저장안되었는데 이번에는 왜 저장될까요? 또 위 사진 rop[i++] 14, 15번째(swapgs_restore... 바로 밑)는 왜 0x41414141로 될까요? 이것도 저번 강의랑 조금 달라 질문드립니다.
안녕하세요. 개발자는 아니지만 업무에 꼭 필요한 내용이 있어서 해당 강의를 수강하게 되었습니다. 사전지식이 전혀 없는 상태에서 열심히 검색하며 강의를 듣고 있는 상태입니다. 함수 프롤로그와 에필로그 강의 9분 20초 부분에 F9 를 눌러 브레이크 걸어주고 F5를 했을 때 브레이크가 되지 않고 넘어가버립니다. 잠깐 1초정도 브레이크가 되었다가 그냥 넘어가는 바람에 디스어셈블리 창도 뜨지 않습니다. [종단점 설정 확인] [F5 실행 시 상태 확인] 혹시 제가 놓치는 부분이 있을까요?
강의 영상에서 보면 루트 권한으로 proc/kallsyms 파일에 내용에서 commit_creds, prepare_kernel_cred의 offset을 찾고 있는데 이건 이미 루트 권한을 획득 했을때 얘기이고 루트 권한을 얻기 위해 익스 코드를 짜야 되는 상황에서의 저런 offset은 어떻게 얻을 수 있나요?
안녕하세요 강사님 11.inlineHook 예제를 debug 빌드로 실행하면 pfOpenProcess에서 Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. 뭔가 강의중에 언급하신 stack memory 고장같은데 이유를 아시나요? function prologue 디스어셈블이 조금차이가있는데 어차피 5바이트만큼 백업해두니 상관없는것은 맞나요?
안녕하세요 강사님 MyMessageBox안에서는 MessageBoxW를 쓴 이유를 제가 제대로 이해한게 맞나요? MessageBoxA로 바꾸니까 stack overflow 가 생기는것 까지는 확인하였습니다. iat hook으로 인해 MessageBoxA 호출 -> IAT 에서 메모리 참조 -> MyMessageBox -> MessageBoxA호출 -> .. 무한 반복 될뻔한것을 MessageBoxA 호출 -> IAT 에서 메모리 참조 -> MyMessageBox -> MessageBoxW호출 후 그냥 return 0 -> main으로 무사히 돌아옴 이렇게 된건가요?
안녕하세요, 강사님 수업에 사용된 예제 (x86) 06:03 해당 강의가 아래 화면과 같이 재생이 되지 않고 있습니다. 우측에 스크립트가 있는 것으로 보아, 소스코드 이외에 강의가 있는 것으로 보이는데, 아래와 같은 에러 메시지가 발생하고 있습니다. 해당 강의 이외에 앞뒤 강의는 정상적으로 재생 되는 것을 확인했습니다. 위 강의에 대해 한번 확인 부탁드립니다! 감사합니다.
echo파일을 만든 후에 chmod o+x echo명령어를 쳐서 order에 실행 권한을 주었습니다./home/flag01/flag01을 쳐서 실행해보니 permissin denied라고 권한이 없다고 뜹니다. chmod 777 echo를 사용해서 권한을 다 주니 정상적으로 flag01권한을 얻을 수 있었는데, 왜 chmod o+x echo는 권한이 없다고 뜨는지 궁금합니다. 1.chmod 777 echo 2.chmod o+x echo