반응형

책소개


제가 요즘 회사일, 집안일 외에 대부분의 시간에 리버싱 서적을 열심히 쓰고 있습니다. 책 홍보를 위해 간략히 소개해 드리자면 타겟 독자층은 "리버싱 입문을 원하는 초보자"와 "리버싱 레퍼런스가 필요한 중급자" 입니다. 컨셉은 "내부 동작 원리를 아주 쉽고 뜨겁게 이야기" 하는 것입니다. 분량은 (제발) 1,000 페이지가 넘지 않도록 노력 중입니다. 책 내용은 블로그 내용을 좀 다듬어서 60% 정도를 채우고, 새로운 주제를 써서 나머지 40% 정도를 채울 예정입니다. 그리고 실습 예제를 많이 넣으려고 합니다.


일정


집필 일정은 늦가을까지로 예정했었습니다. 그런데 쓰면 쓸수록 제 자신이 점점 진지해지면서 입문자에게 필요하다고 생각되는 범위와 분량이 대폭 늘어나고 있습니다. 일정과 분량을 조절할 필요가 있네요. 욕심을 자제하려고 노력도 해봤지만, 진정한 "리버싱 입문서"를 독자에게 제공해야 한다는 사명감(?) 같은 게 생겨서 이젠 굳이 자제하려고 노력하지 않습니다. ^^


조언


제 블로그를 방문하시는 분들 중에서 혹시 제가 책에서 다루면 좋겠다고 생각되는 주제(또는 조언, 건의, 아무거나)가 있으시다면 댓글로 알려주시기 바랍니다. 작업에 큰 도움이 될 것입니다.


블로그


블로그에 글을 많이 올리지 못해서 자주 방문하시는 분들께 죄송하다는 말씀을 드립니다. 집필이 끝나면 제 블로그에는 실전 리버싱 실습 위주로 포스팅을 할 예정입니다. 그리고 책에 미처 쓰지 못한 내용들을 올리게 될 것입니다.

제 블로그는 매일 방문하고 있습니다. 댓글의 질문들에 답변도 올리고, 이메일로 문의하신 내용도 꼭 챙겨읽고 답변 드리고 있습니다. 리버싱 하시다가 궁금한 점 있으시면 부담 갖지 마시고 질문해 주세요. 저는 같이 생각해 보는 것을 좋아합니다. 답변 달면서 제가 더 많이 배우니까요.

그리고 바쁘더라도 종종 글을 올려야겠어요. 예전에는 블로그 포스팅 하는게 저의 즐거움 이었는데 말이죠. 요즘엔 글을 쓰기만 하고 올리지는 않으니 즐거움이 하나 줄었어요.

방문해 주시는 모든 분들께 감사 드립니다.
댓글, 이메일 보내주시는 분들에게도 감사드려요. 여러분께서는 모두 가까운 미래에 '열혈 리버서' 가 되실 것입니다.

감사합니다. 

* 제가 좋아하는 멘트를 하나 남길께요~ 제 트위터에도 쓴 내용입니다. (트위터를 혼잣말 하는 공간으로 활용하기 때문에 Follow, RT 이런거 없어요. ^^)

"똑같은 시기에 비슷한 생각을 하는 사람은 많지만 실천에 옮기는 사람은 드물다. 나는 생각을 행동에 옮겼을 뿐이다. 기회는 도전하고 실천하는 자가 받는 선물 같은 것이다." - 강덕수, STX 그룹 회장 (창업주)

반응형
반응형

제가 개발한 InjDll.exe 프로그램을 소개합니다. 
이 프로그램을 이용해서 원하는 DLL 을 대상 프로세스에 Injection/Ejection 시킬 수 있습니다.



DLL Injection 에 관련된 설명을 아래 링크를 참조하세요.




InjDll.exe (Ver 1.0.0)


제 블로그 study 에서 자주 소개되는 프로그램입니다.
소스를 조금 다듬고 기능을 추가시켜서 정식 버전(1.0.0)으로 배포합니다.

이 프로그램은 공개용이며, 자유롭게 사용하실 수 있습니다.


* 주의!
기본적으로 Windows 2000 이상만 지원합니다. (Windows 7, XP 에서 테스트 되었습니다.)
Windows 9X 계열에서는 사용하실 수 없습니다.


사용방법은 아래와 같습니다.

