Wie kriege ich mit ROP einen "/bin/sh" Pointer in rdi?

Ich versuche, rücksprungorientierte Programmierung (ROP) zu lernen.

Und zwar habe ich ein Programm mit einem Pufferüberlauf auf dem Stack, und ich möchte das Programm dazu bringen, /bin/sh zu öffnen.

Das geht mit dem execve Syscall, wenn ich die richtigen Instruktionen finden kann, um die Funktionsparameter vorzubereiten. Das ist die Signatur von execve:

int execve(const char *pathname, char *const _Nullable argv[], char *const _Nullable envp[]);

Also muss ich die folgenden Register setzen:

  • rax = 0x3b (Syscallnummer von execve)
  • rdi = "/bin/sh" Pointer
  • rsi = NULL
  • rdx = NULL

Die folgenden Instruktionen habe ich bereits gefunden:

pop rax ; ret
pop rdi ; ret
pop rsi ; ret
pop rdx ; ret
syscall

Ich kann also die Instruktionen und Registerwerte mit dem Pufferüberlauf auf den Stack schreiben und so meine Register füllen. Das Problem ist aber, dass ich einen "/bin/sh" Pointer in rdi brauche (also nicht "/bin/sh" im Register, sondern eine Speicheradresse, an der "/bin/sh" steht).

Ich kann natürlich "/bin/sh" in den Puffer auf dem Stack schreiben, aber leider ist die Speicheradresse jedes Mal anders und ich kenne sie vorher nicht.

Ich weiß, dass "/bin/sh" in libc vorkommt, aber auch dort ist die Speicheradresse jedes Mal anders und ich kenne sie vorher nicht.

Wie komme ich also an einen "/bin/sh" Pointer? Gibt es Tricks oder bestimmte Instruktionen, nach denen ich mich umsehen sollte?

hacken, Hack, Programm, programmieren, pointer, Assembler, Hacker, Hacking, Informatik, IT-Sicherheit, Shell, stack, x64, assemblersprache, Assembly, Exploit, hacken lernen, IT-Sicherheitsexperte, Register, Capture The Flag
Einfügen und Löschen in einer sortierten Liste?

Hallo, ich habe eine einfach verkette Liste in C++ mit Einfüge- und Lösch-Operation.

Leider funktioniert sie noch nicht, wie sie soll. Beim Einfügen werden die Werte mit cin gelesen, aber wenn ich die Zahlen 1.4 2.3 5.6 eingebe, wird nur 1.4 ausgegeben.

Habe ich in der Methode inserte() einen Logikfehler?

#include <iostream>

using namespace std;

class Elem {
  private:
    const double zahl;
	Elem *next;
  public:
    Elem(double a, Elem *b): zahl(a), next(b) {
	}
	friend class List;
};

class List {
  private:
    Elem *head;
  public:
    List(): head(nullptr) {
	}

    void inserte(double a) {
	  if ((head == nullptr) || (head->zahl > a)) {
	    head = new Elem(a, head);
	  }
	  else {
        Elem *b = head;
		
		for(; ((b->next != nullptr) || (b->next->zahl <= a)); b = b->next) {
        }
		
		Elem* tmp = new Elem(a, b->next);
		b->next = tmp;
	  }
	}
	
	bool remove(double a) {
	  Elem *tmp;
	  
	  if ((head == nullptr) || (head->zahl > a)) {
	    return false;
	  }
	  else if (head->zahl == a) {
	    tmp = head;
		head = head->next;
		delete tmp;
	  }
	  else {
		for (tmp = head; tmp->next->zahl < a; tmp = tmp->next) {
		}
		
		if ((tmp->next == nullptr) || (tmp -> next->zahl > a)) {
		  return false;
		}
		else {
		  Elem * help = tmp->next;
		  tmp ->next = tmp->next->next;
		  delete help;
		  
		  return true;
		}
	  }
	  
	  return false;
	}
	
	void output() {
	  int i = 0;
	  
	  for (Elem *tmp = head; tmp != nullptr; tmp = tmp->next) {
		cout << tmp->zahl << '\n';
		i++;
	  }
	  
	  cout << "Anzahl der Elemente: " << i << '\n';
	}
};

int main() {
  double a;
  List b;
  
  while (cin >> a) {
	if (a > 0) {
      b.inserte(a);
	}
	else if (a < 0) {
	  b.remove(-a);
	}
	else {
	  break;
	}
	
	b.output();
  }
  
  return 0;
}
pointer, Liste

Meistgelesene Fragen zum Thema Pointer