Layer7 과제/리버싱 23

[VM problem] prob-3, prob-4

prob-3 디컴파일해보면 다음과 같다. 최대 길이가 32인 문자열을 입력받고, init_cpu에서 v5에 이를 복사한다. 그리고 run_cpu에서 연산을 거친 후에 v5[0], v5[1], v5[2], v5[3]의 값이 특정 값과 일치한다면 Correct!를 출력하고, 불일치한다면 Wrong...을 출력한다. int __cdecl main(int argc, const char **argv, const char **envp) { unsigned __int64 v4[6]; // [rsp+0h] [rbp-D0h] BYREF unsigned __int64 v5[20]; // [rsp+30h] [rbp-A0h] BYREF v5[19] = __readfsqword(0x28u); memset(v5, 0, 0x90u..

[리버싱] VM Problem:prob-begin, prob-1

prob-begin: 문제파일을 디컴파일하면 아래와 같다. 사용자로부터 최대 길이 16만큼의 문자열을 입력받아 v5에 저장한다. initcpu(v4, v5)는 아래와 같다. 즉, 사용자의 입력을(v5에 있는 값) v4에 복사한다. runcpu(v4)의 내용은 아래와 같다. a1은 v4, 즉 사용자의 입력을 뜻하는 매개변수이고, stub의 값에 따라서 switch-case 문으로 4가지 경우로 분류된다. 4가지 경우는 각각 mov, add, sub, xor을 담당한다. 배열 stub를 확인해보면, Export data의 Preview에 출력되는 값들을 원소로 갖는 배열이라는 것을 알 수 있다. main 함수로 돌아와서, 맨 아래 부분을 확인해보면 아래와 같다. 이 내용을 이해하기 전에, 앞에 나왔던 내용을..

[리버싱] prob-4

문제를 보면, 위와 같다. 사용자로부터 최대 길이 32인 문자열을 입력받는다. 그리고 if문에서 이를 특정한 방법으로 검증하고, 모든 조건을 만족시키는 값이라면 Correct! 가 출력되고 아니라면 Wrong...이 출력된다. (그동안의 문제를 보면, 아마도 flag의 길이가 32일 것이라고 추측할 수 있다. 물론 32라고 확답할 수 없기 때문에 문제를 풀 때 별로 도움이 되지는 않는다. 하지만, if문을 보면 data[0], data[1], data[2], data[3] 4개를 검증한다는 것을 알 수 있다. 이는 flag를 네 부분으로 나눠서 검증한다고 볼 수 있다) 모든 조건을 만족시키는 값을 일일이 구할 수는 없으니 파이썬의 z3 모듈을 사용해서 코드르 짜야한다. if문을 보면 data[0], da..

[리버싱] prob-3

문제를 보며 다음과 같다. 사용자로부터 16자리 문자열을 입력받는다. 그리고 if문을 통해서 입력값을 특정한 방법(+, -, *)으로 검증한다. 만약 모든 조건을 만족시키는 입력값이라면 Correct!를 출력하고, 아니라면 Wrong...을 출력한다. 즉, 우리가 구해야하는 flag는 모든 조건을 만족시키는 입력값이다. 저 많은 조건들에 맞는 값을 하나하나 계산하는 것은 매우 비효율적이고 어려운 일이다. 따라서 컴퓨터가 알아서 조건을 만족시키는 값을 계산하도록 코드를 짜야한다. 이를 파이썬의 z3모듈을 이용해서 구현하면, from z3 import * FLAG = [Int("FLAG_%d" %i) for i in range(16)] solver =Solver() solver.add(FLAG[0] * FL..

[리버싱] prob-1

사용자로부터 입력을 받고, if문들을 통해서 특정 조건을 만족시키는 값인지 확인하다. 모든 if문이 참이 되는 값이라면 Correct!를 출력하고 아니라면 Wrong...을 출력한다. if문을 보면 v4, v5 변수만 다룬다. v4와 v5가 flag 값의 앞쪽 반과 뒤쪽 반을 담당한다. if문의 조건들을 일일이 손으로 해보는 것은 미친짓이다... 따라서 파이썬의 z3모듈을 이용해서 컴퓨터가 조건에 맞는 값을 대신 구하도록 해야된다. if문을 보면 숫자 뒤에 LL이 붙어있는데, 이는 파이썬에서는 의미가 없으므로 때어버리면 된다. 코드로 구현하면 아래와 같다. from z3 import * v4 = BitVec('v4', 64) v5 = BitVec('v5', 64) solver = Solver() solv..

[리버싱] prob-begin

문제를 보면 사용자로부터 입력을 받고, 그 입력값을 if문을 통해 비교한다. 계속 비교하다가 모두 참이라면 Correct! Flag is ur input 이 출력되고, 거짓이면 Wrong이 출력된다. 일단 변수가 너무 많으므로, y단축키 이용해서 s를 s[16]로 수정하겠다. 코드가 훨씬 깔끔해졌다. s를 보기 좋게 FLAG로 고치면, 다음과 같다. if문들의 조건에 맞는 값을 일일이 계산하는 것도 방법이지만, 너무 어렵고 번거롭다. 따라서 파이썬에서 z3 모듈을 사용해서 컴퓨터가 조건에 맞는 값을 대신 구하도록 하겠다. from z3 import * FLAG = [BitVec("FLAG_%d" %i, 8) for i in range(16)] solver = Solver() solver.add( 378 ..

[Dreamhack] rev-basic-8

분석을 위해 IDA를 사용했다. 파일을 보면, 위와 같다. 사용자로부터 입력을 받고, 이를 if문에서 특정한 방법으로 검증한다. if문이 참이 되는 입력값이었다면 Correct가 출력되고 거짓이 된다면 Wrong이 출력되는 프로그램이다. 우리는 if문이 참이 되는 입력값, 즉 flag를 찾아야 된다. 어셈블리어 형태로 보는 것보단 고급언어 형태로 보는 것이 더 편하므로 디컴파일하였다. main 함수를 디컴파일하면, 위와 같다. 사용자로부터 최대 길이 256만큼의 문자열을 입력받고, 이를 if문에서 sub_140001000라는 함수에 인자로 넘긴다. sub_140001000의 함수가 사용자의 입력을 특정한 방법으로 검증한다. 그때의 반환값이 0(거짓)이라면, Wrong이 출력되고, 1(참)(또는 0이 아닌..