InjDll.exe <procname|pid|*> <-i|-e> <dll path>

<procname|pid|*>
  procname      Process name (ex: explorer.exe, notepad.exe, etc)
  pid           Process ID

<-i|-e>
  -i            Injection Mode
  -e            Ejection Mode

<dll path>      DLL File Path (relative or full)


사용 예
- PID 2840 프로세스에게 dummy.dll 파일을 Injection 시킬 때



- IE 프로세스에게 dummy.dll 파일을 Injection 시킬 때



- 모든 프로세스에게 dummy.dll 파일을 Injection 시킬 때



Ejection 은 –i 대신 –e 를 사용하면 됩니다.



InjDll.exe (Ver 1.1.1)


InjDll.exe 가 버전업 되었습니다. (2010.10.29)




추가/변경 사항


1. 64bit 지원

InjDll64.exe 를 이용하여 64bit 프로세스에 64bit DLL 파일을 인젝션 시킬 수 있습니다. 

* 64bit 프로세스에 DLL Injection 을 하기 위해서는 Injector(InjDll64.exe) & DLL 파일이 모두 64bit(PE32+) 이어야 합니다.


2. <dll path> 의 "상대 경로" 지원 

아래와 같이 Dll 파일 위치를 상대 경로로 입력할 수 있습니다.

InjDll32.exe notepad.exe -i dummy32.dll
InjDll32.exe calc.exe -i ..\hook.dll
...



주의사항


1) 원격 스레드를 실행시켜 LoadLibrary() 를 호출하는 방식이므로 대상 프로세스에 kernel32.dll 이 로딩되어 있지 않다면 Injection/Ejection 작업은 실패합니다.

2) 접근 권한이 제한된 (보호받는) 프로세스나 Anti-Injection 기법이 적용된 프로세스 들에게도 역시 Injection/Ejection 작업은 실패합니다.

3) 원칙적으로 Injection 을 N 번 시켰을 때 Ejection 도 같은 횟수로 호출해 줘야 해당 DLL 이 제대로 unloading 됩니다.



Bugs


사용하시다가 버그가 발견된다면 댓글로 알려주시면 감사하겠습니다.



ReverseCore

위 글이 도움이 되셨다면 추천(VIEW ON) 부탁 드려요~
반응형

'tool' 카테고리의 다른 글

PEView.exe  (21) 2013.01.27
HxD.exe 기능 추가!  (12) 2012.06.14
리버싱 현업에서 사용되는 디버거(Debugger)들  (33) 2010.09.29
Process Explorer - 최고의 작업 관리자  (1) 2009.05.03
www.virustotal.com  (3) 2009.03.20
www.google.com  (2) 2009.03.06
반응형


<photo : skedonk on flickr>

"끓을 만큼 끓어야 밥이 되지, 생쌀이 재촉한다고 밥이 되나."

윤오영님의 수필 [방망이 깎던 노인] 에 나오는 구절입니다.
필수적인 과정을 거쳐야 제대로 된 결과가 나온다는 뜻이지요.


리버싱을 제대로 하려면 공부해야 할 내용이 무척 많다는 것을 잘 아실 것입니다.
우리는 리버싱 공부에 시간과 노력을 쏟아야 합니다.

하지만 조급한 마음이 사람을 초조하게 만들고 반복된 실패를 참을 수 없게 만드는 것 같습니다.
리버싱을 하다 보면 매 순간마다 (내가 알지 못하는) '벽'에 부딪힙니다.
이러한 '벽'을 도전 과제로 삼고 극복하는 과정에서 희열이 느껴집니다.
제 생각에는 이게 바로 리버싱의 본질이 아닐까 생각합니다.

잘 안 된다고 스트레스 받지 마세요.
리버싱은 원래 "잘 안 되는 속성"을 가지고 있습니다.
마음을 편안하게 먹고 차근차근 정보를 수집하세요.
성공할 때까지 계속 시도해보는 겁니다.
머리 아프면 쉬었다 하세요.
중요한 건 포기하지 말고 꾸준히 하는 것입니다.

마치 퍼즐 조각을 맞추는 것과 같습니다.
해결 방법은 분명히 있습니다.
노력과 시간을 투자한다면 결국에는 성공할 수 있습니다.

