관련 지식
#fiddler #proxy

피들러는 PC에서 로컬 프록시 기능을 하는 프로그램으로 URL 모니터링, 웹 모의해킹, 테스트 용도로 자주 사용되는 프로그램입니다.

피들러

피들러는 다양한 강력한 기능을 제공하는데 FiddlerScript 로 작성하는 Customize rules는 경유하는 패킷을 제어하여 피들러를 더욱 다양하게 활용 할 수 있도록 만들어 줍니다.

단축키 ‘Ctrl + R’ 또는 상단 메뉴의 ‘Rules - Customize Rules…’ 를 클릭하면 Script Editor 를 실행할 수 있습니다.(최초 실행시 설정 화면 나타날 수 있음)

FiddlerScript 구성

에디터

좌측에는 소스 에디터가 보이고 우측에는 스크립트에서 사용 가능한 객체와 함수 목록이 있습니다. ‘Rule’을 수정하면서 필요한 기능이나 객체는 우측의 목록에서 찾아서 사용하면 됩니다. Session 객체를 가장 많이 사용하게 되실 겁니다.

피들러에서 제공하는 스크립트 에디터 대신 ‘Visual Studio Code’ 나 ‘Atom’ 같이 평소에 즐겨쓰는 에디터를 사용할 수도 있지만 피들러 스크립트에서 사용되는 객체를 쉽게 확인하기 위해서라도 스크립트 에디터를 사용하는 것이 좋습니다.

OnBeforeRequest

‘OnBeforeRequest()’는 서버로 요청하기 이전에 호출되는 함수 입니다. 여기서 Request Parameter 등을 조작하여 서버에 다른 값을 요청할 수 있습니다. 물론 요청하는 프로그램쪽에선 그러한 상황을 모르고 있죠.

상단 메뉴의 ‘Go - to OnBeforeRequest’를 클릭하여 함수가 정의된 곳으로 이동하겠습니다. 또는 소스에서 직접 찾아가시면 됩니다.

  1. static function OnBeforeRequest(oSession: Session) {
  2. // Sample Rule: Color ASPX requests in RED
  3. // if (oSession.uriContains(".aspx")) { oSession["ui-color"] = "red"; }
  4. // Sample Rule: Flag POSTs to fiddler2.com in italics
  5. // if (oSession.HostnameIs("www.fiddler2.com") && oSession.HTTPMethodIs("POST")) { oSession["ui-italic"] = "yup"; }
  6. // Sample Rule: Break requests for URLs containing "/sandbox/"
  7. // if (oSession.uriContains("/sandbox/")) {
  8. // oSession.oFlags["x-breakrequest"] = "yup"; // Existence of the x-breakrequest flag creates a breakpoint; the "yup" value is unimportant.
  9. // }
  10. if ((null != gs_ReplaceToken) && (oSession.url.indexOf(gs_ReplaceToken)>-1)) { // Case sensitive
  11. oSession.url = oSession.url.Replace(gs_ReplaceToken, gs_ReplaceTokenWith);
  12. }
  13. if ((null != gs_OverridenHost) && (oSession.host.toLowerCase() == gs_OverridenHost)) {
  14. oSession["x-overridehost"] = gs_OverrideHostWith;
  15. }
  16. ... 생략 ...
  17. }

이미 여러 내용이 있는것을 보실 수 있습니다. 피들러에서 사용하는 기본 기능으로 가급적 직접 건드리지 않는 것이 좋습니다. 추가적으로 작성하고 싶으신것은 OnBeforeRequest 함수 이름 바로 아래, 샘플 소스가 보이는 위치에 작성하시면 됩니다.(기본 룰보다 먼저 적용 되도록)

OnBeforeResponse

‘OnBeforeResponse()’는 서버로 부터 응답받은 데이터를 프로그램으로 전달하기 이전에 호출되는 함수 입니다. 여기서 데이터를 수정하게 되면 프로그램에선 수정된 데이터를 기준으로 동작하기 때문에 원래 의도와 다른 기능을 수행할 수가 있습니다.

상단 메뉴의 ‘Go - to OnBeforeResponse’를 클릭하여 함수가 정의된 곳으로 이동하거나 소스에서 직접 찾아가시면 됩니다.

  1. static function OnBeforeResponse(oSession: Session) {
  2. if (m_Hide304s && oSession.responseCode == 304) {
  3. oSession["ui-hide"] = "true";
  4. }
  5. }

기본으로 세팅된 룰 이후에 원하는 룰을 만드시면 됩니다. 만약 HTML의 내용을 수정하게 된다면 브라우저에서는 수정된 내용으로 보이게 될 것입니다.

OnBeforeResponse 수정 해보기

네이버의 메인 화면을 보면 아주 좋은 위치에 광고가 있습니다.

