본문 바로가기

4-1. 2025-1 심화 스터디/워게임 도장 깨기

[3주차] 250401 워게임 도장 깨기

Pwnable 문제 풀이 후 공유

 

1. fd

문제

ssh 접속

ssh fd@pwnable.kr -p2222

 

ls -al

fd, fd.c, flag 확인

flag는 제3자 권한이 없어서 권한 없음

 

fd.c

→ 해당 파일(?)을 실행할 때 같이 값을 입력하며 0x1234와 뺄셈 후 fd의 저장

→ 저장된 fd가 read 함수의 파일 디스크립터로 사용

→ 비교 string과 같은 입력값을 입력 시 flag값 확인 가능

→ fd 저장 값을 0으로 만들어 준 후 read 함수 입력값으로 LETMEWIN 입력

 

0x1234(16진수) → 4660(10진수)

 

flag 확인

good job :) 출력 아래 flag 값 출력됨!

2. collision

문제

해당 문제는 해쉬 충돌 문제이다.

 

ssh 접속하고 ls -al 명령어 입력

 

vim 사용하여 col.c 확인

 

코드 분석

1) main 함수 if 문

main 함수의 인자 개수가 2개 이하면 문자열 출력하고 프로그램 종료

 

argv[1]의 길이를 비교하여 20byte가 아닌 경우 문자열 출력하고 프로그램 종료

 

hashcode와 입력한 check_password 함수에 리턴 값이 같으면 flag 얻을 수 있음

 

2) check_password 함수

-p는 입력한 문자열 20byte

-입력한 문자열을 int형 타입으로 변환

-20byte 문자열을 4byte씩 끊어서 res에 저장

-res 값을 리턴

→ res = ip[0] + ip[1] + ip[2] + ip[3] + ip[4]

⇒ hashcode = 0x21DD09EC를 5번 나눈 입력값을 넣어야 함.

*포인터 변수 → 4byte: 포인터 변수는 주소 값을 넣는 자료형이며 가용할 수 있는 모든 메모리의 경우의 수를 표현하기 위해서 4byte

 

입력값 찾기

-0x21DD09EC / 5 = 0x6C5CEC8, 0x6C5CEC8 * 5 = 0x21DD09E8

→ 0x21DD09EC와 0x21DD09E8은 4byte만큼 차이가 난다.

→ 5로 나누었을 때 값이 0x21DD09E8과 같게 만들어야 한다.

→ 0x21DD09EC - 0x6C5CEC8 * 4 = 0x6C5CECC

⇒ 0x6C5CEC8 * 4 + 0x6C5CECC를 입력값으로 넣어주면 됨.

 

최종

1) 리틀 엔디언으로 변환

0x6C5CEC8 * 4 + 0x6C5CECC → “\xc8\xce\xc5\x06” * 4 + “\xcc\xce\xc5\x06”

 

2) 입력값

파이썬 인터프리터 실행하여 리틀 엔디언을 입력한다.

*인터프리터를 실행하는 방법은 python -c command [arg] …이고 command에 있는 문장들 실행

 

flag 값 출력됨!

 

3. Return Address Over write

문제

 

문제파일 확인

scanf(”%s”, buf)

    입력 길이 제한X, 공백 문자(띄어쓰기, 탭, 개행 문자 등) 들어올 때까지 계속 입력 받음

get_shell()

    해당 함수를 실행하여 셸을 획득

 

간단한 실행

A를 4개 입력했을 때는 프로그램 종료

A를 64개 입력했을 때는 세그먼트 오류가 발생했다고 출력

 

pwndbg 분석

*스택 구조 return address | rbp | buf

스택의 30바이트 공간 할당 → 64bit이므로 공간 할당할 때마다 8바이트씩 할당

⇒ 38바이트 덮어쓰고 실행하고자하는 코드 주소 작성을 통해 실행 흐름 조작

 

print 명령어를 통해 해당 함수의 주소 출력

0x4006aa <get_shell>

 

익스플로잇

 

위 코드 실행시키면 쉘 획득 가능!

 

4. bof

문제

 

접속하면 고양이가 나옴

 

IDA로 확인

하나는 main쪽이고 다른 하나는 string에서 open() error, read() error, close() error 이 부분이 보여

이곳으로 한번 들어가 디컴파일 해봄.

v5에 ./cat 문자열을 담고 v4에 사용자의 입력 받음. (최대 144byte)

v4가 128바이트로 선언되었지만 scanf 부분을 통해 최대 144byte까지 가능하게 했음.

이를 통해 그 다음으로 선언된 v5s나 return address를 덮어쓰는 bof가 발생할 수 있음.

read_cat(v5)은 v5를 읽어 출력해서 ./cat 파일 출력하지만 bof를 일으켜 v5를 다른 문자열로 덮어 임의 파일을 열 수 있음.

즉, ./cat이 아니라 flag로 넘어갈 수 있음!

 

a로 128바이트를 채워 flag가 있는 경로 설정

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/home/bof/flag

위 값 넘어서 flag 획득!