어찌 보면 모든 엔지니어링의 본질적인 속성이 이와 같다고 생각됩니다.
결국 시간을 투자하고 노력할 수록 실력이 늘어나는 이치는 똑 같은 것이니까요.

"시간과 노력을 투자한 만큼 정직하게 실력이 쌓여간다."

전 이 맛에 리버싱을 하나 봅니다.

여러분은 어떠신가요?


+---+


요즘 과도한 업무에 심신이 많이 지쳤답니다.
피곤하고, 스트레스 받고, 시간에 쫓기면 사람은 초심을 잃게 되지요.
제 스스로 초심을 되새기고 목표를 향해 끊임없이 나아가고자 다짐하며 글을 올려봅니다.

ReverseCore

반응형
반응형

API Hooking 에서 사용되는 각종 방법들에 대한 Tech Map 을 소개하고 간략한 설명을 하겠습니다.

API Hooking 의 기본 소개는 아래 글을 참고해주세요.

참고: API Hooking - 리버싱의 '꽃'



API Hooking Tech Map


아래 그림이 API Hooking 의 모든 기술적 범주를 포함하는 Tech Map 입니다.


<Fig. 1>

위 Tech Map 을 이용하면 그 동안 막연하게만 보였던 API 후킹이 (기술적으로) 단번에 파악됩니다.

API 후킹 작업을 할 때 상황에 맞게 위의 Tech Map 에서 적절한 기법을 골라서 적용하시면 됩니다. (가장 널리 사용되는 기법은 빨간색으로 표시하였습니다.)


[ Method – Object (what) ]

API 후킹 방식(Method)에 대한 대분류 입니다.

API 후킹 방식(Method)는 작업 대상(Object)에 따라서 크게 static 방식dynamic 방식으로 나눌 수 있습니다.

static 방식은 작업 대상(Object)이 ‘파일’이며, dynamic 방식은 작업 대상이 프로세스 ‘메모리’ 입니다.
일반적으로 API 후킹이라고 하면 dynamic 방식을 말하며, 매우 특수한 상황에서 static 방식을 사용할 때도 있습니다.

각각에 대한 설명은 아래의 표에 정리하였습니다.


<Fig. 2>

* static 방식은 여러 가지 단점 때문에 일반적으로 사용하기에 어려운 부분이 많이 있습니다. 다만 특수한 경우에 사용되기도 하므로 여기서는 소개 정도만 하고 넘어갑니다.


[ Location (where) ]

대상의 어느 부분을 공략(조작)해야 하는지에 대한 내용입니다.

일반적으로 3 군데의 공략 위치가 있습니다.

1) IAT

IAT 에 있는 API 주소를 후킹 함수 주소로 변경하는 방법입니다.

장점은 가장 단순하며, 구현 방법이 가장 쉽습니다.

단점으로는 IAT 에 없는데 프로그램에서 사용되는 API 들에 대해서는 후킹할 수 없습니다. (예: DLL 을 동적으로 로딩해서 사용하는 API)

2) Code

프로세스 메모리에 매핑된 시스템 라이브러리(*.dll)에서 API 의 실제 주소를 찾아가 코드를 직접 수정해버리는 방법입니다.

참고로 이 방법이 가장 널리 사용되는 방법이며, 구현에 있어서 아래와 같은 여러 가지 다양한 옵션이 있습니다.
 
- 처음 5 byte 를 JMP XXXXXXXX 명령어로 패치하는 방법
- 함수 일부를 덮어쓰는 방법
- 필요한 부분만 일부 변경하는 방법

3) EAT

DLL 의 EAT(Export Address Table) 에 기록된 API 의 시작 주소를 후킹 함수 주소로 변경하는 방법입니다.

개념은 간단하지만 코드 구현에 있어서 위 2) 번 방법이 더 간단하고 강력하므로 EAT 수정 방법은 잘 사용되지 않습니다.


[ Technique (How) ]

후킹 대상 프로세스 메모리에 침투하여 후킹 함수를 설치하는 구체적 기법(Technique)에 대한 내용입니다.

크게 Debug 와 Injection 기법으로 나눌 수 있으며, Injection 기법은 다시 Code 와 Dll 기법으로 나뉘어 집니다.

A) Debug

대상 프로세스를 디버깅하면서 API 후킹을 하는 방법입니다.

