1. 기본적인 SecureString 사용법
Storing credentials to run PowerShell script in PHP application (remotely)
I'm running a Windows 2012 R2 server with XAMPP (php/mysql/apache) and PowerShell v3. For the past couple of months, my code has been working just fine to store and retrieve an encrypted password ...
stackoverflow.com
2. SecureString을 PHP에 올렸다가 실패한 어느 뉴비의 자문자답
Using exec to run PowerShell script hangs if I try to set credentials
Firstly I apologise but I am pretty new to PHP and PowerShell, we all have to start somewhere! I am creating a utility where everyday IT tasks can be performed from a central web based console. I...
stackoverflow.com
3. 우리는 해냈다 늘 그랬듯이
ConvertTo-SecureString gives different experience on different servers
I am running into an issue creating a Credential Object from an XML File on a remote server. Here is the code I am using to test XML File stackoverflow.com
먼저, 이것을 하려는 목적은
1. 파워쉘기반 운영서버에 (감히) WEBWAS를 돌릴 수 없다.
2. 따라서 운영서버 옆에 나만의 WEBWAS를(다른 운영중인 윈도우서버안에) 구축하여, Remote Powershell로 제어를 하고 싶었다.
3. 웹서버는 IIS를 사용하고, PHP는 FastCGI로 구성했다.(feat 구글링)
4. 간단한 원리는 PHP가 되는 서버에서 Remote Powershell로 운영서버에 Powershell을 날려서 데이터를 가져오고 그것을 Web으로 쏘는 것이다. 그러려면 exec_shell 메서드가 필요하다.
[트러블슈팅1] PHP의 exec_shell 메서드를 사용하여 서버 자원에 접근하려면 PHP가 설치된 서버의 cmd.exe에 IIS_IUSRS에 Read 및 Execute 권한이 필요하다. (Users의 권한을 보안상 제어하는 경우)
5. 리모트 파워쉘을 다른 클라이언트에서 접근하려면 수동으로 패스워드를 입력해서 사용한다. 하지만 자동화를 위해서는 반드시 서버의 인증 정보를 가지고 있다가 원격 접속시 사용해야 한다.
6. 그래서 사용하는 방법이 인증 정보를 만들어 명령을 전달하는 방법이다. 서버의 $id와 (반드시 SecureString으로 변환된) $passwd를 가지고 인증정보($cred)를 만든 후(PSCredential), 그 인증정보를 가지고 $session정보를 만들면 된다.(New-PSSession) 그리고 마지막으로 Invoke-Command를 통해 파워쉘 명령을 Target Server에 날린다.
정리하면
1. $passwd를 SecureString으로 변환한다. |
2. $credential = New-Object PSCredential $id, $passwd (SecureString형태) |
3. $Session = New-PSSession -computername $TargetServer -credential $credential |
4. Invoke-Command -session $session -filepath "실행하려는파워쉘.ps1" -argumentlist "인자값" |
※ 필요한 데이터 $id, $passwd, $TargetServer, 실행하려는파워쉘 및 인자값 |
[트러블슈팅2] PHP의 exec_shell이 SecureString 처리를 못함
$password를 SecureString으로 변환하는 방법은 두 가지가 있다.
1. 서버에 저장된 평문패스워드를 불러온 후(Get-Content) 2. $passwd = ConvertTo-SecureString -AsPlainText -Force -String $plainPW(평문패스워드) |
1. 서버에 저장된 암호화된 패스워드를 불러온다. (이는 ConvertFrom-SecureString을 거친 후 서버에 난수로 저장됨) 2. $passwd = ConvertTo-SecureString -String $encryptedPW (암호회된 패스워드) |
그런데 운영자 관점에서 패스워드 유출이 꺼려지니 당연히 암호화된 패스워드를 사용하는 두 번째 방법을 활용하게 된다. 그런데! PHP서버 내부의 cmd에서 돌리면 너무나 잘돌아가던 파워쉘이 exec_shell에만 들어가면...실행을 못한다.
편의상 $pass를 평문암호, $passwd를 SecureString으로 encrypted된 암호라고 하면, 아래의 두 경우 모두 cmd에서는 결과값을 가져오는데, php에서는 결과값을 가져오지 못한다.
$pass = ConvertFrom-SecureString -SecureString $passwd echo $pass #실패 |
$passwd = ConvertTo-SecureString -String $encryptedPW echo $passwd #실패 |
그래서 그 이후의 $credential을 못 만들어서 php 자체를 못 쓰게 된다는 것.
이러한 문제 때문에 나는 계속 첫번째 방법인 평문패스워드를 -AsPlainText로 사용하였으나 이는 커다란 보안 취약점이다. 그래서 찾아보던 중 오아시스같은 3번째 링크에 다음의 설명을 발견했다.
When you use the command ConvertTo-SecureString it encrypts the plaintext password with the encryption key on the local machine, under your user account.
즉, 내가 이해하기로는 SecureString을 만들때 반드시 key값이 필요한데, key값을 별도로 명시하지 않으면, local machine에 있는 user account를 key값으로 쓴다는 것이고, cmd로는 잘 돌던게 php에서는 안 돌아가는 이유는! php가 shell_exec 메서드로 수행하는 user계정이, cmd에서 만든 ConvertFrom-SecureString를 제대로 처리할리가 없던 것이었다.
그래서 key를 별도로 쓰면 해결되는 문제였다. 다음과 같이 해결하였다.
<인코딩><패스워드를 난수화하여 서버에 저장> $key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43) $plainPassword = "평문패스워드" $securePassword = $plainPassword | ConvertTo-SecureString -AsPlainText -Force #암호화된 패스워드 $securePasswordKey = ConvertFrom-SecureString $securePassword -key $key #암호화된 패스워드를 key로 난수화 Set-Content -Path "c:\패스워드.txt" -Value $securePasswordKey |
<디코딩><난수화된 패스워드를 불러와서 사용> $key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43) $pass = Get-Content -Path "c:\패스워드.txt" $passwd = ConvertTo-SecureString -String $pass -Key $key |
이후 $cred, $session 잘 만들어진다.
'Programming > WEBWASDB' 카테고리의 다른 글
[카톡대화저장] 개행문자 DB에 넣고 PHP로 꺼내는 방법 (0) | 2019.08.08 |
---|