Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Gadgets/Gadgets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _GADGETS_H
#define _GADGETS_H 1


#include<bits/stdc++.h>
#include<stdio.h>
#include<sys/mman.h>
#include<unistd.h>
#include<fcntl.h>
#include<elf.h>
#include<capstone/capstone.h>

extern std::vector<std::vector<cs_insn> > gadgets;

int GetGadgets(unsigned char *retptr, unsigned long RetAddress, unsigned long N);
int GetAllGadgets(unsigned char *inst, unsigned long TextSize, unsigned long EntryAddress, unsigned long N);


#endif
5 changes: 5 additions & 0 deletions Gadgets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Objective: Collecting all ROP Gadgets in .text section of a 64-bit executable

## Compile in the following manner to get the tool:

$ g++ main.cpp getgadgets.cpp -std=c++11 -lcapstone
Binary file added Gadgets/code1
Binary file not shown.
5 changes: 5 additions & 0 deletions Gadgets/code1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include<stdio.h>
int main() {
printf("Hello World!\n");
return 0;
}
166 changes: 166 additions & 0 deletions Gadgets/getgadgets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include"Gadgets.h"

enum ret{

ret_near = 1,
ret_far = 2,
ret_near_pop = 3,
ret_far_pop = 4,
};

class Gadget {
unsigned char ret_type;

};

std::vector<std::vector<cs_insn> > gadgets;


//========================================GetGadgets - Get all ret gadgets===================================//

int GetGadgets(unsigned char *retptr, unsigned long RetAddress, unsigned long N) {

unsigned char *ptr = retptr;
unsigned long Address = RetAddress;
csh handle;
cs_insn *insn;
unsigned long InstCount;

if(cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) {
std::cerr<<"Error: Unable to open capstone handle"<<std::endl;
return -1;
}

unsigned long count = 1;
while(count <= N) {

std::vector<cs_insn> gadget;

InstCount = cs_disasm(handle, ptr, count, Address, 0, &insn);
if(InstCount == 0) {
//std::cerr<<"Error: Unable to disassemble - Inside GetGadgets()"<<std::endl;
ptr--;
Address--;
//return -1;
continue;
}

if(strcmp(insn[InstCount-1].mnemonic, "ret")== 0) {
std::cout<<std::endl;
// std::cout << "INTERESTING!" << std::endl;
for(unsigned long j = 0; j < InstCount; j++) {
printf("0x%lx: %s %s ", insn[j].address, insn[j].mnemonic, insn[j].op_str);
gadget.push_back(insn[j]);
printf("\n");
}
}
if(gadget.size() > 0) {
gadgets.push_back(gadget);
}



count++;
ptr--;
Address--;
}

cs_close(&handle);

return 0;
}

//=================================GetAllGadgets: Driver function====================================//

int GetAllGadgets(unsigned char *inst, unsigned long TextSize, unsigned long EntryAddress, unsigned long N) {

//Disassembly of the text section will go into a file named disass.dump.
std::cout<<"Disassembly of .text section is dumped in disass.dump"<<std::endl;
FILE *fdisass;
fdisass = fopen("disass.dump", "wb");
if(fdisass == NULL) {
std::cerr<<"Error: Unable to create file disass.dump"<<std::endl;
std::cerr<<"Exiting..."<<std::endl;
return -1;
}


//Capstone related variables.
csh handle;
cs_insn *insn;
unsigned long InstCount;

//Initialize the handle
if(cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) {
std::cerr<<"Error: Unable to open cs handle"<<std::endl;
return -1;
}

InstCount = cs_disasm(handle,
inst,
TextSize,
EntryAddress,
0,
&insn);

if(InstCount == 0) {
std::cerr<<"Error: Unable to disassemble the .text section"<<std::endl;
return -1;
}

for(unsigned long i = 0; i < InstCount; i++) {
fprintf(fdisass, "0x%lx: %s %s %s\n", insn[i].address, insn[i].bytes, insn[i].mnemonic, insn[i].op_str);
}

fclose(fdisass);

// Disassembly of .text section is done at this point.


//The following code will aim to dump all ret gadgets present in the text section.
std::cout<<"All Gadgets will be dumped in gadgets.rop"<<std::endl;

FILE *fretgg;
fretgg = fopen("gadgets.rop", "wb");
if(fretgg == NULL) {
std::cerr<<"Error: Unable to create file gadgets.rop"<<std::endl;
std::cerr<<"Exiting..."<<std::endl;
return -1;
}

unsigned char *ptr1 = inst, *ptr2 = inst;
unsigned long MovingAddress = EntryAddress, count = 0;
unsigned char buffer[N];
memset(buffer, '\0', sizeof(buffer));
/*
for(unsigned long i = 0; i < TextSize; i++) {

if(*ptr1 == 0xc3 || *ptr1 == 0xc2 || *ptr1 == 0xcb || *ptr1 == 0xca) {
printf("count = %lu, Moving Address = 0x%lx\n", count, MovingAddress);
count++;
}
ptr1++;
MovingAddress++;
}
*/

for(unsigned long i = 0; i < TextSize; i++) {
unsigned long OldAddress = MovingAddress;
if(*ptr2 == 0xc3 || *ptr2 == 0xcb || *ptr2 == 0xc2 || *ptr2 == 0xca) {

//printf("\nCount = %lu, Address: 0x%lx, rettype = %x\n", count, MovingAddress, *ptr1);
GetGadgets(ptr2, MovingAddress, N);
count++;
}

ptr2++;
MovingAddress++;
}



cs_close(&handle);
}



