악용 가능한 PHP 함수
임의 코드 실행에 사용할 수있는 함수 목록을 작성하려고합니다. 블랙리스트에 있거나 허용되지 않는 기능을 나열하는 것이 목적이 아닙니다. 오히려 백도어를 위해 손상된 서버를 검색 할 때 유용한 빨간색 플래그 키워드 grep
목록을 만들고 싶습니다 .
아이디어는 c99 또는 r57과 같은 "웹 쉘"스크립트와 같은 다목적 악성 PHP 스크립트를 빌드하려면 비교적 작은 기능 세트 중 하나 이상을 사용해야한다는 것입니다 사용자가 임의의 코드를 실행할 수 있도록 파일의 어딘가에 있습니다. 이러한 기능을 검색하면 수만 개의 PHP 파일을 더 자세히 검사해야하는 상대적으로 작은 스크립트 집합으로 더 빨리 좁힐 수 있습니다.
예를 들어, 다음 중 하나가 악의적 인 (또는 끔찍한 코딩) 것으로 간주됩니다.
<? eval($_GET['cmd']); ?>
<? system($_GET['cmd']); ?>
<? preg_replace('/.*/e',$_POST['code']); ?>
기타 등등.
저번에 손상된 웹 사이트를 통해 검색, 내가 인식하지 않았기 때문에 악성 코드의 조각 통지를하지 않았 preg_replace
의 사용으로 위험 할 수있는 /e
플래그 ( 진지 왜 심지어 거기이다 ?). 내가 놓친 다른 사람이 있습니까?
지금까지 내 목록은 다음과 같습니다.
쉘 실행
system
exec
popen
backtick operator
pcntl_exec
PHP 실행
eval
preg_replace
(/e
수정 자 포함)create_function
include
[_once
] /require
[_once
] ( 취약 세부 사항 은 마리오의 답변 참조)
파일을 수정할 수있는 함수 목록을 갖는 것이 유용 할 수도 있지만 시간 익스플로잇 코드의 99 %에 위의 함수 중 하나 이상이 포함되어 있다고 생각합니다. 그러나 파일을 편집하거나 출력 할 수있는 모든 기능 목록이 있으면 게시하고 여기에 포함시킵니다. (그리고 그것은 mysql_execute
다른 클래스의 악용의 일부이므로 계산하지 않습니다 .)
이 목록을 작성하기 위해 두 가지 소스를 사용했습니다. 스칼렛 과 RATS에 관한 연구 . 나는 또한 내 자신의 일부를 믹스에 추가 했으며이 스레드의 사람들이 도움을주었습니다.
편집 : 이 목록을 게시 한 후 RIPS 설립자에게 연락했으며 현재이 도구는이 목록의 모든 기능을 사용하기 위해 PHP 코드를 검색합니다.
이러한 함수 호출의 대부분은 싱크로 분류됩니다. 오염 된 변수 (예 : $ _REQUEST)가 싱크 함수로 전달되면 취약점이있는 것입니다. 같은 프로그램 RATS 와 입술은 응용 프로그램에서 모든 싱크를 식별하는 기능과 같은 GREP 사용합니다. 이는 프로그래머가 이러한 기능을 사용할 때 특별한주의를 기울여야한다는 것을 의미하지만, 모든 기능이 금지 된 경우에는 많은 작업을 수행 할 수 없습니다.
" 큰 힘으로 큰 책임이 따른다. "
-스탠 리
명령 실행
exec - Returns last line of commands output
passthru - Passes commands output directly to the browser
system - Passes commands output directly to the browser and returns last line
shell_exec - Returns commands output
`` (backticks) - Same as shell_exec()
popen - Opens read or write pipe to process of a command
proc_open - Similar to popen() but greater degree of control
pcntl_exec - Executes a program
PHP 코드 실행
그렇다에서 eval
PHP 코드를 실행할 수있는 다른 방법이 있습니다 : include
/이 require
의 형태로 원격 코드 실행을 위해 사용할 수있는 로컬 파일이 포함 및 원격 파일 포함 취약점을.
eval()
assert() - identical to eval()
preg_replace('/.*/e',...) - /e does an eval() on the match
create_function()
include()
include_once()
require()
require_once()
$_GET['func_name']($_GET['argument']);
$func = new ReflectionFunction($_GET['func_name']); $func->invoke(); or $func->invokeArgs(array());
콜백을 허용하는 함수 목록
이러한 함수는 공격자가 선택한 함수를 호출하는 데 사용할 수있는 문자열 매개 변수를 허용합니다. 기능에 따라 공격자는 매개 변수를 전달할 수 있거나 없을 수 있습니다. 이 경우 Information Disclosure
와 같은 기능을 사용할 phpinfo()
수 있습니다.
Function => Position of callback arguments
'ob_start' => 0,
'array_diff_uassoc' => -1,
'array_diff_ukey' => -1,
'array_filter' => 1,
'array_intersect_uassoc' => -1,
'array_intersect_ukey' => -1,
'array_map' => 0,
'array_reduce' => 1,
'array_udiff_assoc' => -1,
'array_udiff_uassoc' => array(-1, -2),
'array_udiff' => -1,
'array_uintersect_assoc' => -1,
'array_uintersect_uassoc' => array(-1, -2),
'array_uintersect' => -1,
'array_walk_recursive' => 1,
'array_walk' => 1,
'assert_options' => 1,
'uasort' => 1,
'uksort' => 1,
'usort' => 1,
'preg_replace_callback' => 1,
'spl_autoload_register' => 0,
'iterator_apply' => 1,
'call_user_func' => 0,
'call_user_func_array' => 0,
'register_shutdown_function' => 0,
'register_tick_function' => 0,
'set_error_handler' => 0,
'set_exception_handler' => 0,
'session_set_save_handler' => array(0, 1, 2, 3, 4, 5),
'sqlite_create_aggregate' => array(2, 3),
'sqlite_create_function' => 2,
정보 공개
이러한 함수 호출의 대부분은 싱크가 아닙니다. 그러나 반환 된 데이터를 공격자가 볼 수있는 경우 취약점 일 수 있습니다. 침입자가이를 볼 수 있다면 phpinfo()
분명히 취약점입니다.
phpinfo
posix_mkfifo
posix_getlogin
posix_ttyname
getenv
get_current_user
proc_get_status
get_cfg_var
disk_free_space
disk_total_space
diskfreespace
getcwd
getlastmo
getmygid
getmyinode
getmypid
getmyuid
다른
extract - Opens the door for register_globals attacks (see study in scarlet).
parse_str - works like extract if only one argument is given.
putenv
ini_set
mail - has CRLF injection in the 3rd parameter, opens the door for spam.
header - on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area.
proc_nice
proc_terminate
proc_close
pfsockopen
fsockopen
apache_child_terminate
posix_kill
posix_mkfifo
posix_setpgid
posix_setsid
posix_setuid
파일 시스템 함수
RATS에 따르면 PHP의 모든 파일 시스템 함수 는 불쾌합니다. 이 중 일부는 공격자에게 유용하지 않은 것 같습니다. 다른 것들은 생각보다 유용합니다. 예를 들어 allow_url_fopen=On
, URL을 파일 경로 copy($_GET['s'], $_GET['d']);
로 사용할 수 있으므로 호출을 사용하여 시스템의 어느 곳에서나 PHP 스크립트를 업로드 할 수 있습니다. 또한 사이트가 GET을 통한 요청 전송에 취약한 경우 해당 파일 시스템 기능의 모든 사용자가 서버를 통해 다른 호스트를 채널로 공격하고 공격 할 수 있습니다.
// open filesystem handler
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
// write to filesystem (partially in combination with reading)
chgrp
chmod
chown
copy
file_put_contents
lchgrp
lchown
link
mkdir
move_uploaded_file
rename
rmdir
symlink
tempnam
touch
unlink
imagepng - 2nd parameter is a path.
imagewbmp - 2nd parameter is a path.
image2wbmp - 2nd parameter is a path.
imagejpeg - 2nd parameter is a path.
imagexbm - 2nd parameter is a path.
imagegif - 2nd parameter is a path.
imagegd - 2nd parameter is a path.
imagegd2 - 2nd parameter is a path.
iptcembed
ftp_get
ftp_nb_get
// read from filesystem
file_exists
file_get_contents
file
fileatime
filectime
filegroup
fileinode
filemtime
fileowner
fileperms
filesize
filetype
glob
is_dir
is_executable
is_file
is_link
is_readable
is_uploaded_file
is_writable
is_writeable
linkinfo
lstat
parse_ini_file
pathinfo
readfile
readlink
realpath
stat
gzfile
readgzfile
getimagesize
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
ftp_put
ftp_nb_put
exif_read_data
read_exif_data
exif_thumbnail
exif_imagetype
hash_file
hash_hmac_file
hash_update_file
md5_file
sha1_file
highlight_file
show_source
php_strip_whitespace
get_meta_tags
include ($ tmp) 및 require (HTTP_REFERER) 및 * _once를 스캔해야합니다. 익스플로잇 스크립트가 임시 파일에 쓸 수 있으면 나중에이를 포함 할 수 있습니다. 기본적으로 2 단계 평가입니다.
다음과 같은 해결 방법으로 원격 코드를 숨길 수도 있습니다.
include("data:text/plain;base64,$_GET[code]");
또한 웹 서버가 이미 손상된 경우 항상 인코딩되지 않은 악을 볼 수는 없습니다. 익스플로잇 셸은 종종 gzip으로 인코딩됩니다. include("zlib:script2.png.gz");
여기서도 평가가 없다고 생각 하십시오. 여전히 동일한 효과입니다.
이것은 그 자체로 답은 아니지만 흥미로운 점이 있습니다.
$y = str_replace('z', 'e', 'zxzc');
$y("malicious code");
같은 방식으로 call_user_func_array()
난독 처리 된 기능을 실행하는 데 사용할 수 있습니다.
나는 아무도 언급했다 놀라게하지거야 echo
및 print
보안 착취의 점으로.
XSS (Cross-Site Scripting) 는 서버 측 코드 실행 익스플로잇보다 훨씬 일반적이기 때문에 심각한 보안 익스플로잇입니다.
특히이 목록에 unserialize ()를 추가하고 싶습니다. 임의 코드 실행, 서비스 거부 및 메모리 정보 유출을 포함하여 다양한 취약점의 오랜 역사를 가지고 있습니다. 사용자 제공 데이터에서 호출해서는 안됩니다. 이 vul들 중 다수는 지난 이슬에 걸쳐 릴리스에서 수정되었지만, 현재 글을 쓰는 시점에서 여전히 끔찍한 vulcans 몇 개를 유지합니다.
dodgy php 함수 / 사용법에 대한 다른 정보는 강화 된 PHP 프로젝트 와 그 조언을 살펴보십시오 . 최근 의 PHP 보안 월 및 2007 PHP 의 월 버그 프로젝트
또한 의도적으로 객체를 직렬화 해제하면 생성자 및 소멸자 함수가 실행됩니다. 사용자가 제공 한 데이터를 호출하지 않는 또 다른 이유.
내 VPS가 다음 기능을 비활성화하도록 설정되어 있습니다.
root@vps [~]# grep disable_functions /usr/local/lib/php.ini
disable_functions = dl, exec, shell_exec, system, passthru, popen, pclose, proc_open, proc_nice, proc_terminate, proc_get_status, proc_close, pfsockopen, leak, apache_child_terminate, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid
PHP에는 잠재적으로 파괴 가능한 함수가 충분하므로 목록이 너무 커서 grep하기가 어려울 수 있습니다. 예를 들어, PHP에는 chmod와 chown이 있으며 이는 단순히 웹 사이트를 비활성화하는 데 사용될 수 있습니다.
편집 : 아마도 위험으로 분류 된 기능 배열 (악한 기능, 더 나쁜 기능, 절대 사용해서는 안되는 기능)으로 파일을 검색 한 다음 bash 스크립트를 작성하여 위험의 상대성 계산을 원할 수 있습니다. 파일이 백분율로 부과됩니다. 그런 다음이 값을 30 % 위험 임계 값보다 큰 경우 각 파일 옆에 태그가 지정된 백분율로 디렉토리 트리에 출력하십시오.
또한 임의의 메모리 위치를 읽고 쓸 수있는 "중단 취약성"클래스를 알고 있어야합니다!
이들은 trim (), rtrim (), ltrim (), explode (), strchr (), strstr (), substr (), chunk_split (), strtok (), addcslashes (), str_repeat () 등의 함수에 영향을줍니다. . 이는 10 년 동안 사용되지 않지만 비활성화되지 않은 언어의 호출 시간 기준 통과 기능으로 인한 것이지만 대부분은 아닙니다.
자세한 내용은 BlackHat USA 2009 슬라이드 용지 에서 중단 취약점 및 기타 하위 수준 PHP 문제에 대한 Stefan Esser의 이야기를 참조하십시오.
이 백서 / 표현은 또한 dl ()을 사용하여 임의의 시스템 코드를 실행하는 방법을 보여줍니다.
플랫폼 별이지만 이론적 인 exec 벡터 :
- dotnet_load ()
- 새로운 COM ( "WScript.Shell")
- 새로운 Java ( "java.lang.Runtime")
- event_new ()-매우 결국
그리고 더 많은 위장 방법이 있습니다.
- proc_open은 popen의 별칭입니다.
- call_user_func_array ( "exE".chr (99), array ( "/ usr / bin / damage", "--all"));
- file_put_contents ( "/ cgi-bin / nextinvocation.cgi") && chmod (...)
- PharData :: setDefaultStub-.phar 파일의 코드를 검사하기위한 추가 작업
- runkit_function_rename ( "exec", "innocent_name") 또는 APD rename_function
eval
언어 구조 외에도 임의의 코드 실행을 허용하는 또 다른 함수가 있습니다.assert
assert('ex' . 'ec("kill --bill")');
흥미로운 악용 사례 중 하나는 언급되지 않았습니다. PHP는 문자열이 0x00
바이트 를 가질 수 있도록 합니다. 기본 (libc) 함수는 이것을 문자열의 끝으로 취급합니다.
이를 통해 다음과 같은 상황에서 PHP에서 (잘못 구현 된) 온 전성 검사를 속일 수있는 상황이 발생할 수 있습니다.
/// note: proof of principle code, don't use
$include = $_GET['file'];
if ( preg_match("/\\.php$/",$include) ) include($include);
여기에는 .php
전화로 끝나는 파일뿐만 아니라 모든 파일이 포함될 수 있습니다.script.php?file=somefile%00.php
따라서 PHP의 문자열 길이를 준수하지 않는 함수는 일부 취약점으로 이어질 수 있습니다.
위험한 구문 요소는 어떻습니까?
" 변수 변수 "( $$var
)는 $ var라는 이름으로 현재 범위에서 변수를 찾습니다. 잘못 사용하면 원격 사용자는 현재 범위의 변수를 수정하거나 읽을 수 있습니다. 기본적으로 약한 eval
.
예 : 일부 코드를 작성 $$uservar = 1;
하면 원격 사용자 $uservar
가 "admin" $admin
으로 설정되어 1
현재 범위에서 설정됩니다 .
소스 파일을 파싱하여 가능한 모든 익스플로잇을 찾을 수 없을 것 같습니다.
또한 여기에 정말 훌륭한 목록이 있다면 exploitet 될 수있는 기능을 놓칠 수 있습니다
여전히 이런 "숨겨진"악의 코드가있을 수 있습니다
$ myEvilRegex = base64_decode ( 'Ly4qL2U =');
preg_replace ($ myEvilRegex, $ _POST [ 'code']);
당신은 지금 말할 수 있습니다, 나는 단순히 이것과 일치하도록 스크립트를 확장합니다.
그러나 당신은 그 문맥에서 벗어난 "아마도 악의적 인 코드"를 갖게 될 것입니다
(의사) 안전하기 위해서는 실제로 좋은 코드를 작성 하고 모든 기존 코드를 직접 읽어야합니다.
PHP 매뉴얼의 Backtick Operator Backtick
알고 move_uploaded_file
있지만 파일 업로드는 일반적으로 매우 위험합니다. 의 존재는 $_FILES
약간의 우려를 제기해야합니다.
PHP 코드를 모든 유형의 파일에 포함시킬 수 있습니다. 텍스트 주석으로 인해 이미지가 특히 취약 할 수 있습니다. 코드가 $_FILES
데이터 에서 찾은 확장명을 그대로 받아들이면 문제가 특히 번거 롭습니다 .
예를 들어, 사용자는 포함 된 PHP 코드가 "foo.php"인 유효한 PNG 파일을 업로드 할 수 있습니다. 스크립트가 특히 순진한 경우 실제로 파일을 "/uploads/foo.php"로 복사 할 수 있습니다. 서버가 사용자 업로드 디렉토리에서 스크립트 실행을 허용하도록 구성된 경우 (종종 경우에는 끔찍한 감독) 임의의 PHP 코드를 즉시 실행할 수 있습니다. (이미지가 .png로 저장되어 있어도 다른 보안 결함을 통해 코드를 실행할 수 있습니다.)
업로드를 확인하기위한 (완전하지 않은) 항목 목록 :
- 업로드 내용이 주장하는 유형인지 확인하기 위해 내용을 분석하십시오
- 절대로 실행되지 않는 알려진 안전한 파일 확장명으로 파일을 저장하십시오.
- 사용자 업로드 디렉토리에서 PHP (및 기타 코드 실행)가 비활성화되어 있는지 확인하십시오.
pcntl_signal
와 pcntl_alarm
목록에 추가합시다 .
이러한 함수의 도움으로 php.ini 또는 스크립트에서 생성 된 set_time_limit 제한을 해결할 수 있습니다.
예를 들어이 스크립트는 set_time_limit(1);
(크레딧은 Sebastian Bergmanns 짹짹 과 요지에 간다 :
<?php
declare(ticks = 1);
set_time_limit(1);
function foo() {
for (;;) {}
}
class Invoker_TimeoutException extends RuntimeException {}
class Invoker
{
public function invoke($callable, $timeout)
{
pcntl_signal(SIGALRM, function() { throw new Invoker_TimeoutException; }, TRUE);
pcntl_alarm($timeout);
call_user_func($callable);
}
}
try {
$invoker = new Invoker;
$invoker->invoke('foo', 1);
} catch (Exception $e) {
sleep(10);
echo "Still running despite of the timelimit";
}
PHP.ini 파일의 설정으로 비활성화 할 수있는 많은 PHP 익스플로잇이 있습니다. 명백한 예는 register_globals이지만 설정에 따라 HTTP를 통해 원격 시스템의 파일을 포함하거나 열 수도 있습니다. 프로그램이 include () 또는 파일 처리 함수에 변수 파일 이름을 사용하는 경우 악용 될 수 있습니다.
또한 PHP는 변수 이름 끝에 ()를 추가하여 변수 함수 호출을 허용합니다. 예를 들어 $myvariable();
변수로 지정된 함수 이름을 호출합니다. 이것은 악용 될 수 있습니다. 예를 들어 공격자가 'eval'이라는 단어를 포함하도록 변수를 가져 와서 매개 변수를 제어 할 수 있으면 프로그램에 실제로 eval () 함수가 포함되어 있지 않더라도 원하는 것은 무엇이든 할 수 있습니다.
이러한 기능은 일부 불쾌한 영향을 줄 수 있습니다.
str_repeat()
unserialize()
register_tick_function()
register_shutdown_function()
처음 두 개는 사용 가능한 모든 메모리를 소진하고 후자는 고갈을 계속합니다 ...
최근 security.stackexchange.com 에서 이에 대한 논의가있었습니다.
임의 코드 실행에 사용할 수있는 함수
글쎄, 그것은 범위를 약간 줄입니다. 그러나 'print'는 자바 스크립트를 주입하는 데 사용될 수 있기 때문에 (따라서 세션을 훔치는 등) 여전히 임의적입니다.
블랙리스트에 올리거나 허용되지 않아야하는 기능을 나열하지 않습니다. 오히려 grep-able 목록을 갖고 싶습니다
합리적인 접근 방식입니다.
그래도 자신의 파서를 작성하는 것을 고려하십시오-곧 당신은 grep 기반 접근법을 통제 할 수 없게 될 것입니다 (awk가 조금 나을 것입니다). 머지 않아 화이트리스트도 구현했으면 좋겠다.
명백한 것 외에도 문자열 리터럴 이외의 인수로 포함하는 모든 것을 플래그 지정하는 것이 좋습니다. __autoload ()도 조심하십시오.
내 대답이 너무 부정적 일지 모르겠지만 ...
IMHO, 모든 단일 기능 및 방법은 사악한 목적으로 사용될 수 있습니다. 변수를 사용자 또는 원격 입력에 할당하고 변수를 함수에 사용하며 클래스 속성에 사용 된 함수 반환 값, 파일 함수에 사용 된 클래스 속성, 기타 등등. 위조 된 IP 주소 또는 중간자 공격은 전체 웹 사이트를 악용 할 수 있습니다.
가장 좋은 건에서 시작, 가능한 모든 사용자 또는 원격 입력을 처음부터 끝까지 추적하는 것입니다 $_SERVER
, $_GET
, $_POST
, $_FILE
, $_COOKIE
, include(some remote file)
( 경우 allow_url_fopen
에), 당신은 프로그래밍 방식으로 스택 트레이스 프로파일을 구축 등 원격 파일을 다루는 다른 모든 기능 / 클래스 각 사용자 또는 원격 제공 값. 이것은 할당 된 변수와 함수 또는 메소드의 모든 반복 인스턴스를 얻은 다음 해당 함수 / 메소드의 모든 발생 목록을 재귀 적으로 컴파일하여 프로그래밍 방식으로 수행 할 수 있습니다. 먼저 다른 모든 기능과 관련하여 적절한 필터링 및 유효성 검사 기능을 수행하는지 확인하십시오. 이것은 물론 수동 검사입니다. 그렇지 않으면 총 수case
PHP의 함수 및 메소드 수와 동일한 스위치 (사용자 정의 포함).
또는 사용자 입력 만 처리하려면 1) 허용 된 목적의 화이트리스트에 대해 모든 사용자 제공 입력 값을 확인하고 저장하는 모든 스크립트 의 시작 부분에서 정적 컨트롤러 클래스를 초기화하십시오 . 2) 입력 소스를 지 웁니다 (예 :) $_SERVER = null
. 이것이 나지 스크가 작은 곳을 볼 수 있습니다.
다음은 보안을 위해 공급자가 비활성화 한 기능 목록입니다.
- exec
- dl
- show_source
- apache_note
- apache_setenv
- closelog
- 디버거
- 디버거
- define_syslog_variables
- 탈출
- escapeshellcmd
- ini_restore
- 오픈 로그
- 경유
- 폐쇄
- pcntl_exec
- 교황
- proc_close
- proc_get_status
- proc_nice
- proc_open
- proc_terminate
- shell_exec
- syslog
- 체계
- url_exec
코드에서 대부분의 공격은 여러 액세스 소스 또는 여러 단계를 사용하여 자체적으로 실행됩니다. 코드 또는 악성 코드가있는 메소드뿐만 아니라 모든 메소드, 함수 실행 또는 호출을 검색합니다. 최상의 보안은 양식 데이터가 들어오고 나올 때 인코딩 및 유효성 검사를 포함합니다.
또한 시스템 변수를 정의 할 때 코드의 함수 나 메소드에서 호출 할 수 있습니다.
텍스트를 해석하는 4 비트 문자 기능을 사용하여 여러 버퍼 오버 플로우가 발견되었습니다. htmlentities () htmlspecialchars ()
해석에 앞서 mb_convert_encoding ()을 사용하여 단일 인코딩으로 변환하는 것이 좋습니다.
지속적으로 업데이트되는 민감한 싱크 목록 (탐색 가능한 PHP 기능) 및 해당 매개 변수를 찾을 수 있습니다. PHP 백도어를 탐지하는 PHP 응용 프로그램의 취약점에 대한 정적 소스 코드 분석기 인 RIPS /config/sinks.php .
참고 URL : https://stackoverflow.com/questions/3115559/exploitable-php-functions
'Programing' 카테고리의 다른 글
별도의 자바 스크립트 파일이없는 웹 작업자? (0) | 2020.03.24 |
---|---|
Thrift와 프로토콜 버퍼의 가장 큰 차이점은 무엇입니까? (0) | 2020.03.24 |
Java에서 Sprintf에 해당 (0) | 2020.03.24 |
인증 및 세션 관리를위한 SPA 모범 사례 (0) | 2020.03.24 |
Go에서 구성을 처리하는 방법 (0) | 2020.03.24 |