아마 이 말이 무슨 의미인지 이해가 잘 안 되는 분들이 계실 것입니다.
“그게 디버깅이지 무슨 API 후킹이야?” 하고 말이죠.

디버거(Debugger)는 디버깅 당하는 프로세스(Debuggee)에 대한 모든 권한(실행 제어, 메모리 액세스, 기타)을 가지기 때문에, Debuggee 의 프로세스 메모리에 후킹 함수를 자유롭게 설치 할 수 있습니다.

여기서 얘기하는 Debugger 는 일반적인 OllyDbg, Windbg, IDAPro 등이 아니라, 후킹을 위하여 사용자가 직접 제작한 프로그램입니다.
즉, 프로그램 내에서 Debug API 를 이용하여 대상 프로세스에 Attach 하고 (실행이 잠깐 멈춰진 상태에서) 후킹 함수를 설치합니다. 그 후 실행을 재개시키면 완벽한 API Hooking 이 이뤄지는 것입니다. (XP 이상의 시스템에서는 Debuggee 의 종료 없이 Debugger 를 Detach 시킬 수 도 있습니다.)

물론 기존 디버거(OllyDbg, Windbg, IDAPro)에 자동화 스크립트를 사용하여 API 후킹을 자동화 시키는 방법도 있습니다. (특히 Immunity Debugger 같은 경우 강력한 전용 Python 스크립트를 지원하고 있습니다.)

이 방식의 장점은 구현만 완벽하다면 (하나의 프로세스에 대한) 가장 강력한 후킹 방법입니다. API 후킹 뿐만 아니라 필요에 따라서 실행 흐름 까지도 완벽히 제어할 수 있습니다.

따라서 API 후킹 도중이라도 사용자가 Interactive 하게 프로그램의 실행을 멈추고 API 후킹을 추가/수정/제거 등의 작업을 할 수 있습니다. (다른 방식과 가장 큰 차이점입니다.)

단점은 Debugger 에 대한 지식(혹은 자동화 스크립트에 대한 지식)이 필요합니다. 또한 안정적인 동작을 위해서는 많은 테스트가 요구됩니다. 이와 같은 단점들 때문에 (강력함에도 불구하고) 범용적으로는 사용하기는 쉽지 않습니다.

B) Injection

Injection 기법은 해당 프로세스 메모리 영역에 침투하는 기술로써 Injection 대상에 따라 B-1) Code InjectionB-2) DLL Injection 으로 나눌 수 있습니다. 그 중에서 DLL Injection 기법이 가장 널리 사용됩니다.

DLL Injection 기법은 대상 프로세스로 하여금 강제로 사용자가 원하는 DLL file 을 로딩하게 만드는 기술입니다. (DLL Injection 에 대한 자세한 설명은 예전의 제 글을 참고하세요. DLL Injection - 다른 프로세스에 침투하기 (1))

Injection 할 DLL 에 미리 후킹 코드와 설치 코드를 만들고 DllMain() 에서 설치 코드를 호출해 주면 Injection 되는 순간에 API 후킹이 완료됩니다.

Code Injection 기법은 기존 DLL Injection 보다 좀 더 발전된 (복잡한) 기술이며, 주로 악성코드(바이러스, 쉘코드, 기타)에서 많이 사용됩니다. (DLL Injection 은 AV 제품에서 탐지가 잘 되므로, 악성 코드들은 좀 더 탐지하기 어려운 Code Injection 을 많이 시도하고 있습니다.)

Code Injection 기법의 구현방법은 상당히 까다로운 편입니다. 그 이유는 DLL Injection 처럼 완전한 형태의 PE 이미지가 아니라 실행 코드와 데이터만 Injection 된 상태에서 자신이 필요한 API 주소를 직접 구해서 사용해야 하며, 코드 내의 메모리 주소에 접근할 때 잘못된 주소를 액세스 하지 않도록 매우 주의해야 하기 때문입니다.

말로만 설명하면 어렵습니다. 나중에 코드를 보며 직접 실습을 해보도록 하겠습니다.
(직접 해보시면 왜 어렵다고 말씀 드렸는지 느낌이 팍 오실 것입니다.)

[ API ]

Tech Map 에 소개된 방법들을 실제로 구현하기 위해서 사용되는 API 들을 소개합니다.