광고

광고하시는 분께는 미안하지만 광고를 숨기는 스크립트를 만들어 보겠습니다. 먼저 개발자 도구를 이용하여 해당 광고의 HTML이 어떤것인지 찾아야 합니다.

개발자도구

‘id’가 veta_top인 div에 iframe 요소로 광고가 있는것을 볼 수 있습니다.
그런데 개발자 도구에서 보이는 내용은 자바스크립트가 동적으로 만들어낸 요소가 포함되어있으므로 서버로부터 응답받은 내용과는 차이가 있을수 있습니다. 따라서 해당 요소가 서버로 부터 응답받은 내용에는 어떻게 있는지 확인해 보겠습니다. 서버로부터 응답받은 내용은 소스보기를 하면 확인 가능합니다.(fiddler에서 보셔도 되고 개발자도구네트워크에서 보셔도 상관없습니다.)

소스보기

개발자도구와는 좀 다르게 보이지만 동일한 항목이 있는것이 확인됩니다. 이제 이 소스를 기반으로 OnBeforeResponse() 에 룰을 만드시면 됩니다.

  1. if(oSession.HostnameIs("www.naver.com")) {
  2. oSession.utilDecodeResponse();
  3. }

적용하는 룰이 다른 사이트에도 적용되면 안되므로 네이버에 도메인인지 확인하는 조건을 만들었습니다. oSession.utilDecodeResponse(); 함수는 응답받은 패킷에서chunk 와 compression 부분을 정리(삭제) 해줍니다.

이번엔 응답받은 데이터에서 해당 HTML을 지워보겠습니다. Session 객체에선 문자열을 치환할수 있는 세가지 함수를 제공하고 있습니다.

  • utilReplaceRegexInResponse()
  • utilReplaceInResponse()
  • utilReplaceOnceInReponse()

가장 쉬운 단순 문자열 치환 함수를 써보겠습니다. iframe 태그를 망가뜨려 정상적으로 동작하지 않도록 해볼 것입니다.

  1. oSession.utilReplaceInResponse('<iframe id="da_iframe_time"', '<asd');

소스를 수정하고 저장을 누르면 알림 소리가 들릴 것입니다. 꽥 하는것 같은 소리가 들리면 스크립트 어딘가 오류가 있는것이라 생각하면 됩니다. 알림 소리가 나지 않으면 저장되지 않은 것입니다.

정상적으로 저장된 후 네이버를 다시 호출하고 소스보기를 하면 아래와 같이 iframe 태그가 치환되고 정상적으로 동작하지 않은것을 보실수 있습니다.

결과)

치환

광고없음

그런데 광고가 있던 공간이 남아있는게 영 맘에 안듭니다. veta_top 인 div 때문에 그런것인데 문자열 일부가 아니라 해당 div 전체를 지워보겠습니다.

  1. oSession.utilReplaceRegexInResponse('(<div id="veta_top">)(.*?)(<\/div>)', '');

결과)

영역없앰

이번엔 모양이 더 이상해졌습니다. 아마도 삭제한 div 태그를 기준으로 동작하는 스크립트 로직이 있는것 같습니다. 다른 방법을 써야 할것 같습니다.

  1. oSession.utilReplaceInResponse('<div id="veta_top">', '<div id="veta_top" style="display:none">');

결과)

숨기기

div 영역이 숨겨지도록 display 속성을 추가하니 광고 영역이 사라졌습니다. 소스보기를 해보면 치환환 HTML이 보일 것입니다. 이렇게 수정을 하면 서버에서 보내준것과 다른 화면을 브라우저에서 보게 됩니다.

정리

Fiddler는 강점이 많은 프로그램입니다. 이것과 비슷한 기능을 하는 프로그램으로 Burf Suite 가 있는데 Customize Rule로 인해 보다 비교 우위에 있는것 같습니다. 저는 Synology NAS를 쓰고 있는데 룰을 잘 만들면 시놀로지의 기능중 하나인 다운로드 스테이션을 보다 편리하게 사용하실 수도 있습니다. 각자의 다양한 활용 방법이 생길것 같네요

최종 샘플

  1. static function OnBeforeResponse(oSession: Session) {
  2. if (m_Hide304s && oSession.responseCode == 304) {
  3. oSession["ui-hide"] = "true";
  4. }
  5. if(oSession.HostnameIs("www.naver.com")) {
  6. oSession.utilDecodeResponse();
  7. //oSession.utilReplaceInResponse('<iframe id="da_iframe_time"', '<asd');
  8. //oSession.utilReplaceRegexInResponse('(<div id="veta_top">)(.*?)(<\/div>)', '');
  9. oSession.utilReplaceInResponse('<div id="veta_top">', '<div id="veta_top" style="display:none">');
  10. }
  11. }