일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
- 철학
- CodeEngn
- CodeEngn Basic 01
- 사회적 사실
- BoB 12기
- 디지털 포렌식 트랙
- h4ckinggame
- 자살론
- 논문리뷰
- malware
- 코드엔진 basic 5
- codeengn basic rce 01
- 코드엔진 베이직
- bob
- 사회분업론
- 리버싱
- 코드엔진
- 에밀 뒤르켐
- Best of the Best
- CodeEngn Basic 5
- BoB 12기 최종합격 후기
- Today
- Total
목록IT/DreamHack (8)
woonadz :)
SERIAL을 구하는 문제입니다. DA로 열었을 때, mfc로 GUI를 구현한 프로그램인 것을 확인할 수 있습니다. 이때 사용자 입력값을 찾아가는 방법은 여러가지가 있을 수 있지만 저는 두가지 방법으로 따라가보았습니다. 사용자 입력값과 관련되어 호출되는 문자열을 따라간다. Event ID를 이용하여 사용자 입력값을 검증하는 함수를 따라간다. 2번 방법은 인터넷에서 mfc를 분석할 수 있는 재미있는 방법인 것 같아 해당 예제로 공부해보았습니다. 좀 예전에 풀었던 문제인데 2번 분석을 해보고 싶어 다시 쓰게된 라업이라… 어떻게 풀었는지 잘 기억이 안납니다..ㅎㅎ 주석을 달아두었던 ida 파일도 삭제한 상태여서 처참히 코드만 남았습니다… (라업을 바로바로 작성해야하는 이유) 2번과 관련된 방법은 아래 링크를 ..
sub_160A의 반환값이 1이 되는 조건을 찾아야 합니다. sub_1395, sub_11D6, sub_14B6 함수의 반환값이 모두 1이 되는 조건을 찾아야 합니다. 사용자 입력값의 길이가 43 입니다. 위 로직을 통해 input 값의 형태가 DH{00000000-0000000000-0000000000-00000000} 이라는 것을 알 수 있습니다. calculate_string 함수를 통해 input 값에 대한 연산을 진행하고 반환값을 v4, v3, v2, v1 변수에 할당합니다. 각 문자에 대해 ASCII를 16진수로 변환해주는 연산을 수행하고 그 값을 v5 변수에 더하여 반환합니다. 위 함수들의 연산을 통해 calculate_string 함수의 반환값인 v1, v2, v3, v4의 값을 방정식으로..
덤프된 환경이 아닌 실시간 환경이므로 비휘발성 데이터 수집을 통해 풀이 “로그인 할 때 마다 네트워크 데이터에 민감한 로그인 정보가 유출” ⇒ 로그온 관련 아티팩트 수집 crontab, /var/run, /etc/service, /etc/init.d 등의 스케줄링 관련 아티팩트 X 로그인 시에 발생하는 네트워크 패킷 분석 tcpdump를 뜨면 특정 경로로 불필요한 패킷이 너무 많이 보였습니다. 침해 PC 경로에서 시작하고, 175.117.153.116으로 도착하지 않도록 필터링을 걸어 확인해주었습니다. 다른 터미널에서 로그인을 했을 때 발생하는 패킷을 보면, 123.45.67.89의 경로로 사용자의 로그인 비밀번호가 전송되는 것을 확인할 수 있습니다. 처음에는 root 내의 모든 폴더를 대상으로 키워드 ..
사실 문제 자체는 procmon, malware defense 등의 동적 분석 도구나 동적 디버깅을 통해 쉽게 해결할 수 있지만 코드의 로직을 좀 더 자세히 알아보기 위해 코드 정적 분석을 기반으로 풀이를 작성하였습니다. Cabinet 파일 바탕으로 만들어진 실행파일인 것을 확인할 수 있습니다. 이를 통해 기존 실행 로직에 또 다른 파일이나 폴더가 숨겨져 있을 것이라 추측할 수 있습니다. sub_140004754 함수가 주로 프로그램의 메인 로직을 담당합니다. sub_140004754 함수에서 호출하는 sub_14000526C 함수는 tmp 폴더 내에 폴더를 생성하는 함수입니다. 코드 동적 분석을 통해 생성되는 폴더의 이름과 경로를 확인하였습니다. sub_140004754 함수에서 호출하는 StartAd..
sub_140001000 함수에 사용자 입력값을 인자값으로 주어서 인증 검사를 수행하는 것을 알 수 있습니다. _BOOL8 __fastcall sub_140001000(const char *input) { int i; // [rsp+20h] [rbp-18h] int v3; // [rsp+24h] [rbp-14h] v3 = strlen(input); if ( (v3 + 1) % 8 ) return 0i64; for ( i = 0; i < v3 + 1; i += 8 ) sub_1400010A0(&input[i]); return memcmp(input, &unk_140004000, 0x19ui64) == 0; } 비교 메모리(&unk_140004000) : '0x7E', '0x7D', '0x9A', '0x8B..
DreamHack의 basic reversing 시리즈는 전체적인 로직은 같고, 입력값을 기반으로 serial과 비교하는 부분의 로직이 다르기 때문에 그 부분부터 설명한다. 문자열 참조를 통해 Input 값을 받아 serial 일치 여부를 판단하는 함수가 있는 곳으로 이동했다. rsp 값을 옮긴 rax 레지스터의 값과 18을 비교하는 것으로 보아 serial은 24자리라는 것을 추측할 수 있다. 사용자 입력값을 eax 레지스터에 옮긴다. 16진수 기준으로 0부터 17까지 증가하는 rsp 레지스터의 값을 ecx 레지스터에 옮기고 +1 을 한다. 사용자의 다음 입력값을 ECX 레지스터로 옮긴다. 사용자의 입력값을 더한다. (abcdefg라면 a+b, b+c, c+d 순) 특정 주소에서 값을 가져와 그 값을 ..
DreamHack의 basic reversing 시리즈는 전체적인 로직은 같고, 입력값을 기반으로 serial과 비교하는 부분의 로직이 다르기 때문에 그 부분부터 설명한다. 1C와 비교하는 것으로 보아 총 28자리의 serial인 것을 추측할 수 있다. sar 명령어는 오늘 처음 보았다. sar : 오른쪽으로 밀어 낮은 bit를 내보내고 Carry Flag로 복사, 높은 bit 쪽에 0을 더하여 채운다. But keep sign(1) 해야한다. 사용자가 입력한 첫 값에 대해 위와 같이 계산한다. shl : 왼쪽으로 밀어(shift) 높은 bit를 내보내고 Carry Flag로 복사 낮은 bit쪽에 0을 더하여 채운다. 사용자가 입력한 첫 값에 대해 위와 같이 계산한다. shl 연산을 한 값과 F0을 an..
문제 from Crypto.Util.number import bytes_to_long, getPrime flag = bytes_to_long(b'DH{???????????????????????????????????????????????????????}') p1 = getPrime(420) p2 = getPrime(420) p3 = getPrime(420) print(f'p1 = {p1}') print(f'p2 = {p2}') print(f'p3 = {p3}') print(f'c1 = {flag % p1}') print(f'c2 = {flag % p2}') print(f'c3 = {flag % p3}') output p1 = 152720747024314397374153010591098602427164998..