-
카테고리
-
세부 분야
보안
-
해결 여부
미해결
iOS앱 무결성 체크 샘플 소스
21.11.21 14:36 작성 조회수 2.44k
1
앱무결성 체크를 해시값 검증으로 체크할 수 있다고 말씀해 주셨습니다.
안드로이드 관련 소스는 인터넷에서 검색을 하면 나오는데
iOS관련 샘플 소스는 찾을수가 없습니다.
앱 무결성 체크 샘플소스가 있으시다면 공유 부탁드립니다.
답변을 작성해보세요.
1
김태영
2021.12.10
안녕하세요. 보안프로젝트 김태영입니다.
무결성 관련 내용은 OWASP에서 제공해주는 iOS Anti-Reversing Defenses의 File Integrity Checks 부분 참고 부탁드립니다!
== 일부 내용 발췌 ==
Sample Implementation - Application Source Code
Apple takes care of integrity checks with DRM. However, additional controls (such as in the example below) are possible. The mach_header
is parsed to calculate the start of the instruction data, which is used to generate the signature. Next, the signature is compared to the given signature. Make sure that the generated signature is stored or coded somewhere else.
int xyz(char *dst) {
const struct mach_header * header;
Dl_info dlinfo;
if (dladdr(xyz, &dlinfo) == 0 || dlinfo.dli_fbase == NULL) {
NSLog(@" Error: Could not resolve symbol xyz");
[NSThread exit];
}
while(1) {
header = dlinfo.dli_fbase; // Pointer on the Mach-O header
struct load_command * cmd = (struct load_command *)(header + 1); // First load command
// Now iterate through load command
//to find __text section of __TEXT segment
for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) {
if (cmd->cmd == LC_SEGMENT) {
// __TEXT load command is a LC_SEGMENT load command
struct segment_command * segment = (struct segment_command *)cmd;
if (!strcmp(segment->segname, "__TEXT")) {
// Stop on __TEXT segment load command and go through sections
// to find __text section
struct section * section = (struct section *)(segment + 1);
for (uint32_t j = 0; section != NULL && j < segment->nsects; j++) {
if (!strcmp(section->sectname, "__text"))
break; //Stop on __text section load command
section = (struct section *)(section + 1);
}
// Get here the __text section address, the __text section size
// and the virtual memory address so we can calculate
// a pointer on the __text section
uint32_t * textSectionAddr = (uint32_t *)section->addr;
uint32_t textSectionSize = section->size;
uint32_t * vmaddr = segment->vmaddr;
char * textSectionPtr = (char *)((int)header + (int)textSectionAddr - (int)vmaddr);
// Calculate the signature of the data,
// store the result in a string
// and compare to the original one
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5(textSectionPtr, textSectionSize, digest); // calculate the signature
for (int i = 0; i < sizeof(digest); i++) // fill signature
sprintf(dst + (2 * i), "%02x", digest[i]);
// return strcmp(originalSignature, signature) == 0; // verify signatures match
return 0;
}
}
cmd = (struct load_command *)((uint8_t *)cmd + cmd->cmdsize);
}
}
}
감사합니다.
답변 1