141 changes: 141 additions & 0 deletions Gadgets/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include<bits/stdc++.h>
#include<sys/mman.h>
#include<unistd.h>
#include<fcntl.h>
#include<elf.h>

// To use the capstone framework.
#include<capstone/capstone.h>

// This has routines to collect all gadgets
#include "Gadgets.h"


int main(int argc, char **argv) {

if(argc != 3) {
std::cerr<<"$ "<<argv[0]<<" <BinaryName> <ConfigurableN>"<<std::endl;
return -1;
}

// 1. Open the Binary
// 2. Map it onto the memory
// 3. Find the Entry Address

char *BinaryName = argv[1];
unsigned long SizeofBinary = 0;
unsigned long EntryAddress, TextAddress;
unsigned char *start;
FILE *fp;
int fd;
std::string TextSizeStr;
unsigned long int TextSize;
unsigned long int ConfN = atoi(argv[2]);

// Finding size of the binary.
// 1. Using fopen and fclose() - reading the while file once - slow. TODO: 2. Should devise a faster method.

fp = fopen(BinaryName, "rb");
if(fp == NULL) {
std::cerr<<"Error: Unable to open the file"<<std::endl;
return -1;
}

while(fgetc(fp) != EOF)
SizeofBinary++;

fclose(fp);

// Done finding size of the binary //

// Find Entry Address and Size of .text section //

fd = open(BinaryName, O_RDONLY, S_IRUSR);
if(fd == -1) {
std::cerr<<"Error: Unable to open file while finding entry address"<<std::endl;
return -1;
}

start = (unsigned char *)mmap(NULL,
SizeofBinary,
PROT_READ,
MAP_PRIVATE,
fd,
0);

if(start == MAP_FAILED) {
std::cerr<<"Error: Unable the map the ELF header onto memory"<<std::endl;
return -1;
}


Elf64_Ehdr *elf_hdr = (Elf64_Ehdr *)start;
EntryAddress = (unsigned long int)elf_hdr->e_entry;

if((char)elf_hdr->e_type == ET_EXEC)
TextAddress = EntryAddress - 0x400000;

else if((char)elf_hdr->e_type == ET_DYN)
TextAddress = EntryAddress;

/*
munmap(start, sizeof(Elf64_Ehdr));
*/
close(fd);


// Done finding the Entry Address //

// Find the size of .text section

//1. Finding the size of .text segment.
//2. Using the size command, popen() function.
//3. Parsing the output and getting size.
//4. This is not the right way to be done.

//TODO: Properly parse the ELF file and get the size.

//5. This is just a stop-gap arragement.


char command[50];
sprintf(command, "size %s", BinaryName);

fp = popen(command, "r");
if(fp == NULL) {
std::cerr<<"Error: Unable to execute the command: "<<command<<std::endl;
return -1;
}

char ch = fgetc(fp);
while(ch == ' ' || isalpha(ch) || ch == '\n' || ch == '\t') {
ch = fgetc(fp);
}

TextSizeStr += ch;
while(ch != ' ') {
ch = fgetc(fp);
TextSizeStr += ch;
}

TextSize = std::stoul(TextSizeStr);
fclose(fp);
// Done finding size of .text segment //


std::cout<<"Binary: "<<BinaryName<<std::endl;
std::cout<<"Entry Address: 0x"<<std::hex<<EntryAddress<<std::endl<<std::dec;
std::cout<<"Size of .text section: "<<TextSize<<" bytes"<<std::endl;

// Get all gadgets!

std::cout<<"Collecting all gadgets in .text section"<<std::endl;

unsigned char *inst = (unsigned char *)(start + TextAddress);
if(GetAllGadgets(inst, TextSize, EntryAddress, ConfN) == -1) {
std::cerr<<"Error: GetGadgets() routine failed for some reason"<<std::endl;
return -1;
}

return 0;
}
File renamed without changes.
File renamed without changes.
3 changes: 1 addition & 2 deletions lexparse.cpp → IRGen/IRGen/lexparse.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include "llvm/ADT/STLExtras.h"
#include<bits/stdc++.h>
using namespace std;

Expand Down Expand Up @@ -1377,4 +1376,4 @@ int main(int argc, char **argv) {

fclose(fp);
return 0;
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# ROP-Rough-Space

This is a place where we put whatever we think related to ROP Compiler

1. **Gadgets**: This has a tool which will collect all ROP Gadgets present in executable section of a specified executable.

2. **IRGen**: Plan was to convert ROP Gadgets into LLVM-IR, then feed it to Z3 to extract semantics. This directory has a simple lexer and parser written covering most common x64 assembly instructions.

3. **disasm**: Rough Space for Figuring Out Gadget Harvesting & Storage. In this directory, we have written code to store the gadgets in a trie which will help us access them quickly - useful in later stages.

4. **disassembly tool**: A Simple disassembly tool which will give the disass of .text section of an executable. This is a mini-version of objdump. This tool was written by Arpitha Raghunandan.

5. **exploit_with_memory_leak**: We tried to exploit a vulnerable program using ROP with most security features enabled. ASLR and W^X were enabled. Executable was compiled without Stack canaries. The exploitation was not possible with ROP alone. It needed a memory leak vulnerability to get the idea of memory layout of vulnerable process. This directory has vulnerable programs and respective exploit scripts.


24 changes: 0 additions & 24 deletions code1.asm

This file was deleted.

Empty file added disasm/AllGadgets.dump
Empty file.
Loading