한번씩 읽어 보시고 향후 실습할 때 사용법에 대해서 자세히 살펴보도록 하겠습니다.

참고로 위에 소개된 API 말고도 OpenProcess(), WriteProcessMemory(), ReadProcessMemory() API 들은 다른 프로세스 메모리에 접근하려고 할 때 항상 사용되는 API 들입니다.


+---+

설명이 많이 길었습니다.
다소 지루하시더라도 세부 기술 설명에 앞서 이러한 이론적인 설명은 꼭 필요합니다.

위와 같이 Tech Map 으로 전체 기술에 대해 이론적으로 잘 정리해 두면 기술에 대해서 더 잘 이해할 수 있고, 실전에서 (상황에 맞게) API Hooking 을 적용하기 쉬워집니다.

다음 번 포스트에서는 위 방법을 하나씩 실습해 보도록 하겠습니다. (static 방법에 대한 설명은 생략하겠습니다.) 각 경우에 대한 실습을 진행하면서 그때그때 필요한 설명은 자세히 추가하겠습니다.




ReverseCore


반응형
반응형

API Hooking 에 대한 강좌입니다.
User 에서 API Hooking의 다양한 기법들에 대해서 자세히 설명하도록 하겠습니다.



후킹 (Hooking)

리버싱에서 후킹은 정보를 가로채고, 실행 흐름을 변경하고, 원래와는 다른 기능을 제공하게 하는 기술입니다.

후킹의 전체 프로세스는 아래와 같습니다.

- 디스어셈블러/디버거를 이용하여 프로그램의 구조와 동작원리를 파악
- 버그 수정 또는 기능 개선에 필요한 Hook 코드를 개발 [1]
- 실행 파일과 프로세스 메모리를 자유롭게 조작하여 Hook 코드 설치

위와 같은 일련의 작업들은 그야말로 리버스 엔지니어링 기술의 핵심(Core) 이라고 할 수 있습니다.

그래서 전 후킹을 "리버싱의 꽃" 이라고 부릅니다.

여러가지 후킹 기술이 있지만 그중에서도 API 를 후킹하는 기술을 API Hooking 이라고 하고, User mode 후킹 중에서 메시지 후킹[2]과 함께 가장 널리 사용되는 기술입니다.


[1] 프로그램 소스가 있다면 대부분의 경우 후킹은 필요하지 않을 것입니다. 하지만 특수한 상황(소스 코드가 없거나, 소스 코드의 수정이 여의치 않은 상황)에서는 후킹 기술이 요긴하게 사용될 수 있습니다.

[2] 메시지 후킹(Message Hooking) 에 대한 내용은 제 글을 참고하시기 바랍니다.

- Windows Message Hooking (윈도우 메시지 후킹)



API (Application Programming Interface)


API Hooking 을 설명하려면 먼저 API(Application Programming Interface) 에 대해서 짚고 넘어가야 합니다.

Windows OS 에서는 사용자 어플리케이션이 시스템 자원(메모리, 파일, 네트워크, 비디오, 사운드, 기타)을 사용하고 싶을 때 직접 할 수 있는 방법이 없습니다. 왜냐하면 그것들은 OS 가 직접 관리하며, 여러 가지 이유(안정성, 보안, 효율, 기타)로 사용자 어플리케이션의 직접적인 접근을 막아놓았기 때문입니다.

이럴 때 사용자 어플리케이션은 시스템 커널에게 요청해야 합니다. 요청 방법이 바로 MS 에서 제공한 Win32 API 를 이용하는 것입니다. (API 는 해당 OS 제작사에서 제공합니다.)

즉, API 함수 없이는 어떤 의미 있는 프로그램을 만들어 낼 수 없습니다.

아래 그림은 32 bit Windows OS 의 프로세스 메모리를 간략히 나타낸 것입니다.


<Fig. 1>

실제 어플리케이션 코드를 실행 시키기 위해 많은 시스템 라이브러리(DLL) 들이 로딩됩니다. [3] 모든 프로세스에는 기본적으로 kernel32.dll 이 로딩되구요, kernel32.dll 은 ntdll.dll 을 로딩합니다. (참고로 GUI 어플리케이션에서는 user32.dll 과 gdi32.dll 또한 필수 라이브러리 입니다.)

ntdll.dll 의 역할이 바로 유저 모드 어플리케이션의 코드에서 발생하는 시스템 자원에 대한 접근을 커널 모드에게 요청 하는 것입니다.


