리버싱 24

[layer7 ctf] 리버싱 라이트업(총 2문제)

1. tea_time 일단 문제 파일을 열자마자 프로그램 루틴이 보였다. int __cdecl main(int argc, const char **argv, const char **envp) { char v4; // al int i; // [rsp+8h] [rbp-188h] int v7; // [rsp+Ch] [rbp-184h] unsigned int v8; // [rsp+10h] [rbp-180h] unsigned int v9; // [rsp+14h] [rbp-17Ch] int v10; // [rsp+1Ch] [rbp-174h] int j; // [rsp+20h] [rbp-170h] int k; // [rsp+24h] [rbp-16Ch] char *v13; // [rsp+28h] [rbp-168h] in..

reversing 2022.12.19

Layer7 리버싱 11차시 과제(VM) - prob4

문제 파일을 IDA로 열어 main함수부터 분석해보았다. prob3와 같았다. 사용자로부터 32개의 문자를 입력받고, 그 입력값에 어떤 연산을 수행한 후, 후에 특정 조건과 비교해 만족한다면 Correct!, 다르면 Wrong...을 출력하고 있다. init_cpu는 이전 문제처럼 v5에 입력값을 복사하는 역할이었고, run_cpu는 이전 문제와 모두 같고, 데이터만 달랐다. 그래서 조건 분기 부분을 처리하기 위해 prob3처럼 식을 추출하지 말고 그 자리에서 계산해줬고, 마지막에 플래그를 순서대로 출력해 출력조건을 맞춰주었다. 그럼 구현해보자. 일단, 프로그램의 로직대로 연산을 수행하기 위해 stub코드를 추출해줬고, run_cpu의 코드도 파이썬으로 새롭게 짜줬다. 그 후, 플래그의 순서대로 출력하면..

reversing 2022.08.30

layer7 리버싱 11차시 과제(VM) - prob3

일단 문제 파일을 내려받아 아이다로 열어보았다. 대충 사용자로부터 32개의 문자를 입력받고, 그 문자에 대한 연산을 수행한 후, 그 연산 결과가 아래 조건문과 일치하는지 보고 일치하면 Correct!, 다르면 Wrong...을 출력하는 코드이다. 그럼 사용자로부터 입력받은 후의 첫번째 함수인 init_cpu를 보자. 사용자로부터 입력받은 값을 v5라는 새로운 배열에 복사하는 코드였다. 그럼 다음 코드, run_cpu 부분을 확인해보자. 다른 VM 문제와 같은 형식이었다. stub이라는 배열에 들어있는 값에 따라 연산을 수행해나가는 코드였다. 처음엔 그냥 "코드 그대로 가져다 써서 식 추출한 다음에 그대로 z3-solver 돌리면 되겠지"라고 생각했으나, 밑에 있는 조건문을 보고 생각이 달라졌다. 이렇게 ..

reversing 2022.08.30

Layer7 리버싱 10차시 과제(VM) - prob1

일단 파일을 아이다로 열어 분석해보았다. 대충 사용자로부터 48바이트 문자열을 입력받은 후, v5배열에 내용을 복사하고, run_cpu 함수를 수행한 후에 v5의 15번째 문자가 0(NULL)문자가 아니면 Wrong..., 0이 아니면 Correct!를 출력하고 있다. 우리의 역할은 v5의 15번째 문자가 0이 되는 문자열을 찾아야하는 것이다. 따라서 run_cpu의 내용을 분석해보았다. 바로 전 문제와 크게 다른 게 없었다. 그냥 stub 배열의 값에 따라서 문자열을 변조하는 코드였는데, 이 모든 코드를 복사하고, 값을 변조하는 부분만 문자열로 출력해준다면, 제대로 된 값이 나올 것이다. 일단 코드를 짜기 전 stub의 내용을 [shift+E]로 복사해주었다. 그 후, 이런 식으로 C++ 코드로 복사해..

reversing 2022.08.24

Layer7 리버싱 9차시 과제 - prob4 풀이

이번에도 prob3와 마찬가지로 소스에서 Correct!를 출력하는 부분을 실행시키는 것이 목표인 것 같다. 따라서 저 조건에 맞는 입력을 넣어야 되는데, 미지수가 총 4개이고, 식은 8개이다. 따라서 미지수보다 식의 개수가 많으므로 충분히 풀 수 있다. z3-solver를 이용해 한 번 풀어보자. 일단, unsigned long long형으로 자료를 선언해야하는데, 중간에 xor 등 비트연산자가 나오므로 비트벡터 형식으로 선언해야 한다. 이런 식으로 미지수 4개를 unsigned long long(64비트)의 비트벡터 형식으로 선언했다. 그 후, 임의의 변수에 Solver 객체를 할당하고, 식을 모두 추가한 뒤 check()를 호출하면 방정식이 풀렸다는 뜻의 sat이 출력될 것이다. 이런 식으로 if문..

reversing 2022.08.17

Layer7 리버싱 9차시 과제 - prob3 풀이

이번 과제는 친절하게도 익숙한 C++파일이었고, 내용은 C언어와 다를 게 없었다. 따라서 문자열을 문자 변수 여러개로 인식해서 보기 불편하게 만드는 불상사는 생기지 않았다. 한 번 코드를 살펴보자. 이런 식으로 16자리 문자열을 입력받은 후, 문자열에 대해 특정 연산을 수행한 후에 그 연산 결과가 조건을 만족시키면 Correct!, 다르면 Wrong...을 출력하고 있다. 아마 Correct!를 출력해야 플래그가 나올 것 같기에 저 식을 z3-solver로 풀어 해를 구하면 될 것 같다. (참고로 미지수의 개수만큼 식이 있어야 식을 풀 수 있는데 위의 조건문엔 식이 총 16개이므로, 사용자 입력의 길이와 같아 해를 구할 수 있는 조건을 만족한다. 그럼 한 번 구현해보자. 일단, 비트연산자들은 보이지 않으..

reversing 2022.08.16

Layer7 리버싱 9차시 과제 - prob1 풀이

일단 ida64로 실행파일을 열어보았다. main함수의 초반 부분은 이런데, prob-begin 문제와 같이 %s 형식 지정자로 입력받지만, v4변수가 long long형이기 때문에 char[16]형으로 바꿔주었다. 바꾸기를 원하는 변수를 클릭하고 y키를 누르면 변수 타입을 바꿀 수 있다. 이렇게 변수를 바꿔준 후, 밑에 있는 if문으로 확인했다. 이런 식으로 아주 긴 조건문이 나왔는데, 잘 보면 v4의 0번째부터 QWORD만큼(즉, 8바이트)을 가져와서 쓰고 있다. 이 말은 입력받은 16자리 문자열을 8바이트짜리 long long형 두 개로 바꿔 사용하고 있다는 것이다. 따라서 우린 z3-solver로 방정식을 풀기 전, 변수를 선언할 때 long long의 크기만큼으로 선언해야 하고, 중간에 xor같..

reversing 2022.08.16

Layer7 리버싱 9차시 과제 - prob-begin풀이

일단 파일을 다운받고 ida64로 열어 디컴파일 후 코드를 분석해보았다. 처음 부분에 "%s" 형식 지정자로 입력을 받는데 입력받는 변수 타입이 그냥 char형인 걸 보고 y키를 이용해 변수 타입을 16칸짜리 char형 배열로 바꿔주었다. 정상적으로 변경된 걸 볼 수 있다. 그 후, 밑에 있는 코드를 분석해보았다. 밑에 if문으로 굉장히 복잡한 식으로 입력한 정보가 식에 맞는지 틀린지 확인하고 맞으면 Correct! Flag is ur input, 틀리면 Wrong을 출력하고 프로그램을 종료하고 있다. 따라서 맞는 입력값을 찾으려면 저 식을 모두 만족하는 변수 16개를 모두 찾아야 하는데, 미지수 x개가 있을 때 모든 x를 구하기 위해선 식이 x개 필요하고, 마침 조건문에 들어있는 식의 개수가 16개이니..

reversing 2022.08.16