nic.pl --> 5. iphone/control_center_module-11up
※ iPhone6s+(iOS 13.5.1)에 THEOS를 설치하여 진행하였습니다.
Control Center Module 예제 소스코드는 https://github.com/M4cs/EzCC-Modules 에 많이 있습니다.
원하는 기능과 유사한 코드를 가져와서 쓰면 잘 작동합니다.
Control Center에 사용되는 아이콘은 배경이 제거된 흑백 아이콘 입니다.
컬러 변경은 파워포인트에서 손쉽게 할 수 있고, png 파일의 배경은 https://onlinepngtools.com/create-transparent-png 에서 쉽게 제거할 수 있습니다.
예제 소스코드를 보면 Resources/ 디렉터리 하위에 Icon@2x.png, Icon@3x.png 처럼 모양은 같으나 사이즈가 다른 아이콘들이 들어가 있더군요.
따라서, 배경이 제거된 흑백 아이콘을 이용해 다양한 사이즈의 아이콘을 만들어줄 필요가 있습니다.
해당 기능은 https://hotpot.ai/icon-resizer 에서 제공하고 있습니다.
배경이 제거된 흑백 아이콘을 업로드하고, "iOS Icon" 버튼을 켠다음 Convert 버튼을 누르면 여러사이즈의 아이콘이 포함된 zip 파일이 생성됩니다.
이제 아이콘을 제작하였으면 Resources/ 디렉터리 하위에 위치시켜줍니다. 메인소스코드에서도 해당 아이콘을 쓰겠다고 아이콘의 확장자를 제외한 이름을 명시해줘야 합니다.
// Icon of your module
- (UIImage *)iconGlyph {
return [UIImage imageNamed:@"Icon" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
}
소스코드 상에 명시한 아이콘은 컨트롤 센터에서 보여지는 아이콘입니다.
Resources/ 하위에 위치해있는 SettingsIcon은 Control Center 설정창에서 보여지는 아이콘입니다. 해당 아이콘은 흑백 및 배경이 제거될 필요는 없으며, 소스코드상에 명시해줄 필요도 없습니다. 이름이 SettingsIcon이면 자동으로 인식하는 것으로 생각됩니다.
컨트롤 센터에서 선택했을때 respring 시켜주는 간단한 cc 모듈의 소스코드입니다.
// Makefile
TARGET := iphone:clang:latest:11.0
INSTALL_TARGET_PROCESSES = SpringBoard
ARCHS := arm64
include $(THEOS)/makefiles/common.mk
BUNDLE_NAME = respring
respring_BUNDLE_EXTENSION = bundle
respring_FILES = respring.m
respring_CFLAGS = -fobjc-arc
respring_PRIVATE_FRAMEWORKS = ControlCenterUIKit
respring_INSTALL_PATH = /Library/ControlCenter/Bundles/
include $(THEOS_MAKE_PATH)/bundle.mk
// respring.h
#import <ControlCenterUIKit/CCUIToggleModule.h>
@interface respring : CCUIToggleModule
@property (nonatomic, assign, readwrite) BOOL Hackcatml;
@end
// respring.m
#import "respring.h"
#import <spawn.h>
#import <sys/wait.h>
@implementation respring
// Icon of your module
- (UIImage *)iconGlyph {
return [UIImage imageNamed:@"Icon" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
}
// Selected color of your module
- (UIColor *)selectedColor {
return [UIColor blueColor];
}
// Current state of your module
- (BOOL)isSelected {
return self.Hackcatml;
}
- (void)setSelected:(BOOL)selected {
self.Hackcatml = selected;
[super refreshState];
[self respring];
}
- (void)respring {
pid_t pid;
int status;
const char* args[] = {"sbreload", NULL};
posix_spawn(&pid, "/usr/bin/sbreload", NULL, NULL, (char* const*)args, NULL);
waitpid(pid, &status, WEXITED);
}
@end
여기서 조금 더 깊게 들어가서, 컨트롤 센터에서 터치하여 실행시켜주는 command는 root권한으로 실행되지 않습니다.
respring이나, uicache 같은 명령어는 굳이 root권한으로 실행안해줘도 잘 작동하므로 상관 없습니다.
그러나 제가 일전에 제작한 fricon(https://hackcatml.tistory.com/119) 툴의 경우에는 위의 방식대로 cc 모듈을 만들어도 실행되지 않습니다. fricon 명령어는 "mobile" userId의 권한으로 실행되지만, frida는 실행되지 않았습니다.
Control Center 모듈에서 root 권한으로 command 실행이 필요한 경우에는 어떻게 해야 할까요?
https://github.com/captinc/CommandModule 에서 아이디어를 얻을 수 있었습니다.
위 모듈은 CC에서 루트 권한으로 ShellScript를 실행시켜줍니다.
작동방식은 다음과 같습니다.
CC에서 아이콘 선택 --> 특정 command(ex. fricon)를 위한 command tool(ex. commandtoolforfricon) 호출 --> 호출된 command tool은 "setuid(0);" 가 설정된 상태에서 target command(ex. fricon) 호출 --> target command(ex. fricon)은 root권한으로 명령 수행
요약하면, CC로 수행하고자 하는 target command tool 사이에 권한상승을 위한 command tool을 하나 더 위치시킵니다.
"CC" ------------------------> "command tool for target command" ------------------------> "target command tool"
그런데, 중간에 위치한 "command tool for target command"은 "setuid(0);" 가 설정되었다고 해서 루트권한으로 실행되지 않더군요. chmod +s 명령어로 실행파일에 setuid 비트를 설정해줘야 합니다. 이 과정은 deb 패키지에 postinst 스크립트를 포함하여 해결할 수 있겠지요.
위 아이디어를 적용하여 특정 command를 root권한으로 실행시켜주는 CC 모듈을 작성해보았습니다.
// main.m(commandtoolforfricon)
#include <stdlib.h>
#include <unistd.h>
#include <spawn.h>
int main(int argc, char *argv[], char *envp[]) {
setuid(0); //make us root. if not set this, command not work.
pid_t pid;
int status;
// Process parameters
NSArray *arguments =[[NSProcessInfo processInfo] arguments];
NSString *command = [arguments objectAtIndex:1];
// when cc selected, fricon start
if([command isEqualToString:@"start"]){
const char* args[] = {"/usr/local/bin/fricon", "start", NULL};
posix_spawn(&pid, "/usr/local/bin/fricon", NULL, NULL, (char* const*)args, NULL);
}
// when cc is unselected, fricon stop
else {
const char* args[] = {"/usr/local/bin/fricon", "stop", NULL};
posix_spawn(&pid, "/usr/local/bin/fricon", NULL, NULL, (char* const*)args, NULL);
}
waitpid(pid, &status, WEXITED);
return 0;
}
CC에서 frida아이콘 선택시 정상적으로 fricon 명령어가 루트권한으로 실행되어 frida-server가 구동되는 것을 확인할 수 있습니다.
'Information Security > iOS' 카테고리의 다른 글
iOS UnityGame Tweak 제작 (0) | 2021.08.20 |
---|---|
iOS 앱 알림창 띄우는 트윅 및 활용 (0) | 2021.08.05 |
iOS THEOS deb package with postinst (0) | 2021.08.01 |
iOS Latest Frida Install, Start, Stop, Remove Command Line Tool (0) | 2021.07.28 |
iOS Frida Port Detection Bypass Tweak - 2 (0) | 2021.07.25 |