간단한 를 들어보겠습니다.
notepad.exe 에서 c:\abc.txt 라는 파일을 열고자 합니다.
코드에서는 msvcrt!fopen() API 를 호출합니다. 그 이후의 API 호출 흐름을 보면 아래와 같습니다.

msvcrt!fopen()
 
kernel32!CreateFileW()
    ntdll!ZwCreateFile()
      ntdll!KiFastSystemCall()
        SYSENTER                     // Intel IA-32 Op Code
          => 커널 모드 진입


일반적인 시스템 자원을 사용하는 API 는 kernel32.dll 과 ntdll.dll 을 타고 가다가 결국 SYSENTER 명령을 통해 커널 모드로 진입하게 됩니다.


[3] 'DLL 로딩(loading)' 이라는 용어보다는 'DLL 매핑(mapping)' 이라는 용어가 더 정확한 표현입니다. Windows 운영체제는 DLL 을 최초 한번만 메모리에 적재(loading) 하고, 그 이후부터는 프로세스에게 매핑(mapping) 시켜주는 메커니즘을 사용합니다.



API Hooking


API Hooking 이란 Win32 API 호출을 중간에서 가로채서 제어권을 얻어내는 것입니다.

API Hooking 의 이점은 다음과 같습니다.

- API 호출 전/후에 사용자의 훅 코드(Hook Code)를 실행시킬 수 있습니다.
- API 에 넘어온 파라미터 혹은 API 함수의 리턴값을 엿보거나 조작 할 수 있습니다.
- API 호출 자체를 취소시키거나 사용자 코드로 실행 흐름을 변경시킬 수 있습니다.

이해를 돕기 위해 아래 그림을 봐주시기 바랍니다.

먼저 정상적인 API 호출입니다.


<Fig. 2>

코드 영역 주소에서 CreateFile() API 를 호출하였습니다. [4]

CreateFile() API 는 kernel32.dll 에서 서비스(export) 하므로 kernel32.dll 영역의 CreateFile() API 가 실행되고 정상적으로 리턴합니다.

[4] 실제 kernel32 에서 서비스되는 API 이름은 CreateFileA() 와 CreateFileW() 입니다. 프로그래밍할 때 CreateFile() 만 써주면 컴파일 시에 적절히 CreateFileA()/CreateFileW() 중에서 결정됩니다. 여기서는 설명의 편의상 CreateFile() 로 하였습니다.


다음은 kernel32!CreateFile() 가 후킹된 경우입니다.


<Fig. 3>

사용자가 DLL Injection 기술로 hook.dll 을 프로세스 메모리 공간에 침투 시킵니다. 그리고 kernel32!CreateFile() 를 hook!MyCreateFile() 로 후킹하였습니다. (후킹 함수 설치 방법은 DLL Injection 말고도 더 있습니다.)

이제부터 해당 프로세스에서 CreateFile() API 가 호출 될 때마다 kernel32!CreateFile() 이 호출 되는 것이 아니라, hook!MyCreateFile() 이 호출 됩니다.

후킹 함수(MyCreateFile)와 원본 함수(CreateFile)의 호출 순서는 경우에 따라 달라집니다.
입력된 파라미터를 조작하고 싶을 때는 후킹 함수가 먼저 실행되고 나중에 원본 함수가 실행됩니다. 또한 API 리턴값을 조작하고 싶을 때는 원본 함수가 먼저 실행된 후 후킹 함수가 나중에 실행됩니다.

이 외에도 후킹 목적에 따라서 원본 함수 호출 전/후에 후킹 함수를 실행시키거나 원본 함수를 아예 호출하지 않는 등의 여러 가지 변형이 가능합니다. 따라서 후킹 목적과 상황에 따라서 적절히 사용해 주시면 되겠습니다.

이것이 바로 API Hooking 의 기본 개념입니다.

API Hooking 을 구현하는 방법은 다양합니다. 하지만 후킹의 기본 개념은 변하지 않습니다.

위의 개념을 잘 이해하시면 이후에 설명 드리는 구현 방법에 대해서도 쉽게 이해하실 수 있습니다.


+---+

다음 포스트로 이어집니다.

API Hooking - Tech Map


ReverseCore

반응형

+ Recent posts